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