From c4a82438a7c530aaa3d94e5942355b788de525a2 Mon Sep 17 00:00:00 2001 From: DeLesley Hutchins Date: Mon, 30 Dec 2013 17:24:36 +0000 Subject: Update RecursiveASTVisitor so that it visits attributes. This is currently important for thread safety attributes, which contain expressions that were not being visited, and were thus invisible to various tools. There are now Visit*Attr methods that can be overridden for every attribute. llvm-svn: 198224 --- .../unittests/Tooling/RecursiveASTVisitorTest.cpp | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'clang/unittests') diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp index 323476766e9..cd5767bdfab 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -577,4 +577,43 @@ TEST(RecursiveASTVisitor, LambdaClosureTypesAreImplicit) { EXPECT_TRUE(Visitor.sawOnlyImplicitLambdaClasses()); } + + +// Check to ensure that attributes and expressions within them are being +// visited. +class AttrVisitor : public ExpectedLocationVisitor { +public: + bool VisitMemberExpr(MemberExpr *ME) { + Match(ME->getMemberDecl()->getNameAsString(), ME->getLocStart()); + return true; + } + bool VisitAttr(Attr *A) { + Match("Attr", A->getLocation()); + return true; + } + bool VisitGuardedByAttr(GuardedByAttr *A) { + Match("guarded_by", A->getLocation()); + return true; + } +}; + + +TEST(RecursiveASTVisitor, AttributesAreVisited) { + AttrVisitor Visitor; + Visitor.ExpectMatch("Attr", 4, 24); + Visitor.ExpectMatch("guarded_by", 4, 24); + Visitor.ExpectMatch("mu1", 4, 35); + Visitor.ExpectMatch("Attr", 5, 29); + Visitor.ExpectMatch("mu1", 5, 54); + Visitor.ExpectMatch("mu2", 5, 59); + EXPECT_TRUE(Visitor.runOver( + "class Foo {\n" + " int mu1;\n" + " int mu2;\n" + " int a __attribute__((guarded_by(mu1)));\n" + " void bar() __attribute__((exclusive_locks_required(mu1, mu2)));\n" + "};\n")); +} + + } // end namespace clang -- cgit v1.2.3