summaryrefslogtreecommitdiffstats
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r--lib/AST/Expr.cpp487
1 files changed, 261 insertions, 226 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 7cdd3b2c2a..cf488850d3 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1,9 +1,8 @@
//===--- Expr.cpp - Expression AST Node Implementation --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -1359,6 +1358,8 @@ Decl *Expr::getReferencedDeclOfCallee() {
return DRE->getDecl();
if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
return ME->getMemberDecl();
+ if (auto *BE = dyn_cast<BlockExpr>(CEE))
+ return BE->getBlockDecl();
return nullptr;
}
@@ -1677,7 +1678,7 @@ bool CastExpr::CastConsistency() const {
auto Ty = getType();
auto SETy = getSubExpr()->getType();
assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy));
- if (isRValue()) {
+ if (/*isRValue()*/ !Ty->getPointeeType().isNull()) {
Ty = Ty->getPointeeType();
SETy = SETy->getPointeeType();
}
@@ -1717,6 +1718,8 @@ bool CastExpr::CastConsistency() const {
case CK_ZeroToOCLOpaqueType:
case CK_IntToOCLSampler:
case CK_FixedPointCast:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
assert(!getType()->isBooleanType() && "unheralded conversion to bool");
goto CheckNoBasePath;
@@ -2557,205 +2560,197 @@ QualType Expr::findBoundMemberType(const Expr *expr) {
return QualType();
}
-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 *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;
}
-/// 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 *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;
}
-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;
+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;
}
-/// 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;
+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;
}
-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;
- }
- }
+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)...);
+}
- return E;
+/// 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;
+ E = IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...);
}
+ return E;
+}
+
+Expr *Expr::IgnoreImpCasts() {
+ return IgnoreExprNodes(this, IgnoreImpCastsSingleStep);
+}
+
+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() {
- if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
+ if (auto *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
if (MCE->getMethodDecl() && isa<CXXConversionDecl>(MCE->getMethodDecl()))
return MCE->getImplicitObjectArgument();
}
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(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 {
@@ -3775,55 +3770,95 @@ void ShuffleVectorExpr::setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs) {
memcpy(SubExprs, Exprs.data(), sizeof(Expr *) * Exprs.size());
}
-GenericSelectionExpr::GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack,
- unsigned ResultIndex)
- : Expr(GenericSelectionExprClass,
- AssocExprs[ResultIndex]->getType(),
- AssocExprs[ResultIndex]->getValueKind(),
- AssocExprs[ResultIndex]->getObjectKind(),
- AssocExprs[ResultIndex]->isTypeDependent(),
- AssocExprs[ResultIndex]->isValueDependent(),
- AssocExprs[ResultIndex]->isInstantiationDependent(),
- ContainsUnexpandedParameterPack),
- AssocTypes(new (Context) TypeSourceInfo*[AssocTypes.size()]),
- SubExprs(new (Context) Stmt*[END_EXPR+AssocExprs.size()]),
- NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex),
- GenericLoc(GenericLoc), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
- SubExprs[CONTROLLING] = ControllingExpr;
- assert(AssocTypes.size() == AssocExprs.size());
- std::copy(AssocTypes.begin(), AssocTypes.end(), this->AssocTypes);
- std::copy(AssocExprs.begin(), AssocExprs.end(), SubExprs+END_EXPR);
-}
-
-GenericSelectionExpr::GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack)
- : Expr(GenericSelectionExprClass,
- Context.DependentTy,
- VK_RValue,
- OK_Ordinary,
- /*isTypeDependent=*/true,
- /*isValueDependent=*/true,
- /*isInstantiationDependent=*/true,
- ContainsUnexpandedParameterPack),
- AssocTypes(new (Context) TypeSourceInfo*[AssocTypes.size()]),
- SubExprs(new (Context) Stmt*[END_EXPR+AssocExprs.size()]),
- NumAssocs(AssocExprs.size()), ResultIndex(-1U), GenericLoc(GenericLoc),
- DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
- SubExprs[CONTROLLING] = ControllingExpr;
- assert(AssocTypes.size() == AssocExprs.size());
- std::copy(AssocTypes.begin(), AssocTypes.end(), this->AssocTypes);
- std::copy(AssocExprs.begin(), AssocExprs.end(), SubExprs+END_EXPR);
+GenericSelectionExpr::GenericSelectionExpr(
+ const ASTContext &, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
+ : Expr(GenericSelectionExprClass, AssocExprs[ResultIndex]->getType(),
+ AssocExprs[ResultIndex]->getValueKind(),
+ AssocExprs[ResultIndex]->getObjectKind(),
+ AssocExprs[ResultIndex]->isTypeDependent(),
+ AssocExprs[ResultIndex]->isValueDependent(),
+ AssocExprs[ResultIndex]->isInstantiationDependent(),
+ ContainsUnexpandedParameterPack),
+ NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex),
+ DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
+ assert(AssocTypes.size() == AssocExprs.size() &&
+ "Must have the same number of association expressions"
+ " and TypeSourceInfo!");
+ assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
+
+ GenericSelectionExprBits.GenericLoc = GenericLoc;
+ getTrailingObjects<Stmt *>()[ControllingIndex] = ControllingExpr;
+ std::copy(AssocExprs.begin(), AssocExprs.end(),
+ getTrailingObjects<Stmt *>() + AssocExprStartIndex);
+ std::copy(AssocTypes.begin(), AssocTypes.end(),
+ getTrailingObjects<TypeSourceInfo *>());
+}
+
+GenericSelectionExpr::GenericSelectionExpr(
+ const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack)
+ : Expr(GenericSelectionExprClass, Context.DependentTy, VK_RValue,
+ OK_Ordinary,
+ /*isTypeDependent=*/true,
+ /*isValueDependent=*/true,
+ /*isInstantiationDependent=*/true, ContainsUnexpandedParameterPack),
+ NumAssocs(AssocExprs.size()), ResultIndex(ResultDependentIndex),
+ DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
+ assert(AssocTypes.size() == AssocExprs.size() &&
+ "Must have the same number of association expressions"
+ " and TypeSourceInfo!");
+
+ GenericSelectionExprBits.GenericLoc = GenericLoc;
+ getTrailingObjects<Stmt *>()[ControllingIndex] = ControllingExpr;
+ std::copy(AssocExprs.begin(), AssocExprs.end(),
+ getTrailingObjects<Stmt *>() + AssocExprStartIndex);
+ std::copy(AssocTypes.begin(), AssocTypes.end(),
+ getTrailingObjects<TypeSourceInfo *>());
+}
+
+GenericSelectionExpr::GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs)
+ : Expr(GenericSelectionExprClass, Empty), NumAssocs(NumAssocs) {}
+
+GenericSelectionExpr *GenericSelectionExpr::Create(
+ const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack, unsigned ResultIndex) {
+ unsigned NumAssocs = AssocExprs.size();
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
+ alignof(GenericSelectionExpr));
+ return new (Mem) GenericSelectionExpr(
+ Context, GenericLoc, ControllingExpr, AssocTypes, AssocExprs, DefaultLoc,
+ RParenLoc, ContainsUnexpandedParameterPack, ResultIndex);
+}
+
+GenericSelectionExpr *GenericSelectionExpr::Create(
+ const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack) {
+ unsigned NumAssocs = AssocExprs.size();
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
+ alignof(GenericSelectionExpr));
+ return new (Mem) GenericSelectionExpr(
+ Context, GenericLoc, ControllingExpr, AssocTypes, AssocExprs, DefaultLoc,
+ RParenLoc, ContainsUnexpandedParameterPack);
+}
+
+GenericSelectionExpr *
+GenericSelectionExpr::CreateEmpty(const ASTContext &Context,
+ unsigned NumAssocs) {
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
+ alignof(GenericSelectionExpr));
+ return new (Mem) GenericSelectionExpr(EmptyShell(), NumAssocs);
}
//===----------------------------------------------------------------------===//