}
};
-class ParenListExpr : public Expr {
- Stmt **Exprs;
- unsigned NumExprs;
+class ParenListExpr final
+ : public Expr,
+ private llvm::TrailingObjects<ParenListExpr, Stmt *> {
+ friend class ASTStmtReader;
+ friend TrailingObjects;
+
+ /// The location of the left and right parentheses.
SourceLocation LParenLoc, RParenLoc;
-public:
- ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
- ArrayRef<Expr*> exprs, SourceLocation rparenloc);
+ /// Build a paren list.
+ ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc);
/// Build an empty paren list.
- explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
+ ParenListExpr(EmptyShell Empty, unsigned NumExprs);
+
+public:
+ /// Create a paren list.
+ static ParenListExpr *Create(const ASTContext &Ctx, SourceLocation LParenLoc,
+ ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc);
+
+ /// Create an empty paren list.
+ static ParenListExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumExprs);
- unsigned getNumExprs() const { return NumExprs; }
+ /// Return the number of expressions in this paren list.
+ unsigned getNumExprs() const { return ParenListExprBits.NumExprs; }
- const Expr* getExpr(unsigned Init) const {
+ Expr *getExpr(unsigned Init) {
assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
+ return getExprs()[Init];
}
- Expr* getExpr(unsigned Init) {
- assert(Init < getNumExprs() && "Initializer access out of range!");
- return cast_or_null<Expr>(Exprs[Init]);
+ const Expr *getExpr(unsigned Init) const {
+ return const_cast<ParenListExpr *>(this)->getExpr(Init);
}
- Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
+ Expr **getExprs() {
+ return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>());
+ }
ArrayRef<Expr *> exprs() {
return llvm::makeArrayRef(getExprs(), getNumExprs());
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
-
- SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+ SourceLocation getBeginLoc() const { return getLParenLoc(); }
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ParenListExprClass;
// Iterators
child_range children() {
- return child_range(&Exprs[0], &Exprs[0]+NumExprs);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + getNumExprs());
}
const_child_range children() const {
- return const_child_range(&Exprs[0], &Exprs[0] + NumExprs);
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + getNumExprs());
}
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
};
/// Represents a C11 generic selection.
unsigned HadArrayRangeDesignator : 1;
};
+ class ParenListExprBitfields {
+ friend class ASTStmtReader;
+ friend class ParenListExpr;
+
+ unsigned : NumExprBits;
+
+ /// The number of expressions in the paren list.
+ unsigned NumExprs;
+ };
+
class PseudoObjectExprBitfields {
friend class ASTStmtReader; // deserialization
friend class PseudoObjectExpr;
CastExprBitfields CastExprBits;
BinaryOperatorBitfields BinaryOperatorBits;
InitListExprBitfields InitListExprBits;
+ ParenListExprBitfields ParenListExprBits;
PseudoObjectExprBitfields PseudoObjectExprBits;
// C++ Expressions
if (!ToRParenLocOrErr)
return ToRParenLocOrErr.takeError();
- return new (Importer.getToContext()) ParenListExpr(
- Importer.getToContext(), *ToLParenLocOrErr, ToExprs, *ToRParenLocOrErr);
+ return ParenListExpr::Create(Importer.getToContext(), *ToLParenLocOrErr,
+ ToExprs, *ToRParenLocOrErr);
}
ExpectedStmt ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
return getBase()->getEndLoc();
}
-ParenListExpr::ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
- ArrayRef<Expr*> exprs,
- SourceLocation rparenloc)
- : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary,
- false, false, false, false),
- NumExprs(exprs.size()), LParenLoc(lparenloc), RParenLoc(rparenloc) {
- Exprs = new (C) Stmt*[exprs.size()];
- for (unsigned i = 0; i != exprs.size(); ++i) {
- if (exprs[i]->isTypeDependent())
+ParenListExpr::ParenListExpr(SourceLocation LParenLoc, ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc)
+ : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
+ false, false),
+ LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
+ ParenListExprBits.NumExprs = Exprs.size();
+
+ for (unsigned I = 0, N = Exprs.size(); I != N; ++I) {
+ if (Exprs[I]->isTypeDependent())
ExprBits.TypeDependent = true;
- if (exprs[i]->isValueDependent())
+ if (Exprs[I]->isValueDependent())
ExprBits.ValueDependent = true;
- if (exprs[i]->isInstantiationDependent())
+ if (Exprs[I]->isInstantiationDependent())
ExprBits.InstantiationDependent = true;
- if (exprs[i]->containsUnexpandedParameterPack())
+ if (Exprs[I]->containsUnexpandedParameterPack())
ExprBits.ContainsUnexpandedParameterPack = true;
- Exprs[i] = exprs[i];
+ getTrailingObjects<Stmt *>()[I] = Exprs[I];
}
}
+ParenListExpr::ParenListExpr(EmptyShell Empty, unsigned NumExprs)
+ : Expr(ParenListExprClass, Empty) {
+ ParenListExprBits.NumExprs = NumExprs;
+}
+
+ParenListExpr *ParenListExpr::Create(const ASTContext &Ctx,
+ SourceLocation LParenLoc,
+ ArrayRef<Expr *> Exprs,
+ SourceLocation RParenLoc) {
+ void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(Exprs.size()),
+ alignof(ParenListExpr));
+ return new (Mem) ParenListExpr(LParenLoc, Exprs, RParenLoc);
+}
+
+ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx,
+ unsigned NumExprs) {
+ void *Mem =
+ Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumExprs), alignof(ParenListExpr));
+ return new (Mem) ParenListExpr(EmptyShell(), NumExprs);
+}
+
const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
e = ewc->getSubExpr();
// Create an initialization sequence for the promise type using the
// constructor arguments, wrapped in a parenthesized list expression.
- Expr *PLE = new (Context) ParenListExpr(Context, FD->getLocation(),
- CtorArgExprs, FD->getLocation());
+ Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(),
+ CtorArgExprs, FD->getLocation());
InitializedEntity Entity = InitializedEntity::InitializeVariable(VD);
InitializationKind Kind = InitializationKind::CreateForInit(
VD->getLocation(), /*DirectInit=*/true, PLE);
ArrayRef<Expr *> Args,
SourceLocation RParenLoc,
SourceLocation EllipsisLoc) {
- Expr *List = new (Context) ParenListExpr(Context, LParenLoc,
- Args, RParenLoc);
+ Expr *List = ParenListExpr::Create(Context, LParenLoc, Args, RParenLoc);
return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy,
DS, IdLoc, List, EllipsisLoc);
}
ExprResult Sema::ActOnParenListExpr(SourceLocation L,
SourceLocation R,
MultiExprArg Val) {
- Expr *expr = new (Context) ParenListExpr(Context, L, Val, R);
- return expr;
+ return ParenListExpr::Create(Context, L, Val, R);
}
/// Emit a specialized diagnostic when one expression is a null pointer
void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
VisitExpr(E);
unsigned NumExprs = Record.readInt();
- E->Exprs = new (Record.getContext()) Stmt*[NumExprs];
- for (unsigned i = 0; i != NumExprs; ++i)
- E->Exprs[i] = Record.readSubStmt();
- E->NumExprs = NumExprs;
+ assert((NumExprs == E->getNumExprs()) && "Wrong NumExprs!");
+ for (unsigned I = 0; I != NumExprs; ++I)
+ E->getTrailingObjects<Stmt *>()[I] = Record.readSubStmt();
E->LParenLoc = ReadSourceLocation();
E->RParenLoc = ReadSourceLocation();
}
break;
case EXPR_PAREN_LIST:
- S = new (Context) ParenListExpr(Empty);
+ S = ParenListExpr::CreateEmpty(
+ Context,
+ /* NumExprs=*/Record[ASTStmtReader::NumExprFields + 0]);
break;
case EXPR_UNARY_OPERATOR:
void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
VisitExpr(E);
- Record.push_back(E->NumExprs);
- for (unsigned i=0; i != E->NumExprs; ++i)
- Record.AddStmt(E->Exprs[i]);
- Record.AddSourceLocation(E->LParenLoc);
- Record.AddSourceLocation(E->RParenLoc);
+ Record.push_back(E->getNumExprs());
+ for (auto *SubStmt : E->exprs())
+ Record.AddStmt(SubStmt);
+ Record.AddSourceLocation(E->getLParenLoc());
+ Record.AddSourceLocation(E->getRParenLoc());
Code = serialization::EXPR_PAREN_LIST;
}