Added ParentMap, a class to represent a lazily constructed mapping from child to parents.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52553 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
new file mode 100644
index 0000000..7443f91
--- /dev/null
+++ b/include/clang/AST/ParentMap.h
@@ -0,0 +1,36 @@
+//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- 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 ParentMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARENTMAP_H
+#define LLVM_CLANG_PARENTMAP_H
+
+namespace clang {
+class Stmt;
+  
+class ParentMap {
+  void* Impl;
+public:
+  ParentMap(Stmt* ASTRoot);
+  ~ParentMap();
+
+  Stmt* getParent(Stmt*) const;  
+
+  bool hasParent(Stmt* S) const {
+    return !getParent(S);
+  }
+  
+  bool isSubExpr(Stmt *S) const;
+};
+  
+} // end clang namespace
+#endif
diff --git a/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp
new file mode 100644
index 0000000..bab3f4c
--- /dev/null
+++ b/lib/AST/ParentMap.cpp
@@ -0,0 +1,54 @@
+//===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- 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 ParentMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ParentMap.h"
+#include "clang/AST/Expr.h"
+#include "llvm/ADT/DenseMap.h"
+
+using namespace clang;
+
+typedef llvm::DenseMap<Stmt*, Stmt*> MapTy;
+
+static void BuildParentMap(MapTy& M, Stmt* S) {
+  for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
+    if (*I) {
+      M[*I] = S;
+      BuildParentMap(M, *I);
+    }
+}
+
+ParentMap::ParentMap(Stmt* S) : Impl(0) {
+  if (S) {
+    MapTy *M = new MapTy();
+    BuildParentMap(*M, S);
+    Impl = M;    
+  }
+}
+
+ParentMap::~ParentMap() {
+  delete (MapTy*) Impl;
+}
+
+Stmt* ParentMap::getParent(Stmt* S) const {
+  MapTy* M = (MapTy*) Impl;
+  MapTy::iterator I = M->find(S);
+  return I == M->end() ? 0 : I->second;
+}
+
+bool ParentMap::isSubExpr(Stmt* S) const {
+  if (!isa<Expr>(S))
+    return false;
+  
+  Stmt* P = getParent(S);
+  return P ? !isa<CompoundStmt>(P) : false;
+}