diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index ba6eff49e9c98..baff90faa6eae 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -322,7 +322,7 @@ class ASTWalker : public RecursiveASTVisitor { } bool VisitCleanupAttr(CleanupAttr *attr) { - report(attr->getLocation(), attr->getFunctionDecl()); + report(attr->getArgLoc(), attr->getFunctionDecl()); return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index 19695a34bd63e..0de0b77f33daf 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -573,7 +573,7 @@ TEST(WalkAST, OperatorNewDelete) { TEST(WalkAST, CleanupAttr) { testWalk("void* $explicit^freep(void *p);", - "void foo() { __attribute__((^__cleanup__(freep))) char* x = 0; }"); + "void foo() { __attribute__((__cleanup__(^freep))) char* x = 0; }"); } } // namespace diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a6a7482a94a29..06462b8a26bc0 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1354,6 +1354,17 @@ def Cleanup : InheritableAttr { let Args = [DeclArgument]; let Subjects = SubjectList<[LocalVar]>; let Documentation = [CleanupDocs]; + // FIXME: DeclArgument should be reworked to also store the + // Expr instead of adding attr specific hacks like the following. + // See the discussion in https://github.com/llvm/llvm-project/pull/14023. + let AdditionalMembers = [{ +private: + SourceLocation ArgLoc; + +public: + void setArgLoc(const SourceLocation &Loc) { ArgLoc = Loc; } + auto getArgLoc() const { return ArgLoc; } + }]; } def CmseNSEntry : InheritableAttr, TargetSpecificAttr { @@ -4815,7 +4826,7 @@ def HLSLResourceBinding: InheritableAttr { void setImplicitBindingOrderID(uint32_t Value) { ImplicitBindingOrderID = Value; } - bool hasImplicitBindingOrderID() const { + bool hasImplicitBindingOrderID() const { return ImplicitBindingOrderID.has_value(); } uint32_t getImplicitBindingOrderID() const { diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4d7f0455444f1..ac77a7c2c58a5 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3620,7 +3620,9 @@ static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } - D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD)); + auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD); + attr->setArgLoc(E->getExprLoc()); + D->addAttr(attr); } static void handleEnumExtensibilityAttr(Sema &S, Decl *D,