balazske updated this revision to Diff 505481. balazske added a comment. Added a simple test and another test. Instead of calling getTypeDeclType only the reuse of existing type is done (this was the part that fixes the problem). In this way the underlying type is still imported. The result is not correct but fixes some crash.
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 @@ -8549,6 +8549,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 @@ -1363,12 +1363,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 @@ -8549,6 +8549,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 @@ -1363,12 +1363,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