diff --git a/clang/include/clang/AST/CFG.h b/clang/include/clang/AST/CFG.h index 2cc3c6279e23..162240ab1f79 100644 --- a/clang/include/clang/AST/CFG.h +++ b/clang/include/clang/AST/CFG.h @@ -281,7 +281,7 @@ public: //===--------------------------------------------------------------------===// CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0), - BlkExprMap(NULL), BlkEdgeSet(NULL) {}; + BlkExprMap(NULL), BlkEdgeSet(NULL), Allocator(NULL) {}; ~CFG(); @@ -298,13 +298,16 @@ private: // block-level expressions and their "statement number" in the CFG. void* BlkExprMap; - /// BlkEdgeSet - An opaque pointer to prevent inclusion of . + /// BlkEdgeSet - An opaque pointer to prevent inclusion of FoldingSet.h. /// The set contains std::pair objects that have /// stable references for use by the 'BlockEdge' class. This set is intended /// to be sparse, as it only contains edges whether both the source /// and destination block have multiple successors/predecessors. void* BlkEdgeSet; + /// Alloc - An internal allocator used for BlkEdgeSet. + void* Allocator; + friend class BlockEdge; /// getBlockEdgeImpl - Utility method used by the class BlockEdge. The CFG diff --git a/clang/lib/AST/CFG.cpp b/clang/lib/AST/CFG.cpp index 6277aae85a9f..aa5bbe437daf 100644 --- a/clang/lib/AST/CFG.cpp +++ b/clang/lib/AST/CFG.cpp @@ -21,11 +21,10 @@ #include "llvm/Support/GraphWriter.h" #include "llvm/Support/Streams.h" #include "llvm/Support/Compiler.h" -#include +#include #include #include #include -#include using namespace clang; @@ -115,14 +114,20 @@ public: // FIXME: Add support for ObjC-specific control-flow structures. - CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* Terminator) { + // NYS == Not Yet Supported + CFGBlock* NYS() { badCFG = true; return Block; } - CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* Terminator) { - badCFG = true; - return Block; + CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* S){ return NYS();} + CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S) { return NYS(); } + CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) { return NYS(); } + CFGBlock* VisitObjCAtFinallyStmt(ObjCAtFinallyStmt* S) { return NYS(); } + CFGBlock* VisitObjCAtThrowStmt(ObjCAtThrowStmt* S) { return NYS(); } + + CFGBlock* VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S){ + return NYS(); } private: @@ -1150,21 +1155,77 @@ unsigned CFG::getNumBlkExprs() { } } -typedef std::set > BlkEdgeSetTy; +//===----------------------------------------------------------------------===// +// Internal Block-Edge Set; used for modeling persistent +// pairs for use with ProgramPoint. +//===----------------------------------------------------------------------===// + +typedef std::pair BPairTy; + +namespace llvm { + template<> struct FoldingSetTrait { + static void Profile(const BPairTy* X, FoldingSetNodeID& profile) { + profile.AddPointer(X->first); + profile.AddPointer(X->second); + } + }; +} + +typedef llvm::FoldingSetNodeWrapper PersistPairTy; +typedef llvm::FoldingSet BlkEdgeSetTy; const std::pair* CFG::getBlockEdgeImpl(const CFGBlock* B1, const CFGBlock* B2) { - BlkEdgeSetTy*& p = reinterpret_cast(BlkEdgeSet); - if (!p) p = new BlkEdgeSetTy(); + llvm::BumpPtrAllocator*& Alloc = + reinterpret_cast(Allocator); - return &*(p->insert(std::make_pair(const_cast(B1), - const_cast(B2))).first); + if (!Alloc) + Alloc = new llvm::BumpPtrAllocator(); + + BlkEdgeSetTy*& p = reinterpret_cast(BlkEdgeSet); + + if (!p) + p = new BlkEdgeSetTy(); + + // Profile the edges. + llvm::FoldingSetNodeID profile; + void* InsertPos; + + profile.AddPointer(B1); + profile.AddPointer(B2); + + PersistPairTy* V = p->FindNodeOrInsertPos(profile, InsertPos); + + if (!V) { + assert (llvm::AlignOf::Alignment_LessEqual_8Bytes); + + // Allocate the pair, forcing an 8-byte alignment. + BPairTy* pair = (BPairTy*) Alloc->Allocate(sizeof(*pair), 8); + + new (pair) BPairTy(const_cast(B1), + const_cast(B2)); + + // Allocate the meta data to store the pair in the FoldingSet. + PersistPairTy* ppair = (PersistPairTy*) Alloc->Allocate(); + new (ppair) PersistPairTy(pair); + + p->InsertNode(ppair, InsertPos); + + return pair; + } + + return V->getValue(); } +//===----------------------------------------------------------------------===// +// Cleanup: CFG dstor. +//===----------------------------------------------------------------------===// + CFG::~CFG() { delete reinterpret_cast(BlkExprMap); delete reinterpret_cast(BlkEdgeSet); + delete reinterpret_cast (Allocator); } //===----------------------------------------------------------------------===// @@ -1542,9 +1603,6 @@ void CFG::viewCFG() const { GraphHelper = &H; llvm::ViewGraph(this,"CFG"); GraphHelper = NULL; -#else - std::cerr << "CFG::viewCFG is only available in debug builds on " - << "systems with Graphviz or gv!\n"; #endif }