[clang] b17f292 - [ASTImporter] Improved import of AlignedAttr.
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 28 00:43:05 PST 2020
Author: Balázs Kéri
Date: 2020-02-28T09:40:59+01:00
New Revision: b17f29201089131bf97de21606097e963ca8614d
URL: https://github.com/llvm/llvm-project/commit/b17f29201089131bf97de21606097e963ca8614d
DIFF: https://github.com/llvm/llvm-project/commit/b17f29201089131bf97de21606097e963ca8614d.diff
LOG: [ASTImporter] Improved import of AlignedAttr.
Summary:
It is not enough to clone the attributes at import.
They can contain reference to objects that should be imported.
This work is done now for AlignedAttr.
Reviewers: martong, a.sidorin, shafik
Reviewed By: shafik
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, teemperor, martong, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75048
Added:
Modified:
clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 066dd1b38c06..52288318337d 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7947,12 +7947,47 @@ Expected<TypeSourceInfo *> ASTImporter::Import(TypeSourceInfo *FromTSI) {
}
Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
- Attr *ToAttr = FromAttr->clone(ToContext);
- if (auto ToRangeOrErr = Import(FromAttr->getRange()))
- ToAttr->setRange(*ToRangeOrErr);
- else
- return ToRangeOrErr.takeError();
-
+ Attr *ToAttr = nullptr;
+ SourceRange ToRange;
+ if (Error Err = importInto(ToRange, FromAttr->getRange()))
+ return std::move(Err);
+
+ // FIXME: Is there some kind of AttrVisitor to use here?
+ switch (FromAttr->getKind()) {
+ case attr::Aligned: {
+ auto *From = cast<AlignedAttr>(FromAttr);
+ AlignedAttr *To;
+ auto CreateAlign = [&](bool IsAlignmentExpr, void *Alignment) {
+ return AlignedAttr::Create(ToContext, IsAlignmentExpr, Alignment, ToRange,
+ From->getSyntax(),
+ From->getSemanticSpelling());
+ };
+ if (From->isAlignmentExpr()) {
+ if (auto ToEOrErr = Import(From->getAlignmentExpr()))
+ To = CreateAlign(true, *ToEOrErr);
+ else
+ return ToEOrErr.takeError();
+ } else {
+ if (auto ToTOrErr = Import(From->getAlignmentType()))
+ To = CreateAlign(false, *ToTOrErr);
+ else
+ return ToTOrErr.takeError();
+ }
+ To->setInherited(From->isInherited());
+ To->setPackExpansion(From->isPackExpansion());
+ To->setImplicit(From->isImplicit());
+ ToAttr = To;
+ break;
+ }
+ default:
+ // FIXME: 'clone' copies every member but some of them should be imported.
+ // Handle other Attrs that have parameters that should be imported.
+ ToAttr = FromAttr->clone(ToContext);
+ ToAttr->setRange(ToRange);
+ break;
+ }
+ assert(ToAttr && "Attribute should be created.");
+
return ToAttr;
}
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 6c1d87823562..ea4a49a1c5cb 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -5887,6 +5887,41 @@ TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) {
EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1));
}
+TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) {
+ // Test if import of these packed and aligned attributes does not trigger an
+ // error situation where source location from 'From' context is referenced in
+ // 'To' context through evaluation of the alignof attribute.
+ // This happens if the 'alignof(A)' expression is not imported correctly.
+ Decl *FromTU = getTuDecl(
+ R"(
+ struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; };
+ struct alignas(alignof(A)) S {};
+ )",
+ Lang_CXX11, "input.cc");
+ auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
+ FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit())));
+ ASSERT_TRUE(FromD);
+
+ auto *ToD = Import(FromD, Lang_CXX11);
+ ASSERT_TRUE(ToD);
+
+ auto *FromAttr = FromD->getAttr<AlignedAttr>();
+ auto *ToAttr = ToD->getAttr<AlignedAttr>();
+ EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited());
+ EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion());
+ EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit());
+ EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax());
+ EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling());
+ EXPECT_TRUE(ToAttr->getAlignmentExpr());
+
+ auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match(
+ ToD->getTranslationUnitDecl(),
+ cxxRecordDecl(hasName("A"), unless(isImplicit())));
+ // Ensure that 'struct A' was imported (through reference from attribute of
+ // 'S').
+ EXPECT_TRUE(ToA);
+}
+
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions, );
More information about the cfe-commits
mailing list