riccibruno updated this revision to Diff 183696.
riccibruno added a comment.

Update the comment in `IgnoreImpCastsExtraSingleStep` and return early from 
`IgnoreImpCastsExtraSingleStep` and `IgnoreImplicitSingleStep` when 
`IgnoreImpCastsSingleStep` skipped something.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57267/new/

https://reviews.llvm.org/D57267

Files:
  include/clang/AST/Expr.h
  lib/AST/Expr.cpp

Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -2556,192 +2556,186 @@
   return QualType();
 }
 
-Expr *Expr::IgnoreImpCasts() {
-  Expr *E = this;
-  while (true)
-    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
-      E = ICE->getSubExpr();
-    else if (FullExpr *FE = dyn_cast<FullExpr>(E))
-      E = FE->getSubExpr();
-    else
-      break;
+/************* Logic for the various Expr::Ignore* ****************************/
+
+static Expr *IgnoreImpCastsSingleStep(Expr *E) {
+  if (auto *ICE = dyn_cast_or_null<ImplicitCastExpr>(E))
+    return ICE->getSubExpr();
+
+  else if (auto *FE = dyn_cast_or_null<FullExpr>(E))
+    return FE->getSubExpr();
+
   return E;
 }
 
-Expr *Expr::IgnoreImplicit() {
-  Expr *E = this;
-  Expr *LastE = nullptr;
-  while (E != LastE) {
-    LastE = E;
+static Expr *IgnoreImpCastsExtraSingleStep(Expr *E) {
+  // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in
+  // addition to what IgnoreImpCasts() skips to account for the current
+  // behaviour of IgnoreParenImpCasts().
+  Expr *SubE = IgnoreImpCastsSingleStep(E);
+  if (SubE != E)
+    return SubE;
 
-    if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
-      E = ICE->getSubExpr();
+  if (auto *MTE = dyn_cast_or_null<MaterializeTemporaryExpr>(E))
+    return MTE->GetTemporaryExpr();
 
-    if (auto *FE = dyn_cast<FullExpr>(E))
-      E = FE->getSubExpr();
+  else if (auto *NTTP = dyn_cast_or_null<SubstNonTypeTemplateParmExpr>(E))
+    return NTTP->getReplacement();
 
-    if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
-      E = MTE->GetTemporaryExpr();
+  return E;
+}
+
+static Expr *IgnoreCastsSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast_or_null<CastExpr>(E))
+    return CE->getSubExpr();
+
+  else if (auto *FE = dyn_cast_or_null<FullExpr>(E))
+    return FE->getSubExpr();
+
+  else if (auto *MTE = dyn_cast_or_null<MaterializeTemporaryExpr>(E))
+    return MTE->GetTemporaryExpr();
+
+  else if (auto *NTTP = dyn_cast_or_null<SubstNonTypeTemplateParmExpr>(E))
+    return NTTP->getReplacement();
 
-    if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
-      E = BTE->getSubExpr();
-  }
   return E;
 }
 
-Expr* Expr::IgnoreParens() {
-  Expr* E = this;
-  while (true) {
-    if (ParenExpr* P = dyn_cast<ParenExpr>(E)) {
-      E = P->getSubExpr();
-      continue;
-    }
-    if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
-      if (P->getOpcode() == UO_Extension) {
-        E = P->getSubExpr();
-        continue;
-      }
-    }
-    if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
-      if (!P->isResultDependent()) {
-        E = P->getResultExpr();
-        continue;
-      }
-    }
-    if (ChooseExpr* P = dyn_cast<ChooseExpr>(E)) {
-      if (!P->isConditionDependent()) {
-        E = P->getChosenSubExpr();
-        continue;
-      }
-    }
-    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
-      E = CE->getSubExpr();
-      continue;
-    }
-    return E;
+static Expr *IgnoreLValueCastsSingleStep(Expr *E) {
+  // Skip what IgnoreCastsSingleStep skips, except that only
+  // lvalue-to-rvalue casts are skipped.
+  if (auto *CE = dyn_cast_or_null<CastExpr>(E))
+    if (CE->getCastKind() != CK_LValueToRValue)
+      return E;
+
+  return IgnoreCastsSingleStep(E);
+}
+
+static Expr *IgnoreBaseCastsSingleStep(Expr *E) {
+  if (auto *CE = dyn_cast_or_null<CastExpr>(E))
+    if (CE->getCastKind() == CK_DerivedToBase ||
+        CE->getCastKind() == CK_UncheckedDerivedToBase ||
+        CE->getCastKind() == CK_NoOp)
+      return CE->getSubExpr();
+
+  return E;
+}
+
+static Expr *IgnoreImplicitSingleStep(Expr *E) {
+  Expr *SubE = IgnoreImpCastsSingleStep(E);
+  if (SubE != E)
+    return SubE;
+
+  if (auto *MTE = dyn_cast_or_null<MaterializeTemporaryExpr>(E))
+    return MTE->GetTemporaryExpr();
+
+  else if (auto *BTE = dyn_cast_or_null<CXXBindTemporaryExpr>(E))
+    return BTE->getSubExpr();
+
+  return E;
+}
+
+static Expr *IgnoreParensSingleStep(Expr *E) {
+  if (auto *PE = dyn_cast_or_null<ParenExpr>(E))
+    return PE->getSubExpr();
+
+  else if (auto *UO = dyn_cast_or_null<UnaryOperator>(E)) {
+    if (UO->getOpcode() == UO_Extension)
+      return UO->getSubExpr();
+  }
+
+  else if (auto *GSE = dyn_cast_or_null<GenericSelectionExpr>(E)) {
+    if (!GSE->isResultDependent())
+      return GSE->getResultExpr();
+  }
+
+  else if (auto *CE = dyn_cast_or_null<ChooseExpr>(E)) {
+    if (!CE->isConditionDependent())
+      return CE->getChosenSubExpr();
   }
+
+  else if (auto *CE = dyn_cast_or_null<ConstantExpr>(E))
+    return CE->getSubExpr();
+
+  return E;
 }
 
