From: Aleksei Sidorin Date: Tue, 8 May 2018 12:45:21 +0000 (+0000) Subject: [ASTImporter] Properly import SourceLocations of Attrs X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c03f8bb480be9ae467073e4c9ed3e60e313707f8;p=clang [ASTImporter] Properly import SourceLocations of Attrs Patch by Rafael Stahl! Differential Revision: https://reviews.llvm.org/D46115 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331762 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index 55e46eb201..280c4b2a3f 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -41,6 +41,7 @@ class NamedDecl; class Stmt; class TagDecl; class TypeSourceInfo; +class Attr; /// \brief Imports selected nodes from one AST context into another context, /// merging AST nodes where appropriate. @@ -126,6 +127,12 @@ class TypeSourceInfo; /// 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. + Attr *Import(const Attr *FromAttr); + /// \brief Import the given declaration from the "from" context into the /// "to" context. /// diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 66b596041f..ffe1762d67 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -2687,8 +2687,8 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { 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(A)); ToIndirectField->setAccess(D->getAccess()); ToIndirectField->setLexicalDeclContext(LexicalDC); @@ -4766,15 +4766,8 @@ Stmt *ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) { 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); - }); - for (const auto *ToA : ToAttrs) { - if (!ToA) - return nullptr; - } + if (ImportContainerChecked(FromAttrs, ToAttrs)) + return nullptr; Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); if (!ToSubStmt && S->getSubStmt()) return nullptr; @@ -6657,6 +6650,12 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) { Import(FromTSI->getTypeLoc().getLocStart())); } +Attr *ASTImporter::Import(const Attr *FromAttr) { + 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()) { @@ -7290,8 +7289,8 @@ void ASTImporter::CompleteDecl (Decl *D) { Decl *ASTImporter::Imported(Decl *From, Decl *To) { if (From->hasAttrs()) { - for (auto *FromAttr : From->getAttrs()) - To->addAttr(FromAttr->clone(To->getASTContext())); + for (const auto *FromAttr : From->getAttrs()) + To->addAttr(Import(FromAttr)); } if (From->isUsed()) { To->setIsUsed(); diff --git a/test/Import/attr/Inputs/S.cpp b/test/Import/attr/Inputs/S.cpp new file mode 100644 index 0000000000..28d70c544a --- /dev/null +++ b/test/Import/attr/Inputs/S.cpp @@ -0,0 +1,13 @@ +extern void f() __attribute__((const)); + +struct S { + struct { + int a __attribute__((packed)); + }; +}; + +void stmt() { +#pragma unroll + for (;;) + ; +} diff --git a/test/Import/attr/test.cpp b/test/Import/attr/test.cpp new file mode 100644 index 0000000000..01ea6c1b0e --- /dev/null +++ b/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:26 + +// CHECK: AttributedStmt +// CHECK-NEXT: LoopHintAttr +// CHECK-SAME: line:10:9 + +extern void f() __attribute__((const)); + +struct S; + +void stmt(); + +void expr() { + f(); + struct S s; +}