Consumed.h revision df7bef07eebd5c7913e8be09c62a6a470f255fd2
1//===- Consumed.h ----------------------------------------------*- C++ --*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// A intra-procedural analysis for checking consumed properties. This is based, 11// in part, on research on linear types. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_CONSUMED_H 16#define LLVM_CLANG_CONSUMED_H 17 18#include "clang/AST/DeclCXX.h" 19#include "clang/AST/ExprCXX.h" 20#include "clang/AST/StmtCXX.h" 21#include "clang/Analysis/AnalysisContext.h" 22#include "clang/Analysis/Analyses/PostOrderCFGView.h" 23#include "clang/Basic/SourceLocation.h" 24#include "clang/Sema/ConsumedWarningsHandler.h" 25#include "clang/Sema/Sema.h" 26 27namespace clang { 28namespace consumed { 29 30 enum ConsumedState { 31 // No state information for the given variable. 32 CS_None, 33 34 CS_Unknown, 35 CS_Unconsumed, 36 CS_Consumed 37 }; 38 39 class ConsumedStateMap { 40 41 typedef llvm::DenseMap<const VarDecl *, ConsumedState> MapType; 42 typedef std::pair<const VarDecl *, ConsumedState> PairType; 43 44 protected: 45 46 MapType Map; 47 48 public: 49 /// \brief Get the consumed state of a given variable. 50 ConsumedState getState(const VarDecl *Var); 51 52 /// \brief Merge this state map with another map. 53 void intersect(const ConsumedStateMap *Other); 54 55 /// \brief Mark all variables as unknown. 56 void makeUnknown(); 57 58 /// \brief Set the consumed state of a given variable. 59 void setState(const VarDecl *Var, ConsumedState State); 60 }; 61 62 class ConsumedBlockInfo { 63 64 ConsumedStateMap **StateMapsArray; 65 PostOrderCFGView::CFGBlockSet VisitedBlocks; 66 67 public: 68 69 ConsumedBlockInfo() : StateMapsArray(NULL) {} 70 71 ConsumedBlockInfo(const CFG *CFGraph) 72 : StateMapsArray(new ConsumedStateMap*[CFGraph->getNumBlockIDs()]()), 73 VisitedBlocks(CFGraph) {} 74 75 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, 76 bool &AlreadyOwned); 77 void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap); 78 79 ConsumedStateMap* getInfo(const CFGBlock *Block); 80 81 void markVisited(const CFGBlock *Block); 82 }; 83 84 struct VarTestResult { 85 const VarDecl *Var; 86 SourceLocation Loc; 87 bool UnconsumedInTrueBranch; 88 89 VarTestResult() : Var(NULL), Loc(), UnconsumedInTrueBranch(true) {} 90 91 VarTestResult(const VarDecl *Var, SourceLocation Loc, 92 bool UnconsumedInTrueBranch) 93 : Var(Var), Loc(Loc), UnconsumedInTrueBranch(UnconsumedInTrueBranch) {} 94 }; 95 96 /// A class that handles the analysis of uniqueness violations. 97 class ConsumedAnalyzer { 98 99 typedef llvm::DenseMap<const CXXRecordDecl *, bool> CacheMapType; 100 typedef std::pair<const CXXRecordDecl *, bool> CachePairType; 101 102 Sema &S; 103 104 ConsumedBlockInfo BlockInfo; 105 ConsumedStateMap *CurrStates; 106 107 CacheMapType ConsumableTypeCache; 108 109 bool hasConsumableAttributes(const CXXRecordDecl *RD); 110 void splitState(const CFGBlock *CurrBlock, const IfStmt *Terminator); 111 112 public: 113 114 ConsumedWarningsHandlerBase &WarningsHandler; 115 116 ConsumedAnalyzer(Sema &S, ConsumedWarningsHandlerBase &WarningsHandler) 117 : S(S), WarningsHandler(WarningsHandler) {} 118 119 /// \brief Get a constant reference to the Sema object. 120 const Sema & getSema(void); 121 122 /// \brief Check to see if the type is a consumable type. 123 bool isConsumableType(QualType Type); 124 125 /// \brief Check a function's CFG for consumed violations. 126 /// 127 /// We traverse the blocks in the CFG, keeping track of the state of each 128 /// value who's type has uniquness annotations. If methods are invoked in 129 /// the wrong state a warning is issued. Each block in the CFG is traversed 130 /// exactly once. 131 void run(AnalysisDeclContext &AC); 132 }; 133 134 unsigned checkEnabled(DiagnosticsEngine &D); 135 /// \brief Check to see if a function tests an object's validity. 136 bool isTestingFunction(const CXXMethodDecl *MethodDecl); 137 138}} // end namespace clang::consumed 139 140#endif 141