-/// IgnoreParenCasts - Ignore parentheses and casts.  Strip off any ParenExpr
-/// or CastExprs or ImplicitCastExprs, returning their operand.
-Expr *Expr::IgnoreParenCasts() {
-  Expr *E = this;
-  while (true) {
-    E = E->IgnoreParens();
-    if (CastExpr *P = dyn_cast<CastExpr>(E)) {
-      E = P->getSubExpr();
-      continue;
-    }
-    if (MaterializeTemporaryExpr *Materialize
-                                      = dyn_cast<MaterializeTemporaryExpr>(E)) {
-      E = Materialize->GetTemporaryExpr();
-      continue;
-    }
-    if (SubstNonTypeTemplateParmExpr *NTTP
-                                  = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
-      E = NTTP->getReplacement();
-      continue;
-    }
-    if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
-      E = FE->getSubExpr();
-      continue;
-    }
-    return E;
+static Expr *IgnoreNoopCastsSingleStep(const ASTContext &Ctx, Expr *E) {
+  if (auto *CE = dyn_cast_or_null<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 identity casts.
+    Expr *SubExpr = CE->getSubExpr();
+    bool IsIdentityCast =
+        Ctx.hasSameUnqualifiedType(E->getType(), SubExpr->getType());
+    bool IsSameWidthCast =
+        (E->getType()->isPointerType() || E->getType()->isIntegralType(Ctx)) &&
+        (SubExpr->getType()->isPointerType() ||
+         SubExpr->getType()->isIntegralType(Ctx)) &&
+        (Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SubExpr->getType()));
+
+    if (IsIdentityCast || IsSameWidthCast)
+      return SubExpr;
   }
+
+  else if (auto *NTTP = dyn_cast_or_null<SubstNonTypeTemplateParmExpr>(E))
+    return NTTP->getReplacement();
+
+  return E;
 }
 
