2008-06-21 05:40:36 +08:00
|
|
|
//===--- 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"
|
2008-08-11 14:23:49 +08:00
|
|
|
#include "clang/AST/Decl.h"
|
2008-06-21 05:40:36 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2013-06-06 09:57:24 +08:00
|
|
|
#include "clang/AST/ExprCXX.h"
|
2008-06-21 05:40:36 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
typedef llvm::DenseMap<Stmt*, Stmt*> MapTy;
|
|
|
|
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
enum OpaqueValueMode {
|
|
|
|
OV_Transparent,
|
|
|
|
OV_Opaque
|
|
|
|
};
|
|
|
|
|
2013-05-18 10:26:50 +08:00
|
|
|
static void BuildParentMap(MapTy& M, Stmt* S,
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
OpaqueValueMode OVMode = OV_Transparent) {
|
|
|
|
|
|
|
|
switch (S->getStmtClass()) {
|
|
|
|
case Stmt::PseudoObjectExprClass: {
|
|
|
|
assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
|
|
|
|
PseudoObjectExpr *POE = cast<PseudoObjectExpr>(S);
|
|
|
|
|
2013-05-18 10:27:09 +08:00
|
|
|
// If we are rebuilding the map, clear out any existing state.
|
|
|
|
if (M[POE->getSyntacticForm()])
|
2015-07-03 05:03:14 +08:00
|
|
|
for (Stmt *SubStmt : S->children())
|
|
|
|
M[SubStmt] = nullptr;
|
2013-05-18 10:27:09 +08:00
|
|
|
|
2013-05-18 10:26:50 +08:00
|
|
|
M[POE->getSyntacticForm()] = S;
|
|
|
|
BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent);
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
for (PseudoObjectExpr::semantics_iterator I = POE->semantics_begin(),
|
|
|
|
E = POE->semantics_end();
|
|
|
|
I != E; ++I) {
|
|
|
|
M[*I] = S;
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(M, *I, OV_Opaque);
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Stmt::BinaryConditionalOperatorClass: {
|
|
|
|
assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
|
|
|
|
BinaryConditionalOperator *BCO = cast<BinaryConditionalOperator>(S);
|
|
|
|
|
|
|
|
M[BCO->getCommon()] = S;
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(M, BCO->getCommon(), OV_Transparent);
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
M[BCO->getCond()] = S;
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(M, BCO->getCond(), OV_Opaque);
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
M[BCO->getTrueExpr()] = S;
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(M, BCO->getTrueExpr(), OV_Opaque);
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
M[BCO->getFalseExpr()] = S;
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(M, BCO->getFalseExpr(), OV_Transparent);
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2013-05-18 10:27:09 +08:00
|
|
|
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);
|
2013-05-18 12:32:15 +08:00
|
|
|
if (OVMode == OV_Transparent || !M[OVE->getSourceExpr()]) {
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
M[OVE->getSourceExpr()] = S;
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(M, OVE->getSourceExpr(), OV_Transparent);
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
}
|
|
|
|
break;
|
2013-05-18 10:27:09 +08:00
|
|
|
}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
default:
|
2015-07-03 05:03:14 +08:00
|
|
|
for (Stmt *SubStmt : S->children()) {
|
|
|
|
if (SubStmt) {
|
|
|
|
M[SubStmt] = S;
|
|
|
|
BuildParentMap(M, SubStmt, OVMode);
|
2012-08-07 05:28:11 +08:00
|
|
|
}
|
2008-06-21 05:40:36 +08:00
|
|
|
}
|
ParentMap: Restore the ability to update an existing map.
The Clang ASTs are a DAG, not a pure tree. However, ParentMap has to
choose a single parent for each object. In the main (only?) cases in
which the AST forms a DAG, it protects from multiple traversal by using
OpaqueValueExprs. Previously, ParentMap would just unconditionally look
through all OpaqueValueExprs when building its map.
In order to make this behavior better for the analyzer's diagnostics,
ParentMap was changed to not set a statement's parent if there already
was one in the map. However, ParentMap is supposed to allow updating
existing mappings by calling addStmt once again. This change makes the
"transparency" of OpaqueValueExprs explicit, and disables it when it
is not desired, rather than checking the current contents of the map.
This new code seems like a big change, but it should actually have
essentially the same performance as before. Only OpaqueValueExprs and
their users (PseudoObjectExpr and BinaryConditionalOperator) will
have any different behavior.
There should be no user-visible functionality change, though a test
has been added for the current behavior of BinaryConditionalOperator
source locations and accompanying Xcode arrows (which are not so great...).
llvm-svn: 165355
2012-10-06 09:19:36 +08:00
|
|
|
break;
|
2012-08-07 05:28:11 +08:00
|
|
|
}
|
2008-06-21 05:40:36 +08:00
|
|
|
}
|
|
|
|
|
2014-05-12 13:36:57 +08:00
|
|
|
ParentMap::ParentMap(Stmt *S) : Impl(nullptr) {
|
2008-06-21 05:40:36 +08:00
|
|
|
if (S) {
|
|
|
|
MapTy *M = new MapTy();
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(*M, S);
|
2009-09-09 23:08:12 +08:00
|
|
|
Impl = M;
|
2008-06-21 05:40:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ParentMap::~ParentMap() {
|
|
|
|
delete (MapTy*) Impl;
|
|
|
|
}
|
|
|
|
|
2010-11-16 04:54:24 +08:00
|
|
|
void ParentMap::addStmt(Stmt* S) {
|
|
|
|
if (S) {
|
2013-05-18 10:26:50 +08:00
|
|
|
BuildParentMap(*(MapTy*) Impl, S);
|
2010-11-16 04:54:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[analyzer; new edges] Simplify edges in a C++11 for-range loop.
Previously our edges were completely broken here; now, the final result
is a very simple set of edges in most cases: one up to the "for" keyword
for context, and one into the body of the loop. This matches the behavior
for ObjC for-in loops.
In the AST, however, CXXForRangeStmts are handled very differently from
ObjCForCollectionStmts. Since they are specified in terms of equivalent
statements in the C++ standard, we actually have implicit AST nodes for
all of the semantic statements. This makes evaluation very easy, but
diagnostic locations a bit trickier. Fortunately, the problem can be
generally defined away by marking all of the implicit statements as
part of the top-level for-range statement.
One of the implicit statements in a for-range statement is the declaration
of implicit iterators __begin and __end. The CFG synthesizes two
separate DeclStmts to match each of these decls, but until now these
synthetic DeclStmts weren't in the function's ParentMap. Now, the CFG
keeps track of its synthetic statements, and the AnalysisDeclContext will
make sure to add them to the ParentMap.
<rdar://problem/14038483>
llvm-svn: 183449
2013-06-07 05:53:45 +08:00
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2008-06-21 05:40:36 +08:00
|
|
|
Stmt* ParentMap::getParent(Stmt* S) const {
|
|
|
|
MapTy* M = (MapTy*) Impl;
|
|
|
|
MapTy::iterator I = M->find(S);
|
2014-05-12 13:36:57 +08:00
|
|
|
return I == M->end() ? nullptr : I->second;
|
2008-06-21 05:40:36 +08:00
|
|
|
}
|
2009-04-01 14:52:48 +08:00
|
|
|
|
2009-05-12 03:49:27 +08:00
|
|
|
Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const {
|
|
|
|
do { S = getParent(S); } while (S && isa<ParenExpr>(S));
|
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2011-02-12 08:17:19 +08:00
|
|
|
Stmt *ParentMap::getParentIgnoreParenCasts(Stmt *S) const {
|
|
|
|
do {
|
|
|
|
S = getParent(S);
|
|
|
|
}
|
|
|
|
while (S && (isa<ParenExpr>(S) || isa<CastExpr>(S)));
|
|
|
|
|
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2011-07-27 13:28:18 +08:00
|
|
|
Stmt *ParentMap::getParentIgnoreParenImpCasts(Stmt *S) const {
|
|
|
|
do {
|
|
|
|
S = getParent(S);
|
|
|
|
} while (S && isa<Expr>(S) && cast<Expr>(S)->IgnoreParenImpCasts() != S);
|
|
|
|
|
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
Stmt *ParentMap::getOuterParenParent(Stmt *S) const {
|
2014-05-12 13:36:57 +08:00
|
|
|
Stmt *Paren = nullptr;
|
2011-06-16 07:02:42 +08:00
|
|
|
while (isa<ParenExpr>(S)) {
|
|
|
|
Paren = S;
|
|
|
|
S = getParent(S);
|
|
|
|
};
|
|
|
|
return Paren;
|
|
|
|
}
|
|
|
|
|
2009-04-01 14:52:48 +08:00
|
|
|
bool ParentMap::isConsumedExpr(Expr* E) const {
|
|
|
|
Stmt *P = getParent(E);
|
|
|
|
Stmt *DirectChild = E;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2013-06-06 09:57:24 +08:00
|
|
|
// Ignore parents that don't guarantee consumption.
|
|
|
|
while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P) ||
|
|
|
|
isa<ExprWithCleanups>(P))) {
|
2009-04-01 14:52:48 +08:00
|
|
|
DirectChild = P;
|
|
|
|
P = getParent(P);
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-01 14:52:48 +08:00
|
|
|
if (!P)
|
|
|
|
return false;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-01 14:52:48 +08:00
|
|
|
switch (P->getStmtClass()) {
|
|
|
|
default:
|
|
|
|
return isa<Expr>(P);
|
|
|
|
case Stmt::DeclStmtClass:
|
|
|
|
return true;
|
|
|
|
case Stmt::BinaryOperatorClass: {
|
|
|
|
BinaryOperator *BE = cast<BinaryOperator>(P);
|
2009-04-09 13:34:31 +08:00
|
|
|
// If it is a comma, only the right side is consumed.
|
2009-04-09 02:49:36 +08:00
|
|
|
// If it isn't a comma, both sides are consumed.
|
2010-08-25 19:45:40 +08:00
|
|
|
return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS();
|
2009-04-01 14:52:48 +08:00
|
|
|
}
|
|
|
|
case Stmt::ForStmtClass:
|
|
|
|
return DirectChild == cast<ForStmt>(P)->getCond();
|
|
|
|
case Stmt::WhileStmtClass:
|
2009-09-09 23:08:12 +08:00
|
|
|
return DirectChild == cast<WhileStmt>(P)->getCond();
|
2009-04-01 14:52:48 +08:00
|
|
|
case Stmt::DoStmtClass:
|
|
|
|
return DirectChild == cast<DoStmt>(P)->getCond();
|
|
|
|
case Stmt::IfStmtClass:
|
|
|
|
return DirectChild == cast<IfStmt>(P)->getCond();
|
|
|
|
case Stmt::IndirectGotoStmtClass:
|
|
|
|
return DirectChild == cast<IndirectGotoStmt>(P)->getTarget();
|
|
|
|
case Stmt::SwitchStmtClass:
|
|
|
|
return DirectChild == cast<SwitchStmt>(P)->getCond();
|
|
|
|
case Stmt::ReturnStmtClass:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|