diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/EvaluatedExprVisitor.h | 70 | ||||
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 4 | ||||
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 28 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 1 |
6 files changed, 76 insertions, 54 deletions
diff --git a/clang/include/clang/AST/EvaluatedExprVisitor.h b/clang/include/clang/AST/EvaluatedExprVisitor.h index 59de104b83f..89d86419cfc 100644 --- a/clang/include/clang/AST/EvaluatedExprVisitor.h +++ b/clang/include/clang/AST/EvaluatedExprVisitor.h @@ -26,29 +26,31 @@ class ASTContext; /// \brief Given a potentially-evaluated expression, this visitor visits all /// of its potentially-evaluated subexpressions, recursively. -template<typename ImplClass> -class EvaluatedExprVisitor : public StmtVisitor<ImplClass> { - ASTContext &Context; - +template<template <typename> class Ptr, typename ImplClass> +class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> { + const ASTContext &Context; + public: - explicit EvaluatedExprVisitor(ASTContext &Context) : Context(Context) { } - +#define PTR(CLASS) typename Ptr<CLASS>::type + + explicit EvaluatedExprVisitorBase(const ASTContext &Context) : Context(Context) { } + // Expressions that have no potentially-evaluated subexpressions (but may have // other sub-expressions). - void VisitDeclRefExpr(DeclRefExpr *E) { } - void VisitOffsetOfExpr(OffsetOfExpr *E) { } - void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { } - void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { } - void VisitBlockExpr(BlockExpr *E) { } - void VisitCXXUuidofExpr(CXXUuidofExpr *E) { } - void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { } - - void VisitMemberExpr(MemberExpr *E) { + void VisitDeclRefExpr(PTR(DeclRefExpr) E) { } + void VisitOffsetOfExpr(PTR(OffsetOfExpr) E) { } + void VisitUnaryExprOrTypeTraitExpr(PTR(UnaryExprOrTypeTraitExpr) E) { } + void VisitExpressionTraitExpr(PTR(ExpressionTraitExpr) E) { } + void VisitBlockExpr(PTR(BlockExpr) E) { } + void VisitCXXUuidofExpr(PTR(CXXUuidofExpr) E) { } + void VisitCXXNoexceptExpr(PTR(CXXNoexceptExpr) E) { } + + void VisitMemberExpr(PTR(MemberExpr) E) { // Only the base matters. return this->Visit(E->getBase()); } - - void VisitChooseExpr(ChooseExpr *E) { + + void VisitChooseExpr(PTR(ChooseExpr) E) { // Don't visit either child expression if the condition is dependent. if (E->getCond()->isValueDependent()) return; @@ -56,7 +58,7 @@ public: return this->Visit(E->getChosenSubExpr()); } - void VisitGenericSelectionExpr(GenericSelectionExpr *E) { + void VisitGenericSelectionExpr(PTR(GenericSelectionExpr) E) { // The controlling expression of a generic selection is not evaluated. // Don't visit either child expression if the condition is type-dependent. @@ -67,23 +69,23 @@ public: return this->Visit(E->getResultExpr()); } - void VisitDesignatedInitExpr(DesignatedInitExpr *E) { + void VisitDesignatedInitExpr(PTR(DesignatedInitExpr) E) { // Only the actual initializer matters; the designators are all constant // expressions. return this->Visit(E->getInit()); } - void VisitCXXTypeidExpr(CXXTypeidExpr *E) { + void VisitCXXTypeidExpr(PTR(CXXTypeidExpr) E) { if (E->isPotentiallyEvaluated()) return this->Visit(E->getExprOperand()); } - void VisitCallExpr(CallExpr *CE) { + void VisitCallExpr(PTR(CallExpr) CE) { if (!CE->isUnevaluatedBuiltinCall(Context)) return static_cast<ImplClass*>(this)->VisitExpr(CE); } - void VisitLambdaExpr(LambdaExpr *LE) { + void VisitLambdaExpr(PTR(LambdaExpr) LE) { // Only visit the capture initializers, and not the body. for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(), E = LE->capture_init_end(); @@ -94,11 +96,31 @@ public: /// \brief The basis case walks all of the children of the statement or /// expression, assuming they are all potentially evaluated. - void VisitStmt(Stmt *S) { - for (Stmt::child_range C = S->children(); C; ++C) + void VisitStmt(PTR(Stmt) S) { + for (auto C = S->children(); C; ++C) if (*C) this->Visit(*C); } + +#undef PTR +}; + +/// EvaluatedExprVisitor - This class visits 'Expr *'s +template<typename ImplClass> +class EvaluatedExprVisitor + : public EvaluatedExprVisitorBase<make_ptr, ImplClass> { +public: + explicit EvaluatedExprVisitor(const ASTContext &Context) : + EvaluatedExprVisitorBase<make_ptr, ImplClass>(Context) { } +}; + +/// ConstEvaluatedExprVisitor - This class visits 'const Expr *'s. +template<typename ImplClass> +class ConstEvaluatedExprVisitor + : public EvaluatedExprVisitorBase<make_const_ptr, ImplClass> { +public: + explicit ConstEvaluatedExprVisitor(const ASTContext &Context) : + EvaluatedExprVisitorBase<make_const_ptr, ImplClass>(Context) { } }; } diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 4acc0535f2b..2a5b4c0f5ed 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -598,7 +598,7 @@ public: /// \brief Determine whether this expression involves a call to any function /// that is not trivial. - bool hasNonTrivialCall(ASTContext &Ctx); + bool hasNonTrivialCall(const ASTContext &Ctx) const; /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded /// integer. This must be called on an expression that constant folds to an @@ -2273,7 +2273,7 @@ public: /// \brief Returns \c true if this is a call to a builtin which does not /// evaluate side-effects within its arguments. - bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const; + bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const; /// getCallReturnType - Get the return type of the call expr. This is not /// always the type of the expr itself, if the return type is a reference diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7cc84111469..99c72436b44 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1238,7 +1238,7 @@ unsigned CallExpr::getBuiltinCallee() const { return FDecl->getBuiltinID(); } -bool CallExpr::isUnevaluatedBuiltinCall(ASTContext &Ctx) const { +bool CallExpr::isUnevaluatedBuiltinCall(const ASTContext &Ctx) const { if (unsigned BI = getBuiltinCallee()) return Ctx.BuiltinInfo.isUnevaluated(BI); return false; @@ -3136,21 +3136,21 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, namespace { /// \brief Look for a call to a non-trivial function within an expression. - class NonTrivialCallFinder : public EvaluatedExprVisitor<NonTrivialCallFinder> + class NonTrivialCallFinder : public ConstEvaluatedExprVisitor<NonTrivialCallFinder> { - typedef EvaluatedExprVisitor<NonTrivialCallFinder> Inherited; - + typedef ConstEvaluatedExprVisitor<NonTrivialCallFinder> Inherited; + bool NonTrivial; public: - explicit NonTrivialCallFinder(ASTContext &Context) + explicit NonTrivialCallFinder(const ASTContext &Context) : Inherited(Context), NonTrivial(false) { } bool hasNonTrivialCall() const { return NonTrivial; } - - void VisitCallExpr(CallExpr *E) { - if (CXXMethodDecl *Method - = dyn_cast_or_null<CXXMethodDecl>(E->getCalleeDecl())) { + + void VisitCallExpr(const CallExpr *E) { + if (const CXXMethodDecl *Method + = dyn_cast_or_null<const CXXMethodDecl>(E->getCalleeDecl())) { if (Method->isTrivial()) { // Recurse to children of the call. Inherited::VisitStmt(E); @@ -3160,8 +3160,8 @@ namespace { NonTrivial = true; } - - void VisitCXXConstructExpr(CXXConstructExpr *E) { + + void VisitCXXConstructExpr(const CXXConstructExpr *E) { if (E->getConstructor()->isTrivial()) { // Recurse to children of the call. Inherited::VisitStmt(E); @@ -3170,8 +3170,8 @@ namespace { NonTrivial = true; } - - void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { + + void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E) { if (E->getTemporary()->getDestructor()->isTrivial()) { Inherited::VisitStmt(E); return; @@ -3182,7 +3182,7 @@ namespace { }; } -bool Expr::hasNonTrivialCall(ASTContext &Ctx) { +bool Expr::hasNonTrivialCall(const ASTContext &Ctx) const { NonTrivialCallFinder Finder(Ctx); Finder.Visit(this); return Finder.hasNonTrivialCall(); diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index cd75da27628..1320cd3c89a 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -370,25 +370,25 @@ namespace { /// A visitor which checks whether an initializer uses 'this' in a /// way which requires the vtable to be properly set. - struct DynamicThisUseChecker : EvaluatedExprVisitor<DynamicThisUseChecker> { - typedef EvaluatedExprVisitor<DynamicThisUseChecker> super; + struct DynamicThisUseChecker : ConstEvaluatedExprVisitor<DynamicThisUseChecker> { + typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super; bool UsesThis; - DynamicThisUseChecker(ASTContext &C) : super(C), UsesThis(false) {} + DynamicThisUseChecker(const ASTContext &C) : super(C), UsesThis(false) {} // Black-list all explicit and implicit references to 'this'. // // Do we need to worry about external references to 'this' derived // from arbitrary code? If so, then anything which runs arbitrary // external code might potentially access the vtable. - void VisitCXXThisExpr(CXXThisExpr *E) { UsesThis = true; } + void VisitCXXThisExpr(const CXXThisExpr *E) { UsesThis = true; } }; } static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { DynamicThisUseChecker Checker(C); - Checker.Visit(const_cast<Expr*>(Init)); + Checker.Visit(Init); return Checker.UsesThis; } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 97f4a8def8c..36030b99a30 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -574,28 +574,29 @@ namespace { /// ContainsReference - A visitor class to search for references to /// a particular declaration (the needle) within any evaluated component of an /// expression (recursively). -class ContainsReference : public EvaluatedExprVisitor<ContainsReference> { +class ContainsReference : public ConstEvaluatedExprVisitor<ContainsReference> { bool FoundReference; const DeclRefExpr *Needle; public: + typedef ConstEvaluatedExprVisitor<ContainsReference> Inherited; + ContainsReference(ASTContext &Context, const DeclRefExpr *Needle) - : EvaluatedExprVisitor<ContainsReference>(Context), - FoundReference(false), Needle(Needle) {} + : Inherited(Context), FoundReference(false), Needle(Needle) {} - void VisitExpr(Expr *E) { + void VisitExpr(const Expr *E) { // Stop evaluating if we already have a reference. if (FoundReference) return; - EvaluatedExprVisitor<ContainsReference>::VisitExpr(E); + Inherited::VisitExpr(E); } - void VisitDeclRefExpr(DeclRefExpr *E) { + void VisitDeclRefExpr(const DeclRefExpr *E) { if (E == Needle) FoundReference = true; else - EvaluatedExprVisitor<ContainsReference>::VisitDeclRefExpr(E); + Inherited::VisitDeclRefExpr(E); } bool doesContainReference() const { return FoundReference; } @@ -854,7 +855,7 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD, return false; ContainsReference CR(S.Context, DRE); - CR.Visit(const_cast<Expr*>(Initializer)); + CR.Visit(Initializer); if (CR.doesContainReference()) { S.Diag(DRE->getLocStart(), diag::warn_uninit_self_reference_in_init) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7e305ffa8ed..ef72097e935 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -20,7 +20,6 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" -#include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/RecursiveASTVisitor.h" |

