Index: include/clang/AST/ASTImporter.h =================================================================== --- include/clang/AST/ASTImporter.h +++ include/clang/AST/ASTImporter.h @@ -41,6 +41,7 @@ class Stmt; class TagDecl; class TypeSourceInfo; +class Attr; /// \brief Imports selected nodes from one AST context into another context, /// merging AST nodes where appropriate. @@ -130,6 +131,13 @@ /// context, or NULL if an error occurred. TypeSourceInfo *Import(TypeSourceInfo *FromTSI); + /// \brief Import the given attribute from the "from" context into the + /// "to" context. + /// + /// \returns the equivalent attribute in the "to" context, or NULL if an + /// error occurred. + Attr *Import(Attr *FromAttr); + /// \brief Import the given declaration from the "from" context into the /// "to" context. /// Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2646,8 +2646,8 @@ Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), T, {NamedChain, D->getChainingSize()}); - for (const auto *Attr : D->attrs()) - ToIndirectField->addAttr(Attr->clone(Importer.getToContext())); + for (const auto *A : D->attrs()) + ToIndirectField->addAttr(Importer.Import(const_cast(A))); ToIndirectField->setAccess(D->getAccess()); ToIndirectField->setLexicalDeclContext(LexicalDC); @@ -4721,10 +4721,9 @@ SourceLocation ToAttrLoc = Importer.Import(S->getAttrLoc()); ArrayRef FromAttrs(S->getAttrs()); SmallVector ToAttrs(FromAttrs.size()); - ASTContext &_ToContext = Importer.getToContext(); std::transform(FromAttrs.begin(), FromAttrs.end(), ToAttrs.begin(), - [&_ToContext](const Attr *A) -> const Attr * { - return A->clone(_ToContext); + [this](const Attr *A) -> const Attr * { + return Importer.Import(const_cast(A)); }); for (const auto *ToA : ToAttrs) { if (!ToA) @@ -6544,6 +6543,15 @@ Import(FromTSI->getTypeLoc().getLocStart())); } +Attr *ASTImporter::Import(Attr *FromAttr) { + if (!FromAttr) + return nullptr; + + Attr *ToAttr = FromAttr->clone(ToContext); + ToAttr->setRange(Import(FromAttr->getRange())); + return ToAttr; +} + Decl *ASTImporter::GetAlreadyImportedOrNull(Decl *FromD) { llvm::DenseMap::iterator Pos = ImportedDecls.find(FromD); if (Pos != ImportedDecls.end()) { @@ -7200,7 +7208,7 @@ Decl *ASTImporter::Imported(Decl *From, Decl *To) { if (From->hasAttrs()) { for (auto *FromAttr : From->getAttrs()) - To->addAttr(FromAttr->clone(To->getASTContext())); + To->addAttr(Import(FromAttr)); } if (From->isUsed()) { To->setIsUsed(); Index: test/Import/attr/Inputs/S.cpp =================================================================== --- test/Import/attr/Inputs/S.cpp +++ test/Import/attr/Inputs/S.cpp @@ -0,0 +1,14 @@ +extern void f() __attribute__((const)); + +struct S +{ + struct { + int a __attribute__((packed)); + }; +}; + +void stmt() +{ + #pragma unroll + for (;;); +} Index: test/Import/attr/test.cpp =================================================================== --- test/Import/attr/test.cpp +++ test/Import/attr/test.cpp @@ -0,0 +1,26 @@ +// RUN: clang-import-test -dump-ast -import %S/Inputs/S.cpp -expression %s | FileCheck %s +// CHECK: FunctionDecl +// CHECK-SAME: S.cpp:1:1, col:13 +// CHECK-NEXT: ConstAttr +// CHECK-SAME: col:32 + +// CHECK: IndirectFieldDecl +// CHECK-NEXT: Field +// CHECK-NEXT: Field +// CHECK-NEXT: PackedAttr +// CHECK-SAME: col:30 + +// CHECK: AttributedStmt +// CHECK-NEXT: LoopHintAttr +// CHECK-SAME: line:12:13 + +extern void f() __attribute__((const)); + +struct S; + +void stmt(); + +void expr() { + f(); + struct S s; +}