aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-13 17:28:01 +0000
committerChris Lattner <sabre@nondot.org>2009-03-13 17:28:01 +0000
commitecdd84147c0765caa999ddc22dde25b42712bb4d (patch)
tree14a91e0fb67c5467f161b06963b5668fb7ed3e4a
parentc0dfd53634494872d9560bfa30c0cad6759e4cea (diff)
add a helper function to strip noop casts.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66909 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Expr.h10
-rw-r--r--lib/AST/Expr.cpp34
2 files changed, 43 insertions, 1 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index da739002fa..64e24ccd28 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -253,13 +253,21 @@ public:
/// or CastExprs, returning their operand.
Expr *IgnoreParenCasts();
+ /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
+ /// value (including ptr->int casts of the same size). Strip off any
+ /// ParenExpr or CastExprs, returning their operand.
+ Expr *IgnoreParenNoopCasts(ASTContext &Ctx);
+
const Expr* IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
}
const Expr *IgnoreParenCasts() const {
return const_cast<Expr*>(this)->IgnoreParenCasts();
}
-
+ const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const {
+ return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
+ }
+
static bool hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs);
static bool hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs);
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index bd6bd298e9..9612f7ff2a 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -796,6 +796,40 @@ Expr *Expr::IgnoreParenCasts() {
}
}
+/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
+/// value (including ptr->int casts of the same size). Strip off any
+/// ParenExpr or CastExprs, returning their operand.
+Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) {
+ Expr *E = this;
+ while (true) {
+ if (ParenExpr *P = dyn_cast<ParenExpr>(E)) {
+ E = P->getSubExpr();
+ continue;
+ }
+
+ if (CastExpr *P = dyn_cast<CastExpr>(E)) {
+ // We ignore integer <-> casts that are of the same width, ptr<->ptr and
+ // ptr<->int casts of the same width. We also ignore all identify casts.
+ Expr *SE = P->getSubExpr();
+
+ if (Ctx.hasSameUnqualifiedType(E->getType(), SE->getType())) {
+ E = SE;
+ continue;
+ }
+
+ if ((E->getType()->isPointerType() || E->getType()->isIntegralType()) &&
+ (SE->getType()->isPointerType() || SE->getType()->isIntegralType()) &&
+ Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SE->getType())) {
+ E = SE;
+ continue;
+ }
+ }
+
+ return E;
+ }
+}
+
+
/// hasAnyTypeDependentArguments - Determines if any of the expressions
/// in Exprs is type-dependent.
bool Expr::hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs) {