Index: cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h =================================================================== --- cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h +++ cfe/trunk/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h @@ -1,45 +0,0 @@ -//== PseudoConstantAnalysis.h - Find Pseudo-constants in the AST -*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file tracks the usage of variables in a Decl body to see if they are -// never written to, implying that they constant. This is useful in static -// analysis to see if a developer might have intended a variable to be const. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H -#define LLVM_CLANG_ANALYSIS_ANALYSES_PSEUDOCONSTANTANALYSIS_H - -#include "clang/AST/Stmt.h" - -namespace clang { - -class PseudoConstantAnalysis { -public: - PseudoConstantAnalysis(const Stmt *DeclBody); - ~PseudoConstantAnalysis(); - - bool isPseudoConstant(const VarDecl *VD); - bool wasReferenced(const VarDecl *VD); - -private: - void RunAnalysis(); - inline static const Decl *getDecl(const Expr *E); - - // for storing the result of analyzed ValueDecls - void *NonConstantsImpl; - void *UsedVarsImpl; - - const Stmt *DeclBody; - bool Analyzed; -}; - -} - -#endif Index: cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h =================================================================== --- cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h +++ cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h @@ -40,7 +40,6 @@ class LocationContext; class LocationContextManager; class ParentMap; -class PseudoConstantAnalysis; class StackFrameContext; class Stmt; class VarDecl; @@ -84,7 +83,6 @@ bool builtCFG = false; bool builtCompleteCFG = false; std::unique_ptr PM; - std::unique_ptr PCA; std::unique_ptr CFA; llvm::BumpPtrAllocator A; @@ -175,7 +173,6 @@ bool isCFGBuilt() const { return builtCFG; } ParentMap &getParentMap(); - PseudoConstantAnalysis *getPseudoConstantAnalysis(); using referenced_decls_iterator = const VarDecl * const *; Index: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp =================================================================== --- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp +++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp @@ -27,7 +27,6 @@ #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtVisitor.h" #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" -#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h" #include "clang/Analysis/BodyFarm.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CFGStmtMap.h" @@ -292,12 +291,6 @@ return *PM; } -PseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() { - if (!PCA) - PCA.reset(new PseudoConstantAnalysis(getBody())); - return PCA.get(); -} - AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) { if (const auto *FD = dyn_cast(D)) { // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl Index: cfe/trunk/lib/Analysis/CMakeLists.txt =================================================================== --- cfe/trunk/lib/Analysis/CMakeLists.txt +++ cfe/trunk/lib/Analysis/CMakeLists.txt @@ -23,7 +23,6 @@ PostOrderCFGView.cpp PrintfFormatString.cpp ProgramPoint.cpp - PseudoConstantAnalysis.cpp ReachableCode.cpp ScanfFormatString.cpp ThreadSafety.cpp Index: cfe/trunk/lib/Analysis/PseudoConstantAnalysis.cpp =================================================================== --- cfe/trunk/lib/Analysis/PseudoConstantAnalysis.cpp +++ cfe/trunk/lib/Analysis/PseudoConstantAnalysis.cpp @@ -1,226 +0,0 @@ -//== PseudoConstantAnalysis.cpp - Find Pseudoconstants in the AST-*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file tracks the usage of variables in a Decl body to see if they are -// never written to, implying that they constant. This is useful in static -// analysis to see if a developer might have intended a variable to be const. -// -//===----------------------------------------------------------------------===// - -#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h" -#include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" -#include "clang/AST/Stmt.h" -#include "llvm/ADT/SmallPtrSet.h" -#include - -using namespace clang; - -typedef llvm::SmallPtrSet VarDeclSet; - -PseudoConstantAnalysis::PseudoConstantAnalysis(const Stmt *DeclBody) : - DeclBody(DeclBody), Analyzed(false) { - NonConstantsImpl = new VarDeclSet; - UsedVarsImpl = new VarDeclSet; -} - -PseudoConstantAnalysis::~PseudoConstantAnalysis() { - delete (VarDeclSet*)NonConstantsImpl; - delete (VarDeclSet*)UsedVarsImpl; -} - -// Returns true if the given ValueDecl is never written to in the given DeclBody -bool PseudoConstantAnalysis::isPseudoConstant(const VarDecl *VD) { - // Only local and static variables can be pseudoconstants - if (!VD->hasLocalStorage() && !VD->isStaticLocal()) - return false; - - if (!Analyzed) { - RunAnalysis(); - Analyzed = true; - } - - VarDeclSet *NonConstants = (VarDeclSet*)NonConstantsImpl; - - return !NonConstants->count(VD); -} - -// Returns true if the variable was used (self assignments don't count) -bool PseudoConstantAnalysis::wasReferenced(const VarDecl *VD) { - if (!Analyzed) { - RunAnalysis(); - Analyzed = true; - } - - VarDeclSet *UsedVars = (VarDeclSet*)UsedVarsImpl; - - return UsedVars->count(VD); -} - -// Returns a Decl from a (Block)DeclRefExpr (if any) -const Decl *PseudoConstantAnalysis::getDecl(const Expr *E) { - if (const DeclRefExpr *DR = dyn_cast(E)) - return DR->getDecl(); - else - return nullptr; -} - -void PseudoConstantAnalysis::RunAnalysis() { - std::deque WorkList; - VarDeclSet *NonConstants = (VarDeclSet*)NonConstantsImpl; - VarDeclSet *UsedVars = (VarDeclSet*)UsedVarsImpl; - - // Start with the top level statement of the function - WorkList.push_back(DeclBody); - - while (!WorkList.empty()) { - const Stmt *Head = WorkList.front(); - WorkList.pop_front(); - - if (const Expr *Ex = dyn_cast(Head)) - Head = Ex->IgnoreParenCasts(); - - switch (Head->getStmtClass()) { - // Case 1: Assignment operators modifying VarDecls - case Stmt::BinaryOperatorClass: { - const BinaryOperator *BO = cast(Head); - // Look for a Decl on the LHS - const Decl *LHSDecl = getDecl(BO->getLHS()->IgnoreParenCasts()); - if (!LHSDecl) - break; - - // We found a binary operator with a DeclRefExpr on the LHS. We now check - // for any of the assignment operators, implying that this Decl is being - // written to. - switch (BO->getOpcode()) { - // Self-assignments don't count as use of a variable - case BO_Assign: { - // Look for a DeclRef on the RHS - const Decl *RHSDecl = getDecl(BO->getRHS()->IgnoreParenCasts()); - - // If the Decls match, we have self-assignment - if (LHSDecl == RHSDecl) - // Do not visit the children - continue; - - LLVM_FALLTHROUGH; - } - case BO_AddAssign: - case BO_SubAssign: - case BO_MulAssign: - case BO_DivAssign: - case BO_AndAssign: - case BO_OrAssign: - case BO_XorAssign: - case BO_ShlAssign: - case BO_ShrAssign: { - const VarDecl *VD = dyn_cast(LHSDecl); - // The DeclRefExpr is being assigned to - mark it as non-constant - if (VD) - NonConstants->insert(VD); - break; - } - - default: - break; - } - break; - } - - // Case 2: Pre/post increment/decrement and address of - case Stmt::UnaryOperatorClass: { - const UnaryOperator *UO = cast(Head); - - // Look for a DeclRef in the subexpression - const Decl *D = getDecl(UO->getSubExpr()->IgnoreParenCasts()); - if (!D) - break; - - // We found a unary operator with a DeclRef as a subexpression. We now - // check for any of the increment/decrement operators, as well as - // addressOf. - switch (UO->getOpcode()) { - case UO_PostDec: - case UO_PostInc: - case UO_PreDec: - case UO_PreInc: - // The DeclRef is being changed - mark it as non-constant - case UO_AddrOf: { - // If we are taking the address of the DeclRefExpr, assume it is - // non-constant. - const VarDecl *VD = dyn_cast(D); - if (VD) - NonConstants->insert(VD); - break; - } - - default: - break; - } - break; - } - - // Case 3: Reference Declarations - case Stmt::DeclStmtClass: { - const DeclStmt *DS = cast(Head); - // Iterate over each decl and see if any of them contain reference decls - for (const auto *I : DS->decls()) { - // We only care about VarDecls - const VarDecl *VD = dyn_cast(I); - if (!VD) - continue; - - // We found a VarDecl; make sure it is a reference type - if (!VD->getType().getTypePtr()->isReferenceType()) - continue; - - // Try to find a Decl in the initializer - const Decl *D = getDecl(VD->getInit()->IgnoreParenCasts()); - if (!D) - break; - - // If the reference is to another var, add the var to the non-constant - // list - if (const VarDecl *RefVD = dyn_cast(D)) { - NonConstants->insert(RefVD); - continue; - } - } - break; - } - - // Case 4: Variable references - case Stmt::DeclRefExprClass: { - const DeclRefExpr *DR = cast(Head); - if (const VarDecl *VD = dyn_cast(DR->getDecl())) { - // Add the Decl to the used list - UsedVars->insert(VD); - continue; - } - break; - } - - // Case 5: Block expressions - case Stmt::BlockExprClass: { - const BlockExpr *B = cast(Head); - // Add the body of the block to the list - WorkList.push_back(B->getBody()); - continue; - } - - default: - break; - } // switch (head->getStmtClass()) - - // Add all substatements to the worklist - for (const Stmt *SubStmt : Head->children()) - if (SubStmt) - WorkList.push_back(SubStmt); - } // while (!WorkList.empty()) -}