summaryrefslogtreecommitdiffstats
path: root/include/clang/Analysis/CFG.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/CFG.h')
-rw-r--r--include/clang/Analysis/CFG.h117
1 files changed, 73 insertions, 44 deletions
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();
}
};
OpenPOWER on IntegriCloud