diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 24 | ||||
| -rw-r--r-- | clang/unittests/AST/ASTImporterTest.cpp | 41 |
2 files changed, 50 insertions, 15 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index b360b391063..38ad4e28931 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1147,15 +1147,21 @@ bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC, FunctionDecl *FunDecl; if (isa<RecordDecl>(D) && (FunDecl = dyn_cast<FunctionDecl>(OrigDC)) && FunDecl->hasBody()) { - SourceRange RecR = D->getSourceRange(); - SourceRange BodyR = FunDecl->getBody()->getSourceRange(); - // If RecordDecl is not in Body (it is a param), we bail out. - if (RecR.isValid() && BodyR.isValid() && - (RecR.getBegin() < BodyR.getBegin() || - BodyR.getEnd() < RecR.getEnd())) { - Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node) - << D->getDeclKindName(); - return true; + auto getLeafPointeeType = [](const Type *T) { + while (T->isPointerType() || T->isArrayType()) { + T = T->getPointeeOrArrayElementType(); + } + return T; + }; + for (const ParmVarDecl *P : FunDecl->parameters()) { + const Type *LeafT = + getLeafPointeeType(P->getType().getCanonicalType().getTypePtr()); + auto *RT = dyn_cast<RecordType>(LeafT); + if (RT && RT->getDecl() == D) { + Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node) + << D->getDeclKindName(); + return true; + } } } diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 21b76173c10..04006a0bea3 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -989,7 +989,7 @@ TEST_P(ASTImporterTestBase, ImportRecordTypeInFunc) { " return 0;" "}", Lang_C, "input.c"); - auto FromVar = + auto *FromVar = FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d"))); ASSERT_TRUE(FromVar); auto ToType = @@ -999,12 +999,41 @@ TEST_P(ASTImporterTestBase, ImportRecordTypeInFunc) { TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParams) { // This construct is not supported by ASTImporter. - Decl *FromTU = - getTuDecl("int declToImport(struct data_t{int a;int b;} *d){ return 0; }", - Lang_C, "input.c"); - auto From = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl()); + Decl *FromTU = getTuDecl( + "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }", + Lang_C, "input.c"); + auto *From = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("declToImport"))); + ASSERT_TRUE(From); + auto *To = Import(From, Lang_C); + EXPECT_EQ(To, nullptr); +} + +TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncFromMacro) { + Decl *FromTU = getTuDecl( + "#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n" + "int declToImport(){ return NONAME_SIZEOF(int); }", + Lang_C, "input.c"); + auto *From = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("declToImport"))); + ASSERT_TRUE(From); + auto *To = Import(From, Lang_C); + ASSERT_TRUE(To); + EXPECT_TRUE(MatchVerifier<FunctionDecl>().match( + To, functionDecl(hasName("declToImport"), + hasDescendant(unaryExprOrTypeTraitExpr())))); +} + +TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParamsFromMacro) { + // This construct is not supported by ASTImporter. + Decl *FromTU = getTuDecl( + "#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n" + "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }", + Lang_C, "input.c"); + auto *From = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("declToImport"))); ASSERT_TRUE(From); - auto To = Import(From, Lang_C); + auto *To = Import(From, Lang_C); EXPECT_EQ(To, nullptr); } |

