diff options
Diffstat (limited to 'include/clang/Analysis')
-rw-r--r-- | include/clang/Analysis/Analyses/Dominators.h | 7 | ||||
-rw-r--r-- | include/clang/Analysis/Analyses/FormatString.h | 4 | ||||
-rw-r--r-- | include/clang/Analysis/Analyses/LiveVariables.h | 2 | ||||
-rw-r--r-- | include/clang/Analysis/Analyses/ThreadSafety.h | 23 | ||||
-rw-r--r-- | include/clang/Analysis/Analyses/UninitializedValues.h | 5 | ||||
-rw-r--r-- | include/clang/Analysis/AnalysisContext.h | 25 | ||||
-rw-r--r-- | include/clang/Analysis/CFG.h | 117 | ||||
-rw-r--r-- | include/clang/Analysis/CallGraph.h | 40 | ||||
-rw-r--r-- | include/clang/Analysis/FlowSensitive/DataflowSolver.h | 4 | ||||
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 230 | ||||
-rw-r--r-- | include/clang/Analysis/Support/BlkExprDeclBitVector.h | 2 | ||||
-rw-r--r-- | include/clang/Analysis/Support/BumpVector.h | 4 | ||||
-rw-r--r-- | include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h | 6 |
13 files changed, 311 insertions, 158 deletions
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h index e9a431a..2a806c8 100644 --- a/include/clang/Analysis/Analyses/Dominators.h +++ b/include/clang/Analysis/Analyses/Dominators.h @@ -15,12 +15,11 @@ #define LLVM_CLANG_DOMINATORS_H #include "clang/Analysis/AnalysisContext.h" - -#include "llvm/Module.h" -#include "llvm/ADT/GraphTraits.h" #include "clang/Analysis/CFG.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/ADT/GraphTraits.h" #include "llvm/Analysis/DominatorInternals.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/IR/Module.h" namespace clang { diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h index 5cb9731..4bd989c 100644 --- a/include/clang/Analysis/Analyses/FormatString.h +++ b/include/clang/Analysis/Analyses/FormatString.h @@ -201,7 +201,7 @@ public: bool isPrintfKind() const { return IsPrintf; } - llvm::Optional<ConversionSpecifier> getStandardSpecifier() const; + Optional<ConversionSpecifier> getStandardSpecifier() const; protected: bool IsPrintf; @@ -361,7 +361,7 @@ public: bool hasStandardLengthModifier() const; - llvm::Optional<LengthModifier> getCorrectedLengthModifier() const; + Optional<LengthModifier> getCorrectedLengthModifier() const; bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const; diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h index c9f39b4..bbd2b02 100644 --- a/include/clang/Analysis/Analyses/LiveVariables.h +++ b/include/clang/Analysis/Analyses/LiveVariables.h @@ -14,8 +14,8 @@ #ifndef LLVM_CLANG_LIVEVARIABLES_H #define LLVM_CLANG_LIVEVARIABLES_H -#include "clang/Analysis/AnalysisContext.h" #include "clang/AST/Decl.h" +#include "clang/Analysis/AnalysisContext.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ImmutableSet.h" diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h index ef6b821..8a888e6 100644 --- a/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/include/clang/Analysis/Analyses/ThreadSafety.h @@ -29,24 +29,24 @@ namespace thread_safety { /// This enum distinguishes between different kinds of operations that may /// need to be protected by locks. We use this enum in error handling. enum ProtectedOperationKind { - POK_VarDereference, /// Dereferencing a variable (e.g. p in *p = 5;) - POK_VarAccess, /// Reading or writing a variable (e.g. x in x = 5;) - POK_FunctionCall /// Making a function call (e.g. fool()) + POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;) + POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;) + POK_FunctionCall ///< Making a function call (e.g. fool()) }; /// This enum distinguishes between different kinds of lock actions. For /// example, it is an error to write a variable protected by shared version of a /// mutex. enum LockKind { - LK_Shared, /// Shared/reader lock of a mutex - LK_Exclusive /// Exclusive/writer lock of a mutex + LK_Shared, ///< Shared/reader lock of a mutex. + LK_Exclusive ///< Exclusive/writer lock of a mutex. }; /// This enum distinguishes between different ways to access (read or write) a /// variable. enum AccessKind { - AK_Read, /// Reading a variable - AK_Written /// Writing a variable + AK_Read, ///< Reading a variable. + AK_Written ///< Writing a variable. }; /// This enum distinguishes between different situations where we warn due to @@ -67,7 +67,8 @@ enum LockErrorKind { /// Handler class for thread safety warnings. class ThreadSafetyHandler { public: - typedef llvm::StringRef Name; + typedef StringRef Name; + ThreadSafetyHandler() : IssueBetaWarnings(false) { } virtual ~ThreadSafetyHandler(); /// Warn about lock expressions which fail to resolve to lockable objects. @@ -143,6 +144,12 @@ public: /// \param Loc -- The location of the function call. virtual void handleFunExcludesLock(Name FunName, Name LockName, SourceLocation Loc) {} + + bool issueBetaWarnings() { return IssueBetaWarnings; } + void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; } + +private: + bool IssueBetaWarnings; }; /// \brief Check a function's CFG for thread-safety violations. diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h index 45ce4de..e8810c3 100644 --- a/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/include/clang/Analysis/Analyses/UninitializedValues.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_UNINIT_VALS_H #define LLVM_CLANG_UNINIT_VALS_H +#include "clang/AST/Stmt.h" #include "llvm/ADT/SmallVector.h" namespace clang { @@ -42,7 +43,7 @@ private: /// This use is always uninitialized if it occurs after any of these branches /// is taken. - llvm::SmallVector<Branch, 2> UninitBranches; + SmallVector<Branch, 2> UninitBranches; public: UninitUse(const Expr *User, bool AlwaysUninit) : @@ -71,7 +72,7 @@ public: !branch_empty() ? Sometimes : Maybe; } - typedef llvm::SmallVectorImpl<Branch>::const_iterator branch_iterator; + typedef SmallVectorImpl<Branch>::const_iterator branch_iterator; /// Branches which inevitably result in the variable being used uninitialized. branch_iterator branch_begin() const { return UninitBranches.begin(); } branch_iterator branch_end() const { return UninitBranches.end(); } diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 5246678..46d7d07 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -18,11 +18,11 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/Analysis/CFG.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" namespace clang { @@ -133,7 +133,21 @@ public: void registerForcedBlockExpression(const Stmt *stmt); const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt); + /// \brief Get the body of the Declaration. Stmt *getBody() const; + + /// \brief Get the body of the Declaration. + /// \param[out] IsAutosynthesized Specifies if the body is auto-generated + /// by the BodyFarm. + Stmt *getBody(bool &IsAutosynthesized) const; + + /// \brief Checks if the body of the Decl is generated by the BodyFarm. + /// + /// Note, the lookup is not free. We are going to call getBody behind + /// the scenes. + /// \sa getBody + bool isBodyAutosynthesized() const; + CFG *getCFG(); CFGStmtMap *getCFGStmtMap(); @@ -242,6 +256,8 @@ public: virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; + LLVM_ATTRIBUTE_USED void dumpStack() const; + public: static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, @@ -396,7 +412,8 @@ public: bool addImplicitDtors = false, bool addInitializers = false, bool addTemporaryDtors = false, - bool synthesizeBodies = false); + bool synthesizeBodies = false, + bool addStaticInitBranches = false); ~AnalysisDeclContextManager(); diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index 8cc5d81..ee0be73 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -15,15 +15,16 @@ #ifndef LLVM_CLANG_CFG_H #define LLVM_CLANG_CFG_H -#include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/GraphTraits.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/Casting.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/DenseMap.h" #include "clang/AST/Stmt.h" #include "clang/Analysis/Support/BumpVector.h" #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/Casting.h" #include <bitset> #include <cassert> #include <iterator> @@ -48,7 +49,6 @@ class CFGElement { public: enum Kind { // main kind - Invalid, Statement, Initializer, // dtor kind @@ -69,8 +69,31 @@ protected: : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3), Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {} -public: CFGElement() {} +public: + + /// \brief Convert to the specified CFGElement type, asserting that this + /// CFGElement is of the desired type. + template<typename T> + T castAs() const { + assert(T::isKind(*this)); + T t; + CFGElement& e = t; + e = *this; + return t; + } + + /// \brief Convert to the specified CFGElement type, returning None if this + /// CFGElement is not of the desired type. + template<typename T> + Optional<T> getAs() const { + if (!T::isKind(*this)) + return None; + T t; + CFGElement& e = t; + e = *this; + return t; + } Kind getKind() const { unsigned x = Data2.getInt(); @@ -78,16 +101,6 @@ public: x |= Data1.getInt(); return (Kind) x; } - - bool isValid() const { return getKind() != Invalid; } - - operator bool() const { return isValid(); } - - template<class ElemTy> const ElemTy *getAs() const { - if (llvm::isa<ElemTy>(this)) - return static_cast<const ElemTy*>(this); - return 0; - } }; class CFGStmt : public CFGElement { @@ -98,8 +111,11 @@ public: return static_cast<const Stmt *>(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == Statement; +private: + friend class CFGElement; + CFGStmt() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == Statement; } }; @@ -114,8 +130,11 @@ public: return static_cast<CXXCtorInitializer*>(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == Initializer; +private: + friend class CFGElement; + CFGInitializer() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == Initializer; } }; @@ -123,6 +142,7 @@ public: /// by compiler on various occasions. class CFGImplicitDtor : public CFGElement { protected: + CFGImplicitDtor() {} CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0) : CFGElement(kind, data1, data2) { assert(kind >= DTOR_BEGIN && kind <= DTOR_END); @@ -132,8 +152,10 @@ public: const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const; bool isNoReturn(ASTContext &astContext) const; - static bool classof(const CFGElement *E) { - Kind kind = E->getKind(); +private: + friend class CFGElement; + static bool isKind(const CFGElement &E) { + Kind kind = E.getKind(); return kind >= DTOR_BEGIN && kind <= DTOR_END; } }; @@ -155,8 +177,11 @@ public: return static_cast<Stmt*>(Data2.getPointer()); } - static bool classof(const CFGElement *elem) { - return elem->getKind() == AutomaticObjectDtor; +private: + friend class CFGElement; + CFGAutomaticObjDtor() {} + static bool isKind(const CFGElement &elem) { + return elem.getKind() == AutomaticObjectDtor; } }; @@ -171,8 +196,11 @@ public: return static_cast<const CXXBaseSpecifier*>(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == BaseDtor; +private: + friend class CFGElement; + CFGBaseDtor() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == BaseDtor; } }; @@ -187,8 +215,11 @@ public: return static_cast<const FieldDecl*>(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == MemberDtor; +private: + friend class CFGElement; + CFGMemberDtor() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == MemberDtor; } }; @@ -203,8 +234,11 @@ public: return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == TemporaryDtor; +private: + friend class CFGElement; + CFGTemporaryDtor() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == TemporaryDtor; } }; @@ -535,7 +569,7 @@ public: // the elements beginning at the last position in prepared space. iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, BumpVectorContext &C) { - return iterator(Elements.insert(I.base(), Cnt, CFGElement(), C)); + return iterator(Elements.insert(I.base(), Cnt, CFGAutomaticObjDtor(0, 0), C)); } iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { *I = CFGAutomaticObjDtor(VD, S); @@ -567,6 +601,7 @@ public: bool AddInitializers; bool AddImplicitDtors; bool AddTemporaryDtors; + bool AddStaticInitBranches; bool alwaysAdd(const Stmt *stmt) const { return alwaysAddMask[stmt->getStmtClass()]; @@ -587,7 +622,8 @@ public: ,AddEHEdges(false) ,AddInitializers(false) ,AddImplicitDtors(false) - ,AddTemporaryDtors(false) {} + ,AddTemporaryDtors(false) + ,AddStaticInitBranches(false) {} }; /// \brief Provides a custom implementation of the iterator class to have the @@ -718,7 +754,7 @@ public: for (const_iterator I=begin(), E=end(); I != E; ++I) for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end(); BI != BE; ++BI) { - if (const CFGStmt *stmt = BI->getAs<CFGStmt>()) + if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>()) O(const_cast<Stmt*>(stmt->getStmt())); } } @@ -807,17 +843,10 @@ namespace llvm { /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from /// CFGTerminator to a specific Stmt class. -template <> struct simplify_type<const ::clang::CFGTerminator> { - typedef const ::clang::Stmt *SimpleType; - static SimpleType getSimplifiedValue(const ::clang::CFGTerminator &Val) { - return Val.getStmt(); - } -}; - template <> struct simplify_type< ::clang::CFGTerminator> { typedef ::clang::Stmt *SimpleType; - static SimpleType getSimplifiedValue(const ::clang::CFGTerminator &Val) { - return const_cast<SimpleType>(Val.getStmt()); + static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) { + return Val.getStmt(); } }; diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h index 509de7b..5015eb6 100644 --- a/include/clang/Analysis/CallGraph.h +++ b/include/clang/Analysis/CallGraph.h @@ -39,15 +39,9 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> { /// FunctionMap owns all CallGraphNodes. FunctionMapTy FunctionMap; - /// This is a virtual root node that has edges to all the global functions - - /// 'main' or functions accessible from other translation units. + /// This is a virtual root node that has edges to all the functions. CallGraphNode *Root; - /// The list of nodes that have no parent. These are unreachable from Root. - /// Declarations can get to this list due to impressions in the graph, for - /// example, we do not track functions whose addresses were taken. - llvm::SetVector<CallGraphNode *> ParentlessNodes; - public: CallGraph(); ~CallGraph(); @@ -91,34 +85,35 @@ public: /// failing to add a call edge due to the analysis imprecision. typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator; typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator; - nodes_iterator parentless_begin() { return ParentlessNodes.begin(); } - nodes_iterator parentless_end() { return ParentlessNodes.end(); } - const_nodes_iterator - parentless_begin() const { return ParentlessNodes.begin(); } - const_nodes_iterator - parentless_end() const { return ParentlessNodes.end(); } void print(raw_ostream &os) const; void dump() const; void viewGraph() const; + void addNodesForBlocks(DeclContext *D); + /// Part of recursive declaration visitation. We recursively visit all the - /// Declarations to collect the root functions. + /// declarations to collect the root functions. bool VisitFunctionDecl(FunctionDecl *FD) { // We skip function template definitions, as their semantics is // only determined when they are instantiated. - if (includeInGraph(FD)) + if (includeInGraph(FD)) { + // Add all blocks declared inside this function to the graph. + addNodesForBlocks(FD); // If this function has external linkage, anything could call it. // Note, we are not precise here. For example, the function could have // its address taken. addNodeForDecl(FD, FD->isGlobal()); + } return true; } /// Part of recursive declaration visitation. bool VisitObjCMethodDecl(ObjCMethodDecl *MD) { - if (includeInGraph(MD)) + if (includeInGraph(MD)) { + addNodesForBlocks(MD); addNodeForDecl(MD, true); + } return true; } @@ -144,15 +139,13 @@ private: Decl *FD; /// \brief The list of functions called from this node. - // Small vector might be more efficient since we are only tracking functions - // whose definition is in the current TU. - llvm::SmallVector<CallRecord, 5> CalledFunctions; + SmallVector<CallRecord, 5> CalledFunctions; public: CallGraphNode(Decl *D) : FD(D) {} - typedef llvm::SmallVector<CallRecord, 5>::iterator iterator; - typedef llvm::SmallVector<CallRecord, 5>::const_iterator const_iterator; + typedef SmallVector<CallRecord, 5>::iterator iterator; + typedef SmallVector<CallRecord, 5>::const_iterator const_iterator; /// Iterators through all the callees/children of the node. inline iterator begin() { return CalledFunctions.begin(); } @@ -165,13 +158,10 @@ public: void addCallee(CallGraphNode *N, CallGraph *CG) { CalledFunctions.push_back(N); - CG->ParentlessNodes.remove(N); } Decl *getDecl() const { return FD; } - StringRef getName() const; - void print(raw_ostream &os) const; void dump() const; }; @@ -203,7 +193,7 @@ template <> struct GraphTraits<const clang::CallGraphNode*> { typedef NodeType::const_iterator ChildIteratorType; static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; } static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();} - static inline ChildIteratorType child_end (NodeType *N) { return N->end(); } + static inline ChildIteratorType child_end(NodeType *N) { return N->end(); } }; template <> struct GraphTraits<clang::CallGraph*> diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h index 017da63..0f5e7bf 100644 --- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h +++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h @@ -14,12 +14,12 @@ #ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER #define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER +#include "functional" // STL #include "clang/Analysis/CFG.h" -#include "clang/Analysis/ProgramPoint.h" #include "clang/Analysis/FlowSensitive/DataflowValues.h" +#include "clang/Analysis/ProgramPoint.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" -#include "functional" // STL namespace clang { diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 9479978..333329d 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -17,15 +17,16 @@ #include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/CFG.h" -#include "llvm/Support/DataTypes.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/Support/Casting.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/DataTypes.h" #include <cassert> -#include <utility> #include <string> +#include <utility> namespace clang { @@ -71,9 +72,8 @@ private: llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag; - ProgramPoint(); - protected: + ProgramPoint() {} ProgramPoint(const void *P, Kind k, const LocationContext *l, @@ -110,6 +110,29 @@ public: getLocationContext(), tag); } + /// \brief Convert to the specified ProgramPoint type, asserting that this + /// ProgramPoint is of the desired type. + template<typename T> + T castAs() const { + assert(T::isKind(*this)); + T t; + ProgramPoint& PP = t; + PP = *this; + return t; + } + + /// \brief Convert to the specified ProgramPoint type, returning None if this + /// ProgramPoint is not of the desired type. + template<typename T> + Optional<T> getAs() const { + if (!T::isKind(*this)) + return None; + T t; + ProgramPoint& PP = t; + PP = *this; + return t; + } + Kind getKind() const { unsigned x = Tag.getInt(); x <<= 2; @@ -179,13 +202,16 @@ public: return reinterpret_cast<const CFGBlock*>(getData1()); } - const CFGElement getFirstElement() const { + Optional<CFGElement> getFirstElement() const { const CFGBlock *B = getBlock(); - return B->empty() ? CFGElement() : B->front(); + return B->empty() ? Optional<CFGElement>() : B->front(); } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == BlockEntranceKind; +private: + friend class ProgramPoint; + BlockEntrance() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == BlockEntranceKind; } }; @@ -202,8 +228,11 @@ public: return getBlock()->getTerminator(); } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == BlockExitKind; +private: + friend class ProgramPoint; + BlockExit() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == BlockExitKind; } }; @@ -218,10 +247,14 @@ public: const Stmt *getStmt() const { return (const Stmt*) getData1(); } template <typename T> - const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } + const T* getStmtAs() const { return dyn_cast<T>(getStmt()); } - static bool classof(const ProgramPoint* Location) { - unsigned k = Location->getKind(); +protected: + StmtPoint() {} +private: + friend class ProgramPoint; + static bool isKind(const ProgramPoint &Location) { + unsigned k = Location.getKind(); return k >= PreStmtKind && k <= MaxPostStmtKind; } }; @@ -235,13 +268,17 @@ public: const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PreStmtKind; +private: + friend class ProgramPoint; + PreStmt() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PreStmtKind; } }; class PostStmt : public StmtPoint { protected: + PostStmt() {} PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, const ProgramPointTag *tag = 0) : StmtPoint(S, data, k, L, tag) {} @@ -255,8 +292,10 @@ public: const ProgramPointTag *tag = 0) : StmtPoint(S, NULL, PostStmtKind, L, tag) {} - static bool classof(const ProgramPoint* Location) { - unsigned k = Location->getKind(); +private: + friend class ProgramPoint; + static bool isKind(const ProgramPoint &Location) { + unsigned k = Location.getKind(); return k >= MinPostStmtKind && k <= MaxPostStmtKind; } }; @@ -268,19 +307,25 @@ public: const ProgramPointTag *tag = 0) : PostStmt(S, PostConditionKind, L, tag) {} - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PostConditionKind; +private: + friend class ProgramPoint; + PostCondition() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostConditionKind; } }; class LocationCheck : public StmtPoint { protected: + LocationCheck() {} LocationCheck(const Stmt *S, const LocationContext *L, ProgramPoint::Kind K, const ProgramPointTag *tag) : StmtPoint(S, NULL, K, L, tag) {} - static bool classof(const ProgramPoint *location) { - unsigned k = location->getKind(); +private: + friend class ProgramPoint; + static bool isKind(const ProgramPoint &location) { + unsigned k = location.getKind(); return k == PreLoadKind || k == PreStoreKind; } }; @@ -291,8 +336,11 @@ public: const ProgramPointTag *tag = 0) : LocationCheck(S, L, PreLoadKind, tag) {} - static bool classof(const ProgramPoint *location) { - return location->getKind() == PreLoadKind; +private: + friend class ProgramPoint; + PreLoad() {} + static bool isKind(const ProgramPoint &location) { + return location.getKind() == PreLoadKind; } }; @@ -302,8 +350,11 @@ public: const ProgramPointTag *tag = 0) : LocationCheck(S, L, PreStoreKind, tag) {} - static bool classof(const ProgramPoint *location) { - return location->getKind() == PreStoreKind; +private: + friend class ProgramPoint; + PreStore() {} + static bool isKind(const ProgramPoint &location) { + return location.getKind() == PreStoreKind; } }; @@ -313,8 +364,11 @@ public: const ProgramPointTag *tag = 0) : PostStmt(S, PostLoadKind, L, tag) {} - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PostLoadKind; +private: + friend class ProgramPoint; + PostLoad() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostLoadKind; } }; @@ -331,16 +385,18 @@ public: setData2(Loc); } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PostStoreKind; - } - /// \brief Returns the information about the location used in the store, /// how it was uttered in the code. const void *getLocationValue() const { return getData2(); } +private: + friend class ProgramPoint; + PostStore() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostStoreKind; + } }; class PostLValue : public PostStmt { @@ -349,8 +405,11 @@ public: const ProgramPointTag *tag = 0) : PostStmt(S, PostLValueKind, L, tag) {} - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PostLValueKind; +private: + friend class ProgramPoint; + PostLValue() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostLValueKind; } }; @@ -362,8 +421,11 @@ public: const ProgramPointTag *tag = 0) : StmtPoint(S, 0, PreStmtPurgeDeadSymbolsKind, L, tag) { } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PreStmtPurgeDeadSymbolsKind; +private: + friend class ProgramPoint; + PreStmtPurgeDeadSymbols() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PreStmtPurgeDeadSymbolsKind; } }; @@ -375,8 +437,11 @@ public: const ProgramPointTag *tag = 0) : StmtPoint(S, 0, PostStmtPurgeDeadSymbolsKind, L, tag) { } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == PostStmtPurgeDeadSymbolsKind; +private: + friend class ProgramPoint; + PostStmtPurgeDeadSymbols() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostStmtPurgeDeadSymbolsKind; } }; @@ -396,19 +461,40 @@ public: return static_cast<const CFGBlock*>(getData2()); } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == BlockEdgeKind; +private: + friend class ProgramPoint; + BlockEdge() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == BlockEdgeKind; } }; class PostInitializer : public ProgramPoint { public: - PostInitializer(const CXXCtorInitializer *I, + /// \brief Construct a PostInitializer point that represents a location after + /// CXXCtorInitializer expression evaluation. + /// + /// \param I The initializer. + /// \param Loc The location of the field being initialized. + PostInitializer(const CXXCtorInitializer *I, + const void *Loc, const LocationContext *L) - : ProgramPoint(I, PostInitializerKind, L) {} + : ProgramPoint(I, Loc, PostInitializerKind, L) {} + + const CXXCtorInitializer *getInitializer() const { + return static_cast<const CXXCtorInitializer *>(getData1()); + } - static bool classof(const ProgramPoint *Location) { - return Location->getKind() == PostInitializerKind; + /// \brief Returns the location of the field. + const void *getLocationValue() const { + return getData2(); + } + +private: + friend class ProgramPoint; + PostInitializer() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostInitializerKind; } }; @@ -426,9 +512,13 @@ public: return SourceLocation::getFromPtrEncoding(getData1()); } - static bool classof(const ProgramPoint *Location) { - return Location->getKind() >= MinImplicitCallKind && - Location->getKind() <= MaxImplicitCallKind; +protected: + ImplicitCallPoint() {} +private: + friend class ProgramPoint; + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() >= MinImplicitCallKind && + Location.getKind() <= MaxImplicitCallKind; } }; @@ -441,8 +531,11 @@ public: const LocationContext *L, const ProgramPointTag *Tag = 0) : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {} - static bool classof(const ProgramPoint *Location) { - return Location->getKind() == PreImplicitCallKind; +private: + friend class ProgramPoint; + PreImplicitCall() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PreImplicitCallKind; } }; @@ -455,8 +548,11 @@ public: const LocationContext *L, const ProgramPointTag *Tag = 0) : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {} - static bool classof(const ProgramPoint *Location) { - return Location->getKind() == PostImplicitCallKind; +private: + friend class ProgramPoint; + PostImplicitCall() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == PostImplicitCallKind; } }; @@ -476,8 +572,11 @@ public: return static_cast<const StackFrameContext *>(getData2()); } - static bool classof(const ProgramPoint *Location) { - return Location->getKind() == CallEnterKind; +private: + friend class ProgramPoint; + CallEnter() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == CallEnterKind; } }; @@ -496,8 +595,11 @@ public: CallExitBegin(const StackFrameContext *L) : ProgramPoint(0, CallExitBeginKind, L, 0) {} - static bool classof(const ProgramPoint *Location) { - return Location->getKind() == CallExitBeginKind; +private: + friend class ProgramPoint; + CallExitBegin() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == CallExitBeginKind; } }; @@ -514,8 +616,11 @@ public: return static_cast<const StackFrameContext *>(getData1()); } - static bool classof(const ProgramPoint *Location) { - return Location->getKind() == CallExitEndKind; +private: + friend class ProgramPoint; + CallExitEnd() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == CallExitEndKind; } }; @@ -529,8 +634,11 @@ public: const void *getData() const { return getData1(); } - static bool classof(const ProgramPoint* Location) { - return Location->getKind() == EpsilonKind; +private: + friend class ProgramPoint; + EpsilonPoint() {} + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == EpsilonKind; } }; @@ -544,7 +652,7 @@ public: virtual StringRef getTagDescription() const = 0; protected: - /// Used to implement 'classof' in subclasses. + /// Used to implement 'isKind' in subclasses. const void *getTagKind() { return TagKind; } private: diff --git a/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/include/clang/Analysis/Support/BlkExprDeclBitVector.h index d25b848..35cc799 100644 --- a/include/clang/Analysis/Support/BlkExprDeclBitVector.h +++ b/include/clang/Analysis/Support/BlkExprDeclBitVector.h @@ -17,8 +17,8 @@ #ifndef LLVM_CLANG_STMTDECLBVDVAL_H #define LLVM_CLANG_STMTDECLBVDVAL_H -#include "clang/Analysis/CFG.h" #include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion +#include "clang/Analysis/CFG.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h index 83532e6..387e779 100644 --- a/include/clang/Analysis/Support/BumpVector.h +++ b/include/clang/Analysis/Support/BumpVector.h @@ -19,9 +19,9 @@ #ifndef LLVM_CLANG_BUMP_VECTOR #define LLVM_CLANG_BUMP_VECTOR -#include "llvm/Support/type_traits.h" -#include "llvm/Support/Allocator.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/type_traits.h" #include <algorithm> #include <cstring> #include <iterator> diff --git a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h index c510e20..2bf3eda 100644 --- a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h +++ b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h @@ -17,10 +17,10 @@ #ifndef LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H #define LLVM_CLANG_ANALYSIS_CFG_REC_STMT_DECL_VISITOR_H -#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h" #include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/Analysis/Visitors/CFGRecStmtVisitor.h" #define DISPATCH_CASE(CLASS) \ case Decl::CLASS: \ @@ -63,6 +63,7 @@ public: DISPATCH_CASE(ImplicitParam) DISPATCH_CASE(EnumConstant) DISPATCH_CASE(Typedef) + DISPATCH_CASE(TypeAlias) DISPATCH_CASE(Record) // FIXME: Refine. VisitStructDecl? DISPATCH_CASE(CXXRecord) DISPATCH_CASE(Enum) @@ -82,6 +83,7 @@ public: DEFAULT_DISPATCH(ImplicitParam) DEFAULT_DISPATCH(EnumConstant) DEFAULT_DISPATCH(Typedef) + DEFAULT_DISPATCH(TypeAlias) DEFAULT_DISPATCH(Record) DEFAULT_DISPATCH(Enum) DEFAULT_DISPATCH(Field) |