-Expr *Expr::IgnoreCasts() {
-  Expr *E = this;
-  while (true) {
-    if (CastExpr *P = dyn_cast<CastExpr>(E)) {
-      E = P->getSubExpr();
-      continue;
-    }
-    if (MaterializeTemporaryExpr *Materialize
-        = dyn_cast<MaterializeTemporaryExpr>(E)) {
-      E = Materialize->GetTemporaryExpr();
-      continue;
-    }
-    if (SubstNonTypeTemplateParmExpr *NTTP
-        = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
-      E = NTTP->getReplacement();
-      continue;
-    }
-    if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
-      E = FE->getSubExpr();
-      continue;
-    }
-    return E;
+/************* Implementation of the various Expr::Ignore* ********************/
+
+namespace {
+/// Given an expression E and a function Fn : Expr * -> Expr *,
+/// Recursively apply Fn to E until reaching a fixed point.
+/// Note that a null E is valid; in this case nothing is done.
+template <typename FnTy> Expr *IgnoreExprNodes(Expr *E, FnTy Fn) {
+  Expr *LastE = nullptr;
+  while (E != LastE) {
+    LastE = E;
+    E = Fn(E);
   }
+  return E;
 }
 
-/// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue
-/// casts.  This is intended purely as a temporary workaround for code
-/// that hasn't yet been rewritten to do the right thing about those
-/// casts, and may disappear along with the last internal use.
-Expr *Expr::IgnoreParenLValueCasts() {
-  Expr *E = this;
-  while (true) {
-    E = E->IgnoreParens();
-    if (CastExpr *P = dyn_cast<CastExpr>(E)) {
-      if (P->getCastKind() == CK_LValueToRValue) {
-        E = P->getSubExpr();
-        continue;
-      }
-    } else if (MaterializeTemporaryExpr *Materialize
-                                      = dyn_cast<MaterializeTemporaryExpr>(E)) {
-      E = Materialize->GetTemporaryExpr();
-      continue;
-    } else if (SubstNonTypeTemplateParmExpr *NTTP
-                                  = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
-      E = NTTP->getReplacement();
-      continue;
-    } else if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
-      E = FE->getSubExpr();
-      continue;
-    }
-    break;
+/// Given an expression E and functions Fn1, Fn2 : Expr * -> Expr *,
+/// Recursively apply Fn1 and Fn2 to E until reaching a fixed point.
+/// Note that a null E is valid; in this case nothing is done.
+template <typename FnTy1, typename FnTy2>
+Expr *IgnoreExprNodes(Expr *E, FnTy1 Fn1, FnTy2 Fn2) {
+  Expr *LastE = nullptr;
+  while (E != LastE) {
+    LastE = E;
+    E = Fn1(E);
+    E = Fn2(E);
   }
   return E;
 }
+} // anonymous namespace
 
-Expr *Expr::ignoreParenBaseCasts() {
-  Expr *E = this;
-  while (true) {
-    E = E->IgnoreParens();
-    if (CastExpr *CE = dyn_cast<CastExpr>(E)) {
-      if (CE->getCastKind() == CK_DerivedToBase ||
-          CE->getCastKind() == CK_UncheckedDerivedToBase ||
-          CE->getCastKind() == CK_NoOp) {
-        E = CE->getSubExpr();
-        continue;
-      }
-    }
+Expr *Expr::IgnoreImpCasts() {
+  return IgnoreExprNodes(this, IgnoreImpCastsSingleStep);
+}
 
-    return E;
-  }
+Expr *Expr::IgnoreCasts() {
+  return IgnoreExprNodes(this, IgnoreCastsSingleStep);
+}
+
+Expr *Expr::IgnoreImplicit() {
+  return IgnoreExprNodes(this, IgnoreImplicitSingleStep);
+}
+
+Expr *Expr::IgnoreParens() {
+  return IgnoreExprNodes(this, IgnoreParensSingleStep);
 }
 
 Expr *Expr::IgnoreParenImpCasts() {
-  Expr *E = this;
-  while (true) {
-    E = E->IgnoreParens();
-    if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(E)) {
-      E = P->getSubExpr();
-      continue;
-    }
-    if (MaterializeTemporaryExpr *Materialize
-                                      = dyn_cast<MaterializeTemporaryExpr>(E)) {
-      E = Materialize->GetTemporaryExpr();
-      continue;
-    }
-    if (SubstNonTypeTemplateParmExpr *NTTP
-                                  = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
-      E = NTTP->getReplacement();
-      continue;
-    }
-    return E;
-  }
+  return IgnoreExprNodes(this, IgnoreParensSingleStep,
+                         IgnoreImpCastsExtraSingleStep);
+}
+
+Expr *Expr::IgnoreParenCasts() {
+  return IgnoreExprNodes(this, IgnoreParensSingleStep, IgnoreCastsSingleStep);
 }
 
 Expr *Expr::IgnoreConversionOperator() {
@@ -2752,42 +2746,20 @@
   return this;
 }
 
-/// 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(const ASTContext &Ctx) {
-  Expr *E = this;
-  while (true) {
-    E = E->IgnoreParens();
-
-    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 identity casts.
-      Expr *SE = P->getSubExpr();
-
-      if (Ctx.hasSameUnqualifiedType(E->getType(), SE->getType())) {
-        E = SE;
-        continue;
-      }
-
-      if ((E->getType()->isPointerType() ||
-           E->getType()->isIntegralType(Ctx)) &&
-          (SE->getType()->isPointerType() ||
-           SE->getType()->isIntegralType(Ctx)) &&
-          Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SE->getType())) {
-        E = SE;
-        continue;
-      }
-    }
+Expr *Expr::IgnoreParenLValueCasts() {
+  return IgnoreExprNodes(this, IgnoreParensSingleStep,
+                         IgnoreLValueCastsSingleStep);
+}
 
-    if (SubstNonTypeTemplateParmExpr *NTTP
-                                  = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
-      E = NTTP->getReplacement();
-      continue;
-    }
+Expr *Expr::ignoreParenBaseCasts() {
+  return IgnoreExprNodes(this, IgnoreParensSingleStep,
+                         IgnoreBaseCastsSingleStep);
+}
 
-    return E;
-  }
+Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) {
+  return IgnoreExprNodes(this, IgnoreParensSingleStep, [&Ctx](Expr *E) {
+    return IgnoreNoopCastsSingleStep(Ctx, E);
+  });
 }
 
 bool Expr::isDefaultArgument() const {
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -792,7 +792,7 @@
   /// IgnoreParens() + IgnoreImpCasts() until reaching a fixed point. However
   /// this is currently not the case. Instead IgnoreParenImpCasts() skips:
   /// * What IgnoreParens() skips.
-  /// * ImplicitCastExpr.
+  /// * What IgnoreImpCasts() skips.
   /// * MaterializeTemporaryExpr.
   /// * SubstNonTypeTemplateParmExpr.
   Expr *IgnoreParenImpCasts() LLVM_READONLY;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to