This revision was automatically updated to reflect the committed changes. Closed by commit rG9d0b55f0e4ca: [clang][ASTImporter] Fix import of typedef with unnamed structures (authored by balazske).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D145868/new/ https://reviews.llvm.org/D145868 Files: clang/lib/AST/ASTImporter.cpp clang/unittests/AST/ASTImporterTest.cpp Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -8576,6 +8576,69 @@ Typedef2->getUnderlyingType().getTypePtr()); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportExistingTypedefToUnnamedRecordPtr) { + const char *Code = + R"( + typedef const struct { int fff; } * const T; + extern T x; + )"; + Decl *ToTU = getToTuDecl(Code, Lang_C99); + Decl *FromTU = getTuDecl(Code, Lang_C99); + + auto *FromX = + FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x"))); + auto *ToX = Import(FromX, Lang_C99); + EXPECT_TRUE(ToX); + + auto *Typedef1 = + FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); + auto *Typedef2 = + LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); + // FIXME: These should be imported separately, like in the test above. + // Or: In the test above these should be merged too. + EXPECT_EQ(Typedef1, Typedef2); + + auto *FromR = FirstDeclMatcher<RecordDecl>().match( + FromTU, recordDecl(hasDescendant(fieldDecl(hasName("fff"))))); + auto *ToRExisting = FirstDeclMatcher<RecordDecl>().match( + ToTU, recordDecl(hasDescendant(fieldDecl(hasName("fff"))))); + ASSERT_TRUE(FromR); + auto *ToRImported = Import(FromR, Lang_C99); + // FIXME: If typedefs are not imported separately, do not import ToRImported + // separately. + EXPECT_NE(ToRExisting, ToRImported); +} + +TEST_P(ASTImporterOptionSpecificTestBase, + ImportTypedefWithDifferentUnderlyingType) { + const char *Code = + R"( + using X1 = int; + using Y1 = int; + + using RPB1 = X1*; + typedef RPB1 RPX1; + using RPB1 = Y1*; // redeclared + typedef RPB1 RPY1; + + auto X = 0 ? (RPX1){} : (RPY1){}; + )"; + Decl *ToTU = getToTuDecl("", Lang_CXX11); + Decl *FromTU = getTuDecl(Code, Lang_CXX11); + + auto *FromX = + FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("X"))); + + auto *FromXType = FromX->getType()->getAs<TypedefType>(); + EXPECT_FALSE(FromXType->typeMatchesDecl()); + + auto *ToX = Import(FromX, Lang_CXX11); + auto *ToXType = ToX->getType()->getAs<TypedefType>(); + // FIXME: This should be false. + EXPECT_TRUE(ToXType->typeMatchesDecl()); +} + INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions); Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -1365,12 +1365,16 @@ Expected<TypedefNameDecl *> ToDeclOrErr = import(T->getDecl()); if (!ToDeclOrErr) return ToDeclOrErr.takeError(); + + TypedefNameDecl *ToDecl = *ToDeclOrErr; + if (ToDecl->getTypeForDecl()) + return QualType(ToDecl->getTypeForDecl(), 0); + ExpectedType ToUnderlyingTypeOrErr = import(T->desugar()); if (!ToUnderlyingTypeOrErr) return ToUnderlyingTypeOrErr.takeError(); - return Importer.getToContext().getTypedefType(*ToDeclOrErr, - *ToUnderlyingTypeOrErr); + return Importer.getToContext().getTypedefType(ToDecl, *ToUnderlyingTypeOrErr); } ExpectedType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -8576,6 +8576,69 @@ Typedef2->getUnderlyingType().getTypePtr()); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportExistingTypedefToUnnamedRecordPtr) { + const char *Code = + R"( + typedef const struct { int fff; } * const T; + extern T x; + )"; + Decl *ToTU = getToTuDecl(Code, Lang_C99); + Decl *FromTU = getTuDecl(Code, Lang_C99); + + auto *FromX = + FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x"))); + auto *ToX = Import(FromX, Lang_C99); + EXPECT_TRUE(ToX); + + auto *Typedef1 = + FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); + auto *Typedef2 = + LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T"))); + // FIXME: These should be imported separately, like in the test above. + // Or: In the test above these should be merged too. + EXPECT_EQ(Typedef1, Typedef2); + + auto *FromR = FirstDeclMatcher<RecordDecl>().match( + FromTU, recordDecl(hasDescendant(fieldDecl(hasName("fff"))))); + auto *ToRExisting = FirstDeclMatcher<RecordDecl>().match( + ToTU, recordDecl(hasDescendant(fieldDecl(hasName("fff"))))); + ASSERT_TRUE(FromR); + auto *ToRImported = Import(FromR, Lang_C99); + // FIXME: If typedefs are not imported separately, do not import ToRImported + // separately. + EXPECT_NE(ToRExisting, ToRImported); +} + +TEST_P(ASTImporterOptionSpecificTestBase, + ImportTypedefWithDifferentUnderlyingType) { + const char *Code = + R"( + using X1 = int; + using Y1 = int; + + using RPB1 = X1*; + typedef RPB1 RPX1; + using RPB1 = Y1*; // redeclared + typedef RPB1 RPY1; + + auto X = 0 ? (RPX1){} : (RPY1){}; + )"; + Decl *ToTU = getToTuDecl("", Lang_CXX11); + Decl *FromTU = getTuDecl(Code, Lang_CXX11); + + auto *FromX = + FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("X"))); + + auto *FromXType = FromX->getType()->getAs<TypedefType>(); + EXPECT_FALSE(FromXType->typeMatchesDecl()); + + auto *ToX = Import(FromX, Lang_CXX11); + auto *ToXType = ToX->getType()->getAs<TypedefType>(); + // FIXME: This should be false. + EXPECT_TRUE(ToXType->typeMatchesDecl()); +} + INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions); Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -1365,12 +1365,16 @@ Expected<TypedefNameDecl *> ToDeclOrErr = import(T->getDecl()); if (!ToDeclOrErr) return ToDeclOrErr.takeError(); + + TypedefNameDecl *ToDecl = *ToDeclOrErr; + if (ToDecl->getTypeForDecl()) + return QualType(ToDecl->getTypeForDecl(), 0); + ExpectedType ToUnderlyingTypeOrErr = import(T->desugar()); if (!ToUnderlyingTypeOrErr) return ToUnderlyingTypeOrErr.takeError(); - return Importer.getToContext().getTypedefType(*ToDeclOrErr, - *ToUnderlyingTypeOrErr); + return Importer.getToContext().getTypedefType(ToDecl, *ToUnderlyingTypeOrErr); } ExpectedType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits