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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits