forked from OSchip/llvm-project
[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
This commit is contained in:
parent
48fad110e0
commit
b17f292010
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, );
|
||||
|
||||
|
|
Loading…
Reference in New Issue