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.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
index 1135928..ff44d93 100644
--- a/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ParentMap.cpp
@@ -14,6 +14,7 @@
#include "clang/AST/ParentMap.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "llvm/ADT/DenseMap.h"
using namespace clang;
@@ -33,6 +34,11 @@ static void BuildParentMap(MapTy& M, Stmt* S,
assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
PseudoObjectExpr *POE = cast<PseudoObjectExpr>(S);
+ // If we are rebuilding the map, clear out any existing state.
+ if (M[POE->getSyntacticForm()])
+ for (Stmt::child_range I = S->children(); I; ++I)
+ M[*I] = 0;
+
M[POE->getSyntacticForm()] = S;
BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent);
@@ -62,13 +68,19 @@ static void BuildParentMap(MapTy& M, Stmt* S,
break;
}
- case Stmt::OpaqueValueExprClass:
- if (OVMode == OV_Transparent) {
- OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(S);
+ case Stmt::OpaqueValueExprClass: {
+ // FIXME: This isn't correct; it assumes that multiple OpaqueValueExprs
+ // share a single source expression, but in the AST a single
+ // OpaqueValueExpr is shared among multiple parent expressions.
+ // The right thing to do is to give the OpaqueValueExpr its syntactic
+ // parent, then not reassign that when traversing the semantic expressions.
+ OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(S);
+ if (OVMode == OV_Transparent || !M[OVE->getSourceExpr()]) {
M[OVE->getSourceExpr()] = S;
BuildParentMap(M, OVE->getSourceExpr(), OV_Transparent);
}
break;
+ }
default:
for (Stmt::child_range I = S->children(); I; ++I) {
if (*I) {
@@ -98,6 +110,13 @@ void ParentMap::addStmt(Stmt* S) {
}
}
+void ParentMap::setParent(const Stmt *S, const Stmt *Parent) {
+ assert(S);
+ assert(Parent);
+ MapTy *M = reinterpret_cast<MapTy *>(Impl);
+ M->insert(std::make_pair(const_cast<Stmt *>(S), const_cast<Stmt *>(Parent)));
+}
+
Stmt* ParentMap::getParent(Stmt* S) const {
MapTy* M = (MapTy*) Impl;
MapTy::iterator I = M->find(S);
@@ -139,8 +158,9 @@ bool ParentMap::isConsumedExpr(Expr* E) const {
Stmt *P = getParent(E);
Stmt *DirectChild = E;
- // Ignore parents that are parentheses or casts.
- while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P))) {
+ // Ignore parents that don't guarantee consumption.
+ while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P) ||
+ isa<ExprWithCleanups>(P))) {
DirectChild = P;
P = getParent(P);
}
OpenPOWER on IntegriCloud