davezarzycki created this revision. davezarzycki added reviewers: arphaman, sberg, delesley, james.dennett, jdennett, klimek. Herald added a subscriber: mgorny.
RecursiveASTVisitorTest.cpp is one of the longest compile jobs and a build bottleneck on many-core machines. This patch breaks that file and some peer files up into smaller files to increase build concurrency and overall rebuild performance. Repository: rC Clang https://reviews.llvm.org/D45777 Files: Tooling/CMakeLists.txt Tooling/RecursiveASTVisitorTest.cpp Tooling/RecursiveASTVisitorTestExprVisitor.cpp Tooling/RecursiveASTVisitorTests/Attr.cpp Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp Tooling/RecursiveASTVisitorTests/Class.cpp Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp Tooling/RecursiveASTVisitorTests/ParenExpr.cpp Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp unittests/Tooling/RecursiveASTVisitorTestCallVisitor.cpp unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp
Index: Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp @@ -0,0 +1,40 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class TemplateArgumentLocTraverser + : public ExpectedLocationVisitor<TemplateArgumentLocTraverser> { +public: + bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { + std::string ArgStr; + llvm::raw_string_ostream Stream(ArgStr); + const TemplateArgument &Arg = ArgLoc.getArgument(); + + Arg.print(Context->getPrintingPolicy(), Stream); + Match(Stream.str(), ArgLoc.getLocation()); + return ExpectedLocationVisitor<TemplateArgumentLocTraverser>:: + TraverseTemplateArgumentLoc(ArgLoc); + } +}; + +TEST(RecursiveASTVisitor, VisitsClassTemplateTemplateParmDefaultArgument) { + TemplateArgumentLocTraverser Visitor; + Visitor.ExpectMatch("X", 2, 40); + EXPECT_TRUE(Visitor.runOver( + "template<typename T> class X;\n" + "template<template <typename> class T = X> class Y;\n" + "template<template <typename> class T> class Y {};\n")); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/ParenExpr.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/ParenExpr.cpp @@ -0,0 +1,30 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class ParenExprVisitor : public ExpectedLocationVisitor<ParenExprVisitor> { +public: + bool VisitParenExpr(ParenExpr *Parens) { + Match("", Parens->getExprLoc()); + return true; + } +}; + +TEST(RecursiveASTVisitor, VisitsParensDuringDataRecursion) { + ParenExprVisitor Visitor; + Visitor.ExpectMatch("", 1, 9); + EXPECT_TRUE(Visitor.runOver("int k = (4) + 9;\n")); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp @@ -0,0 +1,74 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +// Check to ensure that nested name specifiers are visited. +class NestedNameSpecifiersVisitor + : public ExpectedLocationVisitor<NestedNameSpecifiersVisitor> { +public: + bool VisitRecordTypeLoc(RecordTypeLoc RTL) { + if (!RTL) + return true; + Match(RTL.getDecl()->getName(), RTL.getNameLoc()); + return true; + } + + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { + if (!NNS) + return true; + if (const NamespaceDecl *ND = + NNS.getNestedNameSpecifier()->getAsNamespace()) + Match(ND->getName(), NNS.getLocalBeginLoc()); + return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); + } +}; + +TEST(RecursiveASTVisitor, + NestedNameSpecifiersForTemplateSpecializationsAreVisited) { + StringRef Source = R"( +namespace ns { +struct Outer { + template<typename T, typename U> + struct Nested { }; + + template<typename T> + static T x; +}; +} + +template<> +struct ns::Outer::Nested<int, int>; + +template<> +struct ns::Outer::Nested<int, int> { }; + +template<typename T> +struct ns::Outer::Nested<int, T> { }; + +template<> +int ns::Outer::x<int> = 0; +)"; + NestedNameSpecifiersVisitor Visitor; + Visitor.ExpectMatch("ns", 13, 8); + Visitor.ExpectMatch("ns", 16, 8); + Visitor.ExpectMatch("ns", 19, 8); + Visitor.ExpectMatch("ns", 22, 5); + Visitor.ExpectMatch("Outer", 13, 12); + Visitor.ExpectMatch("Outer", 16, 12); + Visitor.ExpectMatch("Outer", 19, 12); + Visitor.ExpectMatch("Outer", 22, 9); + EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp @@ -0,0 +1,63 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" +#include <stack> + +using namespace clang; + +namespace { + +class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> { +public: + bool VisitLambdaExpr(LambdaExpr *Lambda) { + PendingBodies.push(Lambda); + Match("", Lambda->getIntroducerRange().getBegin()); + return true; + } + /// For each call to VisitLambdaExpr, we expect a subsequent call (with + /// proper nesting) to TraverseLambdaBody. + bool TraverseLambdaBody(LambdaExpr *Lambda) { + EXPECT_FALSE(PendingBodies.empty()); + EXPECT_EQ(PendingBodies.top(), Lambda); + PendingBodies.pop(); + return TraverseStmt(Lambda->getBody()); + } + /// Determine whether TraverseLambdaBody has been called for every call to + /// VisitLambdaExpr. + bool allBodiesHaveBeenTraversed() const { + return PendingBodies.empty(); + } +private: + std::stack<LambdaExpr *> PendingBodies; +}; + +TEST(RecursiveASTVisitor, VisitsLambdaExpr) { + LambdaExprVisitor Visitor; + Visitor.ExpectMatch("", 1, 12); + EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", + LambdaExprVisitor::Lang_CXX11)); +} + +TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) { + LambdaExprVisitor Visitor; + EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", + LambdaExprVisitor::Lang_CXX11)); + EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); +} + +TEST(RecursiveASTVisitor, VisitsAttributedLambdaExpr) { + LambdaExprVisitor Visitor; + Visitor.ExpectMatch("", 1, 12); + EXPECT_TRUE(Visitor.runOver( + "void f() { [] () __attribute__ (( fastcall )) { return; }(); }", + LambdaExprVisitor::Lang_CXX14)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp @@ -0,0 +1,35 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +// Matches the (optional) capture-default of a lambda-introducer. +class LambdaDefaultCaptureVisitor + : public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> { +public: + bool VisitLambdaExpr(LambdaExpr *Lambda) { + if (Lambda->getCaptureDefault() != LCD_None) { + Match("", Lambda->getCaptureDefaultLoc()); + } + return true; + } +}; + +TEST(RecursiveASTVisitor, HasCaptureDefaultLoc) { + LambdaDefaultCaptureVisitor Visitor; + Visitor.ExpectMatch("", 1, 20); + EXPECT_TRUE(Visitor.runOver("void f() { int a; [=]{a;}; }", + LambdaDefaultCaptureVisitor::Lang_CXX11)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp @@ -0,0 +1,33 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +// Check to ensure that implicit default argument expressions are visited. +class IntegerLiteralVisitor + : public ExpectedLocationVisitor<IntegerLiteralVisitor> { +public: + bool VisitIntegerLiteral(const IntegerLiteral *IL) { + Match("literal", IL->getLocation()); + return true; + } +}; + +TEST(RecursiveASTVisitor, DefaultArgumentsAreVisited) { + IntegerLiteralVisitor Visitor; + Visitor.ExpectMatch("literal", 1, 15, 2); + EXPECT_TRUE(Visitor.runOver("int f(int i = 1);\n" + "static int k = f();\n")); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp @@ -0,0 +1,38 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class InitListExprPreOrderNoQueueVisitor + : public ExpectedLocationVisitor<InitListExprPreOrderNoQueueVisitor> { +public: + bool TraverseInitListExpr(InitListExpr *ILE) { + return ExpectedLocationVisitor::TraverseInitListExpr(ILE); + } + + bool VisitInitListExpr(InitListExpr *ILE) { + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + return true; + } +}; + +TEST(RecursiveASTVisitor, InitListExprIsPreOrderNoQueueVisitedTwice) { + InitListExprPreOrderNoQueueVisitor Visitor; + Visitor.ExpectMatch("syntactic", 2, 21); + Visitor.ExpectMatch("semantic", 2, 21); + EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" + "static struct S s = {.x = 0};\n", + InitListExprPreOrderNoQueueVisitor::Lang_C)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp @@ -0,0 +1,36 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +// Check to ensure that InitListExpr is visited twice, once each for the +// syntactic and semantic form. +class InitListExprPreOrderVisitor + : public ExpectedLocationVisitor<InitListExprPreOrderVisitor> { +public: + bool VisitInitListExpr(InitListExpr *ILE) { + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + return true; + } +}; + +TEST(RecursiveASTVisitor, InitListExprIsPreOrderVisitedTwice) { + InitListExprPreOrderVisitor Visitor; + Visitor.ExpectMatch("syntactic", 2, 21); + Visitor.ExpectMatch("semantic", 2, 21); + EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" + "static struct S s = {.x = 0};\n", + InitListExprPreOrderVisitor::Lang_C)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp @@ -0,0 +1,40 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class InitListExprPostOrderNoQueueVisitor + : public ExpectedLocationVisitor<InitListExprPostOrderNoQueueVisitor> { +public: + bool shouldTraversePostOrder() const { return true; } + + bool TraverseInitListExpr(InitListExpr *ILE) { + return ExpectedLocationVisitor::TraverseInitListExpr(ILE); + } + + bool VisitInitListExpr(InitListExpr *ILE) { + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + return true; + } +}; + +TEST(RecursiveASTVisitor, InitListExprIsPostOrderNoQueueVisitedTwice) { + InitListExprPostOrderNoQueueVisitor Visitor; + Visitor.ExpectMatch("syntactic", 2, 21); + Visitor.ExpectMatch("semantic", 2, 21); + EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" + "static struct S s = {.x = 0};\n", + InitListExprPostOrderNoQueueVisitor::Lang_C)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp @@ -0,0 +1,36 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp -==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class InitListExprPostOrderVisitor + : public ExpectedLocationVisitor<InitListExprPostOrderVisitor> { +public: + bool shouldTraversePostOrder() const { return true; } + + bool VisitInitListExpr(InitListExpr *ILE) { + Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); + return true; + } +}; + +TEST(RecursiveASTVisitor, InitListExprIsPostOrderVisitedTwice) { + InitListExprPostOrderVisitor Visitor; + Visitor.ExpectMatch("syntactic", 2, 21); + Visitor.ExpectMatch("semantic", 2, 21); + EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" + "static struct S s = {.x = 0};\n", + InitListExprPostOrderVisitor::Lang_C)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp @@ -0,0 +1,43 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +// A visitor that visits implicit declarations and matches constructors. +class ImplicitCtorVisitor + : public ExpectedLocationVisitor<ImplicitCtorVisitor> { +public: + bool shouldVisitImplicitCode() const { return true; } + + bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) { + if (Ctor->isImplicit()) { // Was not written in source code + if (const CXXRecordDecl* Class = Ctor->getParent()) { + Match(Class->getName(), Ctor->getLocation()); + } + } + return true; + } +}; + +TEST(RecursiveASTVisitor, VisitsImplicitCopyConstructors) { + ImplicitCtorVisitor Visitor; + Visitor.ExpectMatch("Simple", 2, 8); + // Note: Clang lazily instantiates implicit declarations, so we need + // to use them in order to force them to appear in the AST. + EXPECT_TRUE(Visitor.runOver( + "struct WithCtor { WithCtor(); }; \n" + "struct Simple { Simple(); WithCtor w; }; \n" + "int main() { Simple s; Simple t(s); }\n")); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp @@ -0,0 +1,125 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class DeclRefExprVisitor : public ExpectedLocationVisitor<DeclRefExprVisitor> { +public: + DeclRefExprVisitor() : ShouldVisitImplicitCode(false) {} + + bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } + + void setShouldVisitImplicitCode(bool NewValue) { + ShouldVisitImplicitCode = NewValue; + } + + bool VisitDeclRefExpr(DeclRefExpr *Reference) { + Match(Reference->getNameInfo().getAsString(), Reference->getLocation()); + return true; + } + +private: + bool ShouldVisitImplicitCode; +}; + +TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("x", 2, 3); + EXPECT_TRUE(Visitor.runOver( + "void x(); template <void (*T)()> class X {};\nX<x> y;")); +} + +TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("x", 2, 25); + Visitor.ExpectMatch("x", 2, 30); + EXPECT_TRUE(Visitor.runOver( + "int x[5];\n" + "void f() { for (int i : x) { x[0] = 1; } }", + DeclRefExprVisitor::Lang_CXX11)); +} + +TEST(RecursiveASTVisitor, VisitsCallExpr) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("x", 1, 22); + EXPECT_TRUE(Visitor.runOver( + "void x(); void y() { x(); }")); +} + +TEST(RecursiveASTVisitor, VisitsExplicitLambdaCaptureInit) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("i", 1, 20); + EXPECT_TRUE(Visitor.runOver( + "void f() { int i; [i]{}; }", + DeclRefExprVisitor::Lang_CXX11)); +} + +TEST(RecursiveASTVisitor, VisitsUseOfImplicitLambdaCapture) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("i", 1, 24); + EXPECT_TRUE(Visitor.runOver( + "void f() { int i; [=]{ i; }; }", + DeclRefExprVisitor::Lang_CXX11)); +} + +TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) { + DeclRefExprVisitor Visitor; + Visitor.setShouldVisitImplicitCode(true); + // We're expecting the "i" in the lambda to be visited twice: + // - Once for the DeclRefExpr in the lambda capture initialization (whose + // source code location is set to the first use of the variable). + // - Once for the DeclRefExpr for the use of "i" inside the lambda. + Visitor.ExpectMatch("i", 1, 24, /*Times=*/2); + EXPECT_TRUE(Visitor.runOver( + "void f() { int i; [=]{ i; }; }", + DeclRefExprVisitor::Lang_CXX11)); +} + +TEST(RecursiveASTVisitor, VisitsLambdaInitCaptureInit) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("i", 1, 24); + EXPECT_TRUE(Visitor.runOver( + "void f() { int i; [a = i + 1]{}; }", + DeclRefExprVisitor::Lang_CXX14)); +} + +/* FIXME: According to Richard Smith this is a bug in the AST. +TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("x", 3, 43); + EXPECT_TRUE(Visitor.runOver( + "template <typename T> void x();\n" + "template <void (*T)()> class X {};\n" + "template <typename T> class Y : public X< x<T> > {};\n" + "Y<int> y;")); +} +*/ + +TEST(RecursiveASTVisitor, VisitsExtension) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("s", 1, 24); + EXPECT_TRUE(Visitor.runOver( + "int s = __extension__ (s);\n")); +} + +TEST(RecursiveASTVisitor, VisitsCopyExprOfBlockDeclCapture) { + DeclRefExprVisitor Visitor; + Visitor.ExpectMatch("x", 3, 24); + EXPECT_TRUE(Visitor.runOver("void f(int(^)(int)); \n" + "void g() { \n" + " f([&](int x){ return x; }); \n" + "}", + DeclRefExprVisitor::Lang_OBJCXX11)); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp @@ -0,0 +1,76 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +/// \brief A visitor that optionally includes implicit code and matches +/// CXXConstructExpr. +/// +/// The name recorded for the match is the name of the class whose constructor +/// is invoked by the CXXConstructExpr, not the name of the class whose +/// constructor the CXXConstructExpr is contained in. +class ConstructExprVisitor + : public ExpectedLocationVisitor<ConstructExprVisitor> { +public: + ConstructExprVisitor() : ShouldVisitImplicitCode(false) {} + + bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } + + void setShouldVisitImplicitCode(bool NewValue) { + ShouldVisitImplicitCode = NewValue; + } + + bool VisitCXXConstructExpr(CXXConstructExpr* Expr) { + if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) { + if (const CXXRecordDecl* Class = Ctor->getParent()) { + Match(Class->getName(), Expr->getLocation()); + } + } + return true; + } + + private: + bool ShouldVisitImplicitCode; +}; + +TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) { + ConstructExprVisitor Visitor; + Visitor.setShouldVisitImplicitCode(true); + Visitor.ExpectMatch("WithCtor", 2, 8); + // Simple has a constructor that implicitly initializes 'w'. Test + // that a visitor that visits implicit code visits that initialization. + // Note: Clang lazily instantiates implicit declarations, so we need + // to use them in order to force them to appear in the AST. + EXPECT_TRUE(Visitor.runOver( + "struct WithCtor { WithCtor(); }; \n" + "struct Simple { WithCtor w; }; \n" + "int main() { Simple s; }\n")); +} + +// The same as CanVisitImplicitMemberInitializations, but checking that the +// visits are omitted when the visitor does not include implicit code. +TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) { + ConstructExprVisitor Visitor; + Visitor.setShouldVisitImplicitCode(false); + Visitor.DisallowMatch("WithCtor", 2, 8); + // Simple has a constructor that implicitly initializes 'w'. Test + // that a visitor that skips implicit code skips that initialization. + // Note: Clang lazily instantiates implicit declarations, so we need + // to use them in order to force them to appear in the AST. + EXPECT_TRUE(Visitor.runOver( + "struct WithCtor { WithCtor(); }; \n" + "struct Simple { WithCtor w; }; \n" + "int main() { Simple s; }\n")); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/Class.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/Class.cpp @@ -0,0 +1,41 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/Class.cpp ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +// Checks for lambda classes that are not marked as implicitly-generated. +// (There should be none.) +class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> { +public: + ClassVisitor() : SawNonImplicitLambdaClass(false) {} + bool VisitCXXRecordDecl(CXXRecordDecl* record) { + if (record->isLambda() && !record->isImplicit()) + SawNonImplicitLambdaClass = true; + return true; + } + + bool sawOnlyImplicitLambdaClasses() const { + return !SawNonImplicitLambdaClass; + } + +private: + bool SawNonImplicitLambdaClass; +}; + +TEST(RecursiveASTVisitor, LambdaClosureTypesAreImplicit) { + ClassVisitor Visitor; + EXPECT_TRUE(Visitor.runOver("auto lambda = []{};", ClassVisitor::Lang_CXX11)); + EXPECT_TRUE(Visitor.sawOnlyImplicitLambdaClasses()); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp @@ -0,0 +1,38 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class CXXOperatorCallExprTraverser + : public ExpectedLocationVisitor<CXXOperatorCallExprTraverser> { +public: + // Use Traverse, not Visit, to check that data recursion optimization isn't + // bypassing the call of this function. + bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { + Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc()); + return ExpectedLocationVisitor<CXXOperatorCallExprTraverser>:: + TraverseCXXOperatorCallExpr(CE); + } +}; + +TEST(RecursiveASTVisitor, TraversesOverloadedOperator) { + CXXOperatorCallExprTraverser Visitor; + Visitor.ExpectMatch("()", 4, 9); + EXPECT_TRUE(Visitor.runOver( + "struct A {\n" + " int operator()();\n" + "} a;\n" + "int k = a();\n")); +} + +} // end anonymous namespace Index: unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp =================================================================== --- unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp +++ unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp @@ -1,4 +1,4 @@ -//===- unittest/Tooling/RecursiveASTVisitorTestCallVisitor.cpp ------------===// +//===- unittest/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp --------===// // // The LLVM Compiler Infrastructure // @@ -95,26 +95,4 @@ "template void A::g(const A& a) const;\n")); } -class CXXOperatorCallExprTraverser - : public ExpectedLocationVisitor<CXXOperatorCallExprTraverser> { -public: - // Use Traverse, not Visit, to check that data recursion optimization isn't - // bypassing the call of this function. - bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { - Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc()); - return ExpectedLocationVisitor<CXXOperatorCallExprTraverser>:: - TraverseCXXOperatorCallExpr(CE); - } -}; - -TEST(RecursiveASTVisitor, TraversesOverloadedOperator) { - CXXOperatorCallExprTraverser Visitor; - Visitor.ExpectMatch("()", 4, 9); - EXPECT_TRUE(Visitor.runOver( - "struct A {\n" - " int operator()();\n" - "} a;\n" - "int k = a();\n")); -} - } // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp @@ -0,0 +1,37 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +class CXXBoolLiteralExprVisitor + : public ExpectedLocationVisitor<CXXBoolLiteralExprVisitor> { +public: + bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) { + if (BE->getValue()) + Match("true", BE->getLocation()); + else + Match("false", BE->getLocation()); + return true; + } +}; + +TEST(RecursiveASTVisitor, VisitsClassTemplateNonTypeParmDefaultArgument) { + CXXBoolLiteralExprVisitor Visitor; + Visitor.ExpectMatch("true", 2, 19); + EXPECT_TRUE(Visitor.runOver( + "template<bool B> class X;\n" + "template<bool B = true> class Y;\n" + "template<bool B> class Y {};\n")); +} + +} // end anonymous namespace Index: Tooling/RecursiveASTVisitorTests/Attr.cpp =================================================================== --- /dev/null +++ Tooling/RecursiveASTVisitorTests/Attr.cpp @@ -0,0 +1,52 @@ +//===- unittest/Tooling/RecursiveASTVisitorTests/Attr.cpp -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TestVisitor.h" + +using namespace clang; + +namespace { + +// Check to ensure that attributes and expressions within them are being +// visited. +class AttrVisitor : public ExpectedLocationVisitor<AttrVisitor> { +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 anonymous namespace Index: unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp =================================================================== --- unittests/Tooling/RecursiveASTVisitorTestExprVisitor.cpp +++ /dev/null @@ -1,271 +0,0 @@ -//===- unittest/Tooling/RecursiveASTVisitorTestExprVisitor.cpp ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "TestVisitor.h" - -using namespace clang; - -namespace { - -class ParenExprVisitor : public ExpectedLocationVisitor<ParenExprVisitor> { -public: - bool VisitParenExpr(ParenExpr *Parens) { - Match("", Parens->getExprLoc()); - return true; - } -}; - -TEST(RecursiveASTVisitor, VisitsParensDuringDataRecursion) { - ParenExprVisitor Visitor; - Visitor.ExpectMatch("", 1, 9); - EXPECT_TRUE(Visitor.runOver("int k = (4) + 9;\n")); -} - -class TemplateArgumentLocTraverser - : public ExpectedLocationVisitor<TemplateArgumentLocTraverser> { -public: - bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { - std::string ArgStr; - llvm::raw_string_ostream Stream(ArgStr); - const TemplateArgument &Arg = ArgLoc.getArgument(); - - Arg.print(Context->getPrintingPolicy(), Stream); - Match(Stream.str(), ArgLoc.getLocation()); - return ExpectedLocationVisitor<TemplateArgumentLocTraverser>:: - TraverseTemplateArgumentLoc(ArgLoc); - } -}; - -TEST(RecursiveASTVisitor, VisitsClassTemplateTemplateParmDefaultArgument) { - TemplateArgumentLocTraverser Visitor; - Visitor.ExpectMatch("X", 2, 40); - EXPECT_TRUE(Visitor.runOver( - "template<typename T> class X;\n" - "template<template <typename> class T = X> class Y;\n" - "template<template <typename> class T> class Y {};\n")); -} - -class CXXBoolLiteralExprVisitor - : public ExpectedLocationVisitor<CXXBoolLiteralExprVisitor> { -public: - bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) { - if (BE->getValue()) - Match("true", BE->getLocation()); - else - Match("false", BE->getLocation()); - return true; - } -}; - -TEST(RecursiveASTVisitor, VisitsClassTemplateNonTypeParmDefaultArgument) { - CXXBoolLiteralExprVisitor Visitor; - Visitor.ExpectMatch("true", 2, 19); - EXPECT_TRUE(Visitor.runOver( - "template<bool B> class X;\n" - "template<bool B = true> class Y;\n" - "template<bool B> class Y {};\n")); -} - -// A visitor that visits implicit declarations and matches constructors. -class ImplicitCtorVisitor - : public ExpectedLocationVisitor<ImplicitCtorVisitor> { -public: - bool shouldVisitImplicitCode() const { return true; } - - bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) { - if (Ctor->isImplicit()) { // Was not written in source code - if (const CXXRecordDecl* Class = Ctor->getParent()) { - Match(Class->getName(), Ctor->getLocation()); - } - } - return true; - } -}; - -TEST(RecursiveASTVisitor, VisitsImplicitCopyConstructors) { - ImplicitCtorVisitor Visitor; - Visitor.ExpectMatch("Simple", 2, 8); - // Note: Clang lazily instantiates implicit declarations, so we need - // to use them in order to force them to appear in the AST. - EXPECT_TRUE(Visitor.runOver( - "struct WithCtor { WithCtor(); }; \n" - "struct Simple { Simple(); WithCtor w; }; \n" - "int main() { Simple s; Simple t(s); }\n")); -} - -/// \brief A visitor that optionally includes implicit code and matches -/// CXXConstructExpr. -/// -/// The name recorded for the match is the name of the class whose constructor -/// is invoked by the CXXConstructExpr, not the name of the class whose -/// constructor the CXXConstructExpr is contained in. -class ConstructExprVisitor - : public ExpectedLocationVisitor<ConstructExprVisitor> { -public: - ConstructExprVisitor() : ShouldVisitImplicitCode(false) {} - - bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } - - void setShouldVisitImplicitCode(bool NewValue) { - ShouldVisitImplicitCode = NewValue; - } - - bool VisitCXXConstructExpr(CXXConstructExpr* Expr) { - if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) { - if (const CXXRecordDecl* Class = Ctor->getParent()) { - Match(Class->getName(), Expr->getLocation()); - } - } - return true; - } - - private: - bool ShouldVisitImplicitCode; -}; - -TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) { - ConstructExprVisitor Visitor; - Visitor.setShouldVisitImplicitCode(true); - Visitor.ExpectMatch("WithCtor", 2, 8); - // Simple has a constructor that implicitly initializes 'w'. Test - // that a visitor that visits implicit code visits that initialization. - // Note: Clang lazily instantiates implicit declarations, so we need - // to use them in order to force them to appear in the AST. - EXPECT_TRUE(Visitor.runOver( - "struct WithCtor { WithCtor(); }; \n" - "struct Simple { WithCtor w; }; \n" - "int main() { Simple s; }\n")); -} - -// The same as CanVisitImplicitMemberInitializations, but checking that the -// visits are omitted when the visitor does not include implicit code. -TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) { - ConstructExprVisitor Visitor; - Visitor.setShouldVisitImplicitCode(false); - Visitor.DisallowMatch("WithCtor", 2, 8); - // Simple has a constructor that implicitly initializes 'w'. Test - // that a visitor that skips implicit code skips that initialization. - // Note: Clang lazily instantiates implicit declarations, so we need - // to use them in order to force them to appear in the AST. - EXPECT_TRUE(Visitor.runOver( - "struct WithCtor { WithCtor(); }; \n" - "struct Simple { WithCtor w; }; \n" - "int main() { Simple s; }\n")); -} - -class DeclRefExprVisitor : public ExpectedLocationVisitor<DeclRefExprVisitor> { -public: - DeclRefExprVisitor() : ShouldVisitImplicitCode(false) {} - - bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } - - void setShouldVisitImplicitCode(bool NewValue) { - ShouldVisitImplicitCode = NewValue; - } - - bool VisitDeclRefExpr(DeclRefExpr *Reference) { - Match(Reference->getNameInfo().getAsString(), Reference->getLocation()); - return true; - } - -private: - bool ShouldVisitImplicitCode; -}; - -TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 2, 3); - EXPECT_TRUE(Visitor.runOver( - "void x(); template <void (*T)()> class X {};\nX<x> y;")); -} - -TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 2, 25); - Visitor.ExpectMatch("x", 2, 30); - EXPECT_TRUE(Visitor.runOver( - "int x[5];\n" - "void f() { for (int i : x) { x[0] = 1; } }", - DeclRefExprVisitor::Lang_CXX11)); -} - -TEST(RecursiveASTVisitor, VisitsCallExpr) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 1, 22); - EXPECT_TRUE(Visitor.runOver( - "void x(); void y() { x(); }")); -} - -TEST(RecursiveASTVisitor, VisitsExplicitLambdaCaptureInit) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("i", 1, 20); - EXPECT_TRUE(Visitor.runOver( - "void f() { int i; [i]{}; }", - DeclRefExprVisitor::Lang_CXX11)); -} - -TEST(RecursiveASTVisitor, VisitsUseOfImplicitLambdaCapture) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("i", 1, 24); - EXPECT_TRUE(Visitor.runOver( - "void f() { int i; [=]{ i; }; }", - DeclRefExprVisitor::Lang_CXX11)); -} - -TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) { - DeclRefExprVisitor Visitor; - Visitor.setShouldVisitImplicitCode(true); - // We're expecting the "i" in the lambda to be visited twice: - // - Once for the DeclRefExpr in the lambda capture initialization (whose - // source code location is set to the first use of the variable). - // - Once for the DeclRefExpr for the use of "i" inside the lambda. - Visitor.ExpectMatch("i", 1, 24, /*Times=*/2); - EXPECT_TRUE(Visitor.runOver( - "void f() { int i; [=]{ i; }; }", - DeclRefExprVisitor::Lang_CXX11)); -} - -TEST(RecursiveASTVisitor, VisitsLambdaInitCaptureInit) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("i", 1, 24); - EXPECT_TRUE(Visitor.runOver( - "void f() { int i; [a = i + 1]{}; }", - DeclRefExprVisitor::Lang_CXX14)); -} - -/* FIXME: According to Richard Smith this is a bug in the AST. -TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 3, 43); - EXPECT_TRUE(Visitor.runOver( - "template <typename T> void x();\n" - "template <void (*T)()> class X {};\n" - "template <typename T> class Y : public X< x<T> > {};\n" - "Y<int> y;")); -} -*/ - -TEST(RecursiveASTVisitor, VisitsExtension) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("s", 1, 24); - EXPECT_TRUE(Visitor.runOver( - "int s = __extension__ (s);\n")); -} - -TEST(RecursiveASTVisitor, VisitsCopyExprOfBlockDeclCapture) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 3, 24); - EXPECT_TRUE(Visitor.runOver("void f(int(^)(int)); \n" - "void g() { \n" - " f([&](int x){ return x; }); \n" - "}", - DeclRefExprVisitor::Lang_OBJCXX11)); -} - -} // end anonymous namespace Index: unittests/Tooling/RecursiveASTVisitorTest.cpp =================================================================== --- unittests/Tooling/RecursiveASTVisitorTest.cpp +++ /dev/null @@ -1,305 +0,0 @@ -//===- unittest/Tooling/RecursiveASTVisitorTest.cpp -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "TestVisitor.h" -#include <stack> - -using namespace clang; - -namespace { - -class LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> { -public: - bool VisitLambdaExpr(LambdaExpr *Lambda) { - PendingBodies.push(Lambda); - Match("", Lambda->getIntroducerRange().getBegin()); - return true; - } - /// For each call to VisitLambdaExpr, we expect a subsequent call (with - /// proper nesting) to TraverseLambdaBody. - bool TraverseLambdaBody(LambdaExpr *Lambda) { - EXPECT_FALSE(PendingBodies.empty()); - EXPECT_EQ(PendingBodies.top(), Lambda); - PendingBodies.pop(); - return TraverseStmt(Lambda->getBody()); - } - /// Determine whether TraverseLambdaBody has been called for every call to - /// VisitLambdaExpr. - bool allBodiesHaveBeenTraversed() const { - return PendingBodies.empty(); - } -private: - std::stack<LambdaExpr *> PendingBodies; -}; - -TEST(RecursiveASTVisitor, VisitsLambdaExpr) { - LambdaExprVisitor Visitor; - Visitor.ExpectMatch("", 1, 12); - EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", - LambdaExprVisitor::Lang_CXX11)); -} - -TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) { - LambdaExprVisitor Visitor; - EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", - LambdaExprVisitor::Lang_CXX11)); - EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); -} - -TEST(RecursiveASTVisitor, VisitsAttributedLambdaExpr) { - LambdaExprVisitor Visitor; - Visitor.ExpectMatch("", 1, 12); - EXPECT_TRUE(Visitor.runOver( - "void f() { [] () __attribute__ (( fastcall )) { return; }(); }", - LambdaExprVisitor::Lang_CXX14)); -} - -// Matches the (optional) capture-default of a lambda-introducer. -class LambdaDefaultCaptureVisitor - : public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> { -public: - bool VisitLambdaExpr(LambdaExpr *Lambda) { - if (Lambda->getCaptureDefault() != LCD_None) { - Match("", Lambda->getCaptureDefaultLoc()); - } - return true; - } -}; - -TEST(RecursiveASTVisitor, HasCaptureDefaultLoc) { - LambdaDefaultCaptureVisitor Visitor; - Visitor.ExpectMatch("", 1, 20); - EXPECT_TRUE(Visitor.runOver("void f() { int a; [=]{a;}; }", - LambdaDefaultCaptureVisitor::Lang_CXX11)); -} - -// Checks for lambda classes that are not marked as implicitly-generated. -// (There should be none.) -class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> { -public: - ClassVisitor() : SawNonImplicitLambdaClass(false) {} - bool VisitCXXRecordDecl(CXXRecordDecl* record) { - if (record->isLambda() && !record->isImplicit()) - SawNonImplicitLambdaClass = true; - return true; - } - - bool sawOnlyImplicitLambdaClasses() const { - return !SawNonImplicitLambdaClass; - } - -private: - bool SawNonImplicitLambdaClass; -}; - -TEST(RecursiveASTVisitor, LambdaClosureTypesAreImplicit) { - ClassVisitor Visitor; - EXPECT_TRUE(Visitor.runOver("auto lambda = []{};", ClassVisitor::Lang_CXX11)); - EXPECT_TRUE(Visitor.sawOnlyImplicitLambdaClasses()); -} - - -// Check to ensure that attributes and expressions within them are being -// visited. -class AttrVisitor : public ExpectedLocationVisitor<AttrVisitor> { -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")); -} - -// Check to ensure that implicit default argument expressions are visited. -class IntegerLiteralVisitor - : public ExpectedLocationVisitor<IntegerLiteralVisitor> { -public: - bool VisitIntegerLiteral(const IntegerLiteral *IL) { - Match("literal", IL->getLocation()); - return true; - } -}; - -TEST(RecursiveASTVisitor, DefaultArgumentsAreVisited) { - IntegerLiteralVisitor Visitor; - Visitor.ExpectMatch("literal", 1, 15, 2); - EXPECT_TRUE(Visitor.runOver("int f(int i = 1);\n" - "static int k = f();\n")); -} - -// Check to ensure that InitListExpr is visited twice, once each for the -// syntactic and semantic form. -class InitListExprPreOrderVisitor - : public ExpectedLocationVisitor<InitListExprPreOrderVisitor> { -public: - bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); - return true; - } -}; - -class InitListExprPostOrderVisitor - : public ExpectedLocationVisitor<InitListExprPostOrderVisitor> { -public: - bool shouldTraversePostOrder() const { return true; } - - bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); - return true; - } -}; - -class InitListExprPreOrderNoQueueVisitor - : public ExpectedLocationVisitor<InitListExprPreOrderNoQueueVisitor> { -public: - bool TraverseInitListExpr(InitListExpr *ILE) { - return ExpectedLocationVisitor::TraverseInitListExpr(ILE); - } - - bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); - return true; - } -}; - -class InitListExprPostOrderNoQueueVisitor - : public ExpectedLocationVisitor<InitListExprPostOrderNoQueueVisitor> { -public: - bool shouldTraversePostOrder() const { return true; } - - bool TraverseInitListExpr(InitListExpr *ILE) { - return ExpectedLocationVisitor::TraverseInitListExpr(ILE); - } - - bool VisitInitListExpr(InitListExpr *ILE) { - Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart()); - return true; - } -}; - -TEST(RecursiveASTVisitor, InitListExprIsPreOrderVisitedTwice) { - InitListExprPreOrderVisitor Visitor; - Visitor.ExpectMatch("syntactic", 2, 21); - Visitor.ExpectMatch("semantic", 2, 21); - EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" - "static struct S s = {.x = 0};\n", - InitListExprPreOrderVisitor::Lang_C)); -} - -TEST(RecursiveASTVisitor, InitListExprIsPostOrderVisitedTwice) { - InitListExprPostOrderVisitor Visitor; - Visitor.ExpectMatch("syntactic", 2, 21); - Visitor.ExpectMatch("semantic", 2, 21); - EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" - "static struct S s = {.x = 0};\n", - InitListExprPostOrderVisitor::Lang_C)); -} - -TEST(RecursiveASTVisitor, InitListExprIsPreOrderNoQueueVisitedTwice) { - InitListExprPreOrderNoQueueVisitor Visitor; - Visitor.ExpectMatch("syntactic", 2, 21); - Visitor.ExpectMatch("semantic", 2, 21); - EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" - "static struct S s = {.x = 0};\n", - InitListExprPreOrderNoQueueVisitor::Lang_C)); -} - -TEST(RecursiveASTVisitor, InitListExprIsPostOrderNoQueueVisitedTwice) { - InitListExprPostOrderNoQueueVisitor Visitor; - Visitor.ExpectMatch("syntactic", 2, 21); - Visitor.ExpectMatch("semantic", 2, 21); - EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n" - "static struct S s = {.x = 0};\n", - InitListExprPostOrderNoQueueVisitor::Lang_C)); -} - -// Check to ensure that nested name specifiers are visited. -class NestedNameSpecifiersVisitor - : public ExpectedLocationVisitor<NestedNameSpecifiersVisitor> { -public: - bool VisitRecordTypeLoc(RecordTypeLoc RTL) { - if (!RTL) - return true; - Match(RTL.getDecl()->getName(), RTL.getNameLoc()); - return true; - } - - bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { - if (!NNS) - return true; - if (const NamespaceDecl *ND = - NNS.getNestedNameSpecifier()->getAsNamespace()) - Match(ND->getName(), NNS.getLocalBeginLoc()); - return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS); - } -}; - -TEST(RecursiveASTVisitor, - NestedNameSpecifiersForTemplateSpecializationsAreVisited) { - StringRef Source = R"( -namespace ns { -struct Outer { - template<typename T, typename U> - struct Nested { }; - - template<typename T> - static T x; -}; -} - -template<> -struct ns::Outer::Nested<int, int>; - -template<> -struct ns::Outer::Nested<int, int> { }; - -template<typename T> -struct ns::Outer::Nested<int, T> { }; - -template<> -int ns::Outer::x<int> = 0; -)"; - NestedNameSpecifiersVisitor Visitor; - Visitor.ExpectMatch("ns", 13, 8); - Visitor.ExpectMatch("ns", 16, 8); - Visitor.ExpectMatch("ns", 19, 8); - Visitor.ExpectMatch("ns", 22, 5); - Visitor.ExpectMatch("Outer", 13, 12); - Visitor.ExpectMatch("Outer", 16, 12); - Visitor.ExpectMatch("Outer", 19, 12); - Visitor.ExpectMatch("Outer", 22, 9); - EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14)); -} - -} // end anonymous namespace Index: Tooling/CMakeLists.txt =================================================================== --- Tooling/CMakeLists.txt +++ Tooling/CMakeLists.txt @@ -21,10 +21,25 @@ LexicallyOrderedRecursiveASTVisitorTest.cpp LookupTest.cpp QualTypeNamesTest.cpp - RecursiveASTVisitorTest.cpp - RecursiveASTVisitorTestCallVisitor.cpp + RecursiveASTVisitorTests/Attr.cpp + RecursiveASTVisitorTests/Class.cpp + RecursiveASTVisitorTests/ConstructExpr.cpp + RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp + RecursiveASTVisitorTests/CXXMemberCall.cpp + RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp + RecursiveASTVisitorTests/DeclRefExpr.cpp + RecursiveASTVisitorTests/ImplicitCtor.cpp + RecursiveASTVisitorTests/InitListExprPostOrder.cpp + RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp + RecursiveASTVisitorTests/InitListExprPreOrder.cpp + RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp + RecursiveASTVisitorTests/IntegerLiteral.cpp + RecursiveASTVisitorTests/LambdaDefaultCapture.cpp + RecursiveASTVisitorTests/LambdaExpr.cpp + RecursiveASTVisitorTests/NestedNameSpecifiers.cpp + RecursiveASTVisitorTests/ParenExpr.cpp + RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp RecursiveASTVisitorTestDeclVisitor.cpp - RecursiveASTVisitorTestExprVisitor.cpp RecursiveASTVisitorTestPostOrderVisitor.cpp RecursiveASTVisitorTestTypeLocVisitor.cpp RefactoringActionRulesTest.cpp
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits