diff --git a/clang/unittests/AST/EvaluateAsRValueTest.cpp b/clang/unittests/AST/EvaluateAsRValueTest.cpp index f6261b827671..1e17330863f2 100644 --- a/clang/unittests/AST/EvaluateAsRValueTest.cpp +++ b/clang/unittests/AST/EvaluateAsRValueTest.cpp @@ -13,7 +13,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Tooling/Tooling.h" #include "gtest/gtest.h" #include @@ -28,8 +28,8 @@ typedef std::map VarInfoMap; /// \brief Records information on variable initializers to a map. class EvaluateConstantInitializersVisitor - : public clang::RecursiveASTVisitor { - public: + : public clang::DynamicRecursiveASTVisitor { +public: explicit EvaluateConstantInitializersVisitor(VarInfoMap &VarInfo) : VarInfo(VarInfo) {} @@ -38,7 +38,7 @@ class EvaluateConstantInitializersVisitor /// /// For each VarDecl with an initializer this also records in VarInfo /// whether the initializer could be evaluated as a constant. - bool VisitVarDecl(const clang::VarDecl *VD) { + bool VisitVarDecl(clang::VarDecl *VD) override { if (const clang::Expr *Init = VD->getInit()) { clang::Expr::EvalResult Result; bool WasEvaluated = Init->EvaluateAsRValue(Result, VD->getASTContext()); @@ -109,9 +109,9 @@ TEST(EvaluateAsRValue, FailsGracefullyForUnknownTypes) { } class CheckLValueToRValueConversionVisitor - : public clang::RecursiveASTVisitor { + : public clang::DynamicRecursiveASTVisitor { public: - bool VisitDeclRefExpr(const clang::DeclRefExpr *E) { + bool VisitDeclRefExpr(clang::DeclRefExpr *E) override { clang::Expr::EvalResult Result; E->EvaluateAsRValue(Result, E->getDecl()->getASTContext(), true); diff --git a/clang/unittests/Analysis/CloneDetectionTest.cpp b/clang/unittests/Analysis/CloneDetectionTest.cpp index 738f6efd2018..d0148a8c28c5 100644 --- a/clang/unittests/Analysis/CloneDetectionTest.cpp +++ b/clang/unittests/Analysis/CloneDetectionTest.cpp @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Analysis/CloneDetection.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Tooling/Tooling.h" #include "gtest/gtest.h" @@ -15,15 +15,14 @@ namespace clang { namespace analysis { namespace { -class CloneDetectionVisitor - : public RecursiveASTVisitor { +class CloneDetectionVisitor : public DynamicRecursiveASTVisitor { CloneDetector &Detector; public: explicit CloneDetectionVisitor(CloneDetector &D) : Detector(D) {} - bool VisitFunctionDecl(FunctionDecl *D) { + bool VisitFunctionDecl(FunctionDecl *D) override { Detector.analyzeCodeBody(D); return true; } diff --git a/clang/unittests/Frontend/FrontendActionTest.cpp b/clang/unittests/Frontend/FrontendActionTest.cpp index 818e8cef27e5..6ce9ba6f6a08 100644 --- a/clang/unittests/Frontend/FrontendActionTest.cpp +++ b/clang/unittests/Frontend/FrontendActionTest.cpp @@ -9,7 +9,7 @@ #include "clang/Frontend/FrontendAction.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Basic/LangStandard.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" @@ -53,7 +53,7 @@ public: } private: - class Visitor : public ASTConsumer, public RecursiveASTVisitor { + class Visitor : public ASTConsumer, public DynamicRecursiveASTVisitor { public: Visitor(CompilerInstance &CI, bool ActOnEndOfTranslationUnit, std::vector &decl_names) : @@ -67,7 +67,7 @@ private: TraverseDecl(context.getTranslationUnitDecl()); } - virtual bool VisitNamedDecl(NamedDecl *Decl) { + bool VisitNamedDecl(NamedDecl *Decl) override { decl_names_.push_back(Decl->getQualifiedNameAsString()); return true; } diff --git a/clang/unittests/Tooling/ASTSelectionTest.cpp b/clang/unittests/Tooling/ASTSelectionTest.cpp index 113165f68449..1897bc15196e 100644 --- a/clang/unittests/Tooling/ASTSelectionTest.cpp +++ b/clang/unittests/Tooling/ASTSelectionTest.cpp @@ -26,7 +26,7 @@ struct FileLocation { using FileRange = std::pair; -class SelectionFinderVisitor : public TestVisitor { +class SelectionFinderVisitor : public TestVisitor { FileLocation Location; std::optional SelectionRange; llvm::function_refgetASTContext(); const SourceManager &SM = Context.getSourceManager(); diff --git a/clang/unittests/Tooling/CRTPTestVisitor.h b/clang/unittests/Tooling/CRTPTestVisitor.h new file mode 100644 index 000000000000..67ae36b2e3dd --- /dev/null +++ b/clang/unittests/Tooling/CRTPTestVisitor.h @@ -0,0 +1,42 @@ +//===--- TestVisitor.h ------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines a CRTP-based RecursiveASTVisitor helper for tests. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_UNITTESTS_TOOLING_CRTPTESTVISITOR_H +#define LLVM_CLANG_UNITTESTS_TOOLING_CRTPTESTVISITOR_H + +#include "TestVisitor.h" +#include "clang/AST/RecursiveASTVisitor.h" + +// CRTP versions of the visitors in TestVisitor.h. +namespace clang { +template +class CRTPTestVisitor : public RecursiveASTVisitor, + public detail::TestVisitorHelper { +public: + bool shouldVisitTemplateInstantiations() const { return true; } + bool shouldVisitImplicitCode() const { return true; } + + void InvokeTraverseDecl(TranslationUnitDecl *D) override { + RecursiveASTVisitor::TraverseDecl(D); + } +}; + +template +class CRTPExpectedLocationVisitor + : public CRTPTestVisitor, + public detail::ExpectedLocationVisitorHelper { + ASTContext *getASTContext() override { return this->Context; } +}; +} // namespace clang + +#endif // LLVM_CLANG_UNITTESTS_TOOLING_CRTPTESTVISITOR_H diff --git a/clang/unittests/Tooling/CastExprTest.cpp b/clang/unittests/Tooling/CastExprTest.cpp index eab23a5a98e5..e5a8d994bf01 100644 --- a/clang/unittests/Tooling/CastExprTest.cpp +++ b/clang/unittests/Tooling/CastExprTest.cpp @@ -12,17 +12,17 @@ using namespace clang; namespace { -struct CastExprVisitor : TestVisitor { +struct CastExprVisitor : TestVisitor { std::function OnExplicitCast; std::function OnCast; - bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) { + bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) override { if (OnExplicitCast) OnExplicitCast(Expr); return true; } - bool VisitCastExpr(CastExpr *Expr) { + bool VisitCastExpr(CastExpr *Expr) override { if (OnCast) OnCast(Expr); return true; diff --git a/clang/unittests/Tooling/CommentHandlerTest.cpp b/clang/unittests/Tooling/CommentHandlerTest.cpp index 7eb11ccd6ee2..edfb72e2ec59 100644 --- a/clang/unittests/Tooling/CommentHandlerTest.cpp +++ b/clang/unittests/Tooling/CommentHandlerTest.cpp @@ -22,12 +22,9 @@ struct Comment { class CommentVerifier; typedef std::vector CommentList; -class CommentHandlerVisitor : public TestVisitor, - public CommentHandler { - typedef TestVisitor base; - +class CommentHandlerVisitor : public TestVisitor, public CommentHandler { public: - CommentHandlerVisitor() : base(), PP(nullptr), Verified(false) {} + CommentHandlerVisitor() : PP(nullptr), Verified(false) {} ~CommentHandlerVisitor() override { EXPECT_TRUE(Verified) << "CommentVerifier not accessed"; @@ -64,7 +61,7 @@ private: CommentList Comments; bool Verified; - class CommentHandlerAction : public base::TestAction { + class CommentHandlerAction : public TestAction { public: CommentHandlerAction(CommentHandlerVisitor *Visitor) : TestAction(Visitor) { } diff --git a/clang/unittests/Tooling/ExecutionTest.cpp b/clang/unittests/Tooling/ExecutionTest.cpp index 91ab8594f682..b0fd7ccb950f 100644 --- a/clang/unittests/Tooling/ExecutionTest.cpp +++ b/clang/unittests/Tooling/ExecutionTest.cpp @@ -9,7 +9,7 @@ #include "clang/Tooling/Execution.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/FrontendActions.h" @@ -30,12 +30,9 @@ namespace { // This traverses the AST and outputs function name as key and "1" as value for // each function declaration. -class ASTConsumerWithResult - : public ASTConsumer, - public RecursiveASTVisitor { +class ASTConsumerWithResult : public ASTConsumer, + public DynamicRecursiveASTVisitor { public: - using ASTVisitor = RecursiveASTVisitor; - explicit ASTConsumerWithResult(ExecutionContext *Context) : Context(Context) { assert(Context != nullptr); } @@ -44,12 +41,12 @@ public: TraverseDecl(Context.getTranslationUnitDecl()); } - bool TraverseFunctionDecl(clang::FunctionDecl *Decl) { + bool TraverseFunctionDecl(clang::FunctionDecl *Decl) override { Context->reportResult(Decl->getNameAsString(), Context->getRevision() + ":" + Context->getCorpus() + ":" + Context->getCurrentCompilationUnit() + "/1"); - return ASTVisitor::TraverseFunctionDecl(Decl); + return DynamicRecursiveASTVisitor::TraverseFunctionDecl(Decl); } private: diff --git a/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp b/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp index 5d16595aec80..b167eb4b8117 100644 --- a/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp +++ b/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp @@ -44,13 +44,14 @@ private: llvm::SmallVector TraversalStack; }; -class DummyMatchVisitor : public ExpectedLocationVisitor { +class DummyMatchVisitor : public ExpectedLocationVisitor { bool EmitDeclIndices, EmitStmtIndices; public: DummyMatchVisitor(bool EmitDeclIndices = false, bool EmitStmtIndices = false) : EmitDeclIndices(EmitDeclIndices), EmitStmtIndices(EmitStmtIndices) {} - bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) { + + bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) override { const ASTContext &Context = TU->getASTContext(); const SourceManager &SM = Context.getSourceManager(); LexicallyOrderedDeclVisitor SubVisitor(*this, SM, EmitDeclIndices, diff --git a/clang/unittests/Tooling/LookupTest.cpp b/clang/unittests/Tooling/LookupTest.cpp index 2cf5ebb2a4cb..acd1714a26e0 100644 --- a/clang/unittests/Tooling/LookupTest.cpp +++ b/clang/unittests/Tooling/LookupTest.cpp @@ -13,31 +13,31 @@ using namespace clang; namespace { -struct GetDeclsVisitor : TestVisitor { +struct GetDeclsVisitor : TestVisitor { std::function OnCall; std::function OnRecordTypeLoc; std::function OnUsingTypeLoc; SmallVector DeclStack; - bool VisitCallExpr(CallExpr *Expr) { + bool VisitCallExpr(CallExpr *Expr) override { if (OnCall) OnCall(Expr); return true; } - bool VisitRecordTypeLoc(RecordTypeLoc Loc) { + bool VisitRecordTypeLoc(RecordTypeLoc Loc) override { if (OnRecordTypeLoc) OnRecordTypeLoc(Loc); return true; } - bool VisitUsingTypeLoc(UsingTypeLoc Loc) { + bool VisitUsingTypeLoc(UsingTypeLoc Loc) override { if (OnUsingTypeLoc) OnUsingTypeLoc(Loc); return true; } - bool TraverseDecl(Decl *D) { + bool TraverseDecl(Decl *D) override { DeclStack.push_back(D); bool Ret = TestVisitor::TraverseDecl(D); DeclStack.pop_back(); diff --git a/clang/unittests/Tooling/QualTypeNamesTest.cpp b/clang/unittests/Tooling/QualTypeNamesTest.cpp index 686d189cf69e..5ded64d4fcc8 100644 --- a/clang/unittests/Tooling/QualTypeNamesTest.cpp +++ b/clang/unittests/Tooling/QualTypeNamesTest.cpp @@ -11,12 +11,12 @@ using namespace clang; namespace { -struct TypeNameVisitor : TestVisitor { +struct TypeNameVisitor : TestVisitor { llvm::StringMap ExpectedQualTypeNames; bool WithGlobalNsPrefix = false; // ValueDecls are the least-derived decl with both a qualtype and a name. - bool VisitValueDecl(const ValueDecl *VD) { + bool VisitValueDecl(ValueDecl *VD) override { std::string ExpectedName = ExpectedQualTypeNames.lookup(VD->getNameAsString()); if (ExpectedName != "") { diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp index d72a110d37e0..eed016e9ee7c 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp @@ -12,12 +12,12 @@ using namespace clang; namespace { -class VarDeclVisitor : public ExpectedLocationVisitor { +class VarDeclVisitor : public ExpectedLocationVisitor { public: - bool VisitVarDecl(VarDecl *Variable) { - Match(Variable->getNameAsString(), Variable->getBeginLoc()); - return true; - } + bool VisitVarDecl(VarDecl *Variable) override { + Match(Variable->getNameAsString(), Variable->getBeginLoc()); + return true; + } }; TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) { @@ -29,12 +29,11 @@ TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) { VarDeclVisitor::Lang_CXX11)); } -class ParmVarDeclVisitorForImplicitCode : - public ExpectedLocationVisitor { +class ParmVarDeclVisitorForImplicitCode : public ExpectedLocationVisitor { public: - bool shouldVisitImplicitCode() const { return true; } + ParmVarDeclVisitorForImplicitCode() { ShouldVisitImplicitCode = true; } - bool VisitParmVarDecl(ParmVarDecl *ParamVar) { + bool VisitParmVarDecl(ParmVarDecl *ParamVar) override { Match(ParamVar->getNameAsString(), ParamVar->getBeginLoc()); return true; } @@ -58,10 +57,9 @@ TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) { "void bar(Y a) {Y b = a;}")); } -class NamedDeclVisitor - : public ExpectedLocationVisitor { +class NamedDeclVisitor : public ExpectedLocationVisitor { public: - bool VisitNamedDecl(NamedDecl *Decl) { + bool VisitNamedDecl(NamedDecl *Decl) override { std::string NameWithTemplateArgs; llvm::raw_string_ostream OS(NameWithTemplateArgs); Decl->getNameForDiagnostic(OS, diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp index 8ac0604c0911..481559ed08ef 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp @@ -11,14 +11,12 @@ // //===----------------------------------------------------------------------===// -#include "TestVisitor.h" +#include "CRTPTestVisitor.h" using namespace clang; namespace { - -class RecordingVisitor : public TestVisitor { - +class RecordingVisitor : public CRTPTestVisitor { bool VisitPostOrder; public: diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp index a21186265db6..eec628ca3964 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp @@ -12,9 +12,9 @@ using namespace clang; namespace { -class TypeLocVisitor : public ExpectedLocationVisitor { +class TypeLocVisitor : public ExpectedLocationVisitor { public: - bool VisitTypeLoc(TypeLoc TypeLocation) { + bool VisitTypeLoc(TypeLoc TypeLocation) override { Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc()); return true; } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp index 022ef8b83228..7693e77236b0 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "TestVisitor.h" +#include "CRTPTestVisitor.h" using namespace clang; @@ -14,7 +14,7 @@ namespace { // Check to ensure that attributes and expressions within them are being // visited. -class AttrVisitor : public ExpectedLocationVisitor { +class AttrVisitor : public CRTPExpectedLocationVisitor { public: bool VisitMemberExpr(MemberExpr *ME) { Match(ME->getMemberDecl()->getNameAsString(), ME->getBeginLoc()); @@ -30,7 +30,6 @@ public: } }; - TEST(RecursiveASTVisitor, AttributesAreVisited) { AttrVisitor Visitor; Visitor.ExpectMatch("Attr", 4, 24); diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp index c11e726fe855..c1217179768a 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp @@ -14,10 +14,9 @@ using namespace clang; namespace { // Check to ensure that bitfield initializers are visited. -class BitfieldInitializerVisitor - : public ExpectedLocationVisitor { +class BitfieldInitializerVisitor : public ExpectedLocationVisitor { public: - bool VisitIntegerLiteral(IntegerLiteral *IL) { + bool VisitIntegerLiteral(IntegerLiteral *IL) override { Match(std::to_string(IL->getValue().getSExtValue()), IL->getLocation()); return true; } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp index 1fb192dcda08..4b0c4c31f2dd 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp @@ -12,10 +12,9 @@ using namespace clang; namespace { -class CXXBoolLiteralExprVisitor - : public ExpectedLocationVisitor { +class CXXBoolLiteralExprVisitor : public ExpectedLocationVisitor { public: - bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) { + bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) override { if (BE->getValue()) Match("true", BE->getLocation()); else diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp index c7b31e06e0e8..fe95e8987a73 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp @@ -12,10 +12,9 @@ using namespace clang; namespace { -class CXXMemberCallVisitor - : public ExpectedLocationVisitor { +class CXXMemberCallVisitor : public ExpectedLocationVisitor { public: - bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) { + bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) override { Match(Call->getMethodDecl()->getQualifiedNameAsString(), Call->getBeginLoc()); return true; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp index 90fa84bd4481..1eeb3df81a31 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXMethodDecl.cpp @@ -13,25 +13,21 @@ using namespace clang; namespace { -class CXXMethodDeclVisitor - : public ExpectedLocationVisitor { +class CXXMethodDeclVisitor : public ExpectedLocationVisitor { public: - CXXMethodDeclVisitor(bool VisitImplicitCode) - : VisitImplicitCode(VisitImplicitCode) {} + CXXMethodDeclVisitor(bool VisitImplicitCode) { + ShouldVisitImplicitCode = VisitImplicitCode; + } - bool shouldVisitImplicitCode() const { return VisitImplicitCode; } - - bool VisitDeclRefExpr(DeclRefExpr *D) { + bool VisitDeclRefExpr(DeclRefExpr *D) override { Match("declref", D->getLocation()); return true; } - bool VisitParmVarDecl(ParmVarDecl *P) { + + bool VisitParmVarDecl(ParmVarDecl *P) override { Match("parm", P->getLocation()); return true; } - -private: - bool VisitImplicitCode; }; TEST(RecursiveASTVisitor, CXXMethodDeclNoDefaultBodyVisited) { diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp index 376874eb351d..46686199c05d 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp @@ -12,15 +12,13 @@ using namespace clang; namespace { -class CXXOperatorCallExprTraverser - : public ExpectedLocationVisitor { +class CXXOperatorCallExprTraverser : public ExpectedLocationVisitor { public: // Use Traverse, not Visit, to check that data recursion optimization isn't // bypassing the call of this function. - bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { + bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) override { Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc()); - return ExpectedLocationVisitor:: - TraverseCXXOperatorCallExpr(CE); + return ExpectedLocationVisitor::TraverseCXXOperatorCallExpr(CE); } }; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h b/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h index 92e30c2d46e5..355ecfb452e7 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/CallbacksCommon.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "TestVisitor.h" +#include "CRTPTestVisitor.h" using namespace clang; @@ -21,7 +21,7 @@ enum class ShouldTraversePostOrder : bool { /// sequence of calls to user-defined callbacks like Traverse*(), WalkUp*(), /// Visit*(). template -class RecordingVisitorBase : public TestVisitor { +class RecordingVisitorBase : public CRTPTestVisitor { ShouldTraversePostOrder ShouldTraversePostOrderValue; public: diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp index 3ea5abd46a1e..79dc84b2fdb7 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp @@ -14,10 +14,11 @@ namespace { // Checks for lambda classes that are not marked as implicitly-generated. // (There should be none.) -class ClassVisitor : public ExpectedLocationVisitor { +class ClassVisitor : public ExpectedLocationVisitor { public: ClassVisitor() : SawNonImplicitLambdaClass(false) {} - bool VisitCXXRecordDecl(CXXRecordDecl* record) { + + bool VisitCXXRecordDecl(CXXRecordDecl *record) override { if (record->isLambda() && !record->isImplicit()) SawNonImplicitLambdaClass = true; return true; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp index 6a8d91672f1d..6dd28e27d7ec 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Concept.cpp @@ -16,78 +16,87 @@ using namespace clang; namespace { -struct ConceptVisitor : ExpectedLocationVisitor { - bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) { +struct ConceptVisitor : ExpectedLocationVisitor { + ConceptVisitor(bool VisitImplicitCode = false) { + ShouldVisitImplicitCode = VisitImplicitCode; + } + + bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) override { ++ConceptSpecializationExprsVisited; return true; } - bool TraverseTypeConstraint(const TypeConstraint *C) { + bool TraverseTypeConstraint(const TypeConstraint *C) override { ++TypeConstraintsTraversed; return ExpectedLocationVisitor::TraverseTypeConstraint(C); } - bool TraverseConceptRequirement(concepts::Requirement *R) { + bool TraverseConceptRequirement(concepts::Requirement *R) override { ++ConceptRequirementsTraversed; return ExpectedLocationVisitor::TraverseConceptRequirement(R); } - bool TraverseConceptReference(ConceptReference *CR) { + bool TraverseConceptReference(ConceptReference *CR) override { ++ConceptReferencesTraversed; return ExpectedLocationVisitor::TraverseConceptReference(CR); } - bool VisitConceptReference(ConceptReference *CR) { + bool VisitConceptReference(ConceptReference *CR) override { ++ConceptReferencesVisited; return true; } - bool shouldVisitImplicitCode() { return ShouldVisitImplicitCode; } - int ConceptSpecializationExprsVisited = 0; int TypeConstraintsTraversed = 0; int ConceptRequirementsTraversed = 0; int ConceptReferencesTraversed = 0; int ConceptReferencesVisited = 0; - bool ShouldVisitImplicitCode = false; }; TEST(RecursiveASTVisitor, Concepts) { + { + ConceptVisitor Visitor{true}; + EXPECT_TRUE( + Visitor.runOver("template concept Fooable = true;\n" + "template void bar(T);", + ConceptVisitor::Lang_CXX2a)); + // Check that we traverse the "Fooable T" template parameter's + // TypeConstraint's ImmediatelyDeclaredConstraint, which is a + // ConceptSpecializationExpr. + EXPECT_EQ(1, Visitor.ConceptSpecializationExprsVisited); + // Also check we traversed the TypeConstraint that produced the expr. + EXPECT_EQ(1, Visitor.TypeConstraintsTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesVisited); + } + + { + ConceptVisitor Visitor; // Don't visit implicit code now. + EXPECT_TRUE( + Visitor.runOver("template concept Fooable = true;\n" + "template void bar(T);", + ConceptVisitor::Lang_CXX2a)); + // Check that we only visit the TypeConstraint, but not the implicitly + // generated immediately declared expression. + EXPECT_EQ(0, Visitor.ConceptSpecializationExprsVisited); + EXPECT_EQ(1, Visitor.TypeConstraintsTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesVisited); + } + + { + ConceptVisitor Visitor; + EXPECT_TRUE( + Visitor.runOver("template concept A = true;\n" + "template struct vector {};\n" + "template concept B = requires(T x) {\n" + " typename vector;\n" + " {x} -> A;\n" + " requires true;\n" + "};", + ConceptVisitor::Lang_CXX2a)); + EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); + EXPECT_EQ(1, Visitor.ConceptReferencesVisited); + } + ConceptVisitor Visitor; - Visitor.ShouldVisitImplicitCode = true; - EXPECT_TRUE(Visitor.runOver("template concept Fooable = true;\n" - "template void bar(T);", - ConceptVisitor::Lang_CXX2a)); - // Check that we traverse the "Fooable T" template parameter's - // TypeConstraint's ImmediatelyDeclaredConstraint, which is a - // ConceptSpecializationExpr. - EXPECT_EQ(1, Visitor.ConceptSpecializationExprsVisited); - // Also check we traversed the TypeConstraint that produced the expr. - EXPECT_EQ(1, Visitor.TypeConstraintsTraversed); - EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); - EXPECT_EQ(1, Visitor.ConceptReferencesVisited); - - Visitor = {}; // Don't visit implicit code now. - EXPECT_TRUE(Visitor.runOver("template concept Fooable = true;\n" - "template void bar(T);", - ConceptVisitor::Lang_CXX2a)); - // Check that we only visit the TypeConstraint, but not the implicitly - // generated immediately declared expression. - EXPECT_EQ(0, Visitor.ConceptSpecializationExprsVisited); - EXPECT_EQ(1, Visitor.TypeConstraintsTraversed); - EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); - EXPECT_EQ(1, Visitor.ConceptReferencesVisited); - - Visitor = {}; - EXPECT_TRUE(Visitor.runOver("template concept A = true;\n" - "template struct vector {};\n" - "template concept B = requires(T x) {\n" - " typename vector;\n" - " {x} -> A;\n" - " requires true;\n" - "};", - ConceptVisitor::Lang_CXX2a)); - EXPECT_EQ(3, Visitor.ConceptRequirementsTraversed); - EXPECT_EQ(1, Visitor.ConceptReferencesTraversed); - EXPECT_EQ(1, Visitor.ConceptReferencesVisited); - - Visitor = {}; llvm::StringRef Code = R"cpp( template concept True = false; @@ -107,34 +116,34 @@ struct Foo {}; EXPECT_EQ(2, Visitor.ConceptReferencesVisited); } -struct VisitDeclOnlyOnce : ExpectedLocationVisitor { - bool VisitConceptDecl(ConceptDecl *D) { +struct VisitDeclOnlyOnce : ExpectedLocationVisitor { + VisitDeclOnlyOnce() { ShouldWalkTypesOfTypeLocs = false; } + + bool VisitConceptDecl(ConceptDecl *D) override { ++ConceptDeclsVisited; return true; } - bool VisitAutoType(AutoType *) { + bool VisitAutoType(AutoType *) override { ++AutoTypeVisited; return true; } - bool VisitAutoTypeLoc(AutoTypeLoc) { + bool VisitAutoTypeLoc(AutoTypeLoc) override { ++AutoTypeLocVisited; return true; } - bool VisitConceptReference(ConceptReference *) { + bool VisitConceptReference(ConceptReference *) override { ++ConceptReferencesVisited; return true; } - bool TraverseVarDecl(VarDecl *V) { + bool TraverseVarDecl(VarDecl *V) override { // The base traversal visits only the `TypeLoc`. // However, in the test we also validate the underlying `QualType`. TraverseType(V->getType()); return ExpectedLocationVisitor::TraverseVarDecl(V); } - bool shouldWalkTypesOfTypeLocs() { return false; } - int ConceptDeclsVisited = 0; int AutoTypeVisited = 0; int AutoTypeLocVisited = 0; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp index b4f4f54dc7e2..7b2ed9715aa8 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp @@ -18,18 +18,11 @@ namespace { /// 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 { +class ConstructExprVisitor : public ExpectedLocationVisitor { public: - ConstructExprVisitor() : ShouldVisitImplicitCode(false) {} + ConstructExprVisitor() { ShouldVisitImplicitCode = false; } - bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } - - void setShouldVisitImplicitCode(bool NewValue) { - ShouldVisitImplicitCode = NewValue; - } - - bool VisitCXXConstructExpr(CXXConstructExpr* Expr) { + bool VisitCXXConstructExpr(CXXConstructExpr *Expr) override { if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) { if (const CXXRecordDecl* Class = Ctor->getParent()) { Match(Class->getName(), Expr->getLocation()); @@ -37,14 +30,11 @@ public: } return true; } - - private: - bool ShouldVisitImplicitCode; }; TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) { ConstructExprVisitor Visitor; - Visitor.setShouldVisitImplicitCode(true); + Visitor.ShouldVisitImplicitCode = 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. @@ -60,7 +50,7 @@ TEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) { // visits are omitted when the visitor does not include implicit code. TEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) { ConstructExprVisitor Visitor; - Visitor.setShouldVisitImplicitCode(false); + Visitor.ShouldVisitImplicitCode = 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. diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp index adc972e1c3d9..6ed986c187eb 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp @@ -12,23 +12,14 @@ using namespace clang; namespace { -class DeclRefExprVisitor : public ExpectedLocationVisitor { +class DeclRefExprVisitor : public ExpectedLocationVisitor { public: - DeclRefExprVisitor() : ShouldVisitImplicitCode(false) {} + DeclRefExprVisitor() { ShouldVisitImplicitCode = false; } - bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } - - void setShouldVisitImplicitCode(bool NewValue) { - ShouldVisitImplicitCode = NewValue; - } - - bool VisitDeclRefExpr(DeclRefExpr *Reference) { + bool VisitDeclRefExpr(DeclRefExpr *Reference) override { Match(Reference->getNameInfo().getAsString(), Reference->getLocation()); return true; } - -private: - bool ShouldVisitImplicitCode; }; TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) { @@ -73,7 +64,7 @@ TEST(RecursiveASTVisitor, VisitsUseOfImplicitLambdaCapture) { TEST(RecursiveASTVisitor, VisitsImplicitLambdaCaptureInit) { DeclRefExprVisitor Visitor; - Visitor.setShouldVisitImplicitCode(true); + Visitor.ShouldVisitImplicitCode = true; // We're expecting "i" to be visited twice: once for the initialization expr // for the captured variable "i" outside of the lambda body, and again for // the use of "i" inside the lambda. diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp index df878bfc113e..7d03b2839479 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp @@ -13,23 +13,20 @@ using namespace clang; namespace { -class DeductionGuideVisitor - : public ExpectedLocationVisitor { +class DeductionGuideVisitor : public ExpectedLocationVisitor { public: - DeductionGuideVisitor(bool ShouldVisitImplicitCode) - : ShouldVisitImplicitCode(ShouldVisitImplicitCode) {} - bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { + DeductionGuideVisitor(bool VisitImplicitCode) { + ShouldVisitImplicitCode = VisitImplicitCode; + ShouldVisitTemplateInstantiations = false; + } + + bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) override { std::string Storage; llvm::raw_string_ostream Stream(Storage); D->print(Stream); Match(Storage, D->getLocation()); return true; } - - bool shouldVisitTemplateInstantiations() const { return false; } - - bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } - bool ShouldVisitImplicitCode; }; TEST(RecursiveASTVisitor, DeductionGuideNonImplicitMode) { diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp index 27999e5ef8ef..dc9455a01e48 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp @@ -13,12 +13,9 @@ using namespace clang; namespace { // A visitor that visits implicit declarations and matches constructors. -class ImplicitCtorVisitor - : public ExpectedLocationVisitor { +class ImplicitCtorVisitor : public ExpectedLocationVisitor { public: - bool shouldVisitImplicitCode() const { return true; } - - bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) { + bool VisitCXXConstructorDecl(CXXConstructorDecl *Ctor) override { if (Ctor->isImplicit()) { // Was not written in source code if (const CXXRecordDecl* Class = Ctor->getParent()) { Match(Class->getName(), Ctor->getLocation()); diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp index c762e1cffc36..ae952c33bfe7 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtorInitializer.cpp @@ -12,26 +12,20 @@ using namespace clang; namespace { -class CXXCtorInitializerVisitor - : public ExpectedLocationVisitor { +class CXXCtorInitializerVisitor : public ExpectedLocationVisitor { public: - CXXCtorInitializerVisitor(bool VisitImplicitCode) - : VisitImplicitCode(VisitImplicitCode) {} + CXXCtorInitializerVisitor(bool VisitImplicitCode) { + ShouldVisitImplicitCode = VisitImplicitCode; + } - bool shouldVisitImplicitCode() const { return VisitImplicitCode; } - - bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override { if (!Init->isWritten()) VisitedImplicitInitializer = true; Match("initializer", Init->getSourceLocation()); - return ExpectedLocationVisitor< - CXXCtorInitializerVisitor>::TraverseConstructorInitializer(Init); + return ExpectedLocationVisitor::TraverseConstructorInitializer(Init); } bool VisitedImplicitInitializer = false; - -private: - bool VisitImplicitCode; }; // Check to ensure that CXXCtorInitializer is not visited when implicit code diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp index 80d9c9873505..5836fc1b2e8d 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "TestVisitor.h" +#include "CRTPTestVisitor.h" using namespace clang; namespace { class InitListExprPostOrderVisitor - : public ExpectedLocationVisitor { + : public CRTPExpectedLocationVisitor { public: bool shouldTraversePostOrder() const { return true; } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp index 8750f7834944..20140d2dcbf9 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp @@ -6,19 +6,19 @@ // //===----------------------------------------------------------------------===// -#include "TestVisitor.h" +#include "CRTPTestVisitor.h" using namespace clang; namespace { class InitListExprPostOrderNoQueueVisitor - : public ExpectedLocationVisitor { + : public CRTPExpectedLocationVisitor { public: bool shouldTraversePostOrder() const { return true; } bool TraverseInitListExpr(InitListExpr *ILE) { - return ExpectedLocationVisitor::TraverseInitListExpr(ILE); + return CRTPExpectedLocationVisitor::TraverseInitListExpr(ILE); } bool VisitInitListExpr(InitListExpr *ILE) { diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp index 3fa1529ea0ee..933d25898390 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp @@ -14,21 +14,16 @@ namespace { // Check to ensure that InitListExpr is visited twice, once each for the // syntactic and semantic form. -class InitListExprPreOrderVisitor - : public ExpectedLocationVisitor { +class InitListExprPreOrderVisitor : public ExpectedLocationVisitor { public: - InitListExprPreOrderVisitor(bool VisitImplicitCode) - : VisitImplicitCode(VisitImplicitCode) {} + InitListExprPreOrderVisitor(bool VisitImplicitCode) { + ShouldVisitImplicitCode = VisitImplicitCode; + } - bool shouldVisitImplicitCode() const { return VisitImplicitCode; } - - bool VisitInitListExpr(InitListExpr *ILE) { + bool VisitInitListExpr(InitListExpr *ILE) override { Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc()); return true; } - -private: - bool VisitImplicitCode; }; TEST(RecursiveASTVisitor, InitListExprIsPreOrderVisitedTwice) { diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp index 8db88e1e0639..0dcd11b8027f 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp @@ -12,14 +12,13 @@ using namespace clang; namespace { -class InitListExprPreOrderNoQueueVisitor - : public ExpectedLocationVisitor { +class InitListExprPreOrderNoQueueVisitor : public ExpectedLocationVisitor { public: - bool TraverseInitListExpr(InitListExpr *ILE) { + bool TraverseInitListExpr(InitListExpr *ILE) override { return ExpectedLocationVisitor::TraverseInitListExpr(ILE); } - bool VisitInitListExpr(InitListExpr *ILE) { + bool VisitInitListExpr(InitListExpr *ILE) override { Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getBeginLoc()); return true; } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp index 3fc3cb1a99a7..83136fc11edb 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp @@ -13,10 +13,9 @@ using namespace clang; namespace { // Check to ensure that implicit default argument expressions are visited. -class IntegerLiteralVisitor - : public ExpectedLocationVisitor { +class IntegerLiteralVisitor : public ExpectedLocationVisitor { public: - bool VisitIntegerLiteral(const IntegerLiteral *IL) { + bool VisitIntegerLiteral(IntegerLiteral *IL) override { Match("literal", IL->getLocation()); return true; } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp index b1d6d593e733..4a9175ed2dda 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp @@ -13,10 +13,9 @@ using namespace clang; namespace { // Matches the (optional) capture-default of a lambda-introducer. -class LambdaDefaultCaptureVisitor - : public ExpectedLocationVisitor { +class LambdaDefaultCaptureVisitor : public ExpectedLocationVisitor { public: - bool VisitLambdaExpr(LambdaExpr *Lambda) { + bool VisitLambdaExpr(LambdaExpr *Lambda) override { if (Lambda->getCaptureDefault() != LCD_None) { Match("", Lambda->getCaptureDefaultLoc()); } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp index 337dace5fd22..0ce7f4b18762 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp @@ -14,9 +14,11 @@ using namespace clang; namespace { -class LambdaExprVisitor : public ExpectedLocationVisitor { +class LambdaExprVisitor : public ExpectedLocationVisitor { public: - bool VisitLambdaExpr(LambdaExpr *Lambda) { + LambdaExprVisitor() { ShouldVisitImplicitCode = false; } + + bool VisitLambdaExpr(LambdaExpr *Lambda) override { PendingBodies.push(Lambda->getBody()); PendingClasses.push(Lambda->getLambdaClass()); Match("", Lambda->getIntroducerRange().getBegin()); @@ -24,12 +26,12 @@ public: } /// For each call to VisitLambdaExpr, we expect a subsequent call to visit /// the body (and maybe the lambda class, which is implicit). - bool VisitStmt(Stmt *S) { + bool VisitStmt(Stmt *S) override { if (!PendingBodies.empty() && S == PendingBodies.top()) PendingBodies.pop(); return true; } - bool VisitDecl(Decl *D) { + bool VisitDecl(Decl *D) override { if (!PendingClasses.empty() && D == PendingClasses.top()) PendingClasses.pop(); return true; @@ -38,9 +40,6 @@ public: bool allBodiesHaveBeenTraversed() const { return PendingBodies.empty(); } bool allClassesHaveBeenTraversed() const { return PendingClasses.empty(); } - bool VisitImplicitCode = false; - bool shouldVisitImplicitCode() const { return VisitImplicitCode; } - private: std::stack PendingBodies; std::stack PendingClasses; @@ -67,7 +66,7 @@ TEST(RecursiveASTVisitor, LambdaInLambda) { TEST(RecursiveASTVisitor, TopLevelLambda) { LambdaExprVisitor Visitor; - Visitor.VisitImplicitCode = true; + Visitor.ShouldVisitImplicitCode = true; Visitor.ExpectMatch("", 1, 10); Visitor.ExpectMatch("", 1, 14); EXPECT_TRUE(Visitor.runOver("auto x = []{ [] {}; };", @@ -78,7 +77,7 @@ TEST(RecursiveASTVisitor, TopLevelLambda) { TEST(RecursiveASTVisitor, VisitsLambdaExprAndImplicitClass) { LambdaExprVisitor Visitor; - Visitor.VisitImplicitCode = true; + Visitor.ShouldVisitImplicitCode = true; Visitor.ExpectMatch("", 1, 12); EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", LambdaExprVisitor::Lang_CXX11)); diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp index c355e3f1083f..cfac3a3c5ad9 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp @@ -13,24 +13,23 @@ using namespace clang; namespace { // Matches (optional) explicit template parameters. -class LambdaTemplateParametersVisitor - : public ExpectedLocationVisitor { +class LambdaTemplateParametersVisitor : public ExpectedLocationVisitor { public: - bool shouldVisitImplicitCode() const { return false; } + LambdaTemplateParametersVisitor() { ShouldVisitImplicitCode = false; } - bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { + bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) override { EXPECT_FALSE(D->isImplicit()); Match(D->getName(), D->getBeginLoc()); return true; } - bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { + bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) override { EXPECT_FALSE(D->isImplicit()); Match(D->getName(), D->getBeginLoc()); return true; } - bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { + bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) override { EXPECT_FALSE(D->isImplicit()); Match(D->getName(), D->getBeginLoc()); return true; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp index d67bd0395a67..587a00dd2705 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp @@ -13,16 +13,15 @@ using namespace clang; namespace { -class MemberPointerTypeLocVisitor - : public ExpectedLocationVisitor { +class MemberPointerTypeLocVisitor : public ExpectedLocationVisitor { public: - bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override { if (!TL) return true; Match(TL.getDecl()->getName(), TL.getNameLoc()); return true; } - bool VisitRecordTypeLoc(RecordTypeLoc RTL) { + bool VisitRecordTypeLoc(RecordTypeLoc RTL) override { if (!RTL) return true; Match(RTL.getDecl()->getName(), RTL.getNameLoc()); diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp index 868a3988c756..ddc663e2b6fd 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp @@ -13,17 +13,16 @@ using namespace clang; namespace { // Check to ensure that nested name specifiers are visited. -class NestedNameSpecifiersVisitor - : public ExpectedLocationVisitor { +class NestedNameSpecifiersVisitor : public ExpectedLocationVisitor { public: - bool VisitRecordTypeLoc(RecordTypeLoc RTL) { + bool VisitRecordTypeLoc(RecordTypeLoc RTL) override { if (!RTL) return true; Match(RTL.getDecl()->getName(), RTL.getNameLoc()); return true; } - bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override { if (!NNS) return true; if (const NamespaceDecl *ND = diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp index c316f98f40ce..89ccf20587ad 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp @@ -12,9 +12,9 @@ using namespace clang; namespace { -class ParenExprVisitor : public ExpectedLocationVisitor { +class ParenExprVisitor : public ExpectedLocationVisitor { public: - bool VisitParenExpr(ParenExpr *Parens) { + bool VisitParenExpr(ParenExpr *Parens) override { Match("", Parens->getExprLoc()); return true; } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp index b87e89f3fd56..e5e743ab8d76 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp @@ -12,18 +12,16 @@ using namespace clang; namespace { -class TemplateArgumentLocTraverser - : public ExpectedLocationVisitor { +class TemplateArgumentLocTraverser : public ExpectedLocationVisitor { public: - bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { + bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) override { std::string ArgStr; llvm::raw_string_ostream Stream(ArgStr); const TemplateArgument &Arg = ArgLoc.getArgument(); Arg.print(Context->getPrintingPolicy(), Stream, /*IncludeType*/ true); Match(ArgStr, ArgLoc.getLocation()); - return ExpectedLocationVisitor:: - TraverseTemplateArgumentLoc(ArgLoc); + return ExpectedLocationVisitor::TraverseTemplateArgumentLoc(ArgLoc); } }; diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp index 9e71f9554e59..2feddf58cac7 100644 --- a/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp @@ -12,17 +12,17 @@ using namespace clang; namespace { -class Visitor : public ExpectedLocationVisitor { +class Visitor : public ExpectedLocationVisitor { public: Visitor(ASTContext *Context) { this->Context = Context; } - bool VisitTranslationUnitDecl(TranslationUnitDecl *D) { + bool VisitTranslationUnitDecl(TranslationUnitDecl *D) override { auto &SM = D->getParentASTContext().getSourceManager(); Match("TU", SM.getLocForStartOfFile(SM.getMainFileID())); return true; } - bool VisitNamedDecl(NamedDecl *D) { + bool VisitNamedDecl(NamedDecl *D) override { if (!D->isImplicit()) Match(D->getName(), D->getLocation()); return true; diff --git a/clang/unittests/Tooling/RefactoringTest.cpp b/clang/unittests/Tooling/RefactoringTest.cpp index 4f0cccdc2749..254d95bc20cb 100644 --- a/clang/unittests/Tooling/RefactoringTest.cpp +++ b/clang/unittests/Tooling/RefactoringTest.cpp @@ -13,7 +13,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" @@ -647,8 +647,7 @@ TEST_F(FlushRewrittenFilesTest, StoresChangesOnDisk) { } namespace { -template -class TestVisitor : public clang::RecursiveASTVisitor { +class TestVisitor : public DynamicRecursiveASTVisitor { public: bool runOver(StringRef Code) { return runToolOnCode(std::make_unique(this), Code); @@ -698,9 +697,9 @@ void expectReplacementAt(const Replacement &Replace, EXPECT_EQ(Length, Replace.getLength()); } -class ClassDeclXVisitor : public TestVisitor { +class ClassDeclXVisitor : public TestVisitor { public: - bool VisitCXXRecordDecl(CXXRecordDecl *Record) { + bool VisitCXXRecordDecl(CXXRecordDecl *Record) override { if (Record->getName() == "X") { Replace = Replacement(*SM, Record, ""); } @@ -721,9 +720,9 @@ TEST(Replacement, ReplacesAtSpellingLocation) { expectReplacementAt(ClassDeclX.Replace, "input.cc", 17, 7); } -class CallToFVisitor : public TestVisitor { +class CallToFVisitor : public TestVisitor { public: - bool VisitCallExpr(CallExpr *Call) { + bool VisitCallExpr(CallExpr *Call) override { if (Call->getDirectCallee()->getName() == "F") { Replace = Replacement(*SM, Call, ""); } @@ -745,10 +744,9 @@ TEST(Replacement, TemplatedFunctionCall) { expectReplacementAt(CallToF.Replace, "input.cc", 43, 8); } -class NestedNameSpecifierAVisitor - : public TestVisitor { +class NestedNameSpecifierAVisitor : public TestVisitor { public: - bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLoc) { + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLoc) override { if (NNSLoc.getNestedNameSpecifier()) { if (const NamespaceDecl* NS = NNSLoc.getNestedNameSpecifier()->getAsNamespace()) { if (NS->getName() == "a") { @@ -756,8 +754,7 @@ public: } } } - return TestVisitor::TraverseNestedNameSpecifierLoc( - NNSLoc); + return TestVisitor::TraverseNestedNameSpecifierLoc(NNSLoc); } Replacement Replace; }; diff --git a/clang/unittests/Tooling/SourceCodeTest.cpp b/clang/unittests/Tooling/SourceCodeTest.cpp index 3c24b6220a22..549b77752f1c 100644 --- a/clang/unittests/Tooling/SourceCodeTest.cpp +++ b/clang/unittests/Tooling/SourceCodeTest.cpp @@ -35,8 +35,8 @@ using tooling::validateEditRange; namespace { -struct IntLitVisitor : TestVisitor { - bool VisitIntegerLiteral(IntegerLiteral *Expr) { +struct IntLitVisitor : TestVisitor { + bool VisitIntegerLiteral(IntegerLiteral *Expr) override { OnIntLit(Expr, Context); return true; } @@ -44,8 +44,8 @@ struct IntLitVisitor : TestVisitor { std::function OnIntLit; }; -struct CallsVisitor : TestVisitor { - bool VisitCallExpr(CallExpr *Expr) { +struct CallsVisitor : TestVisitor { + bool VisitCallExpr(CallExpr *Expr) override { OnCall(Expr, Context); return true; } @@ -53,8 +53,8 @@ struct CallsVisitor : TestVisitor { std::function OnCall; }; -struct TypeLocVisitor : TestVisitor { - bool VisitTypeLoc(TypeLoc TL) { +struct TypeLocVisitor : TestVisitor { + bool VisitTypeLoc(TypeLoc TL) override { OnTypeLoc(TL, Context); return true; } @@ -97,7 +97,7 @@ static ::testing::Matcher AsRange(const SourceManager &SM, // Base class for visitors that expect a single match corresponding to a // specific annotated range. -template class AnnotatedCodeVisitor : public TestVisitor { +class AnnotatedCodeVisitor : public TestVisitor { protected: int MatchCount = 0; llvm::Annotations Code; @@ -199,9 +199,8 @@ TEST(SourceCodeTest, getExtendedText) { } TEST(SourceCodeTest, maybeExtendRange_TokenRange) { - struct ExtendTokenRangeVisitor - : AnnotatedCodeVisitor { - bool VisitCallExpr(CallExpr *CE) { + struct ExtendTokenRangeVisitor : AnnotatedCodeVisitor { + bool VisitCallExpr(CallExpr *CE) override { ++MatchCount; EXPECT_THAT(getExtendedRange(*CE, tok::TokenKind::semi, *Context), EqualsAnnotatedRange(Context, Code.range("r"))); @@ -218,8 +217,8 @@ TEST(SourceCodeTest, maybeExtendRange_TokenRange) { } TEST(SourceCodeTest, maybeExtendRange_CharRange) { - struct ExtendCharRangeVisitor : AnnotatedCodeVisitor { - bool VisitCallExpr(CallExpr *CE) { + struct ExtendCharRangeVisitor : AnnotatedCodeVisitor { + bool VisitCallExpr(CallExpr *CE) override { ++MatchCount; CharSourceRange Call = Lexer::getAsCharRange(CE->getSourceRange(), Context->getSourceManager(), @@ -238,8 +237,8 @@ TEST(SourceCodeTest, maybeExtendRange_CharRange) { } TEST(SourceCodeTest, getAssociatedRange) { - struct VarDeclsVisitor : AnnotatedCodeVisitor { - bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); } + struct VarDeclsVisitor : AnnotatedCodeVisitor { + bool VisitVarDecl(VarDecl *Decl) override { return VisitDeclHelper(Decl); } }; VarDeclsVisitor Visitor; @@ -283,8 +282,10 @@ TEST(SourceCodeTest, getAssociatedRange) { } TEST(SourceCodeTest, getAssociatedRangeClasses) { - struct RecordDeclsVisitor : AnnotatedCodeVisitor { - bool VisitRecordDecl(RecordDecl *Decl) { return VisitDeclHelper(Decl); } + struct RecordDeclsVisitor : AnnotatedCodeVisitor { + bool VisitRecordDecl(RecordDecl *Decl) override { + return VisitDeclHelper(Decl); + } }; RecordDeclsVisitor Visitor; @@ -297,8 +298,8 @@ TEST(SourceCodeTest, getAssociatedRangeClasses) { } TEST(SourceCodeTest, getAssociatedRangeClassTemplateSpecializations) { - struct CXXRecordDeclsVisitor : AnnotatedCodeVisitor { - bool VisitCXXRecordDecl(CXXRecordDecl *Decl) { + struct CXXRecordDeclsVisitor : AnnotatedCodeVisitor { + bool VisitCXXRecordDecl(CXXRecordDecl *Decl) override { return Decl->getTemplateSpecializationKind() != TSK_ExplicitSpecialization || VisitDeclHelper(Decl); @@ -315,8 +316,10 @@ TEST(SourceCodeTest, getAssociatedRangeClassTemplateSpecializations) { } TEST(SourceCodeTest, getAssociatedRangeFunctions) { - struct FunctionDeclsVisitor : AnnotatedCodeVisitor { - bool VisitFunctionDecl(FunctionDecl *Decl) { return VisitDeclHelper(Decl); } + struct FunctionDeclsVisitor : AnnotatedCodeVisitor { + bool VisitFunctionDecl(FunctionDecl *Decl) override { + return VisitDeclHelper(Decl); + } }; FunctionDeclsVisitor Visitor; @@ -328,8 +331,8 @@ TEST(SourceCodeTest, getAssociatedRangeFunctions) { } TEST(SourceCodeTest, getAssociatedRangeMemberTemplates) { - struct CXXMethodDeclsVisitor : AnnotatedCodeVisitor { - bool VisitCXXMethodDecl(CXXMethodDecl *Decl) { + struct CXXMethodDeclsVisitor : AnnotatedCodeVisitor { + bool VisitCXXMethodDecl(CXXMethodDecl *Decl) override { // Only consider the definition of the template. return !Decl->doesThisDeclarationHaveABody() || VisitDeclHelper(Decl); } @@ -346,8 +349,8 @@ TEST(SourceCodeTest, getAssociatedRangeMemberTemplates) { } TEST(SourceCodeTest, getAssociatedRangeWithComments) { - struct VarDeclsVisitor : AnnotatedCodeVisitor { - bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); } + struct VarDeclsVisitor : AnnotatedCodeVisitor { + bool VisitVarDecl(VarDecl *Decl) override { return VisitDeclHelper(Decl); } }; VarDeclsVisitor Visitor; @@ -447,9 +450,9 @@ TEST(SourceCodeTest, getAssociatedRangeWithComments) { } TEST(SourceCodeTest, getAssociatedRangeInvalidForPartialExpansions) { - struct FailingVarDeclsVisitor : TestVisitor { + struct FailingVarDeclsVisitor : TestVisitor { FailingVarDeclsVisitor() {} - bool VisitVarDecl(VarDecl *Decl) { + bool VisitVarDecl(VarDecl *Decl) override { EXPECT_TRUE(getAssociatedRange(*Decl, *Context).isInvalid()); return true; } diff --git a/clang/unittests/Tooling/TestVisitor.h b/clang/unittests/Tooling/TestVisitor.h index 751ca74d1a88..fdf57a946a6e 100644 --- a/clang/unittests/Tooling/TestVisitor.h +++ b/clang/unittests/Tooling/TestVisitor.h @@ -16,7 +16,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Tooling/Tooling.h" @@ -24,20 +24,11 @@ #include namespace clang { - -/// \brief Base class for simple RecursiveASTVisitor based tests. -/// -/// This is a drop-in replacement for RecursiveASTVisitor itself, with the -/// additional capability of running it over a snippet of code. -/// -/// Visits template instantiations and implicit code by default. -template -class TestVisitor : public RecursiveASTVisitor { +namespace detail { +// Use 'TestVisitor' or include 'CRTPTestVisitor.h' and use 'CRTPTestVisitor' +// instead of using this directly. +class TestVisitorHelper { public: - TestVisitor() { } - - virtual ~TestVisitor() { } - enum Language { Lang_C, Lang_CXX98, @@ -54,57 +45,63 @@ public: bool runOver(StringRef Code, Language L = Lang_CXX) { std::vector Args; switch (L) { - case Lang_C: - Args.push_back("-x"); - Args.push_back("c"); - break; - case Lang_CXX98: Args.push_back("-std=c++98"); break; - case Lang_CXX11: Args.push_back("-std=c++11"); break; - case Lang_CXX14: Args.push_back("-std=c++14"); break; - case Lang_CXX17: Args.push_back("-std=c++17"); break; - case Lang_CXX2a: Args.push_back("-std=c++2a"); break; - case Lang_OBJC: - Args.push_back("-ObjC"); - Args.push_back("-fobjc-runtime=macosx-10.12.0"); - break; - case Lang_OBJCXX11: - Args.push_back("-ObjC++"); - Args.push_back("-std=c++11"); - Args.push_back("-fblocks"); - break; + case Lang_C: + Args.push_back("-x"); + Args.push_back("c"); + break; + case Lang_CXX98: + Args.push_back("-std=c++98"); + break; + case Lang_CXX11: + Args.push_back("-std=c++11"); + break; + case Lang_CXX14: + Args.push_back("-std=c++14"); + break; + case Lang_CXX17: + Args.push_back("-std=c++17"); + break; + case Lang_CXX2a: + Args.push_back("-std=c++2a"); + break; + case Lang_OBJC: + Args.push_back("-ObjC"); + Args.push_back("-fobjc-runtime=macosx-10.12.0"); + break; + case Lang_OBJCXX11: + Args.push_back("-ObjC++"); + Args.push_back("-std=c++11"); + Args.push_back("-fblocks"); + break; } return tooling::runToolOnCodeWithArgs(CreateTestAction(), Code, Args); } - bool shouldVisitTemplateInstantiations() const { - return true; - } - - bool shouldVisitImplicitCode() const { - return true; - } - protected: + TestVisitorHelper() = default; + virtual ~TestVisitorHelper() = default; + virtual void InvokeTraverseDecl(TranslationUnitDecl *D) = 0; + virtual std::unique_ptr CreateTestAction() { return std::make_unique(this); } class FindConsumer : public ASTConsumer { public: - FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {} + FindConsumer(TestVisitorHelper *Visitor) : Visitor(Visitor) {} void HandleTranslationUnit(clang::ASTContext &Context) override { Visitor->Context = &Context; - Visitor->TraverseDecl(Context.getTranslationUnitDecl()); + Visitor->InvokeTraverseDecl(Context.getTranslationUnitDecl()); } private: - TestVisitor *Visitor; + TestVisitorHelper *Visitor; }; class TestAction : public ASTFrontendAction { public: - TestAction(TestVisitor *Visitor) : Visitor(Visitor) {} + TestAction(TestVisitorHelper *Visitor) : Visitor(Visitor) {} std::unique_ptr CreateASTConsumer(CompilerInstance &, llvm::StringRef dummy) override { @@ -113,20 +110,13 @@ protected: } protected: - TestVisitor *Visitor; + TestVisitorHelper *Visitor; }; ASTContext *Context; }; -/// \brief A RecursiveASTVisitor to check that certain matches are (or are -/// not) observed during visitation. -/// -/// This is a RecursiveASTVisitor for testing the RecursiveASTVisitor itself, -/// and allows simple creation of test visitors running matches on only a small -/// subset of the Visit* methods. -template class Visitor = TestVisitor> -class ExpectedLocationVisitor : public Visitor { +class ExpectedLocationVisitorHelper { public: /// \brief Expect 'Match' *not* to occur at the given 'Line' and 'Column'. /// @@ -147,37 +137,44 @@ public: } /// \brief Checks that all expected matches have been found. - ~ExpectedLocationVisitor() override { - for (typename std::vector::const_iterator - It = ExpectedMatches.begin(), End = ExpectedMatches.end(); + virtual ~ExpectedLocationVisitorHelper() { + // FIXME: Range-based for loop. + for (std::vector::const_iterator + It = ExpectedMatches.begin(), + End = ExpectedMatches.end(); It != End; ++It) { It->ExpectFound(); } } protected: + virtual ASTContext *getASTContext() = 0; + /// \brief Checks an actual match against expected and disallowed matches. /// /// Implementations are required to call this with appropriate values /// for 'Name' during visitation. void Match(StringRef Name, SourceLocation Location) { - const FullSourceLoc FullLocation = this->Context->getFullLoc(Location); + const FullSourceLoc FullLocation = getASTContext()->getFullLoc(Location); - for (typename std::vector::const_iterator - It = DisallowedMatches.begin(), End = DisallowedMatches.end(); + // FIXME: Range-based for loop. + for (std::vector::const_iterator + It = DisallowedMatches.begin(), + End = DisallowedMatches.end(); It != End; ++It) { EXPECT_FALSE(It->Matches(Name, FullLocation)) << "Matched disallowed " << *It; } - for (typename std::vector::iterator - It = ExpectedMatches.begin(), End = ExpectedMatches.end(); + // FIXME: Range-based for loop. + for (std::vector::iterator It = ExpectedMatches.begin(), + End = ExpectedMatches.end(); It != End; ++It) { - It->UpdateFor(Name, FullLocation, this->Context->getSourceManager()); + It->UpdateFor(Name, FullLocation, getASTContext()->getSourceManager()); } } - private: +private: struct MatchCandidate { std::string ExpectedName; unsigned LineNumber; @@ -247,6 +244,41 @@ protected: std::vector DisallowedMatches; std::vector ExpectedMatches; }; -} +} // namespace detail + +/// \brief Base class for simple (Dynamic)RecursiveASTVisitor based tests. +/// +/// This is a drop-in replacement for DynamicRecursiveASTVisitor itself, with +/// the additional capability of running it over a snippet of code. +/// +/// Visits template instantiations and implicit code by default. +/// +/// For post-order traversal etc. use CTRPTestVisitor from +/// CTRPTestVisitor.h instead. +class TestVisitor : public DynamicRecursiveASTVisitor, + public detail::TestVisitorHelper { +public: + TestVisitor() { + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = true; + } + + void InvokeTraverseDecl(TranslationUnitDecl *D) override { TraverseDecl(D); } +}; + +/// \brief A RecursiveASTVisitor to check that certain matches are (or are +/// not) observed during visitation. +/// +/// This is a RecursiveASTVisitor for testing the RecursiveASTVisitor itself, +/// and allows simple creation of test visitors running matches on only a small +/// subset of the Visit* methods. +/// +/// For post-order traversal etc. use CTRPExpectedLocationVisitor from +/// CTRPTestVisitor.h instead. +class ExpectedLocationVisitor : public TestVisitor, + public detail::ExpectedLocationVisitorHelper { + ASTContext *getASTContext() override { return Context; } +}; +} // namespace clang #endif