summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/Expr.h
diff options
context:
space:
mode:
authorBruno Ricci <riccibrun@gmail.com>2019-01-26 14:15:10 +0000
committerBruno Ricci <riccibrun@gmail.com>2019-01-26 14:15:10 +0000
commitd4197d25f51c022ce7ca24d39f6619aa621d7804 (patch)
tree5a08ba9b37754319108cb8f1d541f7864123d3d5 /include/clang/AST/Expr.h
parent304d9640c7127e99868db13a9e364515dbede975 (diff)
[AST] Pack GenericSelectionExpr
Store the controlling expression, the association expressions and the corresponding TypeSourceInfos as trailing objects. Additionally use the bit-fields of Stmt to store one SourceLocation, saving one additional pointer. This saves 3 pointers in total per GenericSelectionExpr. Differential Revision: https://reviews.llvm.org/D57104 Reviewed By: aaron.ballman Reviewers: aaron.ballman, steveire git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@352276 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST/Expr.h')
-rw-r--r--include/clang/AST/Expr.h96
1 files changed, 73 insertions, 23 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 405d0cfd4a..f770cf327c 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -5013,9 +5013,13 @@ public:
/// which names a dependent type in its association list is result-dependent,
/// which means that the choice of result expression is dependent.
/// Result-dependent generic associations are both type- and value-dependent.
-class GenericSelectionExpr : public Expr {
+class GenericSelectionExpr final
+ : public Expr,
+ private llvm::TrailingObjects<GenericSelectionExpr, Stmt *,
+ TypeSourceInfo *> {
friend class ASTStmtReader;
friend class ASTStmtWriter;
+ friend TrailingObjects;
/// The number of association expressions and the index of the result
/// expression in the case where the generic selection expression is not
@@ -5028,13 +5032,27 @@ class GenericSelectionExpr : public Expr {
AssocExprStartIndex = 1
};
- /// The location of the "_Generic", "default" and of the right parenthesis.
- SourceLocation GenericLoc, DefaultLoc, RParenLoc;
+ /// The location of the "default" and of the right parenthesis.
+ SourceLocation DefaultLoc, RParenLoc;
- TypeSourceInfo **AssocTypes;
- Stmt **SubExprs;
+ // GenericSelectionExpr is followed by several trailing objects.
+ // They are (in order):
+ //
+ // * A single Stmt * for the controlling expression.
+ // * An array of getNumAssocs() Stmt * for the association expressions.
+ // * An array of getNumAssocs() TypeSourceInfo *, one for each of the
+ // association expressions.
+ unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
+ // Add one to account for the controlling expression; the remainder
+ // are the associated expressions.
+ return 1 + getNumAssocs();
+ }
-public:
+ unsigned numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
+ return getNumAssocs();
+ }
+
+ /// Build a non-result-dependent generic selection expression.
GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr,
ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5043,7 +5061,7 @@ public:
bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
- /// This constructor is used in the result-dependent case.
+ /// Build a result-dependent generic selection expression.
GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr,
ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5051,8 +5069,28 @@ public:
SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack);
- explicit GenericSelectionExpr(EmptyShell Empty)
- : Expr(GenericSelectionExprClass, Empty) {}
+ /// Build an empty generic selection expression for deserialization.
+ explicit GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs);
+
+public:
+ /// Create a non-result-dependent generic selection expression.
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
+ unsigned ResultIndex);
+
+ /// Create a result-dependent generic selection expression.
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack);
+
+ /// Create an empty generic selection expression for deserialization.
+ static GenericSelectionExpr *CreateEmpty(const ASTContext &Context,
+ unsigned NumAssocs);
/// The number of association expressions.
unsigned getNumAssocs() const { return NumAssocs; }
@@ -5070,38 +5108,45 @@ public:
bool isResultDependent() const { return ResultIndex == ResultDependentIndex; }
/// Return the controlling expression of this generic selection expression.
- Expr *getControllingExpr() { return cast<Expr>(SubExprs[ControllingIndex]); }
+ Expr *getControllingExpr() {
+ return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
+ }
const Expr *getControllingExpr() const {
- return cast<Expr>(SubExprs[ControllingIndex]);
+ return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
}
/// Return the result expression of this controlling expression. Defined if
/// and only if the generic selection expression is not result-dependent.
Expr *getResultExpr() {
- return cast<Expr>(SubExprs[AssocExprStartIndex + getResultIndex()]);
+ return cast<Expr>(
+ getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]);
}
const Expr *getResultExpr() const {
- return cast<Expr>(SubExprs[AssocExprStartIndex + getResultIndex()]);
+ return cast<Expr>(
+ getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]);
}
ArrayRef<Expr *> getAssocExprs() const {
- return {reinterpret_cast<Expr *const *>(SubExprs + AssocExprStartIndex),
+ return {reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>() +
+ AssocExprStartIndex),
NumAssocs};
}
ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
- return {AssocTypes, NumAssocs};
+ return {getTrailingObjects<TypeSourceInfo *>(), NumAssocs};
}
Expr *getAssocExpr(unsigned i) {
- return cast<Expr>(SubExprs[AssocExprStartIndex + i]);
+ return cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + i]);
}
const Expr *getAssocExpr(unsigned i) const {
- return cast<Expr>(SubExprs[AssocExprStartIndex + i]);
+ return cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + i]);
}
- TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
+ TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) {
+ return getTrailingObjects<TypeSourceInfo *>()[i];
+ }
const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
- return AssocTypes[i];
+ return getTrailingObjects<TypeSourceInfo *>()[i];
}
QualType getAssocType(unsigned i) const {
@@ -5109,7 +5154,9 @@ public:
return TSI ? TSI->getType() : QualType();
}
- SourceLocation getGenericLoc() const { return GenericLoc; }
+ SourceLocation getGenericLoc() const {
+ return GenericSelectionExprBits.GenericLoc;
+ }
SourceLocation getDefaultLoc() const { return DefaultLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
SourceLocation getBeginLoc() const { return getGenericLoc(); }
@@ -5120,11 +5167,14 @@ public:
}
child_range children() {
- return child_range(SubExprs, SubExprs + AssocExprStartIndex + NumAssocs);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
const_child_range children() const {
- return const_child_range(SubExprs,
- SubExprs + AssocExprStartIndex + NumAssocs);
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
};