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
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index da73900..64e24cc 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -253,13 +253,21 @@
   /// 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 bd6bd29..9612f7f 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -796,6 +796,40 @@
   }
 }
 
+/// 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) {