forked from OSchip/llvm-project
[AST] Factor out the logic of the various Expr::Ignore*
Now that the implementation of all of the Expr::Ignore* is in Expr.cpp we can try to remove some duplication. Do this by separating the logic of the Expr::Ignore* from the iterative loop. This is NFC, except for one change: IgnoreParenImpCasts now skips, among other things, everything that IgnoreImpCasts skips. This means FullExpr are now skipped by IgnoreParenImpCasts. This was likely an oversight when FullExpr was added to the nodes skipped by IgnoreImpCasts. Differential Revision: https://reviews.llvm.org/D57267 Reviewed By: aaron.ballman (with comments from void and rnk) llvm-svn: 354215
This commit is contained in:
parent
07df86c377
commit
3985172b4f
|
@ -794,7 +794,7 @@ public:
|
|||
/// 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;
|
||||
|
|
|
@ -2556,185 +2556,173 @@ QualType Expr::findBoundMemberType(const Expr *expr) {
|
|||
return QualType();
|
||||
}
|
||||
|
||||
Expr *Expr::IgnoreImpCasts() {
|
||||
Expr *E = this;
|
||||
while (true) {
|
||||
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
|
||||
E = ICE->getSubExpr();
|
||||
else if (auto *FE = dyn_cast<FullExpr>(E))
|
||||
E = FE->getSubExpr();
|
||||
else
|
||||
break;
|
||||
}
|
||||
static Expr *IgnoreImpCastsSingleStep(Expr *E) {
|
||||
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
|
||||
return ICE->getSubExpr();
|
||||
|
||||
if (auto *FE = dyn_cast<FullExpr>(E))
|
||||
return FE->getSubExpr();
|
||||
|
||||
return E;
|
||||
}
|
||||
|
||||
Expr *Expr::IgnoreImplicit() {
|
||||
Expr *E = this;
|
||||
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 *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
|
||||
return MTE->GetTemporaryExpr();
|
||||
|
||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
|
||||
return NTTP->getReplacement();
|
||||
|
||||
return E;
|
||||
}
|
||||
|
||||
static Expr *IgnoreCastsSingleStep(Expr *E) {
|
||||
if (auto *CE = dyn_cast<CastExpr>(E))
|
||||
return CE->getSubExpr();
|
||||
|
||||
if (auto *FE = dyn_cast<FullExpr>(E))
|
||||
return FE->getSubExpr();
|
||||
|
||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
|
||||
return MTE->GetTemporaryExpr();
|
||||
|
||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
|
||||
return NTTP->getReplacement();
|
||||
|
||||
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<CastExpr>(E))
|
||||
if (CE->getCastKind() != CK_LValueToRValue)
|
||||
return E;
|
||||
|
||||
return IgnoreCastsSingleStep(E);
|
||||
}
|
||||
|
||||
static Expr *IgnoreBaseCastsSingleStep(Expr *E) {
|
||||
if (auto *CE = dyn_cast<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<MaterializeTemporaryExpr>(E))
|
||||
return MTE->GetTemporaryExpr();
|
||||
|
||||
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
|
||||
return BTE->getSubExpr();
|
||||
|
||||
return E;
|
||||
}
|
||||
|
||||
static Expr *IgnoreParensSingleStep(Expr *E) {
|
||||
if (auto *PE = dyn_cast<ParenExpr>(E))
|
||||
return PE->getSubExpr();
|
||||
|
||||
if (auto *UO = dyn_cast<UnaryOperator>(E)) {
|
||||
if (UO->getOpcode() == UO_Extension)
|
||||
return UO->getSubExpr();
|
||||
}
|
||||
|
||||
else if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
|
||||
if (!GSE->isResultDependent())
|
||||
return GSE->getResultExpr();
|
||||
}
|
||||
|
||||
else if (auto *CE = dyn_cast<ChooseExpr>(E)) {
|
||||
if (!CE->isConditionDependent())
|
||||
return CE->getChosenSubExpr();
|
||||
}
|
||||
|
||||
else if (auto *CE = dyn_cast<ConstantExpr>(E))
|
||||
return CE->getSubExpr();
|
||||
|
||||
return E;
|
||||
}
|
||||
|
||||
static Expr *IgnoreNoopCastsSingleStep(const ASTContext &Ctx, Expr *E) {
|
||||
if (auto *CE = 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 *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<SubstNonTypeTemplateParmExpr>(E))
|
||||
return NTTP->getReplacement();
|
||||
|
||||
return E;
|
||||
}
|
||||
|
||||
static Expr *IgnoreExprNodesImpl(Expr *E) { return E; }
|
||||
template <typename FnTy, typename... FnTys>
|
||||
static Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) {
|
||||
return IgnoreExprNodesImpl(Fn(E), std::forward<FnTys>(Fns)...);
|
||||
}
|
||||
|
||||
/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
|
||||
/// Recursively apply each of the functions to E until reaching a fixed point.
|
||||
/// Note that a null E is valid; in this case nothing is done.
|
||||
template <typename... FnTys>
|
||||
static Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) {
|
||||
Expr *LastE = nullptr;
|
||||
while (E != LastE) {
|
||||
LastE = E;
|
||||
|
||||
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
|
||||
E = ICE->getSubExpr();
|
||||
|
||||
if (auto *FE = dyn_cast<FullExpr>(E))
|
||||
E = FE->getSubExpr();
|
||||
|
||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
|
||||
E = MTE->GetTemporaryExpr();
|
||||
|
||||
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
|
||||
E = BTE->getSubExpr();
|
||||
E = IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...);
|
||||
}
|
||||
return E;
|
||||
}
|
||||
|
||||
Expr *Expr::IgnoreParens() {
|
||||
Expr *E = this;
|
||||
while (true) {
|
||||
if (auto *PE = dyn_cast<ParenExpr>(E)) {
|
||||
E = PE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
if (auto *UO = dyn_cast<UnaryOperator>(E)) {
|
||||
if (UO->getOpcode() == UO_Extension) {
|
||||
E = UO->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
|
||||
if (!GSE->isResultDependent()) {
|
||||
E = GSE->getResultExpr();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (auto *CE = dyn_cast<ChooseExpr>(E)) {
|
||||
if (!CE->isConditionDependent()) {
|
||||
E = CE->getChosenSubExpr();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (auto *CE = dyn_cast<ConstantExpr>(E)) {
|
||||
E = CE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
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 (auto *CE = dyn_cast<CastExpr>(E)) {
|
||||
E = CE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
|
||||
E = MTE->GetTemporaryExpr();
|
||||
continue;
|
||||
}
|
||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
||||
E = NTTP->getReplacement();
|
||||
continue;
|
||||
}
|
||||
if (auto *FE = dyn_cast<FullExpr>(E)) {
|
||||
E = FE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
return E;
|
||||
}
|
||||
Expr *Expr::IgnoreImpCasts() {
|
||||
return IgnoreExprNodes(this, IgnoreImpCastsSingleStep);
|
||||
}
|
||||
|
||||
Expr *Expr::IgnoreCasts() {
|
||||
Expr *E = this;
|
||||
while (true) {
|
||||
if (auto *CE = dyn_cast<CastExpr>(E)) {
|
||||
E = CE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
|
||||
E = MTE->GetTemporaryExpr();
|
||||
continue;
|
||||
}
|
||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
||||
E = NTTP->getReplacement();
|
||||
continue;
|
||||
}
|
||||
if (auto *FE = dyn_cast<FullExpr>(E)) {
|
||||
E = FE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
return E;
|
||||
}
|
||||
return IgnoreExprNodes(this, IgnoreCastsSingleStep);
|
||||
}
|
||||
|
||||
/// 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 (auto *CE = dyn_cast<CastExpr>(E)) {
|
||||
if (CE->getCastKind() == CK_LValueToRValue) {
|
||||
E = CE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
} else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
|
||||
E = MTE->GetTemporaryExpr();
|
||||
continue;
|
||||
} else if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
||||
E = NTTP->getReplacement();
|
||||
continue;
|
||||
} else if (auto *FE = dyn_cast<FullExpr>(E)) {
|
||||
E = FE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return E;
|
||||
Expr *Expr::IgnoreImplicit() {
|
||||
return IgnoreExprNodes(this, IgnoreImplicitSingleStep);
|
||||
}
|
||||
|
||||
Expr *Expr::ignoreParenBaseCasts() {
|
||||
Expr *E = this;
|
||||
while (true) {
|
||||
E = E->IgnoreParens();
|
||||
if (auto *CE = dyn_cast<CastExpr>(E)) {
|
||||
if (CE->getCastKind() == CK_DerivedToBase ||
|
||||
CE->getCastKind() == CK_UncheckedDerivedToBase ||
|
||||
CE->getCastKind() == CK_NoOp) {
|
||||
E = CE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return E;
|
||||
}
|
||||
Expr *Expr::IgnoreParens() {
|
||||
return IgnoreExprNodes(this, IgnoreParensSingleStep);
|
||||
}
|
||||
|
||||
Expr *Expr::IgnoreParenImpCasts() {
|
||||
Expr *E = this;
|
||||
while (true) {
|
||||
E = E->IgnoreParens();
|
||||
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
||||
E = ICE->getSubExpr();
|
||||
continue;
|
||||
}
|
||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
|
||||
E = MTE->GetTemporaryExpr();
|
||||
continue;
|
||||
}
|
||||
if (auto *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() {
|
||||
|
@ -2745,41 +2733,20 @@ Expr *Expr::IgnoreConversionOperator() {
|
|||
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::IgnoreParenLValueCasts() {
|
||||
return IgnoreExprNodes(this, IgnoreParensSingleStep,
|
||||
IgnoreLValueCastsSingleStep);
|
||||
}
|
||||
|
||||
Expr *Expr::ignoreParenBaseCasts() {
|
||||
return IgnoreExprNodes(this, IgnoreParensSingleStep,
|
||||
IgnoreBaseCastsSingleStep);
|
||||
}
|
||||
|
||||
Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) {
|
||||
Expr *E = this;
|
||||
while (true) {
|
||||
E = E->IgnoreParens();
|
||||
|
||||
if (auto *CE = 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 = CE->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;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
||||
E = NTTP->getReplacement();
|
||||
continue;
|
||||
}
|
||||
|
||||
return E;
|
||||
}
|
||||
return IgnoreExprNodes(this, IgnoreParensSingleStep, [&Ctx](Expr *E) {
|
||||
return IgnoreNoopCastsSingleStep(Ctx, E);
|
||||
});
|
||||
}
|
||||
|
||||
bool Expr::isDefaultArgument() const {
|
||||
|
|
Loading…
Reference in New Issue