forked from OSchip/llvm-project
[AST] Store the expressions in ParenListExpr in a trailing array
Use the newly available space in the bit-fields of Stmt and store the expressions in a trailing array. This saves 2 pointer per ParenListExpr. Differential Revision: https://reviews.llvm.org/D54675 Reviewed By: rjmccall llvm-svn: 347320
This commit is contained in:
parent
855dfee2c2
commit
f49e1ca04d
|
@ -4844,31 +4844,46 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
unsigned getNumExprs() const { return NumExprs; }
|
||||
public:
|
||||
/// Create a paren list.
|
||||
static ParenListExpr *Create(const ASTContext &Ctx, SourceLocation LParenLoc,
|
||||
ArrayRef<Expr *> Exprs,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
const Expr* getExpr(unsigned Init) const {
|
||||
/// Create an empty paren list.
|
||||
static ParenListExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumExprs);
|
||||
|
||||
/// Return the number of expressions in this paren list.
|
||||
unsigned getNumExprs() const { return ParenListExprBits.NumExprs; }
|
||||
|
||||
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());
|
||||
|
@ -4876,9 +4891,8 @@ public:
|
|||
|
||||
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;
|
||||
|
@ -4886,14 +4900,13 @@ public:
|
|||
|
||||
// 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.
|
||||
|
|
|
@ -496,6 +496,16 @@ protected:
|
|||
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;
|
||||
|
@ -672,6 +682,7 @@ protected:
|
|||
CastExprBitfields CastExprBits;
|
||||
BinaryOperatorBitfields BinaryOperatorBits;
|
||||
InitListExprBitfields InitListExprBits;
|
||||
ParenListExprBitfields ParenListExprBits;
|
||||
PseudoObjectExprBitfields PseudoObjectExprBits;
|
||||
|
||||
// C++ Expressions
|
||||
|
|
|
@ -6409,8 +6409,8 @@ ExpectedStmt ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) {
|
|||
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) {
|
||||
|
|
|
@ -4004,27 +4004,48 @@ SourceLocation DesignatedInitUpdateExpr::getEndLoc() const {
|
|||
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();
|
||||
|
|
|
@ -565,8 +565,8 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
|
|||
|
||||
// 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);
|
||||
|
|
|
@ -3731,8 +3731,7 @@ Sema::ActOnMemInitializer(Decl *ConstructorD,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -6410,8 +6410,7 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
|
|||
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
|
||||
|
|
|
@ -643,10 +643,9 @@ void ASTStmtReader::VisitParenExpr(ParenExpr *E) {
|
|||
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();
|
||||
}
|
||||
|
@ -2452,7 +2451,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
break;
|
||||
|
||||
case EXPR_PAREN_LIST:
|
||||
S = new (Context) ParenListExpr(Empty);
|
||||
S = ParenListExpr::CreateEmpty(
|
||||
Context,
|
||||
/* NumExprs=*/Record[ASTStmtReader::NumExprFields + 0]);
|
||||
break;
|
||||
|
||||
case EXPR_UNARY_OPERATOR:
|
||||
|
|
|
@ -559,11 +559,11 @@ void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue