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;
+}