diff options
author | Chris Lattner <sabre@nondot.org> | 2009-03-13 17:28:01 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-03-13 17:28:01 +0000 |
commit | ecdd84147c0765caa999ddc22dde25b42712bb4d (patch) | |
tree | 14a91e0fb67c5467f161b06963b5668fb7ed3e4a | |
parent | c0dfd53634494872d9560bfa30c0cad6759e4cea (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.h | 10 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 34 |
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) { |