Author: Raphael Isemann Date: 2020-01-02T14:47:04+01:00 New Revision: 7ead00872929a994ac40fc2c99fce15968e2c5a6
URL: https://github.com/llvm/llvm-project/commit/7ead00872929a994ac40fc2c99fce15968e2c5a6 DIFF: https://github.com/llvm/llvm-project/commit/7ead00872929a994ac40fc2c99fce15968e2c5a6.diff LOG: [lldb] Fix crash in AccessDeclContextSanity when copying FunctionTemplateDecl inside a record. Summary: We currently don't set access specifiers for function template declarations. This seems to be fine as long as the function template is not declared inside any record in which case Clang asserts with the following once we try to query it's access: ``` Assertion failed: (Access != AS_none && "Access specifier is AS_none inside a record decl"), function AccessDeclContextSanity, ``` This patch just marks these function template declarations as public to make Clang happy. Reviewers: shafik, teemperor Reviewed By: teemperor Subscribers: JDevlieghere, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D71909 Added: lldb/packages/Python/lldbsuite/test/commands/expression/regression-access-function-template-in-record/TestRegressionAccessFunctionTemplateInRecord.py lldb/packages/Python/lldbsuite/test/commands/expression/regression-access-function-template-in-record/main.cpp Modified: lldb/source/Symbol/ClangASTContext.cpp lldb/unittests/Symbol/TestClangASTContext.cpp Removed: lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash2/TestCompletionCrash2.py lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash2/main.cpp ################################################################################ diff --git a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash2/TestCompletionCrash2.py b/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash2/TestCompletionCrash2.py deleted file mode 100644 index 922347aa7810..000000000000 --- a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash2/TestCompletionCrash2.py +++ /dev/null @@ -1,4 +0,0 @@ -from lldbsuite.test import lldbinline -from lldbsuite.test import decorators - -lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIf(bugnumber="rdar://53754063")]) diff --git a/lldb/packages/Python/lldbsuite/test/commands/expression/regression-access-function-template-in-record/TestRegressionAccessFunctionTemplateInRecord.py b/lldb/packages/Python/lldbsuite/test/commands/expression/regression-access-function-template-in-record/TestRegressionAccessFunctionTemplateInRecord.py new file mode 100644 index 000000000000..f08c0dcbda98 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/expression/regression-access-function-template-in-record/TestRegressionAccessFunctionTemplateInRecord.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), []) diff --git a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash2/main.cpp b/lldb/packages/Python/lldbsuite/test/commands/expression/regression-access-function-template-in-record/main.cpp similarity index 100% rename from lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash2/main.cpp rename to lldb/packages/Python/lldbsuite/test/commands/expression/regression-access-function-template-in-record/main.cpp diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 4cf70fa9c1cb..99299c3c6c42 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -1340,6 +1340,11 @@ clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl( // TODO: verify which decl context we should put template_param_decls into.. template_param_decls[i]->setDeclContext(func_decl); } + // Function templates inside a record need to have an access specifier. + // It doesn't matter what access specifier we give the template as LLDB + // anyway allows accessing everything inside a record. + if (decl_ctx->isRecord()) + func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public); return func_tmpl_decl; } diff --git a/lldb/unittests/Symbol/TestClangASTContext.cpp b/lldb/unittests/Symbol/TestClangASTContext.cpp index 2cbd94982aa0..cea3a2912e30 100644 --- a/lldb/unittests/Symbol/TestClangASTContext.cpp +++ b/lldb/unittests/Symbol/TestClangASTContext.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/Symbol/ClangTestUtils.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Symbol/ClangASTContext.h" @@ -471,3 +472,51 @@ TEST_F(TestClangASTContext, TestGetTypeClassNested) { QualType t = ctxt.getTypeOfType(t_base); EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); } + +TEST_F(TestClangASTContext, TestFunctionTemplateConstruction) { + // Tests creating a function template. + + CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); + clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); + + // Prepare the declarations/types we need for the template. + CompilerType clang_type = + m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); + FunctionDecl *func = + m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false); + ClangASTContext::TemplateParameterInfos empty_params; + + // Create the actual function template. + clang::FunctionTemplateDecl *func_template = + m_ast->CreateFunctionTemplateDecl(TU, func, "foo", empty_params); + + EXPECT_EQ(TU, func_template->getDeclContext()); + EXPECT_EQ("foo", func_template->getName()); + EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess()); +} + +TEST_F(TestClangASTContext, TestFunctionTemplateInRecordConstruction) { + // Tests creating a function template inside a record. + + CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); + + // Create a record we can put the function template int. + CompilerType record_type = + clang_utils::createRecordWithField(*m_ast, "record", int_type, "field"); + clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type); + + // Prepare the declarations/types we need for the template. + CompilerType clang_type = + m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); + FunctionDecl *func = + m_ast->CreateFunctionDeclaration(record, "foo", clang_type, 0, false); + ClangASTContext::TemplateParameterInfos empty_params; + + // Create the actual function template. + clang::FunctionTemplateDecl *func_template = + m_ast->CreateFunctionTemplateDecl(record, func, "foo", empty_params); + + EXPECT_EQ(record, func_template->getDeclContext()); + EXPECT_EQ("foo", func_template->getName()); + EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess()); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits