summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-04 17:33:58 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-04 17:33:58 +0000
commit820ba7ba43a25a9caefb3bf1f9049d1d73935fdb (patch)
tree770ce4bc86bcf6df4fef9686843807ca5802dd64 /clang/lib/Parse/ParseExpr.cpp
parent3b264ba91aedb2b7161fd93d1d4a517099be39b5 (diff)
downloadbcm5719-llvm-820ba7ba43a25a9caefb3bf1f9049d1d73935fdb.tar.gz
bcm5719-llvm-820ba7ba43a25a9caefb3bf1f9049d1d73935fdb.zip
Implement the sizeof...(pack) expression to compute the length of a
parameter pack. Note that we're missing proper libclang support for the new SizeOfPackExpr expression node. llvm-svn: 122813
Diffstat (limited to 'clang/lib/Parse/ParseExpr.cpp')
-rw-r--r--clang/lib/Parse/ParseExpr.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index be5c7d7808f..7133b610225 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -444,6 +444,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
/// unary-operator cast-expression
/// 'sizeof' unary-expression
/// 'sizeof' '(' type-name ')'
+/// [C++0x] 'sizeof' '...' '(' identifier ')'
/// [GNU] '__alignof' unary-expression
/// [GNU] '__alignof' '(' type-name ')'
/// [C++0x] 'alignof' '(' type-id ')'
@@ -1291,6 +1292,7 @@ Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
/// unary-expression: [C99 6.5.3]
/// 'sizeof' unary-expression
/// 'sizeof' '(' type-name ')'
+/// [C++0x] 'sizeof' '...' '(' identifier ')'
/// [GNU] '__alignof' unary-expression
/// [GNU] '__alignof' '(' type-name ')'
/// [C++0x] 'alignof' '(' type-id ')'
@@ -1301,6 +1303,46 @@ ExprResult Parser::ParseSizeofAlignofExpression() {
Token OpTok = Tok;
ConsumeToken();
+ // [C++0x] 'sizeof' '...' '(' identifier ')'
+ if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) {
+ SourceLocation EllipsisLoc = ConsumeToken();
+ SourceLocation LParenLoc, RParenLoc;
+ IdentifierInfo *Name = 0;
+ SourceLocation NameLoc;
+ if (Tok.is(tok::l_paren)) {
+ LParenLoc = ConsumeParen();
+ if (Tok.is(tok::identifier)) {
+ Name = Tok.getIdentifierInfo();
+ NameLoc = ConsumeToken();
+ RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ if (RParenLoc.isInvalid())
+ RParenLoc = PP.getLocForEndOfToken(NameLoc);
+ } else {
+ Diag(Tok, diag::err_expected_parameter_pack);
+ SkipUntil(tok::r_paren);
+ }
+ } else if (Tok.is(tok::identifier)) {
+ Name = Tok.getIdentifierInfo();
+ NameLoc = ConsumeToken();
+ LParenLoc = PP.getLocForEndOfToken(EllipsisLoc);
+ RParenLoc = PP.getLocForEndOfToken(NameLoc);
+ Diag(LParenLoc, diag::err_paren_sizeof_parameter_pack)
+ << Name
+ << FixItHint::CreateInsertion(LParenLoc, "(")
+ << FixItHint::CreateInsertion(RParenLoc, ")");
+ } else {
+ Diag(Tok, diag::err_sizeof_parameter_pack);
+ }
+
+ if (!Name)
+ return ExprError();
+
+ return Actions.ActOnSizeofParameterPackExpr(getCurScope(),
+ OpTok.getLocation(),
+ *Name, NameLoc,
+ RParenLoc);
+ }
+
bool isCastExpr;
ParsedType CastTy;
SourceRange CastRange;
OpenPOWER on IntegriCloud