Author: Pavel Kosov Date: 2023-03-21T17:26:36+03:00 New Revision: 88e5206f2c96a34e23a4d63f0a38afb2db044f0a
URL: https://github.com/llvm/llvm-project/commit/88e5206f2c96a34e23a4d63f0a38afb2db044f0a DIFF: https://github.com/llvm/llvm-project/commit/88e5206f2c96a34e23a4d63f0a38afb2db044f0a.diff LOG: Reland [clang][ASTImport] Add support for import of empty records Patch represents the clang part of changes in D143347 Reviewed By: balazske Differential Revision: https://reviews.llvm.org/D145057 ~~ Huawei RRI, OS Lab Added: Modified: clang/include/clang/AST/ASTImporter.h clang/include/clang/AST/DeclCXX.h clang/lib/AST/ASTImporter.cpp clang/unittests/AST/ASTImporterTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h index f851decd0965c..4ffd913846575 100644 --- a/clang/include/clang/AST/ASTImporter.h +++ b/clang/include/clang/AST/ASTImporter.h @@ -258,6 +258,7 @@ class TypeSourceInfo; FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name); void AddToLookupTable(Decl *ToD); + llvm::Error ImportAttrs(Decl *ToD, Decl *FromD); protected: /// Can be overwritten by subclasses to implement their own import logic. diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index ff8f8a1bb12d6..dd35ef4adfd70 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1165,6 +1165,10 @@ class CXXRecordDecl : public RecordDecl { /// /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } + /// Marks this record as empty. This is used by DWARFASTParserClang + /// when parsing records with empty fields having [[no_unique_address]] + /// attribute + void markEmpty() { data().Empty = true; } void setInitMethod(bool Val) { data().HasInitMethod = Val; } bool hasInitMethod() const { return data().HasInitMethod; } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index bd055082778df..d0da2dae3aa23 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3895,6 +3895,12 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { D->getInClassInitStyle())) return ToField; + // We need [[no_unqiue_address]] attributes to be added to FieldDecl, before + // we add fields in CXXRecordDecl::addedMember, otherwise record will be + // marked as having non-zero size. + Err = Importer.ImportAttrs(ToField, D); + if (Err) + return std::move(Err); ToField->setAccess(D->getAccess()); ToField->setLexicalDeclContext(LexicalDC); if (ToInitializer) @@ -8981,6 +8987,19 @@ TranslationUnitDecl *ASTImporter::GetFromTU(Decl *ToD) { return FromDPos->second->getTranslationUnitDecl(); } +Error ASTImporter::ImportAttrs(Decl *ToD, Decl *FromD) { + if (!FromD->hasAttrs() || ToD->hasAttrs()) + return Error::success(); + for (const Attr *FromAttr : FromD->getAttrs()) { + auto ToAttrOrErr = Import(FromAttr); + if (ToAttrOrErr) + ToD->addAttr(*ToAttrOrErr); + else + return ToAttrOrErr.takeError(); + } + return Error::success(); +} + Expected<Decl *> ASTImporter::Import(Decl *FromD) { if (!FromD) return nullptr; @@ -9115,15 +9134,8 @@ Expected<Decl *> ASTImporter::Import(Decl *FromD) { // Make sure that ImportImpl registered the imported decl. assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?"); - - if (FromD->hasAttrs()) - for (const Attr *FromAttr : FromD->getAttrs()) { - auto ToAttrOrErr = Import(FromAttr); - if (ToAttrOrErr) - ToD->addAttr(*ToAttrOrErr); - else - return ToAttrOrErr.takeError(); - } + if (auto Error = ImportAttrs(ToD, FromD)) + return std::move(Error); // Notify subclasses. Imported(FromD, ToD); diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 6300551ca4469..95ff850860300 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -8478,6 +8478,29 @@ TEST_P(ASTImporterOptionSpecificTestBase, VaListCpp) { ToVaList->getUnderlyingType(), ToBuiltinVaList->getUnderlyingType())); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportDefinitionOfEmptyClassWithNoUniqueAddressField) { + Decl *FromTU = getTuDecl( + R"( + struct B {}; + struct A { B b; }; + )", + Lang_CXX20); + + CXXRecordDecl *FromD = FirstDeclMatcher<CXXRecordDecl>().match( + FromTU, cxxRecordDecl(hasName("A"))); + + for (auto *FD : FromD->fields()) + FD->addAttr(clang::NoUniqueAddressAttr::Create(FromD->getASTContext(), + clang::SourceRange())); + FromD->markEmpty(); + + CXXRecordDecl *ToD = Import(FromD, Lang_CXX20); + EXPECT_TRUE(ToD->isEmpty()); + for (auto *FD : ToD->fields()) + EXPECT_EQ(true, FD->hasAttr<NoUniqueAddressAttr>()); +} + INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits