summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ParentMap.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ParentMap.cpp69
1 files changed, 55 insertions, 14 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
index fa87afd..1135928 100644
--- a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
@@ -20,22 +20,63 @@ using namespace clang;
typedef llvm::DenseMap<Stmt*, Stmt*> MapTy;
-static void BuildParentMap(MapTy& M, Stmt* S) {
- for (Stmt::child_range I = S->children(); I; ++I)
- if (*I) {
- // Prefer the first time we see this statement in the traversal.
- // This is important for PseudoObjectExprs.
- Stmt *&Parent = M[*I];
- if (!Parent) {
- Parent = S;
- BuildParentMap(M, *I);
+enum OpaqueValueMode {
+ OV_Transparent,
+ OV_Opaque
+};
+
+static void BuildParentMap(MapTy& M, Stmt* S,
+ OpaqueValueMode OVMode = OV_Transparent) {
+
+ switch (S->getStmtClass()) {
+ case Stmt::PseudoObjectExprClass: {
+ assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
+ PseudoObjectExpr *POE = cast<PseudoObjectExpr>(S);
+
+ M[POE->getSyntacticForm()] = S;
+ BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent);
+
+ for (PseudoObjectExpr::semantics_iterator I = POE->semantics_begin(),
+ E = POE->semantics_end();
+ I != E; ++I) {
+ M[*I] = S;
+ BuildParentMap(M, *I, OV_Opaque);
+ }
+ break;
+ }
+ case Stmt::BinaryConditionalOperatorClass: {
+ assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
+ BinaryConditionalOperator *BCO = cast<BinaryConditionalOperator>(S);
+
+ M[BCO->getCommon()] = S;
+ BuildParentMap(M, BCO->getCommon(), OV_Transparent);
+
+ M[BCO->getCond()] = S;
+ BuildParentMap(M, BCO->getCond(), OV_Opaque);
+
+ M[BCO->getTrueExpr()] = S;
+ BuildParentMap(M, BCO->getTrueExpr(), OV_Opaque);
+
+ M[BCO->getFalseExpr()] = S;
+ BuildParentMap(M, BCO->getFalseExpr(), OV_Transparent);
+
+ break;
+ }
+ case Stmt::OpaqueValueExprClass:
+ if (OVMode == OV_Transparent) {
+ OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(S);
+ M[OVE->getSourceExpr()] = S;
+ BuildParentMap(M, OVE->getSourceExpr(), OV_Transparent);
+ }
+ break;
+ default:
+ for (Stmt::child_range I = S->children(); I; ++I) {
+ if (*I) {
+ M[*I] = S;
+ BuildParentMap(M, *I, OVMode);
}
}
-
- // Also include the source expr tree of an OpaqueValueExpr in the map.
- if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) {
- M[OVE->getSourceExpr()] = S;
- BuildParentMap(M, OVE->getSourceExpr());
+ break;
}
}
OpenPOWER on IntegriCloud