[cfe-commits] r110230 - in /cfe/trunk: include/clang/Analysis/CFGStmtMap.h lib/Analysis/CFGStmtMap.cpp lib/Analysis/CMakeLists.txt

Ted Kremenek kremenek at apple.com
Wed Aug 4 11:23:15 PDT 2010


Author: kremenek
Date: Wed Aug  4 13:23:15 2010
New Revision: 110230

URL: http://llvm.org/viewvc/llvm-project?rev=110230&view=rev
Log:
Add CFGStmtMap, which defines a mapping from Stmt* to CFGBlock*.  The immediate intended use is in the unreachable code analysis.

Added:
    cfe/trunk/include/clang/Analysis/CFGStmtMap.h
    cfe/trunk/lib/Analysis/CFGStmtMap.cpp
Modified:
    cfe/trunk/lib/Analysis/CMakeLists.txt

Added: cfe/trunk/include/clang/Analysis/CFGStmtMap.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFGStmtMap.h?rev=110230&view=auto
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFGStmtMap.h (added)
+++ cfe/trunk/include/clang/Analysis/CFGStmtMap.h Wed Aug  4 13:23:15 2010
@@ -0,0 +1,52 @@
+//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CFGStmtMap class, which defines a mapping from
+//  Stmt* to CFGBlock*
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CFGSTMTMAP_H
+#define LLVM_CLANG_CFGSTMTMAP_H
+
+#include "clang/Analysis/CFG.h"
+
+namespace clang {
+
+class CFG;
+class CFGBlock;
+class ParentMap;
+class Stmt;
+
+class CFGStmtMap {
+  ParentMap *PM;
+  void *M;
+  
+  CFGStmtMap(ParentMap *pm, void *m) : PM(pm), M(m) {}
+  
+public:
+  ~CFGStmtMap();
+  
+  /// Returns a new CFGMap for the given CFG.  It is the caller's
+  /// responsibility to 'delete' this object when done using it.
+  static CFGStmtMap *Build(CFG* C, ParentMap *PM);
+
+  /// Returns the CFGBlock the specified Stmt* appears in.  For Stmt* that
+  /// are terminators, the CFGBlock is the block they appear as a terminator,
+  /// and not the block they appear as a block-level expression (e.g, '&&').
+  /// CaseStmts and LabelStmts map to the CFGBlock they label.
+  CFGBlock *getBlock(Stmt * S);
+
+  const CFGBlock *getBlock(const Stmt * S) const {
+    return const_cast<CFGStmtMap*>(this)->getBlock(const_cast<Stmt*>(S));
+  }
+};
+
+} // end clang namespace
+#endif

Added: cfe/trunk/lib/Analysis/CFGStmtMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFGStmtMap.cpp?rev=110230&view=auto
==============================================================================
--- cfe/trunk/lib/Analysis/CFGStmtMap.cpp (added)
+++ cfe/trunk/lib/Analysis/CFGStmtMap.cpp Wed Aug  4 13:23:15 2010
@@ -0,0 +1,88 @@
+//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the CFGStmtMap class, which defines a mapping from
+//  Stmt* to CFGBlock*
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DenseMap.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/CFGStmtMap.h"
+
+using namespace clang;
+
+typedef llvm::DenseMap<Stmt*,CFGBlock*> SMap;
+static SMap *AsMap(void *m) { return (SMap*) m; }
+
+CFGStmtMap::~CFGStmtMap() { delete AsMap(M); }
+
+CFGBlock *CFGStmtMap::getBlock(Stmt *S) {  
+  SMap *SM = AsMap(M);
+  Stmt *X = S;
+
+  // If 'S' isn't in the map, walk the ParentMap to see if one of its ancestors
+  // is in the map.
+  while (X) {
+    SMap::iterator I = SM->find(S);
+    if (I != SM->end()) {
+      CFGBlock *B = I->second;
+      // Memoize this lookup.
+      if (X != S)
+        (*SM)[X] = B;
+      return B;
+    }
+
+    Stmt *X = PM->getParentIgnoreParens(X);
+  }
+  
+  return 0;
+}
+
+static void Accumulate(SMap &SM, CFGBlock *B) {
+  // First walk the block-level expressions.
+  for (CFGBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) {
+    const CFGElement &CE = *I;
+    if (Stmt *S = CE.getStmt()) {
+      CFGBlock *&Entry = SM[S];
+      // If 'Entry' is already initialized (e.g., a terminator was already),
+      // skip.
+      if (Entry)
+        continue;
+      
+      Entry = B;
+    }
+  }
+  
+  // Look at the label of the block.
+  if (Stmt *Label = B->getLabel())
+    SM[Label] = B;
+
+  // Finally, look at the terminator.  If the terminator was already added
+  // because it is a block-level expression in another block, overwrite
+  // that mapping.
+  if (Stmt *Term = B->getTerminator())
+    SM[Term] = B;
+}
+
+CFGStmtMap *CFGStmtMap::Build(CFG *C, ParentMap *PM) {
+  if (!C || !PM)
+    return 0;
+
+  SMap *SM = new SMap();
+
+  // Walk all blocks, accumulating the block-level expressions, labels,
+  // and terminators.  
+  for (CFG::iterator I = C->begin(), E = C->end(); I != E; ++I)
+    Accumulate(*SM, *I);
+
+  return new CFGStmtMap(PM, SM);
+}
+

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=110230&r1=110229&r2=110230&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Wed Aug  4 13:23:15 2010
@@ -3,6 +3,7 @@
 add_clang_library(clangAnalysis
   AnalysisContext.cpp
   CFG.cpp
+  CFGStmtMap.cpp
   FormatString.cpp
   LiveVariables.cpp
   PrintfFormatString.cpp





More information about the cfe-commits mailing list