diff options
Diffstat (limited to 'include/clang/Analysis/CFG.h')
-rw-r--r-- | include/clang/Analysis/CFG.h | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index 38d4bdf..e87784f 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -20,12 +20,14 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" #include "clang/Analysis/Support/BumpVector.h" +#include "clang/Basic/SourceLocation.h" #include <cassert> namespace llvm { class raw_ostream; } namespace clang { + class Decl; class Stmt; class Expr; class CFG; @@ -33,15 +35,39 @@ namespace clang { class LangOptions; class ASTContext; +namespace { +// An element of the CFG for implicit descructor calls implied by the language +// rules. +class Dtor { + // Statement that introduces the variable. + Stmt *S; + // A token which ends the scope, return, goto, throw, }. + SourceLocation Loc; +public: + Dtor(Stmt *s, SourceLocation l) : S(s), Loc(l) { + } + SourceLocation getLoc() { return Loc; } + Stmt *getStmt() { return S; } +}; +} + /// CFGElement - Represents a top-level expression in a basic block. class CFGElement { - llvm::PointerIntPair<Stmt *, 1> Data; + llvm::PointerIntPair<Stmt *, 2> Data; public: + enum Type { StartScope, EndScope }; explicit CFGElement() {} CFGElement(Stmt *S, bool lvalue) : Data(S, lvalue ? 1 : 0) {} + CFGElement(Stmt *S, Type t) : Data(S, t == StartScope ? 2 : 3) {} + // CFGElement(Dtor *S, Type t) : Data(reinterpret_cast<Stmt*>(S), 4) {} Stmt *getStmt() const { return Data.getPointer(); } bool asLValue() const { return Data.getInt() == 1; } + bool asStartScope() const { return Data.getInt() == 2; } + bool asEndScope() const { return Data.getInt() == 3; } + bool asDtor() const { return Data.getInt() == 4; } operator Stmt*() const { return getStmt(); } + operator bool() const { return getStmt() != 0; } + operator Dtor*() const { return reinterpret_cast<Dtor*>(getStmt()); } }; /// CFGBlock - Represents a single basic block in a source-level CFG. @@ -107,7 +133,7 @@ class CFGBlock { /// Label - An (optional) label that prefixes the executable /// statements in the block. When this variable is non-NULL, it is - /// either an instance of LabelStmt or SwitchCase. + /// either an instance of LabelStmt, SwitchCase or CXXCatchStmt. Stmt *Label; /// Terminator - The terminator for a basic block that @@ -236,6 +262,12 @@ public: void appendStmt(Stmt* Statement, BumpVectorContext &C, bool asLValue) { Stmts.push_back(CFGElement(Statement, asLValue), C); } + void StartScope(Stmt* S, BumpVectorContext &C) { + Stmts.push_back(CFGElement(S, CFGElement::StartScope), C); + } + void EndScope(Stmt* S, BumpVectorContext &C) { + Stmts.push_back(CFGElement(S, CFGElement::EndScope), C); + } }; @@ -254,7 +286,9 @@ public: /// buildCFG - Builds a CFG from an AST. The responsibility to free the /// constructed CFG belongs to the caller. - static CFG* buildCFG(Stmt* AST, ASTContext *C); + static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C, + bool AddEHEdges = false, + bool AddScopes = false); /// createBlock - Create a new block in the CFG. The CFG owns the block; /// the caller should not directly free it. |