Author: scott-0 Date: Wed Jun 10 08:53:15 2015 New Revision: 239474 URL: http://llvm.org/viewvc/llvm-project?rev=239474&view=rev Log: add ConstEvaluatedExprVisitor
Differential Revision: http://reviews.llvm.org/D10210 Modified: cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h cfe/trunk/include/clang/AST/Expr.h cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/CodeGen/CGClass.cpp cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp Modified: cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h?rev=239474&r1=239473&r2=239474&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h (original) +++ cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h Wed Jun 10 08:53:15 2015 @@ -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) { } }; } Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=239474&r1=239473&r2=239474&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Wed Jun 10 08:53:15 2015 @@ -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 Modified: cfe/trunk/lib/AST/Expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=239474&r1=239473&r2=239474&view=diff ============================================================================== --- cfe/trunk/lib/AST/Expr.cpp (original) +++ cfe/trunk/lib/AST/Expr.cpp Wed Jun 10 08:53:15 2015 @@ -1238,7 +1238,7 @@ unsigned CallExpr::getBuiltinCallee() co 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 ASTConte 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(); Modified: cfe/trunk/lib/CodeGen/CGClass.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=239474&r1=239473&r2=239474&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) +++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Jun 10 08:53:15 2015 @@ -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; } Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=239474&r1=239473&r2=239474&view=diff ============================================================================== --- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original) +++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Wed Jun 10 08:53:15 2015 @@ -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(Sem 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) Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=239474&r1=239473&r2=239474&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Jun 10 08:53:15 2015 @@ -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" _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
