Changeset View
Changeset View
Standalone View
Standalone View
cfe/trunk/lib/AST/Expr.cpp
Show First 20 Lines • Show All 2,550 Lines • ▼ Show 20 Lines | if (const BinaryOperator *op = dyn_cast<BinaryOperator>(expr)) { | ||||
assert(type->isFunctionType()); | assert(type->isFunctionType()); | ||||
return type; | return type; | ||||
} | } | ||||
assert(isa<UnresolvedMemberExpr>(expr) || isa<CXXPseudoDestructorExpr>(expr)); | assert(isa<UnresolvedMemberExpr>(expr) || isa<CXXPseudoDestructorExpr>(expr)); | ||||
return QualType(); | return QualType(); | ||||
} | } | ||||
Expr *Expr::IgnoreImpCasts() { | static Expr *IgnoreImpCastsSingleStep(Expr *E) { | ||||
Expr *E = this; | |||||
while (true) { | |||||
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) | if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) | ||||
E = ICE->getSubExpr(); | return ICE->getSubExpr(); | ||||
else if (auto *FE = dyn_cast<FullExpr>(E)) | |||||
E = FE->getSubExpr(); | if (auto *FE = dyn_cast<FullExpr>(E)) | ||||
else | return FE->getSubExpr(); | ||||
break; | |||||
} | |||||
return E; | return E; | ||||
} | } | ||||
Expr *Expr::IgnoreImplicit() { | static Expr *IgnoreImpCastsExtraSingleStep(Expr *E) { | ||||
Expr *E = this; | // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in | ||||
Expr *LastE = nullptr; | // addition to what IgnoreImpCasts() skips to account for the current | ||||
while (E != LastE) { | // behaviour of IgnoreParenImpCasts(). | ||||
LastE = E; | Expr *SubE = IgnoreImpCastsSingleStep(E); | ||||
if (SubE != E) | |||||
return SubE; | |||||
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) | if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) | ||||
E = ICE->getSubExpr(); | 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)) | if (auto *FE = dyn_cast<FullExpr>(E)) | ||||
E = FE->getSubExpr(); | return FE->getSubExpr(); | ||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) | if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) | ||||
E = MTE->GetTemporaryExpr(); | return MTE->GetTemporaryExpr(); | ||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) | |||||
return NTTP->getReplacement(); | |||||
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E)) | |||||
E = BTE->getSubExpr(); | |||||
} | |||||
return E; | return E; | ||||
} | } | ||||
Expr *Expr::IgnoreParens() { | static Expr *IgnoreLValueCastsSingleStep(Expr *E) { | ||||
Expr *E = this; | // Skip what IgnoreCastsSingleStep skips, except that only | ||||
while (true) { | // lvalue-to-rvalue casts are skipped. | ||||
if (auto *PE = dyn_cast<ParenExpr>(E)) { | if (auto *CE = dyn_cast<CastExpr>(E)) | ||||
E = PE->getSubExpr(); | if (CE->getCastKind() != CK_LValueToRValue) | ||||
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; | 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; | |||||
} | } | ||||
/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr | static Expr *IgnoreImplicitSingleStep(Expr *E) { | ||||
/// or CastExprs or ImplicitCastExprs, returning their operand. | Expr *SubE = IgnoreImpCastsSingleStep(E); | ||||
Expr *Expr::IgnoreParenCasts() { | if (SubE != E) | ||||
Expr *E = this; | return SubE; | ||||
while (true) { | |||||
E = E->IgnoreParens(); | if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) | ||||
if (auto *CE = dyn_cast<CastExpr>(E)) { | return MTE->GetTemporaryExpr(); | ||||
E = CE->getSubExpr(); | |||||
continue; | if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E)) | ||||
return BTE->getSubExpr(); | |||||
return E; | |||||
} | } | ||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) { | |||||
E = MTE->GetTemporaryExpr(); | static Expr *IgnoreParensSingleStep(Expr *E) { | ||||
continue; | 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(); | |||||
} | } | ||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) { | |||||
E = NTTP->getReplacement(); | else if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) { | ||||
continue; | if (!GSE->isResultDependent()) | ||||
return GSE->getResultExpr(); | |||||
} | } | ||||
if (auto *FE = dyn_cast<FullExpr>(E)) { | |||||
E = FE->getSubExpr(); | else if (auto *CE = dyn_cast<ChooseExpr>(E)) { | ||||
continue; | if (!CE->isConditionDependent()) | ||||
return CE->getChosenSubExpr(); | |||||
} | } | ||||
else if (auto *CE = dyn_cast<ConstantExpr>(E)) | |||||
return CE->getSubExpr(); | |||||
return E; | return E; | ||||
} | } | ||||
} | |||||
Expr *Expr::IgnoreCasts() { | static Expr *IgnoreNoopCastsSingleStep(const ASTContext &Ctx, Expr *E) { | ||||
Expr *E = this; | |||||
while (true) { | |||||
if (auto *CE = dyn_cast<CastExpr>(E)) { | if (auto *CE = dyn_cast<CastExpr>(E)) { | ||||
E = CE->getSubExpr(); | // We ignore integer <-> casts that are of the same width, ptr<->ptr and | ||||
continue; | // ptr<->int casts of the same width. We also ignore all identity casts. | ||||
} | Expr *SubExpr = CE->getSubExpr(); | ||||
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) { | bool IsIdentityCast = | ||||
E = MTE->GetTemporaryExpr(); | Ctx.hasSameUnqualifiedType(E->getType(), SubExpr->getType()); | ||||
continue; | bool IsSameWidthCast = | ||||
} | (E->getType()->isPointerType() || E->getType()->isIntegralType(Ctx)) && | ||||
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) { | (SubExpr->getType()->isPointerType() || | ||||
E = NTTP->getReplacement(); | SubExpr->getType()->isIntegralType(Ctx)) && | ||||
continue; | (Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SubExpr->getType())); | ||||
} | |||||
if (auto *FE = dyn_cast<FullExpr>(E)) { | if (IsIdentityCast || IsSameWidthCast) | ||||
E = FE->getSubExpr(); | return SubExpr; | ||||
continue; | |||||
} | } | ||||
else if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) | |||||
return NTTP->getReplacement(); | |||||
return E; | return E; | ||||
} | } | ||||
} | |||||
/// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue | static Expr *IgnoreExprNodesImpl(Expr *E) { return E; } | ||||
/// casts. This is intended purely as a temporary workaround for code | template <typename FnTy, typename... FnTys> | ||||
/// that hasn't yet been rewritten to do the right thing about those | static Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) { | ||||
/// casts, and may disappear along with the last internal use. | return IgnoreExprNodesImpl(Fn(E), std::forward<FnTys>(Fns)...); | ||||
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(); | /// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, | ||||
continue; | /// Recursively apply each of the functions to E until reaching a fixed point. | ||||
} else if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) { | /// Note that a null E is valid; in this case nothing is done. | ||||
E = NTTP->getReplacement(); | template <typename... FnTys> | ||||
continue; | static Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) { | ||||
} else if (auto *FE = dyn_cast<FullExpr>(E)) { | Expr *LastE = nullptr; | ||||
E = FE->getSubExpr(); | while (E != LastE) { | ||||
continue; | LastE = E; | ||||
} | E = IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...); | ||||
break; | |||||
} | } | ||||
return E; | return E; | ||||
} | } | ||||
Expr *Expr::ignoreParenBaseCasts() { | Expr *Expr::IgnoreImpCasts() { | ||||
Expr *E = this; | return IgnoreExprNodes(this, IgnoreImpCastsSingleStep); | ||||
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; | |||||
} | } | ||||
Expr *Expr::IgnoreCasts() { | |||||
return IgnoreExprNodes(this, IgnoreCastsSingleStep); | |||||
} | } | ||||
return E; | Expr *Expr::IgnoreImplicit() { | ||||
return IgnoreExprNodes(this, IgnoreImplicitSingleStep); | |||||
} | } | ||||
Expr *Expr::IgnoreParens() { | |||||
return IgnoreExprNodes(this, IgnoreParensSingleStep); | |||||
} | } | ||||
Expr *Expr::IgnoreParenImpCasts() { | Expr *Expr::IgnoreParenImpCasts() { | ||||
Expr *E = this; | return IgnoreExprNodes(this, IgnoreParensSingleStep, | ||||
while (true) { | IgnoreImpCastsExtraSingleStep); | ||||
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; | |||||
} | } | ||||
Expr *Expr::IgnoreParenCasts() { | |||||
return IgnoreExprNodes(this, IgnoreParensSingleStep, IgnoreCastsSingleStep); | |||||
} | } | ||||
Expr *Expr::IgnoreConversionOperator() { | Expr *Expr::IgnoreConversionOperator() { | ||||
if (auto *MCE = dyn_cast<CXXMemberCallExpr>(this)) { | if (auto *MCE = dyn_cast<CXXMemberCallExpr>(this)) { | ||||
if (MCE->getMethodDecl() && isa<CXXConversionDecl>(MCE->getMethodDecl())) | if (MCE->getMethodDecl() && isa<CXXConversionDecl>(MCE->getMethodDecl())) | ||||
return MCE->getImplicitObjectArgument(); | return MCE->getImplicitObjectArgument(); | ||||
} | } | ||||
return this; | return this; | ||||
} | } | ||||
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the | Expr *Expr::IgnoreParenLValueCasts() { | ||||
/// value (including ptr->int casts of the same size). Strip off any | return IgnoreExprNodes(this, IgnoreParensSingleStep, | ||||
/// ParenExpr or CastExprs, returning their operand. | IgnoreLValueCastsSingleStep); | ||||
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)) { | Expr *Expr::ignoreParenBaseCasts() { | ||||
E = NTTP->getReplacement(); | return IgnoreExprNodes(this, IgnoreParensSingleStep, | ||||
continue; | IgnoreBaseCastsSingleStep); | ||||
} | } | ||||
return E; | Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) { | ||||
} | return IgnoreExprNodes(this, IgnoreParensSingleStep, [&Ctx](Expr *E) { | ||||
return IgnoreNoopCastsSingleStep(Ctx, E); | |||||
}); | |||||
} | } | ||||
bool Expr::isDefaultArgument() const { | bool Expr::isDefaultArgument() const { | ||||
const Expr *E = this; | const Expr *E = this; | ||||
if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E)) | if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E)) | ||||
E = M->GetTemporaryExpr(); | E = M->GetTemporaryExpr(); | ||||
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) | while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) | ||||
▲ Show 20 Lines • Show All 1,557 Lines • Show Last 20 Lines |