diff options
39 files changed, 542 insertions, 565 deletions
diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h index 78f8d11..c11d163 100644 --- a/clang/include/clang/Analysis/CallGraph.h +++ b/clang/include/clang/Analysis/CallGraph.h @@ -18,7 +18,8 @@ #define LLVM_CLANG_ANALYSIS_CALLGRAPH_H #include "clang/AST/Decl.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/STLExtras.h" @@ -39,7 +40,7 @@ class Stmt; /// The call graph extends itself with the given declarations by implementing /// the recursive AST visitor, which constructs the graph by visiting the given /// declarations. -class CallGraph : public RecursiveASTVisitor<CallGraph> { +class CallGraph : public DynamicRecursiveASTVisitor { friend class CallGraphNode; using FunctionMapTy = @@ -109,7 +110,7 @@ public: /// Part of recursive declaration visitation. We recursively visit all the /// declarations to collect the root functions. - bool VisitFunctionDecl(FunctionDecl *FD) { + bool VisitFunctionDecl(FunctionDecl *FD) override { // We skip function template definitions, as their semantics is // only determined when they are instantiated. if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) { @@ -124,7 +125,7 @@ public: } /// Part of recursive declaration visitation. - bool VisitObjCMethodDecl(ObjCMethodDecl *MD) { + bool VisitObjCMethodDecl(ObjCMethodDecl *MD) override { if (includeInGraph(MD)) { addNodesForBlocks(MD); addNodeForDecl(MD, true); @@ -133,11 +134,7 @@ public: } // We are only collecting the declarations, so do not step into the bodies. - bool TraverseStmt(Stmt *S) { return true; } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return true; } + bool TraverseStmt(Stmt *S) override { return true; } private: /// Add the given declaration to the call graph. diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h index ec4d041..6294c81 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h @@ -14,8 +14,9 @@ #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H #include "clang/AST/Decl.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/Type.h" #include "clang/Analysis/FlowSensitive/StorageLocation.h" #include "llvm/ADT/DenseSet.h" @@ -88,14 +89,14 @@ private: /// the function to analyze. Don't call `TraverseDecl()` on the function itself; /// this won't work as `TraverseDecl()` contains code to avoid traversing nested /// functions. -template <class Derived> -class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> { +class AnalysisASTVisitor : public DynamicRecursiveASTVisitor { public: - bool shouldVisitImplicitCode() { return true; } - - bool shouldVisitLambdaBody() const { return false; } + AnalysisASTVisitor() { + ShouldVisitImplicitCode = true; + ShouldVisitLambdaBody = false; + } - bool TraverseDecl(Decl *D) { + bool TraverseDecl(Decl *D) override { // Don't traverse nested record or function declarations. // - We won't be analyzing code contained in these anyway // - We don't model fields that are used only in these nested declaration, @@ -104,30 +105,30 @@ public: if (isa_and_nonnull<RecordDecl>(D) || isa_and_nonnull<FunctionDecl>(D)) return true; - return RecursiveASTVisitor<Derived>::TraverseDecl(D); + return DynamicRecursiveASTVisitor::TraverseDecl(D); } // Don't traverse expressions in unevaluated contexts, as we don't model // fields that are only used in these. // Note: The operand of the `noexcept` operator is an unevaluated operand, but // nevertheless it appears in the Clang CFG, so we don't exclude it here. - bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; } - bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; } - bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) { + bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) override { return true; } + bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) override { return true; } + bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) override { if (TIE->isPotentiallyEvaluated()) - return RecursiveASTVisitor<Derived>::TraverseCXXTypeidExpr(TIE); + return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(TIE); return true; } - bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) { + bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) override { return true; } - bool TraverseBindingDecl(BindingDecl *BD) { + bool TraverseBindingDecl(BindingDecl *BD) override { // `RecursiveASTVisitor` doesn't traverse holding variables for // `BindingDecl`s by itself, so we need to tell it to. if (VarDecl *HoldingVar = BD->getHoldingVar()) TraverseDecl(HoldingVar); - return RecursiveASTVisitor<Derived>::TraverseBindingDecl(BD); + return DynamicRecursiveASTVisitor::TraverseBindingDecl(BD); } }; diff --git a/clang/lib/Analysis/CallGraph.cpp b/clang/lib/Analysis/CallGraph.cpp index f892980..d9da74d 100644 --- a/clang/lib/Analysis/CallGraph.cpp +++ b/clang/lib/Analysis/CallGraph.cpp @@ -147,6 +147,9 @@ void CallGraph::addNodesForBlocks(DeclContext *D) { } CallGraph::CallGraph() { + ShouldWalkTypesOfTypeLocs = false; + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = true; Root = getOrInsertNode(nullptr); } diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp index 30cbd25..1554eab 100644 --- a/clang/lib/Analysis/CalledOnceCheck.cpp +++ b/clang/lib/Analysis/CalledOnceCheck.cpp @@ -11,11 +11,11 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/StmtVisitor.h" @@ -426,7 +426,7 @@ const Expr *getCondition(const Stmt *S) { /// of the AST will end up in the results. /// Results might have duplicate names, if this is a problem, convert to /// string sets afterwards. -class NamesCollector : public RecursiveASTVisitor<NamesCollector> { +class NamesCollector : public DynamicRecursiveASTVisitor { public: static constexpr unsigned EXPECTED_NUMBER_OF_NAMES = 5; using NameCollection = @@ -438,12 +438,12 @@ public: return Impl.Result; } - bool VisitDeclRefExpr(const DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { Result.push_back(E->getDecl()->getName()); return true; } - bool VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) { + bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) override { llvm::StringRef Name; if (E->isImplicitProperty()) { diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp index fdba139..9e7821b 100644 --- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp @@ -198,13 +198,12 @@ static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) { return nullptr; } -class ReferencedDeclsVisitor - : public AnalysisASTVisitor<ReferencedDeclsVisitor> { +class ReferencedDeclsVisitor : public AnalysisASTVisitor { public: ReferencedDeclsVisitor(ReferencedDecls &Referenced) : Referenced(Referenced) {} - void TraverseConstructorInits(const CXXConstructorDecl *Ctor) { + void traverseConstructorInits(const CXXConstructorDecl *Ctor) { for (const CXXCtorInitializer *Init : Ctor->inits()) { if (Init->isMemberInitializer()) { Referenced.Fields.insert(Init->getMember()); @@ -225,21 +224,21 @@ public: } } - bool VisitDecl(Decl *D) { + bool VisitDecl(Decl *D) override { insertIfGlobal(*D, Referenced.Globals); insertIfLocal(*D, Referenced.Locals); insertIfFunction(*D, Referenced.Functions); return true; } - bool VisitDeclRefExpr(DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { insertIfGlobal(*E->getDecl(), Referenced.Globals); insertIfLocal(*E->getDecl(), Referenced.Locals); insertIfFunction(*E->getDecl(), Referenced.Functions); return true; } - bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) { + bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) override { // If this is a method that returns a member variable but does nothing else, // model the field of the return value. if (MemberExpr *E = getMemberForAccessor(*C)) @@ -248,7 +247,7 @@ public: return true; } - bool VisitMemberExpr(MemberExpr *E) { + bool VisitMemberExpr(MemberExpr *E) override { // FIXME: should we be using `E->getFoundDecl()`? const ValueDecl *VD = E->getMemberDecl(); insertIfGlobal(*VD, Referenced.Globals); @@ -258,14 +257,14 @@ public: return true; } - bool VisitInitListExpr(InitListExpr *InitList) { + bool VisitInitListExpr(InitListExpr *InitList) override { if (InitList->getType()->isRecordType()) for (const auto *FD : getFieldsForInitListExpr(InitList)) Referenced.Fields.insert(FD); return true; } - bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) { + bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) override { if (ParenInitList->getType()->isRecordType()) for (const auto *FD : getFieldsForInitListExpr(ParenInitList)) Referenced.Fields.insert(FD); @@ -281,7 +280,7 @@ ReferencedDecls getReferencedDecls(const FunctionDecl &FD) { ReferencedDeclsVisitor Visitor(Result); Visitor.TraverseStmt(FD.getBody()); if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(&FD)) - Visitor.TraverseConstructorInits(CtorDecl); + Visitor.traverseConstructorInits(CtorDecl); return Result; } diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index e1f68e4..c5c6e90 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -298,7 +298,7 @@ namespace { // Visitor that builds a map from record prvalues to result objects. // For each result object that it encounters, it propagates the storage location // of the result object to all record prvalues that can initialize it. -class ResultObjectVisitor : public AnalysisASTVisitor<ResultObjectVisitor> { +class ResultObjectVisitor : public AnalysisASTVisitor { public: // `ResultObjectMap` will be filled with a map from record prvalues to result // object. If this visitor will traverse a function that returns a record by @@ -315,7 +315,7 @@ public: // called by `RecursiveASTVisitor`; it should be called manually if we are // analyzing a constructor. `ThisPointeeLoc` is the storage location that // `this` points to. - void TraverseConstructorInits(const CXXConstructorDecl *Ctor, + void traverseConstructorInits(const CXXConstructorDecl *Ctor, RecordStorageLocation *ThisPointeeLoc) { assert(ThisPointeeLoc != nullptr); for (const CXXCtorInitializer *Init : Ctor->inits()) { @@ -339,7 +339,7 @@ public: } } - bool VisitVarDecl(VarDecl *VD) { + bool VisitVarDecl(VarDecl *VD) override { if (VD->getType()->isRecordType() && VD->hasInit()) PropagateResultObject( VD->getInit(), @@ -347,7 +347,7 @@ public: return true; } - bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) { + bool VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *MTE) override { if (MTE->getType()->isRecordType()) PropagateResultObject( MTE->getSubExpr(), @@ -355,7 +355,7 @@ public: return true; } - bool VisitReturnStmt(ReturnStmt *Return) { + bool VisitReturnStmt(ReturnStmt *Return) override { Expr *RetValue = Return->getRetValue(); if (RetValue != nullptr && RetValue->getType()->isRecordType() && RetValue->isPRValue()) @@ -363,7 +363,7 @@ public: return true; } - bool VisitExpr(Expr *E) { + bool VisitExpr(Expr *E) override { // Clang's AST can have record-type prvalues without a result object -- for // example as full-expressions contained in a compound statement or as // arguments of call expressions. We notice this if we get here and a @@ -1211,7 +1211,7 @@ Environment::PrValueToResultObject Environment::buildResultObjectMap( ResultObjectVisitor Visitor(Map, LocForRecordReturnVal, *DACtx); if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(FuncDecl)) - Visitor.TraverseConstructorInits(Ctor, ThisPointeeLoc); + Visitor.traverseConstructorInits(Ctor, ThisPointeeLoc); return Map; } diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp index acbe147..dd81c8e 100644 --- a/clang/lib/Analysis/ReachableCode.cpp +++ b/clang/lib/Analysis/ReachableCode.cpp @@ -13,11 +13,11 @@ #include "clang/Analysis/Analyses/ReachableCode.h" #include "clang/AST/Attr.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtCXX.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" @@ -476,17 +476,19 @@ static bool isInCoroutineStmt(const Stmt *DeadStmt, const CFGBlock *Block) { } if (!CoroStmt) return false; - struct Checker : RecursiveASTVisitor<Checker> { + struct Checker : DynamicRecursiveASTVisitor { const Stmt *DeadStmt; bool CoroutineSubStmt = false; - Checker(const Stmt *S) : DeadStmt(S) {} - bool VisitStmt(const Stmt *S) { + Checker(const Stmt *S) : DeadStmt(S) { + // Statements captured in the CFG can be implicit. + ShouldVisitImplicitCode = true; + } + + bool VisitStmt(Stmt *S) override { if (S == DeadStmt) CoroutineSubStmt = true; return true; } - // Statements captured in the CFG can be implicit. - bool shouldVisitImplicitCode() const { return true; } }; Checker checker(DeadStmt); checker.TraverseStmt(const_cast<Stmt *>(CoroStmt)); diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index 81e9b68..5f36ffa 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -9,9 +9,9 @@ #include "clang/Analysis/Analyses/UnsafeBufferUsage.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/FormatString.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/Type.h" @@ -82,11 +82,8 @@ static std::string getDREAncestorString(const DeclRefExpr *DRE, namespace clang::ast_matchers { // A `RecursiveASTVisitor` that traverses all descendants of a given node "n" // except for those belonging to a different callable of "n". -class MatchDescendantVisitor - : public RecursiveASTVisitor<MatchDescendantVisitor> { +class MatchDescendantVisitor : public DynamicRecursiveASTVisitor { public: - typedef RecursiveASTVisitor<MatchDescendantVisitor> VisitorBase; - // Creates an AST visitor that matches `Matcher` on all // descendants of a given node "n" except for the ones // belonging to a different callable of "n". @@ -96,7 +93,10 @@ public: internal::ASTMatchFinder::BindKind Bind, const bool ignoreUnevaluatedContext) : Matcher(Matcher), Finder(Finder), Builder(Builder), Bind(Bind), - Matches(false), ignoreUnevaluatedContext(ignoreUnevaluatedContext) {} + Matches(false), ignoreUnevaluatedContext(ignoreUnevaluatedContext) { + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = false; // TODO: let's ignore implicit code for now + } // Returns true if a match is found in a subtree of `DynNode`, which belongs // to the same callable of `DynNode`. @@ -117,7 +117,7 @@ public: // For the matchers so far used in safe buffers, we only need to match // `Stmt`s. To override more as needed. - bool TraverseDecl(Decl *Node) { + bool TraverseDecl(Decl *Node) override { if (!Node) return true; if (!match(*Node)) @@ -126,63 +126,58 @@ public: if (isa<FunctionDecl, BlockDecl, ObjCMethodDecl>(Node)) return true; // Traverse descendants - return VisitorBase::TraverseDecl(Node); + return DynamicRecursiveASTVisitor::TraverseDecl(Node); } - bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) { + bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override { // These are unevaluated, except the result expression. if (ignoreUnevaluatedContext) return TraverseStmt(Node->getResultExpr()); - return VisitorBase::TraverseGenericSelectionExpr(Node); + return DynamicRecursiveASTVisitor::TraverseGenericSelectionExpr(Node); } - bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) { + bool + TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override { // Unevaluated context. if (ignoreUnevaluatedContext) return true; - return VisitorBase::TraverseUnaryExprOrTypeTraitExpr(Node); + return DynamicRecursiveASTVisitor::TraverseUnaryExprOrTypeTraitExpr(Node); } - bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) { + bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override { // Unevaluated context. if (ignoreUnevaluatedContext) return true; - return VisitorBase::TraverseTypeOfExprTypeLoc(Node); + return DynamicRecursiveASTVisitor::TraverseTypeOfExprTypeLoc(Node); } - bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) { + bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override { // Unevaluated context. if (ignoreUnevaluatedContext) return true; - return VisitorBase::TraverseDecltypeTypeLoc(Node); + return DynamicRecursiveASTVisitor::TraverseDecltypeTypeLoc(Node); } - bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) { + bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override { // Unevaluated context. if (ignoreUnevaluatedContext) return true; - return VisitorBase::TraverseCXXNoexceptExpr(Node); + return DynamicRecursiveASTVisitor::TraverseCXXNoexceptExpr(Node); } - bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) { + bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override { // Unevaluated context. if (ignoreUnevaluatedContext) return true; - return VisitorBase::TraverseCXXTypeidExpr(Node); + return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(Node); } - bool TraverseStmt(Stmt *Node, DataRecursionQueue *Queue = nullptr) { + bool TraverseStmt(Stmt *Node) override { if (!Node) return true; if (!match(*Node)) return false; - return VisitorBase::TraverseStmt(Node); - } - - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { - // TODO: let's ignore implicit code for now - return false; + return DynamicRecursiveASTVisitor::TraverseStmt(Node); } private: diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index c76733e..2ec98dc 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -16,13 +16,13 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/StmtVisitor.h" @@ -1067,81 +1067,79 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, } namespace { - class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> { - public: - FallthroughMapper(Sema &S) - : FoundSwitchStatements(false), - S(S) { - } +class FallthroughMapper : public DynamicRecursiveASTVisitor { +public: + FallthroughMapper(Sema &S) : FoundSwitchStatements(false), S(S) { + ShouldWalkTypesOfTypeLocs = false; + } - bool foundSwitchStatements() const { return FoundSwitchStatements; } + bool foundSwitchStatements() const { return FoundSwitchStatements; } - void markFallthroughVisited(const AttributedStmt *Stmt) { - bool Found = FallthroughStmts.erase(Stmt); - assert(Found); - (void)Found; - } + void markFallthroughVisited(const AttributedStmt *Stmt) { + bool Found = FallthroughStmts.erase(Stmt); + assert(Found); + (void)Found; + } + + typedef llvm::SmallPtrSet<const AttributedStmt *, 8> AttrStmts; + + const AttrStmts &getFallthroughStmts() const { return FallthroughStmts; } - typedef llvm::SmallPtrSet<const AttributedStmt*, 8> AttrStmts; + void fillReachableBlocks(CFG *Cfg) { + assert(ReachableBlocks.empty() && "ReachableBlocks already filled"); + std::deque<const CFGBlock *> BlockQueue; - const AttrStmts &getFallthroughStmts() const { - return FallthroughStmts; + ReachableBlocks.insert(&Cfg->getEntry()); + BlockQueue.push_back(&Cfg->getEntry()); + // Mark all case blocks reachable to avoid problems with switching on + // constants, covered enums, etc. + // These blocks can contain fall-through annotations, and we don't want to + // issue a warn_fallthrough_attr_unreachable for them. + for (const auto *B : *Cfg) { + const Stmt *L = B->getLabel(); + if (isa_and_nonnull<SwitchCase>(L) && ReachableBlocks.insert(B).second) + BlockQueue.push_back(B); } - void fillReachableBlocks(CFG *Cfg) { - assert(ReachableBlocks.empty() && "ReachableBlocks already filled"); - std::deque<const CFGBlock *> BlockQueue; - - ReachableBlocks.insert(&Cfg->getEntry()); - BlockQueue.push_back(&Cfg->getEntry()); - // Mark all case blocks reachable to avoid problems with switching on - // constants, covered enums, etc. - // These blocks can contain fall-through annotations, and we don't want to - // issue a warn_fallthrough_attr_unreachable for them. - for (const auto *B : *Cfg) { - const Stmt *L = B->getLabel(); - if (isa_and_nonnull<SwitchCase>(L) && ReachableBlocks.insert(B).second) + while (!BlockQueue.empty()) { + const CFGBlock *P = BlockQueue.front(); + BlockQueue.pop_front(); + for (const CFGBlock *B : P->succs()) { + if (B && ReachableBlocks.insert(B).second) BlockQueue.push_back(B); } - - while (!BlockQueue.empty()) { - const CFGBlock *P = BlockQueue.front(); - BlockQueue.pop_front(); - for (const CFGBlock *B : P->succs()) { - if (B && ReachableBlocks.insert(B).second) - BlockQueue.push_back(B); - } - } } + } - bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt, - bool IsTemplateInstantiation) { - assert(!ReachableBlocks.empty() && "ReachableBlocks empty"); + bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt, + bool IsTemplateInstantiation) { + assert(!ReachableBlocks.empty() && "ReachableBlocks empty"); - int UnannotatedCnt = 0; - AnnotatedCnt = 0; + int UnannotatedCnt = 0; + AnnotatedCnt = 0; - std::deque<const CFGBlock*> BlockQueue(B.pred_begin(), B.pred_end()); - while (!BlockQueue.empty()) { - const CFGBlock *P = BlockQueue.front(); - BlockQueue.pop_front(); - if (!P) continue; + std::deque<const CFGBlock *> BlockQueue(B.pred_begin(), B.pred_end()); + while (!BlockQueue.empty()) { + const CFGBlock *P = BlockQueue.front(); + BlockQueue.pop_front(); + if (!P) + continue; - const Stmt *Term = P->getTerminatorStmt(); - if (isa_and_nonnull<SwitchStmt>(Term)) - continue; // Switch statement, good. + const Stmt *Term = P->getTerminatorStmt(); + if (isa_and_nonnull<SwitchStmt>(Term)) + continue; // Switch statement, good. - const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel()); - if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end()) - continue; // Previous case label has no statements, good. + const SwitchCase *SW = dyn_cast_or_null<SwitchCase>(P->getLabel()); + if (SW && SW->getSubStmt() == B.getLabel() && P->begin() == P->end()) + continue; // Previous case label has no statements, good. - const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel()); - if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end()) - continue; // Case label is preceded with a normal label, good. + const LabelStmt *L = dyn_cast_or_null<LabelStmt>(P->getLabel()); + if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end()) + continue; // Case label is preceded with a normal label, good. - if (!ReachableBlocks.count(P)) { - for (const CFGElement &Elem : llvm::reverse(*P)) { - if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) { + if (!ReachableBlocks.count(P)) { + for (const CFGElement &Elem : llvm::reverse(*P)) { + if (std::optional<CFGStmt> CS = Elem.getAs<CFGStmt>()) { if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) { // Don't issue a warning for an unreachable fallthrough // attribute in template instantiations as it may not be @@ -1154,8 +1152,8 @@ namespace { break; } // Don't care about other unreachable statements. - } } + } // If there are no unreachable statements, this may be a special // case in CFG: // case X: { @@ -1165,7 +1163,7 @@ namespace { // // <<<< This place is represented by a 'hanging' CFG block. // case Y: continue; - } + } const Stmt *LastStmt = getLastStmt(*P); if (const AttributedStmt *AS = asFallThroughAttr(LastStmt)) { @@ -1182,30 +1180,27 @@ namespace { } ++UnannotatedCnt; - } - return !!UnannotatedCnt; } + return !!UnannotatedCnt; + } - // RecursiveASTVisitor setup. - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitAttributedStmt(AttributedStmt *S) { - if (asFallThroughAttr(S)) - FallthroughStmts.insert(S); - return true; - } + bool VisitAttributedStmt(AttributedStmt *S) override { + if (asFallThroughAttr(S)) + FallthroughStmts.insert(S); + return true; + } - bool VisitSwitchStmt(SwitchStmt *S) { - FoundSwitchStatements = true; - return true; - } + bool VisitSwitchStmt(SwitchStmt *S) override { + FoundSwitchStatements = true; + return true; + } // We don't want to traverse local type declarations. We analyze their // methods separately. - bool TraverseDecl(Decl *D) { return true; } + bool TraverseDecl(Decl *D) override { return true; } // We analyze lambda bodies separately. Skip them here. - bool TraverseLambdaExpr(LambdaExpr *LE) { + bool TraverseLambdaExpr(LambdaExpr *LE) override { // Traverse the captures, but not the body. for (const auto C : zip(LE->captures(), LE->capture_inits())) TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C)); @@ -1242,7 +1237,7 @@ namespace { AttrStmts FallthroughStmts; Sema &S; llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks; - }; +}; } // anonymous namespace static StringRef getFallthroughAttrSpelling(Preprocessor &PP, @@ -2502,15 +2497,18 @@ static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) { // An AST Visitor that calls a callback function on each callable DEFINITION // that is NOT in a dependent context: -class CallableVisitor : public RecursiveASTVisitor<CallableVisitor> { +class CallableVisitor : public DynamicRecursiveASTVisitor { private: llvm::function_ref<void(const Decl *)> Callback; public: CallableVisitor(llvm::function_ref<void(const Decl *)> Callback) - : Callback(Callback) {} + : Callback(Callback) { + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = false; + } - bool VisitFunctionDecl(FunctionDecl *Node) { + bool VisitFunctionDecl(FunctionDecl *Node) override { if (cast<DeclContext>(Node)->isDependentContext()) return true; // Not to analyze dependent decl // `FunctionDecl->hasBody()` returns true if the function has a body @@ -2521,14 +2519,14 @@ public: return true; } - bool VisitBlockDecl(BlockDecl *Node) { + bool VisitBlockDecl(BlockDecl *Node) override { if (cast<DeclContext>(Node)->isDependentContext()) return true; // Not to analyze dependent decl Callback(Node); return true; } - bool VisitObjCMethodDecl(ObjCMethodDecl *Node) { + bool VisitObjCMethodDecl(ObjCMethodDecl *Node) override { if (cast<DeclContext>(Node)->isDependentContext()) return true; // Not to analyze dependent decl if (Node->hasBody()) @@ -2536,12 +2534,9 @@ public: return true; } - bool VisitLambdaExpr(LambdaExpr *Node) { + bool VisitLambdaExpr(LambdaExpr *Node) override { return VisitFunctionDecl(Node->getCallOperator()); } - - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return false; } }; void clang::sema::AnalysisBasedWarnings::IssueWarnings( diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index 076d348..c806b83 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -13,7 +13,9 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclTemplate.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" +#include "clang/AST/ExprObjC.h" +#include "clang/AST/StmtObjC.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" @@ -741,11 +743,11 @@ bool isBodyLikeChildStmt(const Stmt *S, const Stmt *Parent) { } } -class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> { +class StmtUSEFinder : public DynamicRecursiveASTVisitor { const Stmt *Target; public: - bool VisitStmt(Stmt *S) { return S != Target; } + bool VisitStmt(Stmt *S) override { return S != Target; } /// Returns true if the given statement is present in the given declaration. static bool isContained(const Stmt *Target, const Decl *D) { @@ -757,11 +759,11 @@ public: /// Traverses the AST and finds the last statement that used a given /// declaration. -class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> { +class LastDeclUSEFinder : public DynamicRecursiveASTVisitor { const Decl *D; public: - bool VisitDeclRefExpr(DeclRefExpr *DRE) { + bool VisitDeclRefExpr(DeclRefExpr *DRE) override { if (DRE->getDecl() == D) return false; return true; @@ -785,10 +787,7 @@ public: /// to a partially available declaration. Whenever we encounter an \c if of the /// form: \c if(@available(...)), we use the version from the condition to visit /// the then statement. -class DiagnoseUnguardedAvailability - : public RecursiveASTVisitor<DiagnoseUnguardedAvailability> { - typedef RecursiveASTVisitor<DiagnoseUnguardedAvailability> Base; - +class DiagnoseUnguardedAvailability : public DynamicRecursiveASTVisitor { Sema &SemaRef; Decl *Ctx; @@ -806,26 +805,26 @@ public: SemaRef.Context.getTargetInfo().getPlatformMinVersion()); } - bool TraverseStmt(Stmt *S) { + bool TraverseStmt(Stmt *S) override { if (!S) return true; StmtStack.push_back(S); - bool Result = Base::TraverseStmt(S); + bool Result = DynamicRecursiveASTVisitor::TraverseStmt(S); StmtStack.pop_back(); return Result; } void IssueDiagnostics(Stmt *S) { TraverseStmt(S); } - bool TraverseIfStmt(IfStmt *If); + bool TraverseIfStmt(IfStmt *If) override; // for 'case X:' statements, don't bother looking at the 'X'; it can't lead // to any useful diagnostics. - bool TraverseCaseStmt(CaseStmt *CS) { return TraverseStmt(CS->getSubStmt()); } - - bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { return true; } + bool TraverseCaseStmt(CaseStmt *CS) override { + return TraverseStmt(CS->getSubStmt()); + } - bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) { + bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override { if (ObjCMethodDecl *D = Msg->getMethodDecl()) { ObjCInterfaceDecl *ID = nullptr; QualType ReceiverTy = Msg->getClassReceiver(); @@ -838,25 +837,25 @@ public: return true; } - bool VisitDeclRefExpr(DeclRefExpr *DRE) { + bool VisitDeclRefExpr(DeclRefExpr *DRE) override { DiagnoseDeclAvailability(DRE->getDecl(), SourceRange(DRE->getBeginLoc(), DRE->getEndLoc())); return true; } - bool VisitMemberExpr(MemberExpr *ME) { + bool VisitMemberExpr(MemberExpr *ME) override { DiagnoseDeclAvailability(ME->getMemberDecl(), SourceRange(ME->getBeginLoc(), ME->getEndLoc())); return true; } - bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) { + bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) override { SemaRef.Diag(E->getBeginLoc(), diag::warn_at_available_unchecked_use) << (!SemaRef.getLangOpts().ObjC); return true; } - bool VisitTypeLoc(TypeLoc Ty); + bool VisitTypeLoc(TypeLoc Ty) override; }; void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability( @@ -1038,7 +1037,7 @@ bool DiagnoseUnguardedAvailability::TraverseIfStmt(IfStmt *If) { ExtractedAvailabilityExpr IfCond = extractAvailabilityExpr(If->getCond()); if (!IfCond.E) { // This isn't an availability checking 'if', we can just continue. - return Base::TraverseIfStmt(If); + return DynamicRecursiveASTVisitor::TraverseIfStmt(If); } VersionTuple CondVersion = IfCond.E->getVersion(); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 16a76ff..45fc8a6 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprConcepts.h" @@ -22,7 +23,6 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/QualTypeNames.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/CharInfo.h" @@ -5422,7 +5422,7 @@ private: // This visitor infers members of T based on traversing expressions/types // that involve T. It is invoked with code known to be valid for T. - class ValidVisitor : public RecursiveASTVisitor<ValidVisitor> { + class ValidVisitor : public DynamicRecursiveASTVisitor { ConceptInfo *Outer; const TemplateTypeParmType *T; @@ -5440,7 +5440,8 @@ private: } // In T.foo or T->foo, `foo` is a member function/variable. - bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) { + bool + VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) override { const Type *Base = E->getBaseType().getTypePtr(); bool IsArrow = E->isArrow(); if (Base->isPointerType() && IsArrow) { @@ -5453,14 +5454,14 @@ private: } // In T::foo, `foo` is a static member function/variable. - bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { + bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) override { if (E->getQualifier() && isApprox(E->getQualifier()->getAsType(), T)) addValue(E, E->getDeclName(), Member::Colons); return true; } // In T::typename foo, `foo` is a type. - bool VisitDependentNameType(DependentNameType *DNT) { + bool VisitDependentNameType(DependentNameType *DNT) override { const auto *Q = DNT->getQualifier(); if (Q && isApprox(Q->getAsType(), T)) addType(DNT->getIdentifier()); @@ -5469,7 +5470,7 @@ private: // In T::foo::bar, `foo` must be a type. // VisitNNS() doesn't exist, and TraverseNNS isn't always called :-( - bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) { + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) override { if (NNSL) { NestedNameSpecifier *NNS = NNSL.getNestedNameSpecifier(); const auto *Q = NNS->getPrefix(); @@ -5477,14 +5478,14 @@ private: addType(NNS->getAsIdentifier()); } // FIXME: also handle T::foo<X>::bar - return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL); + return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL); } // FIXME also handle T::foo<X> // Track the innermost caller/callee relationship so we can tell if a // nested expr is being called as a function. - bool VisitCallExpr(CallExpr *CE) { + bool VisitCallExpr(CallExpr *CE) override { Caller = CE; Callee = CE->getCallee(); return true; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 379d348..4a15400 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -18,10 +18,10 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/Mangle.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Cuda.h" @@ -725,8 +725,7 @@ static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D, namespace { /// Determines if a given Expr references any of the given function's /// ParmVarDecls, or the function's implicit `this` parameter (if applicable). -class ArgumentDependenceChecker - : public RecursiveASTVisitor<ArgumentDependenceChecker> { +class ArgumentDependenceChecker : public DynamicRecursiveASTVisitor { #ifndef NDEBUG const CXXRecordDecl *ClassType; #endif @@ -750,14 +749,14 @@ public: return Result; } - bool VisitCXXThisExpr(CXXThisExpr *E) { + bool VisitCXXThisExpr(CXXThisExpr *E) override { assert(E->getType()->getPointeeCXXRecordDecl() == ClassType && "`this` doesn't refer to the enclosing class?"); Result = true; return false; } - bool VisitDeclRefExpr(DeclRefExpr *DRE) { + bool VisitDeclRefExpr(DeclRefExpr *DRE) override { if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) if (Parms.count(PVD)) { Result = true; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8d76a35..5d81d6d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -19,11 +19,11 @@ #include "clang/AST/ComparisonCategories.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/RecordLayout.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" @@ -2499,10 +2499,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) { assert(FD->isImmediateEscalating() && !FD->isConsteval() && "expected an immediate function"); assert(FD->hasBody() && "expected the function to have a body"); - struct ImmediateEscalatingExpressionsVisitor - : public RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor> { - - using Base = RecursiveASTVisitor<ImmediateEscalatingExpressionsVisitor>; + struct ImmediateEscalatingExpressionsVisitor : DynamicRecursiveASTVisitor { Sema &SemaRef; const FunctionDecl *ImmediateFn; @@ -2512,10 +2509,10 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) { ImmediateEscalatingExpressionsVisitor(Sema &SemaRef, FunctionDecl *FD) : SemaRef(SemaRef), ImmediateFn(FD), - ImmediateFnIsConstructor(isa<CXXConstructorDecl>(FD)) {} - - bool shouldVisitImplicitCode() const { return true; } - bool shouldVisitLambdaBody() const { return false; } + ImmediateFnIsConstructor(isa<CXXConstructorDecl>(FD)) { + ShouldVisitImplicitCode = true; + ShouldVisitLambdaBody = false; + } void Diag(const Expr *E, const FunctionDecl *Fn, bool IsCall) { SourceLocation Loc = E->getBeginLoc(); @@ -2535,7 +2532,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) { << (CurrentInit && !CurrentInit->isWritten()) << InitializedField << Range; } - bool TraverseCallExpr(CallExpr *E) { + bool TraverseCallExpr(CallExpr *E) override { if (const auto *DR = dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImplicit()); DR && DR->isImmediateEscalating()) { @@ -2544,13 +2541,13 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) { } for (Expr *A : E->arguments()) - if (!getDerived().TraverseStmt(A)) + if (!TraverseStmt(A)) return false; return true; } - bool VisitDeclRefExpr(DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { if (const auto *ReferencedFn = dyn_cast<FunctionDecl>(E->getDecl()); ReferencedFn && E->isImmediateEscalating()) { Diag(E, ReferencedFn, /*IsCall=*/false); @@ -2560,7 +2557,7 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) { return true; } - bool VisitCXXConstructExpr(CXXConstructExpr *E) { + bool VisitCXXConstructExpr(CXXConstructExpr *E) override { CXXConstructorDecl *D = E->getConstructor(); if (E->isImmediateEscalating()) { Diag(E, D, /*IsCall=*/true); @@ -2569,18 +2566,18 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) { return true; } - bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override { llvm::SaveAndRestore RAII(CurrentInit, Init); - return Base::TraverseConstructorInitializer(Init); + return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init); } - bool TraverseCXXConstructorDecl(CXXConstructorDecl *Ctr) { + bool TraverseCXXConstructorDecl(CXXConstructorDecl *Ctr) override { llvm::SaveAndRestore RAII(CurrentConstructor, Ctr); - return Base::TraverseCXXConstructorDecl(Ctr); + return DynamicRecursiveASTVisitor::TraverseCXXConstructorDecl(Ctr); } - bool TraverseType(QualType T) { return true; } - bool VisitBlockExpr(BlockExpr *T) { return true; } + bool TraverseType(QualType T) override { return true; } + bool VisitBlockExpr(BlockExpr *T) override { return true; } } Visitor(*this, FD); Visitor.TraverseDecl(FD); @@ -18750,18 +18747,18 @@ void Sema::CheckDelegatingCtorCycles() { namespace { /// AST visitor that finds references to the 'this' expression. - class FindCXXThisExpr : public RecursiveASTVisitor<FindCXXThisExpr> { - Sema &S; +class FindCXXThisExpr : public DynamicRecursiveASTVisitor { + Sema &S; - public: - explicit FindCXXThisExpr(Sema &S) : S(S) { } +public: + explicit FindCXXThisExpr(Sema &S) : S(S) {} - bool VisitCXXThisExpr(CXXThisExpr *E) { - S.Diag(E->getLocation(), diag::err_this_static_member_func) + bool VisitCXXThisExpr(CXXThisExpr *E) override { + S.Diag(E->getLocation(), diag::err_this_static_member_func) << E->isImplicit(); - return false; - } - }; + return false; + } +}; } bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) { diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 431f267..10af06d 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -15,9 +15,9 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" @@ -5317,8 +5317,7 @@ SemaObjC::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, namespace { /// Used by SemaObjC::DiagnoseUnusedBackingIvarInAccessor to check if a property /// accessor references the backing ivar. -class UnusedBackingIvarChecker - : public RecursiveASTVisitor<UnusedBackingIvarChecker> { +class UnusedBackingIvarChecker : public DynamicRecursiveASTVisitor { public: Sema &S; const ObjCMethodDecl *Method; @@ -5333,7 +5332,7 @@ public: assert(IvarD); } - bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { + bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) override { if (E->getDecl() == IvarD) { AccessedIvar = true; return false; @@ -5341,7 +5340,7 @@ public: return true; } - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { + bool VisitObjCMessageExpr(ObjCMessageExpr *E) override { if (E->getReceiverKind() == ObjCMessageExpr::Instance && S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) { InvokedSelfMethod = true; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 01d4331..c9de781 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -21,6 +21,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -29,7 +30,6 @@ #include "clang/AST/MangleNumberingContext.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/ParentMapContext.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" @@ -5395,32 +5395,33 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, return false; } -struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> { +struct ImmediateCallVisitor : DynamicRecursiveASTVisitor { const ASTContext &Context; - ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) {} + ImmediateCallVisitor(const ASTContext &Ctx) : Context(Ctx) { + ShouldVisitImplicitCode = true; + } bool HasImmediateCalls = false; - bool shouldVisitImplicitCode() const { return true; } - bool VisitCallExpr(CallExpr *E) { + bool VisitCallExpr(CallExpr *E) override { if (const FunctionDecl *FD = E->getDirectCallee()) HasImmediateCalls |= FD->isImmediateFunction(); - return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E); + return DynamicRecursiveASTVisitor::VisitStmt(E); } - bool VisitCXXConstructExpr(CXXConstructExpr *E) { + bool VisitCXXConstructExpr(CXXConstructExpr *E) override { if (const FunctionDecl *FD = E->getConstructor()) HasImmediateCalls |= FD->isImmediateFunction(); - return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E); + return DynamicRecursiveASTVisitor::VisitStmt(E); } // SourceLocExpr are not immediate invocations // but CXXDefaultInitExpr/CXXDefaultArgExpr containing a SourceLocExpr // need to be rebuilt so that they refer to the correct SourceLocation and // DeclContext. - bool VisitSourceLocExpr(SourceLocExpr *E) { + bool VisitSourceLocExpr(SourceLocExpr *E) override { HasImmediateCalls = true; - return RecursiveASTVisitor<ImmediateCallVisitor>::VisitStmt(E); + return DynamicRecursiveASTVisitor::VisitStmt(E); } // A nested lambda might have parameters with immediate invocations @@ -5429,15 +5430,15 @@ struct ImmediateCallVisitor : public RecursiveASTVisitor<ImmediateCallVisitor> { // subexpression). // FIXME: We should consider visiting and transforming captures // with init expressions. - bool VisitLambdaExpr(LambdaExpr *E) { + bool VisitLambdaExpr(LambdaExpr *E) override { return VisitCXXMethodDecl(E->getCallOperator()); } - bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { + bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) override { return TraverseStmt(E->getExpr()); } - bool VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { + bool VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) override { return TraverseStmt(E->getExpr()); } }; @@ -9201,17 +9202,17 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // __builtin_counted_by_ref cannot be assigned to a variable, used in // function call, or in a return. auto FindBuiltinCountedByRefExpr = [&](Expr *E) -> CallExpr * { - struct BuiltinCountedByRefVisitor - : public RecursiveASTVisitor<BuiltinCountedByRefVisitor> { + struct BuiltinCountedByRefVisitor : DynamicRecursiveASTVisitor { CallExpr *TheCall = nullptr; - bool VisitCallExpr(CallExpr *CE) { + bool VisitCallExpr(CallExpr *CE) override { if (CE->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref) { TheCall = CE; return false; } return true; } - bool VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) { + bool + VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) override { // A UnaryExprOrTypeTraitExpr---e.g. sizeof, __alignof, etc.---isn't // the same as a CallExpr, so if we find a __builtin_counted_by_ref() // call in one, ignore it. @@ -13782,13 +13783,12 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, // subscript on the LHS. int DiagOption = -1; auto FindInvalidUseOfBoundsSafetyCounter = [&](Expr *E) -> CallExpr * { - struct BuiltinCountedByRefVisitor - : public RecursiveASTVisitor<BuiltinCountedByRefVisitor> { + struct BuiltinCountedByRefVisitor : DynamicRecursiveASTVisitor { CallExpr *CE = nullptr; bool InvalidUse = false; int Option = -1; - bool VisitCallExpr(CallExpr *E) { + bool VisitCallExpr(CallExpr *E) override { if (E->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref) { CE = E; return false; @@ -13796,12 +13796,12 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, return true; } - bool VisitArraySubscriptExpr(ArraySubscriptExpr *E) { + bool VisitArraySubscriptExpr(ArraySubscriptExpr *E) override { InvalidUse = true; Option = 0; // report 'array expression' in diagnostic. return true; } - bool VisitBinaryOperator(BinaryOperator *E) { + bool VisitBinaryOperator(BinaryOperator *E) override { InvalidUse = true; Option = 1; // report 'binary expression' in diagnostic. return true; @@ -17742,10 +17742,10 @@ HandleImmediateInvocations(Sema &SemaRef, RemoveNestedImmediateInvocation(SemaRef, Rec, It); } else if (Rec.ImmediateInvocationCandidates.size() == 1 && Rec.ReferenceToConsteval.size()) { - struct SimpleRemove : RecursiveASTVisitor<SimpleRemove> { + struct SimpleRemove : DynamicRecursiveASTVisitor { llvm::SmallPtrSetImpl<DeclRefExpr *> &DRSet; SimpleRemove(llvm::SmallPtrSetImpl<DeclRefExpr *> &S) : DRSet(S) {} - bool VisitDeclRefExpr(DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { DRSet.erase(E); return DRSet.size(); } @@ -20054,17 +20054,15 @@ namespace { // TreeTransforms rebuilding the type in a new context. Rather than // duplicating the TreeTransform logic, we should consider reusing it here. // Currently that causes problems when rebuilding LambdaExprs. - class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> { - Sema &S; - SourceLocation Loc; - - public: - typedef RecursiveASTVisitor<MarkReferencedDecls> Inherited; +class MarkReferencedDecls : public DynamicRecursiveASTVisitor { + Sema &S; + SourceLocation Loc; - MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) { } +public: + MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) {} - bool TraverseTemplateArgument(const TemplateArgument &Arg); - }; + bool TraverseTemplateArgument(const TemplateArgument &Arg) override; +}; } bool MarkReferencedDecls::TraverseTemplateArgument( @@ -20081,7 +20079,7 @@ bool MarkReferencedDecls::TraverseTemplateArgument( } } - return Inherited::TraverseTemplateArgument(Arg); + return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg); } void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) { diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index ab9367f..4e3e968 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -18,10 +18,10 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/AlignedAllocation.h" @@ -8821,13 +8821,13 @@ static ExprResult attemptRecovery(Sema &SemaRef, } namespace { -class FindTypoExprs : public RecursiveASTVisitor<FindTypoExprs> { +class FindTypoExprs : public DynamicRecursiveASTVisitor { llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs; public: explicit FindTypoExprs(llvm::SmallSetVector<TypoExpr *, 2> &TypoExprs) : TypoExprs(TypoExprs) {} - bool VisitTypoExpr(TypoExpr *TE) { + bool VisitTypoExpr(TypoExpr *TE) override { TypoExprs.insert(TE); return true; } diff --git a/clang/lib/Sema/SemaFunctionEffects.cpp b/clang/lib/Sema/SemaFunctionEffects.cpp index a76a0a4..4b5ddb7 100644 --- a/clang/lib/Sema/SemaFunctionEffects.cpp +++ b/clang/lib/Sema/SemaFunctionEffects.cpp @@ -12,8 +12,10 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtObjC.h" #include "clang/AST/Type.h" #include "clang/Basic/SourceManager.h" #include "clang/Sema/SemaInternal.h" @@ -964,9 +966,7 @@ private: // being checked for implicit conformance. // // Violations are always routed to a PendingFunctionAnalysis. - struct FunctionBodyASTVisitor : RecursiveASTVisitor<FunctionBodyASTVisitor> { - using Base = RecursiveASTVisitor<FunctionBodyASTVisitor>; - + struct FunctionBodyASTVisitor : DynamicRecursiveASTVisitor { Analyzer &Outer; PendingFunctionAnalysis &CurrentFunction; CallableInfo &CurrentCaller; @@ -978,7 +978,10 @@ private: PendingFunctionAnalysis &CurrentFunction, CallableInfo &CurrentCaller) : Outer(Outer), CurrentFunction(CurrentFunction), - CurrentCaller(CurrentCaller) {} + CurrentCaller(CurrentCaller) { + ShouldVisitImplicitCode = true; + ShouldWalkTypesOfTypeLocs = false; + } // -- Entry point -- void run() { @@ -1119,53 +1122,49 @@ private: // -- Methods for use of RecursiveASTVisitor -- - bool shouldVisitImplicitCode() const { return true; } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitCXXThrowExpr(CXXThrowExpr *Throw) { + bool VisitCXXThrowExpr(CXXThrowExpr *Throw) override { diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow, ViolationID::ThrowsOrCatchesExceptions, Throw->getThrowLoc()); return true; } - bool VisitCXXCatchStmt(CXXCatchStmt *Catch) { + bool VisitCXXCatchStmt(CXXCatchStmt *Catch) override { diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch, ViolationID::ThrowsOrCatchesExceptions, Catch->getCatchLoc()); return true; } - bool VisitObjCAtThrowStmt(ObjCAtThrowStmt *Throw) { + bool VisitObjCAtThrowStmt(ObjCAtThrowStmt *Throw) override { diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow, ViolationID::ThrowsOrCatchesExceptions, Throw->getThrowLoc()); return true; } - bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *Catch) { + bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *Catch) override { diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch, ViolationID::ThrowsOrCatchesExceptions, Catch->getAtCatchLoc()); return true; } - bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) { + bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) override { diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch, ViolationID::ThrowsOrCatchesExceptions, Finally->getAtFinallyLoc()); return true; } - bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) { + bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override { diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend, ViolationID::AccessesObjCMethodOrProperty, Msg->getBeginLoc()); return true; } - bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) { + bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) override { // Under the hood, @autorelease (potentially?) allocates memory and // invokes ObjC methods. We don't currently have memory allocation as // a "language construct" but we do have ObjC messaging, so diagnose that. @@ -1175,7 +1174,7 @@ private: return true; } - bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) { + bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) override { // Under the hood, this calls objc_sync_enter and objc_sync_exit, wrapped // in a @try/@finally block. Diagnose this generically as "ObjC // messaging". @@ -1185,14 +1184,14 @@ private: return true; } - bool VisitSEHExceptStmt(SEHExceptStmt *Exc) { + bool VisitSEHExceptStmt(SEHExceptStmt *Exc) override { diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch, ViolationID::ThrowsOrCatchesExceptions, Exc->getExceptLoc()); return true; } - bool VisitCallExpr(CallExpr *Call) { + bool VisitCallExpr(CallExpr *Call) override { LLVM_DEBUG(llvm::dbgs() << "VisitCallExpr : " << Call->getBeginLoc().printToString(Outer.S.SourceMgr) @@ -1216,7 +1215,7 @@ private: return true; } - bool VisitVarDecl(VarDecl *Var) { + bool VisitVarDecl(VarDecl *Var) override { LLVM_DEBUG(llvm::dbgs() << "VisitVarDecl : " << Var->getBeginLoc().printToString(Outer.S.SourceMgr) @@ -1234,7 +1233,7 @@ private: return true; } - bool VisitCXXNewExpr(CXXNewExpr *New) { + bool VisitCXXNewExpr(CXXNewExpr *New) override { // RecursiveASTVisitor does not visit the implicit call to operator new. if (FunctionDecl *FD = New->getOperatorNew()) { CallableInfo CI(*FD, SpecialFuncType::OperatorNew); @@ -1249,7 +1248,7 @@ private: return true; } - bool VisitCXXDeleteExpr(CXXDeleteExpr *Delete) { + bool VisitCXXDeleteExpr(CXXDeleteExpr *Delete) override { // RecursiveASTVisitor does not visit the implicit call to operator // delete. if (FunctionDecl *FD = Delete->getOperatorDelete()) { @@ -1262,7 +1261,7 @@ private: return true; } - bool VisitCXXConstructExpr(CXXConstructExpr *Construct) { + bool VisitCXXConstructExpr(CXXConstructExpr *Construct) override { LLVM_DEBUG(llvm::dbgs() << "VisitCXXConstructExpr : " << Construct->getBeginLoc().printToString( Outer.S.SourceMgr) @@ -1277,28 +1276,28 @@ private: return true; } - bool TraverseStmt(Stmt *Statement) { + bool TraverseStmt(Stmt *Statement) override { // If this statement is a `requires` clause from the top-level function // being traversed, ignore it, since it's not generating runtime code. // We skip the traversal of lambdas (beyond their captures, see // TraverseLambdaExpr below), so just caching this from our constructor // should suffice. - // The exact same is true for a conditional `noexcept()` clause. if (Statement != TrailingRequiresClause && Statement != NoexceptExpr) - return Base::TraverseStmt(Statement); + return DynamicRecursiveASTVisitor::TraverseStmt(Statement); return true; } - bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override { ViolationSite PrevVS = VSite; if (Init->isAnyMemberInitializer()) VSite.setKind(ViolationSite::Kind::MemberInitializer); - bool Result = Base::TraverseConstructorInitializer(Init); + bool Result = + DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init); VSite = PrevVS; return Result; } - bool TraverseCXXDefaultArgExpr(CXXDefaultArgExpr *E) { + bool TraverseCXXDefaultArgExpr(CXXDefaultArgExpr *E) override { LLVM_DEBUG(llvm::dbgs() << "TraverseCXXDefaultArgExpr : " << E->getUsedLocation().printToString(Outer.S.SourceMgr) @@ -1308,12 +1307,12 @@ private: if (VSite.kind() == ViolationSite::Kind::Default) VSite = ViolationSite{E}; - bool Result = Base::TraverseCXXDefaultArgExpr(E); + bool Result = DynamicRecursiveASTVisitor::TraverseCXXDefaultArgExpr(E); VSite = PrevVS; return Result; } - bool TraverseLambdaExpr(LambdaExpr *Lambda) { + bool TraverseLambdaExpr(LambdaExpr *Lambda) override { // We override this so as to be able to skip traversal of the lambda's // body. We have to explicitly traverse the captures. Why not return // false from shouldVisitLambdaBody()? Because we need to visit a lambda's @@ -1326,13 +1325,13 @@ private: return true; } - bool TraverseBlockExpr(BlockExpr * /*unused*/) { + bool TraverseBlockExpr(BlockExpr * /*unused*/) override { // As with lambdas, don't traverse the block's body. // TODO: are the capture expressions (ctor call?) safe? return true; } - bool VisitDeclRefExpr(const DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { const ValueDecl *Val = E->getDecl(); if (const auto *Var = dyn_cast<VarDecl>(Val)) { if (Var->getTLSKind() != VarDecl::TLS_None) { @@ -1346,23 +1345,30 @@ private: return true; } - bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) { + bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override { return TraverseStmt(Node->getResultExpr()); } - bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) { + bool + TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override { return true; } - bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) { return true; } + bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override { + return true; + } - bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) { return true; } + bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override { return true; } - bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) { return true; } + bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override { + return true; + } - bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) { return true; } + bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override { return true; } // Skip concept requirements since they don't generate code. - bool TraverseConceptRequirement(concepts::Requirement *R) { return true; } + bool TraverseConceptRequirement(concepts::Requirement *R) override { + return true; + } }; }; diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 79d0d73..92d6436 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -15,8 +15,8 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" @@ -1304,9 +1304,7 @@ namespace { /// and of all exported functions, and any functions that are referenced /// from this AST. In other words, any functions that are reachable from /// the entry points. -class DiagnoseHLSLAvailability - : public RecursiveASTVisitor<DiagnoseHLSLAvailability> { - +class DiagnoseHLSLAvailability : public DynamicRecursiveASTVisitor { Sema &SemaRef; // Stack of functions to be scaned @@ -1409,14 +1407,14 @@ public: void RunOnTranslationUnit(const TranslationUnitDecl *TU); void RunOnFunction(const FunctionDecl *FD); - bool VisitDeclRefExpr(DeclRefExpr *DRE) { + bool VisitDeclRefExpr(DeclRefExpr *DRE) override { FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(DRE->getDecl()); if (FD) HandleFunctionOrMethodRef(FD, DRE); return true; } - bool VisitMemberExpr(MemberExpr *ME) { + bool VisitMemberExpr(MemberExpr *ME) override { FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(ME->getMemberDecl()); if (FD) HandleFunctionOrMethodRef(FD, ME); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index fe8bb99..19d5675 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -20,8 +20,8 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclOpenMP.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/OpenMPClause.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtOpenMP.h" #include "clang/AST/StmtVisitor.h" @@ -7684,7 +7684,7 @@ struct LoopIterationSpace final { /// Scan an AST subtree, checking that no decls in the CollapsedLoopVarDecls /// set are referenced. Used for verifying loop nest structure before /// performing a loop collapse operation. -class ForSubExprChecker final : public RecursiveASTVisitor<ForSubExprChecker> { +class ForSubExprChecker : public DynamicRecursiveASTVisitor { const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls; VarDecl *ForbiddenVar = nullptr; SourceRange ErrLoc; @@ -7692,13 +7692,13 @@ class ForSubExprChecker final : public RecursiveASTVisitor<ForSubExprChecker> { public: explicit ForSubExprChecker( const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls) - : CollapsedLoopVarDecls(CollapsedLoopVarDecls) {} - - // We want to visit implicit code, i.e. synthetic initialisation statements - // created during range-for lowering. - bool shouldVisitImplicitCode() const { return true; } + : CollapsedLoopVarDecls(CollapsedLoopVarDecls) { + // We want to visit implicit code, i.e. synthetic initialisation statements + // created during range-for lowering. + ShouldVisitImplicitCode = true; + } - bool VisitDeclRefExpr(DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { ValueDecl *VD = E->getDecl(); if (!isa<VarDecl, BindingDecl>(VD)) return true; @@ -9581,7 +9581,7 @@ static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { /// Look for variables declared in the body parts of a for-loop nest. Used /// for verifying loop nest structure before performing a loop collapse /// operation. -class ForVarDeclFinder final : public RecursiveASTVisitor<ForVarDeclFinder> { +class ForVarDeclFinder : public DynamicRecursiveASTVisitor { int NestingDepth = 0; llvm::SmallPtrSetImpl<const Decl *> &VarDecls; @@ -9589,21 +9589,21 @@ public: explicit ForVarDeclFinder(llvm::SmallPtrSetImpl<const Decl *> &VD) : VarDecls(VD) {} - bool VisitForStmt(ForStmt *F) { + bool VisitForStmt(ForStmt *F) override { ++NestingDepth; TraverseStmt(F->getBody()); --NestingDepth; return false; } - bool VisitCXXForRangeStmt(CXXForRangeStmt *RF) { + bool VisitCXXForRangeStmt(CXXForRangeStmt *RF) override { ++NestingDepth; TraverseStmt(RF->getBody()); --NestingDepth; return false; } - bool VisitVarDecl(VarDecl *D) { + bool VisitVarDecl(VarDecl *D) override { Decl *C = D->getCanonicalDecl(); if (NestingDepth > 0) VarDecls.insert(C); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 38ae6d8..2372059 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -17,11 +17,11 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/IgnoreExpr.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/TypeLoc.h" @@ -3606,15 +3606,15 @@ namespace { /// others. Pretend that all local typedefs are always referenced, to not warn /// on this. This isn't necessary if f has internal linkage, or the typedef /// is private. -class LocalTypedefNameReferencer - : public RecursiveASTVisitor<LocalTypedefNameReferencer> { +class LocalTypedefNameReferencer : public DynamicRecursiveASTVisitor { public: LocalTypedefNameReferencer(Sema &S) : S(S) {} - bool VisitRecordType(const RecordType *RT); + bool VisitRecordType(RecordType *RT) override; + private: Sema &S; }; -bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) { +bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) { auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl()); if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() || R->isDependentType()) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 8527219..58b1c39 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -14,9 +14,9 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateName.h" #include "clang/AST/TypeVisitor.h" #include "clang/Basic/Builtins.h" @@ -2563,9 +2563,7 @@ namespace { /// A class which looks for a use of a certain level of template /// parameter. -struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { - typedef RecursiveASTVisitor<DependencyChecker> super; - +struct DependencyChecker : DynamicRecursiveASTVisitor { unsigned Depth; // Whether we're looking for a use of a template parameter that makes the @@ -2603,7 +2601,7 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { return false; } - bool TraverseStmt(Stmt *S, DataRecursionQueue *Q = nullptr) { + bool TraverseStmt(Stmt *S) override { // Prune out non-type-dependent expressions if requested. This can // sometimes result in us failing to find a template parameter reference // (if a value-dependent expression creates a dependent type), but this @@ -2611,51 +2609,51 @@ struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { if (auto *E = dyn_cast_or_null<Expr>(S)) if (IgnoreNonTypeDependent && !E->isTypeDependent()) return true; - return super::TraverseStmt(S, Q); + return DynamicRecursiveASTVisitor::TraverseStmt(S); } - bool TraverseTypeLoc(TypeLoc TL) { + bool TraverseTypeLoc(TypeLoc TL) override { if (IgnoreNonTypeDependent && !TL.isNull() && !TL.getType()->isDependentType()) return true; - return super::TraverseTypeLoc(TL); + return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL); } - bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override { return !Matches(TL.getTypePtr()->getDepth(), TL.getNameLoc()); } - bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) { + bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override { // For a best-effort search, keep looking until we find a location. return IgnoreNonTypeDependent || !Matches(T->getDepth()); } - bool TraverseTemplateName(TemplateName N) { + bool TraverseTemplateName(TemplateName N) override { if (TemplateTemplateParmDecl *PD = dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl())) if (Matches(PD->getDepth())) return false; - return super::TraverseTemplateName(N); + return DynamicRecursiveASTVisitor::TraverseTemplateName(N); } - bool VisitDeclRefExpr(DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { if (NonTypeTemplateParmDecl *PD = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) if (Matches(PD->getDepth(), E->getExprLoc())) return false; - return super::VisitDeclRefExpr(E); + return DynamicRecursiveASTVisitor::VisitDeclRefExpr(E); } - bool VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + bool VisitSubstTemplateTypeParmType(SubstTemplateTypeParmType *T) override { return TraverseType(T->getReplacementType()); } - bool - VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { + bool VisitSubstTemplateTypeParmPackType( + SubstTemplateTypeParmPackType *T) override { return TraverseTemplateArgument(T->getArgumentPack()); } - bool TraverseInjectedClassNameType(const InjectedClassNameType *T) { + bool TraverseInjectedClassNameType(InjectedClassNameType *T) override { return TraverseType(T->getInjectedSpecializationType()); } }; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 2946d810..89fe4f4 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -20,10 +20,10 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -6478,8 +6478,7 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( } namespace { -struct MarkUsedTemplateParameterVisitor : - RecursiveASTVisitor<MarkUsedTemplateParameterVisitor> { +struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor { llvm::SmallBitVector &Used; unsigned Depth; @@ -6487,23 +6486,22 @@ struct MarkUsedTemplateParameterVisitor : unsigned Depth) : Used(Used), Depth(Depth) { } - bool VisitTemplateTypeParmType(TemplateTypeParmType *T) { + bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override { if (T->getDepth() == Depth) Used[T->getIndex()] = true; return true; } - bool TraverseTemplateName(TemplateName Template) { + bool TraverseTemplateName(TemplateName Template) override { if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>( Template.getAsTemplateDecl())) if (TTP->getDepth() == Depth) Used[TTP->getIndex()] = true; - RecursiveASTVisitor<MarkUsedTemplateParameterVisitor>:: - TraverseTemplateName(Template); + DynamicRecursiveASTVisitor::TraverseTemplateName(Template); return true; } - bool VisitDeclRefExpr(DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) if (NTTP->getDepth() == Depth) Used[NTTP->getIndex()] = true; diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index e422ef0..a1c750c 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -21,10 +21,10 @@ #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/OperationKinds.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -637,8 +637,7 @@ private: SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList( const TemplateParameterList *TemplateParamsList, ArrayRef<TemplateArgument> DeducedArgs) { - struct TemplateParamsReferencedFinder - : public RecursiveASTVisitor<TemplateParamsReferencedFinder> { + struct TemplateParamsReferencedFinder : DynamicRecursiveASTVisitor { const TemplateParameterList *TemplateParamList; llvm::BitVector ReferencedTemplateParams; @@ -647,22 +646,22 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList( : TemplateParamList(TemplateParamList), ReferencedTemplateParams(TemplateParamList->size()) {} - bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) override { // We use the index and depth to retrieve the corresponding template // parameter from the parameter list, which is more robost. Mark(TTP->getDepth(), TTP->getIndex()); return true; } - bool VisitDeclRefExpr(DeclRefExpr *DRE) { + bool VisitDeclRefExpr(DeclRefExpr *DRE) override { MarkAppeared(DRE->getFoundDecl()); return true; } - bool TraverseTemplateName(TemplateName Template) { + bool TraverseTemplateName(TemplateName Template) override { if (auto *TD = Template.getAsTemplateDecl()) MarkAppeared(TD); - return RecursiveASTVisitor::TraverseTemplateName(Template); + return DynamicRecursiveASTVisitor::TraverseTemplateName(Template); } void MarkAppeared(NamedDecl *ND) { diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 3a3b598..784a02c 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -17,10 +17,10 @@ #include "clang/AST/ASTMutationListener.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprConcepts.h" #include "clang/AST/PrettyDeclStackTrace.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeVisitor.h" @@ -153,9 +153,9 @@ getEnclosingTypeAliasTemplateDecl(Sema &SemaRef) { bool isLambdaEnclosedByTypeAliasDecl( const FunctionDecl *LambdaCallOperator, const TypeAliasTemplateDecl *PrimaryTypeAliasDecl) { - struct Visitor : RecursiveASTVisitor<Visitor> { + struct Visitor : DynamicRecursiveASTVisitor { Visitor(const FunctionDecl *CallOperator) : CallOperator(CallOperator) {} - bool VisitLambdaExpr(const LambdaExpr *LE) { + bool VisitLambdaExpr(LambdaExpr *LE) override { // Return true to bail out of the traversal, implying the Decl contains // the lambda. return getPrimaryTemplateOfGenericLambda(LE->getCallOperator()) != diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 151b328..2ea2a36 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -8,14 +8,15 @@ // This file implements semantic analysis for C++0x variadic templates. //===----------------------------------------------------------------------===/ -#include "clang/Sema/Sema.h" #include "TypeLocBuilder.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/TypeLoc.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" #include "llvm/Support/SaveAndRestore.h" @@ -29,16 +30,12 @@ using namespace clang; namespace { /// A class that collects unexpanded parameter packs. - class CollectUnexpandedParameterPacksVisitor : - public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> - { - typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> - inherited; +class CollectUnexpandedParameterPacksVisitor + : public DynamicRecursiveASTVisitor { + SmallVectorImpl<UnexpandedParameterPack> &Unexpanded; - SmallVectorImpl<UnexpandedParameterPack> &Unexpanded; - - bool InLambdaOrBlock = false; - unsigned DepthLimit = (unsigned)-1; + bool InLambdaOrBlock = false; + unsigned DepthLimit = (unsigned)-1; #ifndef NDEBUG bool ContainsIntermediatePacks = false; @@ -67,19 +64,19 @@ namespace { public: explicit CollectUnexpandedParameterPacksVisitor( SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) - : Unexpanded(Unexpanded) {} - - bool shouldWalkTypesOfTypeLocs() const { return false; } + : Unexpanded(Unexpanded) { + ShouldWalkTypesOfTypeLocs = false; - // We need this so we can find e.g. attributes on lambdas. - bool shouldVisitImplicitCode() const { return true; } + // We need this so we can find e.g. attributes on lambdas. + ShouldVisitImplicitCode = true; + } //------------------------------------------------------------------------ // Recording occurrences of (unexpanded) parameter packs. //------------------------------------------------------------------------ /// Record occurrences of template type parameter packs. - bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override { if (TL.getTypePtr()->isParameterPack()) addUnexpanded(TL.getTypePtr(), TL.getNameLoc()); return true; @@ -90,7 +87,7 @@ namespace { /// them. /// /// Ideally, this routine would never be used. - bool VisitTemplateTypeParmType(TemplateTypeParmType *T) { + bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override { if (T->isParameterPack()) addUnexpanded(T); @@ -99,7 +96,7 @@ namespace { /// Record occurrences of function and non-type template /// parameter packs in an expression. - bool VisitDeclRefExpr(DeclRefExpr *E) { + bool VisitDeclRefExpr(DeclRefExpr *E) override { if (E->getDecl()->isParameterPack()) addUnexpanded(E->getDecl(), E->getLocation()); @@ -107,7 +104,7 @@ namespace { } /// Record occurrences of template template parameter packs. - bool TraverseTemplateName(TemplateName Template) { + bool TraverseTemplateName(TemplateName Template) override { if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( Template.getAsTemplateDecl())) { if (TTP->isParameterPack()) @@ -119,12 +116,12 @@ namespace { (bool)Template.getAsSubstTemplateTemplateParmPack(); #endif - return inherited::TraverseTemplateName(Template); + return DynamicRecursiveASTVisitor::TraverseTemplateName(Template); } /// Suppress traversal into Objective-C container literal /// elements that are pack expansions. - bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { + bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) override { if (!E->containsUnexpandedParameterPack()) return true; @@ -144,118 +141,127 @@ namespace { /// Suppress traversal into statements and expressions that /// do not contain unexpanded parameter packs. - bool TraverseStmt(Stmt *S) { + bool TraverseStmt(Stmt *S) override { Expr *E = dyn_cast_or_null<Expr>(S); if ((E && E->containsUnexpandedParameterPack()) || InLambdaOrBlock) - return inherited::TraverseStmt(S); + return DynamicRecursiveASTVisitor::TraverseStmt(S); return true; } /// Suppress traversal into types that do not contain /// unexpanded parameter packs. - bool TraverseType(QualType T) { + bool TraverseType(QualType T) override { if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambdaOrBlock) - return inherited::TraverseType(T); + return DynamicRecursiveASTVisitor::TraverseType(T); return true; } /// Suppress traversal into types with location information /// that do not contain unexpanded parameter packs. - bool TraverseTypeLoc(TypeLoc TL) { + bool TraverseTypeLoc(TypeLoc TL) override { if ((!TL.getType().isNull() && TL.getType()->containsUnexpandedParameterPack()) || InLambdaOrBlock) - return inherited::TraverseTypeLoc(TL); + return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL); return true; } /// Suppress traversal of parameter packs. - bool TraverseDecl(Decl *D) { + bool TraverseDecl(Decl *D) override { // A function parameter pack is a pack expansion, so cannot contain // an unexpanded parameter pack. Likewise for a template parameter // pack that contains any references to other packs. if (D && D->isParameterPack()) return true; - return inherited::TraverseDecl(D); + return DynamicRecursiveASTVisitor::TraverseDecl(D); } /// Suppress traversal of pack-expanded attributes. - bool TraverseAttr(Attr *A) { + bool TraverseAttr(Attr *A) override { if (A->isPackExpansion()) return true; - return inherited::TraverseAttr(A); + return DynamicRecursiveASTVisitor::TraverseAttr(A); } /// Suppress traversal of pack expansion expressions and types. ///@{ - bool TraversePackExpansionType(PackExpansionType *T) { return true; } - bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; } - bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; } - bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; } - bool TraversePackIndexingExpr(PackIndexingExpr *E) { - return inherited::TraverseStmt(E->getIndexExpr()); + bool TraversePackExpansionType(PackExpansionType *T) override { + return true; } - bool TraversePackIndexingType(PackIndexingType *E) { - return inherited::TraverseStmt(E->getIndexExpr()); + bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) override { + return true; } - bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) { - return inherited::TraverseStmt(TL.getIndexExpr()); + bool TraversePackExpansionExpr(PackExpansionExpr *E) override { + return true; + } + bool TraverseCXXFoldExpr(CXXFoldExpr *E) override { return true; } + bool TraversePackIndexingExpr(PackIndexingExpr *E) override { + return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr()); + } + bool TraversePackIndexingType(PackIndexingType *E) override { + return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr()); + } + bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) override { + return DynamicRecursiveASTVisitor::TraverseStmt(TL.getIndexExpr()); } ///@} /// Suppress traversal of using-declaration pack expansion. - bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { + bool + TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) override { if (D->isPackExpansion()) return true; - return inherited::TraverseUnresolvedUsingValueDecl(D); + return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingValueDecl(D); } /// Suppress traversal of using-declaration pack expansion. - bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { + bool TraverseUnresolvedUsingTypenameDecl( + UnresolvedUsingTypenameDecl *D) override { if (D->isPackExpansion()) return true; - return inherited::TraverseUnresolvedUsingTypenameDecl(D); + return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingTypenameDecl(D); } /// Suppress traversal of template argument pack expansions. - bool TraverseTemplateArgument(const TemplateArgument &Arg) { + bool TraverseTemplateArgument(const TemplateArgument &Arg) override { if (Arg.isPackExpansion()) return true; - return inherited::TraverseTemplateArgument(Arg); + return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg); } /// Suppress traversal of template argument pack expansions. - bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { + bool + TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) override { if (ArgLoc.getArgument().isPackExpansion()) return true; - return inherited::TraverseTemplateArgumentLoc(ArgLoc); + return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(ArgLoc); } /// Suppress traversal of base specifier pack expansions. - bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { + bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) override { if (Base.isPackExpansion()) return true; - return inherited::TraverseCXXBaseSpecifier(Base); + return DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier(Base); } /// Suppress traversal of mem-initializer pack expansions. - bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override { if (Init->isPackExpansion()) return true; - return inherited::TraverseConstructorInitializer(Init); + return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init); } /// Note whether we're traversing a lambda containing an unexpanded @@ -263,7 +269,7 @@ namespace { /// including all the places where we normally wouldn't look. Within a /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit /// outside an expression. - bool TraverseLambdaExpr(LambdaExpr *Lambda) { + bool TraverseLambdaExpr(LambdaExpr *Lambda) override { // The ContainsUnexpandedParameterPack bit on a lambda is always correct, // even if it's contained within another lambda. if (!Lambda->containsUnexpandedParameterPack()) @@ -275,57 +281,58 @@ namespace { if (auto *TPL = Lambda->getTemplateParameterList()) DepthLimit = TPL->getDepth(); - inherited::TraverseLambdaExpr(Lambda); + DynamicRecursiveASTVisitor::TraverseLambdaExpr(Lambda); DepthLimit = OldDepthLimit; return true; } /// Analogously for blocks. - bool TraverseBlockExpr(BlockExpr *Block) { + bool TraverseBlockExpr(BlockExpr *Block) override { if (!Block->containsUnexpandedParameterPack()) return true; SaveAndRestore _(InLambdaOrBlock, true); - inherited::TraverseBlockExpr(Block); + DynamicRecursiveASTVisitor::TraverseBlockExpr(Block); return true; } /// Suppress traversal within pack expansions in lambda captures. bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C, - Expr *Init) { + Expr *Init) override { if (C->isPackExpansion()) return true; - return inherited::TraverseLambdaCapture(Lambda, C, Init); + return DynamicRecursiveASTVisitor::TraverseLambdaCapture(Lambda, C, Init); } #ifndef NDEBUG - bool TraverseFunctionParmPackExpr(FunctionParmPackExpr *) { + bool TraverseFunctionParmPackExpr(FunctionParmPackExpr *) override { ContainsIntermediatePacks = true; return true; } bool TraverseSubstNonTypeTemplateParmPackExpr( - SubstNonTypeTemplateParmPackExpr *) { + SubstNonTypeTemplateParmPackExpr *) override { ContainsIntermediatePacks = true; return true; } - bool VisitSubstTemplateTypeParmPackType(SubstTemplateTypeParmPackType *) { + bool VisitSubstTemplateTypeParmPackType( + SubstTemplateTypeParmPackType *) override { ContainsIntermediatePacks = true; return true; } - bool - VisitSubstTemplateTypeParmPackTypeLoc(SubstTemplateTypeParmPackTypeLoc) { + bool VisitSubstTemplateTypeParmPackTypeLoc( + SubstTemplateTypeParmPackTypeLoc) override { ContainsIntermediatePacks = true; return true; } bool containsIntermediatePacks() const { return ContainsIntermediatePacks; } #endif - }; +}; } /// Determine whether it's possible for an unexpanded parameter pack to diff --git a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp index e674ec43..3e87ad0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -23,7 +23,7 @@ using namespace clang; using namespace ento; namespace { -class CastToStructVisitor : public RecursiveASTVisitor<CastToStructVisitor> { +class CastToStructVisitor : public DynamicRecursiveASTVisitor { BugReporter &BR; const CheckerBase *Checker; AnalysisDeclContext *AC; @@ -32,11 +32,11 @@ public: explicit CastToStructVisitor(BugReporter &B, const CheckerBase *Checker, AnalysisDeclContext *A) : BR(B), Checker(Checker), AC(A) {} - bool VisitCastExpr(const CastExpr *CE); + bool VisitCastExpr(CastExpr *CE) override; }; } -bool CastToStructVisitor::VisitCastExpr(const CastExpr *CE) { +bool CastToStructVisitor::VisitCastExpr(CastExpr *CE) { const Expr *E = CE->getSubExpr(); ASTContext &Ctx = AC->getASTContext(); QualType OrigTy = Ctx.getCanonicalType(E->getType()); diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp index 86f446f..4e3919e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -13,8 +13,8 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Lex/Lexer.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" @@ -32,27 +32,27 @@ using namespace ento; namespace { /// A simple visitor to record what VarDecls occur in EH-handling code. -class EHCodeVisitor : public RecursiveASTVisitor<EHCodeVisitor> { +class EHCodeVisitor : public DynamicRecursiveASTVisitor { public: bool inEH; llvm::DenseSet<const VarDecl *> &S; - bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { + bool TraverseObjCAtFinallyStmt(ObjCAtFinallyStmt *S) override { SaveAndRestore inFinally(inEH, true); - return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtFinallyStmt(S); + return DynamicRecursiveASTVisitor::TraverseObjCAtFinallyStmt(S); } - bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) { + bool TraverseObjCAtCatchStmt(ObjCAtCatchStmt *S) override { SaveAndRestore inCatch(inEH, true); - return ::RecursiveASTVisitor<EHCodeVisitor>::TraverseObjCAtCatchStmt(S); + return DynamicRecursiveASTVisitor::TraverseObjCAtCatchStmt(S); } - bool TraverseCXXCatchStmt(CXXCatchStmt *S) { + bool TraverseCXXCatchStmt(CXXCatchStmt *S) override { SaveAndRestore inCatch(inEH, true); return TraverseStmt(S->getHandlerBlock()); } - bool VisitDeclRefExpr(DeclRefExpr *DR) { + bool VisitDeclRefExpr(DeclRefExpr *DR) override { if (inEH) if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl())) S.insert(D); diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp index 034774a..a0bf776 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -20,8 +20,8 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" @@ -711,10 +711,10 @@ static bool isObjCTypeParamDependent(QualType Type) { // an Objective-C type can only be dependent on a type parameter when the type // parameter structurally present in the type itself. class IsObjCTypeParamDependentTypeVisitor - : public RecursiveASTVisitor<IsObjCTypeParamDependentTypeVisitor> { + : public DynamicRecursiveASTVisitor { public: IsObjCTypeParamDependentTypeVisitor() = default; - bool VisitObjCTypeParamType(const ObjCTypeParamType *Type) { + bool VisitObjCTypeParamType(ObjCTypeParamType *Type) override { if (isa<ObjCTypeParamDecl>(Type->getDecl())) { Result = true; return false; diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index 7ac34ef..4564248 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -15,8 +15,8 @@ /// //===----------------------------------------------------------------------===// +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -32,8 +32,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, //===----------------------------------------------------------------------===// namespace { -class FindIdenticalExprVisitor - : public RecursiveASTVisitor<FindIdenticalExprVisitor> { +class FindIdenticalExprVisitor : public DynamicRecursiveASTVisitor { BugReporter &BR; const CheckerBase *Checker; AnalysisDeclContext *AC; @@ -45,9 +44,9 @@ public: // FindIdenticalExprVisitor only visits nodes // that are binary operators, if statements or // conditional operators. - bool VisitBinaryOperator(const BinaryOperator *B); - bool VisitIfStmt(const IfStmt *I); - bool VisitConditionalOperator(const ConditionalOperator *C); + bool VisitBinaryOperator(BinaryOperator *B) override; + bool VisitIfStmt(IfStmt *I) override; + bool VisitConditionalOperator(ConditionalOperator *C) override; private: void reportIdenticalExpr(const BinaryOperator *B, bool CheckBitwise, @@ -103,7 +102,7 @@ void FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B, } } -bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) { +bool FindIdenticalExprVisitor::VisitIfStmt(IfStmt *I) { const Stmt *Stmt1 = I->getThen(); const Stmt *Stmt2 = I->getElse(); @@ -178,7 +177,7 @@ bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) { return true; } -bool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) { +bool FindIdenticalExprVisitor::VisitBinaryOperator(BinaryOperator *B) { BinaryOperator::Opcode Op = B->getOpcode(); if (BinaryOperator::isBitwiseOp(Op)) @@ -268,7 +267,7 @@ void FindIdenticalExprVisitor::checkComparisonOp(const BinaryOperator *B) { } bool FindIdenticalExprVisitor::VisitConditionalOperator( - const ConditionalOperator *C) { + ConditionalOperator *C) { // Check if expressions in conditional expression are identical // from a symbolic point of view. diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp index e1ad591..ddcf046 100644 --- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -17,7 +17,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/Lex/Lexer.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" @@ -1189,7 +1189,7 @@ namespace { class PluralMisuseChecker : public Checker<check::ASTCodeBody> { // A helper class, which walks the AST - class MethodCrawler : public RecursiveASTVisitor<MethodCrawler> { + class MethodCrawler : public DynamicRecursiveASTVisitor { BugReporter &BR; const CheckerBase *Checker; AnalysisDeclContext *AC; @@ -1207,13 +1207,13 @@ class PluralMisuseChecker : public Checker<check::ASTCodeBody> { AnalysisDeclContext *InAC) : BR(InBR), Checker(Checker), AC(InAC) {} - bool VisitIfStmt(const IfStmt *I); + bool VisitIfStmt(IfStmt *I) override; bool EndVisitIfStmt(IfStmt *I); - bool TraverseIfStmt(IfStmt *x); - bool VisitConditionalOperator(const ConditionalOperator *C); - bool TraverseConditionalOperator(ConditionalOperator *C); - bool VisitCallExpr(const CallExpr *CE); - bool VisitObjCMessageExpr(const ObjCMessageExpr *ME); + bool TraverseIfStmt(IfStmt *x) override; + bool VisitConditionalOperator(ConditionalOperator *C) override; + bool TraverseConditionalOperator(ConditionalOperator *C) override; + bool VisitCallExpr(CallExpr *CE) override; + bool VisitObjCMessageExpr(ObjCMessageExpr *ME) override; private: void reportPluralMisuseError(const Stmt *S) const; @@ -1272,7 +1272,7 @@ bool PluralMisuseChecker::MethodCrawler::isCheckingPlurality( // has been shown to almost always be a function that returns a localized // string. Raise a diagnostic when this is in a statement that matches // the condition. -bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(const CallExpr *CE) { +bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(CallExpr *CE) { if (InMatchingStatement) { if (const FunctionDecl *FD = CE->getDirectCallee()) { std::string NormalizedName = @@ -1294,7 +1294,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(const CallExpr *CE) { // diagnostic when this is in a statement that matches // the condition. bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr( - const ObjCMessageExpr *ME) { + ObjCMessageExpr *ME) { const ObjCInterfaceDecl *OD = ME->getReceiverInterface(); if (!OD) return true; @@ -1312,7 +1312,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr( /// Override TraverseIfStmt so we know when we are done traversing an IfStmt bool PluralMisuseChecker::MethodCrawler::TraverseIfStmt(IfStmt *I) { - RecursiveASTVisitor<MethodCrawler>::TraverseIfStmt(I); + DynamicRecursiveASTVisitor::TraverseIfStmt(I); return EndVisitIfStmt(I); } @@ -1331,7 +1331,7 @@ bool PluralMisuseChecker::MethodCrawler::EndVisitIfStmt(IfStmt *I) { return true; } -bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(const IfStmt *I) { +bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(IfStmt *I) { const Expr *Condition = I->getCond(); if (!Condition) return true; @@ -1350,7 +1350,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(const IfStmt *I) { // Preliminary support for conditional operators. bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator( ConditionalOperator *C) { - RecursiveASTVisitor<MethodCrawler>::TraverseConditionalOperator(C); + DynamicRecursiveASTVisitor::TraverseConditionalOperator(C); MatchingStatements.pop_back(); if (!MatchingStatements.empty()) { if (MatchingStatements.back() != nullptr) @@ -1364,7 +1364,7 @@ bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator( } bool PluralMisuseChecker::MethodCrawler::VisitConditionalOperator( - const ConditionalOperator *C) { + ConditionalOperator *C) { const Expr *Condition = C->getCond()->IgnoreParenImpCasts(); if (isCheckingPlurality(Condition)) { MatchingStatements.push_back(C); diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp index 03dab4f..495502e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp @@ -12,12 +12,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/Analysis/PathDiagnostic.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Analysis/PathDiagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -38,11 +38,11 @@ struct SelectorDescriptor { // FindSuperCallVisitor - Identify specific calls to the superclass. //===----------------------------------------------------------------------===// -class FindSuperCallVisitor : public RecursiveASTVisitor<FindSuperCallVisitor> { +class FindSuperCallVisitor : public DynamicRecursiveASTVisitor { public: explicit FindSuperCallVisitor(Selector S) : DoesCallSuper(false), Sel(S) {} - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { + bool VisitObjCMessageExpr(ObjCMessageExpr *E) override { if (E->getSelector() == Sel) if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) DoesCallSuper = true; diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index 4f35d94..bb882c9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -11,12 +11,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/RecordLayout.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Driver/DriverDiagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -45,16 +45,17 @@ public: // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We // want to visit those, so we make our own RecursiveASTVisitor. - struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { + struct LocalVisitor : DynamicRecursiveASTVisitor { const PaddingChecker *Checker; - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return true; } - explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {} - bool VisitRecordDecl(const RecordDecl *RD) { + explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) { + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = true; + } + bool VisitRecordDecl(RecordDecl *RD) override { Checker->visitRecord(RD); return true; } - bool VisitVarDecl(const VarDecl *VD) { + bool VisitVarDecl(VarDecl *VD) override { Checker->visitVariable(VD); return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp index d7f766da..ef2d42c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp @@ -12,7 +12,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Basic/SourceLocation.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" @@ -49,34 +49,31 @@ public: // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We // want to visit those, so we make our own RecursiveASTVisitor. - struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { - using Base = RecursiveASTVisitor<LocalVisitor>; - + struct LocalVisitor : DynamicRecursiveASTVisitor { const RawPtrRefCallArgsChecker *Checker; Decl *DeclWithIssue{nullptr}; explicit LocalVisitor(const RawPtrRefCallArgsChecker *Checker) : Checker(Checker) { assert(Checker); + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = false; } - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return false; } - - bool TraverseClassTemplateDecl(ClassTemplateDecl *Decl) { + bool TraverseClassTemplateDecl(ClassTemplateDecl *Decl) override { if (isRefType(safeGetName(Decl))) return true; - return Base::TraverseClassTemplateDecl(Decl); + return DynamicRecursiveASTVisitor::TraverseClassTemplateDecl(Decl); } - bool TraverseDecl(Decl *D) { + bool TraverseDecl(Decl *D) override { llvm::SaveAndRestore SavedDecl(DeclWithIssue); if (D && (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D))) DeclWithIssue = D; - return Base::TraverseDecl(D); + return DynamicRecursiveASTVisitor::TraverseDecl(D); } - bool VisitCallExpr(const CallExpr *CE) { + bool VisitCallExpr(CallExpr *CE) override { Checker->visitCallExpr(CE, DeclWithIssue); return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp index 48c3dc4..e0433c5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp @@ -12,8 +12,8 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/ParentMapContext.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceLocation.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" @@ -48,17 +48,14 @@ bool isRefcountedStringsHack(const VarDecl *V) { return false; } -struct GuardianVisitor : public RecursiveASTVisitor<GuardianVisitor> { - using Base = RecursiveASTVisitor<GuardianVisitor>; - +struct GuardianVisitor : DynamicRecursiveASTVisitor { const VarDecl *Guardian{nullptr}; -public: explicit GuardianVisitor(const VarDecl *Guardian) : Guardian(Guardian) { assert(Guardian); } - bool VisitBinaryOperator(const BinaryOperator *BO) { + bool VisitBinaryOperator(BinaryOperator *BO) override { if (BO->isAssignmentOp()) { if (auto *VarRef = dyn_cast<DeclRefExpr>(BO->getLHS())) { if (VarRef->getDecl() == Guardian) @@ -68,7 +65,7 @@ public: return true; } - bool VisitCXXConstructExpr(const CXXConstructExpr *CE) { + bool VisitCXXConstructExpr(CXXConstructExpr *CE) override { if (auto *Ctor = CE->getConstructor()) { if (Ctor->isMoveConstructor() && CE->getNumArgs() == 1) { auto *Arg = CE->getArg(0)->IgnoreParenCasts(); @@ -81,7 +78,7 @@ public: return true; } - bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE) { + bool VisitCXXMemberCallExpr(CXXMemberCallExpr *MCE) override { auto MethodName = safeGetName(MCE->getMethodDecl()); if (MethodName == "swap" || MethodName == "leakRef" || MethodName == "releaseNonNull") { @@ -94,7 +91,7 @@ public: return true; } - bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE) { + bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *OCE) override { if (OCE->isAssignmentOp()) { assert(OCE->getNumArgs() == 2); auto *ThisArg = OCE->getArg(0)->IgnoreParenCasts(); @@ -184,37 +181,34 @@ public: // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We // want to visit those, so we make our own RecursiveASTVisitor. - struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { + struct LocalVisitor : DynamicRecursiveASTVisitor { const RawPtrRefLocalVarsChecker *Checker; Decl *DeclWithIssue{nullptr}; TrivialFunctionAnalysis TFA; - using Base = RecursiveASTVisitor<LocalVisitor>; - explicit LocalVisitor(const RawPtrRefLocalVarsChecker *Checker) : Checker(Checker) { assert(Checker); + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = false; } - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return false; } - - bool TraverseDecl(Decl *D) { + bool TraverseDecl(Decl *D) override { llvm::SaveAndRestore SavedDecl(DeclWithIssue); if (D && (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D))) DeclWithIssue = D; - return Base::TraverseDecl(D); + return DynamicRecursiveASTVisitor::TraverseDecl(D); } - bool VisitVarDecl(VarDecl *V) { + bool VisitVarDecl(VarDecl *V) override { auto *Init = V->getInit(); if (Init && V->isLocalVarDecl()) Checker->visitVarDecl(V, Init, DeclWithIssue); return true; } - bool VisitBinaryOperator(const BinaryOperator *BO) { + bool VisitBinaryOperator(BinaryOperator *BO) override { if (BO->isAssignmentOp()) { if (auto *VarRef = dyn_cast<DeclRefExpr>(BO->getLHS())) { if (auto *V = dyn_cast<VarDecl>(VarRef->getDecl())) @@ -224,33 +218,33 @@ public: return true; } - bool TraverseIfStmt(IfStmt *IS) { + bool TraverseIfStmt(IfStmt *IS) override { if (!TFA.isTrivial(IS)) - return Base::TraverseIfStmt(IS); + return DynamicRecursiveASTVisitor::TraverseIfStmt(IS); return true; } - bool TraverseForStmt(ForStmt *FS) { + bool TraverseForStmt(ForStmt *FS) override { if (!TFA.isTrivial(FS)) - return Base::TraverseForStmt(FS); + return DynamicRecursiveASTVisitor::TraverseForStmt(FS); return true; } - bool TraverseCXXForRangeStmt(CXXForRangeStmt *FRS) { + bool TraverseCXXForRangeStmt(CXXForRangeStmt *FRS) override { if (!TFA.isTrivial(FRS)) - return Base::TraverseCXXForRangeStmt(FRS); + return DynamicRecursiveASTVisitor::TraverseCXXForRangeStmt(FRS); return true; } - bool TraverseWhileStmt(WhileStmt *WS) { + bool TraverseWhileStmt(WhileStmt *WS) override { if (!TFA.isTrivial(WS)) - return Base::TraverseWhileStmt(WS); + return DynamicRecursiveASTVisitor::TraverseWhileStmt(WS); return true; } - bool TraverseCompoundStmt(CompoundStmt *CS) { + bool TraverseCompoundStmt(CompoundStmt *CS) override { if (!TFA.isTrivial(CS)) - return Base::TraverseCompoundStmt(CS); + return DynamicRecursiveASTVisitor::TraverseCompoundStmt(CS); return true; } }; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp index 2ce6bc3..d7e5ebe 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp @@ -12,7 +12,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" @@ -48,17 +48,16 @@ public: // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We // want to visit those, so we make our own RecursiveASTVisitor. - struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { + struct LocalVisitor : DynamicRecursiveASTVisitor { const RawPtrRefMemberChecker *Checker; explicit LocalVisitor(const RawPtrRefMemberChecker *Checker) : Checker(Checker) { assert(Checker); + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = false; } - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return false; } - - bool VisitRecordDecl(const RecordDecl *RD) { + bool VisitRecordDecl(RecordDecl *RD) override { Checker->visitRecordDecl(RD); return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp index e80246f..77520f1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp @@ -10,7 +10,7 @@ #include "DiagOutputUtils.h" #include "PtrTypesSemantics.h" #include "clang/AST/CXXInheritance.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" @@ -173,17 +173,16 @@ public: // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We // want to visit those, so we make our own RecursiveASTVisitor. - struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { + struct LocalVisitor : DynamicRecursiveASTVisitor { const RefCntblBaseVirtualDtorChecker *Checker; explicit LocalVisitor(const RefCntblBaseVirtualDtorChecker *Checker) : Checker(Checker) { assert(Checker); + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = false; } - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return false; } - - bool VisitCXXRecordDecl(const CXXRecordDecl *RD) { + bool VisitCXXRecordDecl(CXXRecordDecl *RD) override { if (!RD->hasDefinition()) return true; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp index 914ff6d..3fb763e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp @@ -10,7 +10,7 @@ #include "DiagOutputUtils.h" #include "PtrTypesSemantics.h" #include "clang/AST/CXXInheritance.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" @@ -37,25 +37,22 @@ public: // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We // want to visit those, so we make our own RecursiveASTVisitor. - struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { + struct LocalVisitor : DynamicRecursiveASTVisitor { const UncountedLambdaCapturesChecker *Checker; llvm::DenseSet<const DeclRefExpr *> DeclRefExprsToIgnore; QualType ClsType; - using Base = RecursiveASTVisitor<LocalVisitor>; - explicit LocalVisitor(const UncountedLambdaCapturesChecker *Checker) : Checker(Checker) { assert(Checker); + ShouldVisitTemplateInstantiations = true; + ShouldVisitImplicitCode = false; } - bool shouldVisitTemplateInstantiations() const { return true; } - bool shouldVisitImplicitCode() const { return false; } - - bool TraverseCXXMethodDecl(CXXMethodDecl *CXXMD) { + bool TraverseCXXMethodDecl(CXXMethodDecl *CXXMD) override { llvm::SaveAndRestore SavedDecl(ClsType); ClsType = CXXMD->getThisType(); - return Base::TraverseCXXMethodDecl(CXXMD); + return DynamicRecursiveASTVisitor::TraverseCXXMethodDecl(CXXMD); } bool shouldCheckThis() { @@ -63,7 +60,7 @@ public: return result && *result; } - bool VisitDeclRefExpr(DeclRefExpr *DRE) { + bool VisitDeclRefExpr(DeclRefExpr *DRE) override { if (DeclRefExprsToIgnore.contains(DRE)) return true; auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl()); @@ -88,7 +85,7 @@ public: return safeGetName(NsDecl) == "WTF" && safeGetName(Decl) == "switchOn"; } - bool VisitCallExpr(CallExpr *CE) { + bool VisitCallExpr(CallExpr *CE) override { checkCalleeLambda(CE); if (auto *Callee = CE->getDirectCallee()) { bool TreatAllArgsAsNoEscape = shouldTreatAllArgAsNoEscape(Callee); diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp index 84004b8..05c99c4 100644 --- a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" using namespace clang; @@ -76,13 +76,13 @@ inline bool fullyContains(SourceRange Larger, SourceRange Smaller, isLessOrEqual(Smaller.getEnd(), Larger.getEnd(), SM); } -class CacheInitializer : public RecursiveASTVisitor<CacheInitializer> { +class CacheInitializer : public DynamicRecursiveASTVisitor { public: static void initialize(const Decl *D, Ranges &ToInit) { CacheInitializer(ToInit).TraverseDecl(const_cast<Decl *>(D)); } - bool VisitDecl(Decl *D) { + bool VisitDecl(Decl *D) override { // Bug location could be somewhere in the init value of // a freshly declared variable. Even though it looks like the // user applied attribute to a statement, it will apply to a @@ -90,7 +90,7 @@ public: return VisitAttributedNode(D); } - bool VisitAttributedStmt(AttributedStmt *AS) { + bool VisitAttributedStmt(AttributedStmt *AS) override { // When we apply attributes to statements, it actually creates // a wrapper statement that only contains attributes and the wrapped // statement. diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 03bc4080..91c9b08 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -15,7 +15,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" -#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CallGraph.h" @@ -68,7 +68,7 @@ STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function."); namespace { class AnalysisConsumer : public AnalysisASTConsumer, - public RecursiveASTVisitor<AnalysisConsumer> { + public DynamicRecursiveASTVisitor { enum { AM_None = 0, AM_Syntax = 0x1, @@ -147,6 +147,9 @@ public: if (Opts.ShouldDisplayMacroExpansions) MacroExpansions.registerForPreprocessor(PP); + + // Visitor options. + ShouldWalkTypesOfTypeLocs = false; } ~AnalysisConsumer() override { @@ -261,11 +264,8 @@ public: ExprEngine::InliningModes IMode, SetOfConstDecls *VisitedCallees); - /// Visitors for the RecursiveASTVisitor. - bool shouldWalkTypesOfTypeLocs() const { return false; } - /// Handle callbacks for arbitrary Decls. - bool VisitDecl(Decl *D) { + bool VisitDecl(Decl *D) override { AnalysisMode Mode = getModeForDecl(D, RecVisitorMode); if (Mode & AM_Syntax) { if (SyntaxCheckTimer) @@ -277,7 +277,7 @@ public: return true; } - bool VisitVarDecl(VarDecl *VD) { + bool VisitVarDecl(VarDecl *VD) override { if (!Opts.IsNaiveCTUEnabled) return true; @@ -306,7 +306,7 @@ public: return true; } - bool VisitFunctionDecl(FunctionDecl *FD) { + bool VisitFunctionDecl(FunctionDecl *FD) override { IdentifierInfo *II = FD->getIdentifier(); if (II && II->getName().starts_with("__inline")) return true; @@ -321,7 +321,7 @@ public: return true; } - bool VisitObjCMethodDecl(ObjCMethodDecl *MD) { + bool VisitObjCMethodDecl(ObjCMethodDecl *MD) override { if (MD->isThisDeclarationADefinition()) { assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false); HandleCode(MD, RecVisitorMode); @@ -329,7 +329,7 @@ public: return true; } - bool VisitBlockDecl(BlockDecl *BD) { + bool VisitBlockDecl(BlockDecl *BD) override { if (BD->hasBody()) { assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false); // Since we skip function template definitions, we should skip blocks |