[clang] 21cd04c - [clang][ASTImport] Add support for import of empty records
Pavel Kosov via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 20 07:35:34 PDT 2023
Author: Pavel Kosov
Date: 2023-03-20T17:33:04+03:00
New Revision: 21cd04c46fe0a2bee224899f56518a09bce5306e
URL: https://github.com/llvm/llvm-project/commit/21cd04c46fe0a2bee224899f56518a09bce5306e
DIFF: https://github.com/llvm/llvm-project/commit/21cd04c46fe0a2bee224899f56518a09bce5306e.diff
LOG: [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
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..7dd4c81074c76 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 = cast<CXXRecordDecl>(Import(FromD, Lang_CXX20));
+ EXPECT_EQ(true, ToD->isEmpty());
+ for (auto *FD : ToD->fields())
+ EXPECT_EQ(true, FD->hasAttr<NoUniqueAddressAttr>());
+}
+
INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions);
More information about the cfe-commits
mailing list