blob: a416838250988bdd93cc278303f9a29ce9c0bfc6 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
Chris Lattner500d3292009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Chris Lattner31e05722007-08-26 06:24:45 +000016#include "clang/Parse/Scope.h"
Chris Lattnerc46d1a12008-10-20 06:45:43 +000017#include "ExtensionRAIIObject.h"
Sebastian Redla55e52c2008-11-25 22:21:31 +000018#include "AstGuard.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000019#include "llvm/ADT/SmallSet.h"
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
23// C99 6.7: Declarations.
24//===----------------------------------------------------------------------===//
25
26/// ParseTypeName
27/// type-name: [C99 6.7.6]
28/// specifier-qualifier-list abstract-declarator[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +000029///
30/// Called type-id in C++.
Douglas Gregor809070a2009-02-18 17:45:20 +000031Action::TypeResult Parser::ParseTypeName() {
Reid Spencer5f016e22007-07-11 17:01:13 +000032 // Parse the common declaration-specifiers piece.
33 DeclSpec DS;
34 ParseSpecifierQualifierList(DS);
35
36 // Parse the abstract-declarator, if present.
37 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
38 ParseDeclarator(DeclaratorInfo);
39
Douglas Gregor809070a2009-02-18 17:45:20 +000040 if (DeclaratorInfo.getInvalidType())
41 return true;
42
43 return Actions.ActOnTypeName(CurScope, DeclaratorInfo);
Reid Spencer5f016e22007-07-11 17:01:13 +000044}
45
46/// ParseAttributes - Parse a non-empty attributes list.
47///
48/// [GNU] attributes:
49/// attribute
50/// attributes attribute
51///
52/// [GNU] attribute:
53/// '__attribute__' '(' '(' attribute-list ')' ')'
54///
55/// [GNU] attribute-list:
56/// attrib
57/// attribute_list ',' attrib
58///
59/// [GNU] attrib:
60/// empty
61/// attrib-name
62/// attrib-name '(' identifier ')'
63/// attrib-name '(' identifier ',' nonempty-expr-list ')'
64/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
65///
66/// [GNU] attrib-name:
67/// identifier
68/// typespec
69/// typequal
70/// storageclass
71///
72/// FIXME: The GCC grammar/code for this construct implies we need two
73/// token lookahead. Comment from gcc: "If they start with an identifier
74/// which is followed by a comma or close parenthesis, then the arguments
75/// start with that identifier; otherwise they are an expression list."
76///
77/// At the moment, I am not doing 2 token lookahead. I am also unaware of
78/// any attributes that don't work (based on my limited testing). Most
79/// attributes are very simple in practice. Until we find a bug, I don't see
80/// a pressing need to implement the 2 token lookahead.
81
Sebastian Redlab197ba2009-02-09 18:23:29 +000082AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
Chris Lattner04d66662007-10-09 17:33:22 +000083 assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
Reid Spencer5f016e22007-07-11 17:01:13 +000084
85 AttributeList *CurrAttr = 0;
86
Chris Lattner04d66662007-10-09 17:33:22 +000087 while (Tok.is(tok::kw___attribute)) {
Reid Spencer5f016e22007-07-11 17:01:13 +000088 ConsumeToken();
89 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
90 "attribute")) {
91 SkipUntil(tok::r_paren, true); // skip until ) or ;
92 return CurrAttr;
93 }
94 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
95 SkipUntil(tok::r_paren, true); // skip until ) or ;
96 return CurrAttr;
97 }
98 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner04d66662007-10-09 17:33:22 +000099 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
100 Tok.is(tok::comma)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000101
Chris Lattner04d66662007-10-09 17:33:22 +0000102 if (Tok.is(tok::comma)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000103 // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
104 ConsumeToken();
105 continue;
106 }
107 // we have an identifier or declaration specifier (const, int, etc.)
108 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
109 SourceLocation AttrNameLoc = ConsumeToken();
110
111 // check if we have a "paramterized" attribute
Chris Lattner04d66662007-10-09 17:33:22 +0000112 if (Tok.is(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000113 ConsumeParen(); // ignore the left paren loc for now
114
Chris Lattner04d66662007-10-09 17:33:22 +0000115 if (Tok.is(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000116 IdentifierInfo *ParmName = Tok.getIdentifierInfo();
117 SourceLocation ParmLoc = ConsumeToken();
118
Chris Lattner04d66662007-10-09 17:33:22 +0000119 if (Tok.is(tok::r_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000120 // __attribute__(( mode(byte) ))
121 ConsumeParen(); // ignore the right paren loc for now
122 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
123 ParmName, ParmLoc, 0, 0, CurrAttr);
Chris Lattner04d66662007-10-09 17:33:22 +0000124 } else if (Tok.is(tok::comma)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000125 ConsumeToken();
126 // __attribute__(( format(printf, 1, 2) ))
Sebastian Redla55e52c2008-11-25 22:21:31 +0000127 ExprVector ArgExprs(Actions);
Reid Spencer5f016e22007-07-11 17:01:13 +0000128 bool ArgExprsOk = true;
129
130 // now parse the non-empty comma separated list of expressions
131 while (1) {
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000132 OwningExprResult ArgExpr(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000133 if (ArgExpr.isInvalid()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000134 ArgExprsOk = false;
135 SkipUntil(tok::r_paren);
136 break;
137 } else {
Sebastian Redleffa8d12008-12-10 00:02:53 +0000138 ArgExprs.push_back(ArgExpr.release());
Reid Spencer5f016e22007-07-11 17:01:13 +0000139 }
Chris Lattner04d66662007-10-09 17:33:22 +0000140 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +0000141 break;
142 ConsumeToken(); // Eat the comma, move to the next argument
143 }
Chris Lattner04d66662007-10-09 17:33:22 +0000144 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000145 ConsumeParen(); // ignore the right paren loc for now
146 CurrAttr = new AttributeList(AttrName, AttrNameLoc, ParmName,
Sebastian Redla55e52c2008-11-25 22:21:31 +0000147 ParmLoc, ArgExprs.take(), ArgExprs.size(), CurrAttr);
Reid Spencer5f016e22007-07-11 17:01:13 +0000148 }
149 }
150 } else { // not an identifier
151 // parse a possibly empty comma separated list of expressions
Chris Lattner04d66662007-10-09 17:33:22 +0000152 if (Tok.is(tok::r_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000153 // __attribute__(( nonnull() ))
154 ConsumeParen(); // ignore the right paren loc for now
155 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
156 0, SourceLocation(), 0, 0, CurrAttr);
157 } else {
158 // __attribute__(( aligned(16) ))
Sebastian Redla55e52c2008-11-25 22:21:31 +0000159 ExprVector ArgExprs(Actions);
Reid Spencer5f016e22007-07-11 17:01:13 +0000160 bool ArgExprsOk = true;
161
162 // now parse the list of expressions
163 while (1) {
Sebastian Redl2f7ece72008-12-11 21:36:32 +0000164 OwningExprResult ArgExpr(ParseAssignmentExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000165 if (ArgExpr.isInvalid()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000166 ArgExprsOk = false;
167 SkipUntil(tok::r_paren);
168 break;
169 } else {
Sebastian Redleffa8d12008-12-10 00:02:53 +0000170 ArgExprs.push_back(ArgExpr.release());
Reid Spencer5f016e22007-07-11 17:01:13 +0000171 }
Chris Lattner04d66662007-10-09 17:33:22 +0000172 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +0000173 break;
174 ConsumeToken(); // Eat the comma, move to the next argument
175 }
176 // Match the ')'.
Chris Lattner04d66662007-10-09 17:33:22 +0000177 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000178 ConsumeParen(); // ignore the right paren loc for now
Sebastian Redla55e52c2008-11-25 22:21:31 +0000179 CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
180 SourceLocation(), ArgExprs.take(), ArgExprs.size(),
Reid Spencer5f016e22007-07-11 17:01:13 +0000181 CurrAttr);
182 }
183 }
184 }
185 } else {
186 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
187 0, SourceLocation(), 0, 0, CurrAttr);
188 }
189 }
190 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
Reid Spencer5f016e22007-07-11 17:01:13 +0000191 SkipUntil(tok::r_paren, false);
Sebastian Redlab197ba2009-02-09 18:23:29 +0000192 SourceLocation Loc = Tok.getLocation();;
193 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
194 SkipUntil(tok::r_paren, false);
195 }
196 if (EndLoc)
197 *EndLoc = Loc;
Reid Spencer5f016e22007-07-11 17:01:13 +0000198 }
199 return CurrAttr;
200}
201
Steve Narofff59e17e2008-12-24 20:59:21 +0000202/// FuzzyParseMicrosoftDeclSpec. When -fms-extensions is enabled, this
203/// routine is called to skip/ignore tokens that comprise the MS declspec.
204void Parser::FuzzyParseMicrosoftDeclSpec() {
205 assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
206 ConsumeToken();
207 if (Tok.is(tok::l_paren)) {
208 unsigned short savedParenCount = ParenCount;
209 do {
210 ConsumeAnyToken();
211 } while (ParenCount > savedParenCount && Tok.isNot(tok::eof));
212 }
213 return;
214}
215
Reid Spencer5f016e22007-07-11 17:01:13 +0000216/// ParseDeclaration - Parse a full 'declaration', which consists of
217/// declaration-specifiers, some number of declarators, and a semicolon.
Chris Lattner97144fc2009-04-02 04:16:50 +0000218/// 'Context' should be a Declarator::TheContext value. This returns the
219/// location of the semicolon in DeclEnd.
Chris Lattner8f08cb72007-08-25 06:57:03 +0000220///
221/// declaration: [C99 6.7]
222/// block-declaration ->
223/// simple-declaration
224/// others [FIXME]
Douglas Gregoradcac882008-12-01 23:54:00 +0000225/// [C++] template-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +0000226/// [C++] namespace-definition
Douglas Gregorf780abc2008-12-30 03:27:21 +0000227/// [C++] using-directive
228/// [C++] using-declaration [TODO]
Sebastian Redl50de12f2009-03-24 22:27:57 +0000229/// [C++0x] static_assert-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +0000230/// others... [FIXME]
231///
Chris Lattner97144fc2009-04-02 04:16:50 +0000232Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
233 SourceLocation &DeclEnd) {
Chris Lattner682bf922009-03-29 16:50:03 +0000234 DeclPtrTy SingleDecl;
Chris Lattner8f08cb72007-08-25 06:57:03 +0000235 switch (Tok.getKind()) {
Douglas Gregoradcac882008-12-01 23:54:00 +0000236 case tok::kw_export:
237 case tok::kw_template:
Chris Lattner97144fc2009-04-02 04:16:50 +0000238 SingleDecl = ParseTemplateDeclarationOrSpecialization(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +0000239 break;
Chris Lattner8f08cb72007-08-25 06:57:03 +0000240 case tok::kw_namespace:
Chris Lattner97144fc2009-04-02 04:16:50 +0000241 SingleDecl = ParseNamespace(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +0000242 break;
Douglas Gregorf780abc2008-12-30 03:27:21 +0000243 case tok::kw_using:
Chris Lattner97144fc2009-04-02 04:16:50 +0000244 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +0000245 break;
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000246 case tok::kw_static_assert:
Chris Lattner97144fc2009-04-02 04:16:50 +0000247 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +0000248 break;
Chris Lattner8f08cb72007-08-25 06:57:03 +0000249 default:
Chris Lattner97144fc2009-04-02 04:16:50 +0000250 return ParseSimpleDeclaration(Context, DeclEnd);
Chris Lattner8f08cb72007-08-25 06:57:03 +0000251 }
Chris Lattner682bf922009-03-29 16:50:03 +0000252
253 // This routine returns a DeclGroup, if the thing we parsed only contains a
254 // single decl, convert it now.
255 return Actions.ConvertDeclToDeclGroup(SingleDecl);
Chris Lattner8f08cb72007-08-25 06:57:03 +0000256}
257
258/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
259/// declaration-specifiers init-declarator-list[opt] ';'
260///[C90/C++]init-declarator-list ';' [TODO]
261/// [OMP] threadprivate-directive [TODO]
Chris Lattnercd147752009-03-29 17:27:48 +0000262///
263/// If RequireSemi is false, this does not check for a ';' at the end of the
264/// declaration.
265Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
Chris Lattner97144fc2009-04-02 04:16:50 +0000266 SourceLocation &DeclEnd,
Chris Lattnercd147752009-03-29 17:27:48 +0000267 bool RequireSemi) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000268 // Parse the common declaration-specifiers piece.
269 DeclSpec DS;
270 ParseDeclarationSpecifiers(DS);
271
272 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
273 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner04d66662007-10-09 17:33:22 +0000274 if (Tok.is(tok::semi)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000275 ConsumeToken();
Chris Lattner682bf922009-03-29 16:50:03 +0000276 DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
277 return Actions.ConvertDeclToDeclGroup(TheDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +0000278 }
279
280 Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
281 ParseDeclarator(DeclaratorInfo);
282
Chris Lattner23c4b182009-03-29 17:18:04 +0000283 DeclGroupPtrTy DG =
284 ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
Chris Lattnercd147752009-03-29 17:27:48 +0000285
Chris Lattner97144fc2009-04-02 04:16:50 +0000286 DeclEnd = Tok.getLocation();
287
Chris Lattnercd147752009-03-29 17:27:48 +0000288 // If the client wants to check what comes after the declaration, just return
289 // immediately without checking anything!
290 if (!RequireSemi) return DG;
Chris Lattner23c4b182009-03-29 17:18:04 +0000291
292 if (Tok.is(tok::semi)) {
293 ConsumeToken();
Chris Lattner23c4b182009-03-29 17:18:04 +0000294 return DG;
295 }
296
Chris Lattner23c4b182009-03-29 17:18:04 +0000297 Diag(Tok, diag::err_expected_semi_declation);
298 // Skip to end of block or statement
299 SkipUntil(tok::r_brace, true, true);
300 if (Tok.is(tok::semi))
301 ConsumeToken();
302 return DG;
Reid Spencer5f016e22007-07-11 17:01:13 +0000303}
304
Chris Lattner8f08cb72007-08-25 06:57:03 +0000305
Reid Spencer5f016e22007-07-11 17:01:13 +0000306/// ParseInitDeclaratorListAfterFirstDeclarator - Parse 'declaration' after
307/// parsing 'declaration-specifiers declarator'. This method is split out this
308/// way to handle the ambiguity between top-level function-definitions and
309/// declarations.
310///
Reid Spencer5f016e22007-07-11 17:01:13 +0000311/// init-declarator-list: [C99 6.7]
312/// init-declarator
313/// init-declarator-list ',' init-declarator
314/// init-declarator: [C99 6.7]
315/// declarator
316/// declarator '=' initializer
317/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
318/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +0000319/// [C++] declarator initializer[opt]
320///
321/// [C++] initializer:
322/// [C++] '=' initializer-clause
323/// [C++] '(' expression-list ')'
Sebastian Redl50de12f2009-03-24 22:27:57 +0000324/// [C++0x] '=' 'default' [TODO]
325/// [C++0x] '=' 'delete'
326///
327/// According to the standard grammar, =default and =delete are function
328/// definitions, but that definitely doesn't fit with the parser here.
Reid Spencer5f016e22007-07-11 17:01:13 +0000329///
Chris Lattner682bf922009-03-29 16:50:03 +0000330Parser::DeclGroupPtrTy Parser::
Reid Spencer5f016e22007-07-11 17:01:13 +0000331ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
Chris Lattner682bf922009-03-29 16:50:03 +0000332 // Declarators may be grouped together ("int X, *Y, Z();"). Remember the decls
333 // that we parse together here.
334 llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
Reid Spencer5f016e22007-07-11 17:01:13 +0000335
336 // At this point, we know that it is not a function definition. Parse the
337 // rest of the init-declarator-list.
338 while (1) {
339 // If a simple-asm-expr is present, parse it.
Daniel Dunbara80f8742008-08-05 01:35:17 +0000340 if (Tok.is(tok::kw_asm)) {
Sebastian Redlab197ba2009-02-09 18:23:29 +0000341 SourceLocation Loc;
342 OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000343 if (AsmLabel.isInvalid()) {
Chris Lattner23c4b182009-03-29 17:18:04 +0000344 SkipUntil(tok::semi, true, true);
Chris Lattner682bf922009-03-29 16:50:03 +0000345 return DeclGroupPtrTy();
Daniel Dunbara80f8742008-08-05 01:35:17 +0000346 }
Sebastian Redlab197ba2009-02-09 18:23:29 +0000347
Sebastian Redleffa8d12008-12-10 00:02:53 +0000348 D.setAsmLabel(AsmLabel.release());
Sebastian Redlab197ba2009-02-09 18:23:29 +0000349 D.SetRangeEnd(Loc);
Daniel Dunbara80f8742008-08-05 01:35:17 +0000350 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000351
352 // If attributes are present, parse them.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000353 if (Tok.is(tok::kw___attribute)) {
354 SourceLocation Loc;
355 AttributeList *AttrList = ParseAttributes(&Loc);
356 D.AddAttributes(AttrList, Loc);
357 }
Steve Naroffbb204692007-09-12 14:07:44 +0000358
359 // Inform the current actions module that we just parsed this declarator.
Chris Lattner682bf922009-03-29 16:50:03 +0000360 DeclPtrTy ThisDecl = Actions.ActOnDeclarator(CurScope, D);
361 DeclsInGroup.push_back(ThisDecl);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000362
Reid Spencer5f016e22007-07-11 17:01:13 +0000363 // Parse declarator '=' initializer.
Chris Lattner04d66662007-10-09 17:33:22 +0000364 if (Tok.is(tok::equal)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000365 ConsumeToken();
Sebastian Redl50de12f2009-03-24 22:27:57 +0000366 if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
367 SourceLocation DelLoc = ConsumeToken();
Chris Lattner682bf922009-03-29 16:50:03 +0000368 Actions.SetDeclDeleted(ThisDecl, DelLoc);
Sebastian Redl50de12f2009-03-24 22:27:57 +0000369 } else {
370 OwningExprResult Init(ParseInitializer());
371 if (Init.isInvalid()) {
Chris Lattner23c4b182009-03-29 17:18:04 +0000372 SkipUntil(tok::semi, true, true);
Chris Lattner682bf922009-03-29 16:50:03 +0000373 return DeclGroupPtrTy();
Sebastian Redl50de12f2009-03-24 22:27:57 +0000374 }
Chris Lattner682bf922009-03-29 16:50:03 +0000375 Actions.AddInitializerToDecl(ThisDecl, move(Init));
Reid Spencer5f016e22007-07-11 17:01:13 +0000376 }
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +0000377 } else if (Tok.is(tok::l_paren)) {
378 // Parse C++ direct initializer: '(' expression-list ')'
379 SourceLocation LParenLoc = ConsumeParen();
Sebastian Redla55e52c2008-11-25 22:21:31 +0000380 ExprVector Exprs(Actions);
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +0000381 CommaLocsTy CommaLocs;
382
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +0000383 if (ParseExpressionList(Exprs, CommaLocs)) {
384 SkipUntil(tok::r_paren);
Chris Lattner8129edb2009-04-12 22:23:27 +0000385 } else {
386 // Match the ')'.
387 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +0000388
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +0000389 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
390 "Unexpected number of commas!");
Chris Lattner682bf922009-03-29 16:50:03 +0000391 Actions.AddCXXDirectInitializerToDecl(ThisDecl, LParenLoc,
Sebastian Redlf53597f2009-03-15 17:47:39 +0000392 move_arg(Exprs),
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +0000393 &CommaLocs[0], RParenLoc);
394 }
Douglas Gregor27c8dc02008-10-29 00:13:59 +0000395 } else {
Chris Lattner682bf922009-03-29 16:50:03 +0000396 Actions.ActOnUninitializedDecl(ThisDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +0000397 }
398
Reid Spencer5f016e22007-07-11 17:01:13 +0000399 // If we don't have a comma, it is either the end of the list (a ';') or an
400 // error, bail out.
Chris Lattner04d66662007-10-09 17:33:22 +0000401 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +0000402 break;
403
404 // Consume the comma.
405 ConsumeToken();
406
407 // Parse the next declarator.
408 D.clear();
Chris Lattneraab740a2008-10-20 04:57:38 +0000409
410 // Accept attributes in an init-declarator. In the first declarator in a
411 // declaration, these would be part of the declspec. In subsequent
412 // declarators, they become part of the declarator itself, so that they
413 // don't apply to declarators after *this* one. Examples:
414 // short __attribute__((common)) var; -> declspec
415 // short var __attribute__((common)); -> declarator
416 // short x, __attribute__((common)) var; -> declarator
Sebastian Redlab197ba2009-02-09 18:23:29 +0000417 if (Tok.is(tok::kw___attribute)) {
418 SourceLocation Loc;
419 AttributeList *AttrList = ParseAttributes(&Loc);
420 D.AddAttributes(AttrList, Loc);
421 }
Chris Lattneraab740a2008-10-20 04:57:38 +0000422
Reid Spencer5f016e22007-07-11 17:01:13 +0000423 ParseDeclarator(D);
424 }
425
Chris Lattner23c4b182009-03-29 17:18:04 +0000426 return Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0],
427 DeclsInGroup.size());
Reid Spencer5f016e22007-07-11 17:01:13 +0000428}
429
430/// ParseSpecifierQualifierList
431/// specifier-qualifier-list:
432/// type-specifier specifier-qualifier-list[opt]
433/// type-qualifier specifier-qualifier-list[opt]
434/// [GNU] attributes specifier-qualifier-list[opt]
435///
436void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
437 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
438 /// parse declaration-specifiers and complain about extra stuff.
Reid Spencer5f016e22007-07-11 17:01:13 +0000439 ParseDeclarationSpecifiers(DS);
440
441 // Validate declspec for type-name.
442 unsigned Specs = DS.getParsedSpecifiers();
Chris Lattnerb6645dd2009-04-14 21:16:09 +0000443 if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
444 !DS.getAttributes())
Reid Spencer5f016e22007-07-11 17:01:13 +0000445 Diag(Tok, diag::err_typename_requires_specqual);
446
447 // Issue diagnostic and remove storage class if present.
448 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
449 if (DS.getStorageClassSpecLoc().isValid())
450 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
451 else
452 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
453 DS.ClearStorageClassSpecs();
454 }
455
456 // Issue diagnostic and remove function specfier if present.
457 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregorb48fe382008-10-31 09:07:45 +0000458 if (DS.isInlineSpecified())
459 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
460 if (DS.isVirtualSpecified())
461 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
462 if (DS.isExplicitSpecified())
463 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
Reid Spencer5f016e22007-07-11 17:01:13 +0000464 DS.ClearFunctionSpecs();
465 }
466}
467
Chris Lattnerc199ab32009-04-12 20:42:31 +0000468/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
469/// specified token is valid after the identifier in a declarator which
470/// immediately follows the declspec. For example, these things are valid:
471///
472/// int x [ 4]; // direct-declarator
473/// int x ( int y); // direct-declarator
474/// int(int x ) // direct-declarator
475/// int x ; // simple-declaration
476/// int x = 17; // init-declarator-list
477/// int x , y; // init-declarator-list
478/// int x __asm__ ("foo"); // init-declarator-list
Chris Lattnerb6645dd2009-04-14 21:16:09 +0000479/// int x : 4; // struct-declarator
Chris Lattnerc83c27a2009-04-12 22:29:43 +0000480/// int x { 5}; // C++'0x unified initializers
Chris Lattnerc199ab32009-04-12 20:42:31 +0000481///
482/// This is not, because 'x' does not immediately follow the declspec (though
483/// ')' happens to be valid anyway).
484/// int (x)
485///
486static bool isValidAfterIdentifierInDeclarator(const Token &T) {
487 return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
488 T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
Chris Lattnerb6645dd2009-04-14 21:16:09 +0000489 T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
Chris Lattnerc199ab32009-04-12 20:42:31 +0000490}
491
Reid Spencer5f016e22007-07-11 17:01:13 +0000492/// ParseDeclarationSpecifiers
493/// declaration-specifiers: [C99 6.7]
494/// storage-class-specifier declaration-specifiers[opt]
495/// type-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +0000496/// [C99] function-specifier declaration-specifiers[opt]
497/// [GNU] attributes declaration-specifiers[opt]
498///
499/// storage-class-specifier: [C99 6.7.1]
500/// 'typedef'
501/// 'extern'
502/// 'static'
503/// 'auto'
504/// 'register'
Sebastian Redl669d5d72008-11-14 23:42:31 +0000505/// [C++] 'mutable'
Reid Spencer5f016e22007-07-11 17:01:13 +0000506/// [GNU] '__thread'
Reid Spencer5f016e22007-07-11 17:01:13 +0000507/// function-specifier: [C99 6.7.4]
508/// [C99] 'inline'
Douglas Gregorb48fe382008-10-31 09:07:45 +0000509/// [C++] 'virtual'
510/// [C++] 'explicit'
Reid Spencer5f016e22007-07-11 17:01:13 +0000511///
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +0000512void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000513 TemplateParameterLists *TemplateParams,
Chris Lattnerc199ab32009-04-12 20:42:31 +0000514 AccessSpecifier AS) {
Chris Lattner81c018d2008-03-13 06:29:04 +0000515 DS.SetRangeStart(Tok.getLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +0000516 while (1) {
517 int isInvalid = false;
518 const char *PrevSpec = 0;
519 SourceLocation Loc = Tok.getLocation();
Douglas Gregor12e083c2008-11-07 15:42:26 +0000520
Reid Spencer5f016e22007-07-11 17:01:13 +0000521 switch (Tok.getKind()) {
Douglas Gregor12e083c2008-11-07 15:42:26 +0000522 default:
Chris Lattnerbce61352008-07-26 00:20:22 +0000523 DoneWithDeclSpec:
Reid Spencer5f016e22007-07-11 17:01:13 +0000524 // If this is not a declaration specifier token, we're done reading decl
525 // specifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +0000526 DS.Finish(Diags, PP);
Reid Spencer5f016e22007-07-11 17:01:13 +0000527 return;
Chris Lattner5e02c472009-01-05 00:07:25 +0000528
529 case tok::coloncolon: // ::foo::bar
530 // Annotate C++ scope specifiers. If we get one, loop.
531 if (TryAnnotateCXXScopeToken())
532 continue;
533 goto DoneWithDeclSpec;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000534
535 case tok::annot_cxxscope: {
536 if (DS.hasTypeSpecifier())
537 goto DoneWithDeclSpec;
538
539 // We are looking for a qualified typename.
Douglas Gregor9135c722009-03-25 15:40:00 +0000540 Token Next = NextToken();
541 if (Next.is(tok::annot_template_id) &&
542 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
Douglas Gregorc45c2322009-03-31 00:43:58 +0000543 ->Kind == TNK_Type_template) {
Douglas Gregor9135c722009-03-25 15:40:00 +0000544 // We have a qualified template-id, e.g., N::A<int>
545 CXXScopeSpec SS;
546 ParseOptionalCXXScopeSpecifier(SS);
547 assert(Tok.is(tok::annot_template_id) &&
548 "ParseOptionalCXXScopeSpecifier not working");
549 AnnotateTemplateIdTokenAsType(&SS);
550 continue;
551 }
552
553 if (Next.isNot(tok::identifier))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000554 goto DoneWithDeclSpec;
555
556 CXXScopeSpec SS;
Douglas Gregor35073692009-03-26 23:56:24 +0000557 SS.setScopeRep(Tok.getAnnotationValue());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000558 SS.setRange(Tok.getAnnotationRange());
559
560 // If the next token is the name of the class type that the C++ scope
561 // denotes, followed by a '(', then this is a constructor declaration.
562 // We're done with the decl-specifiers.
563 if (Actions.isCurrentClassName(*NextToken().getIdentifierInfo(),
564 CurScope, &SS) &&
565 GetLookAheadToken(2).is(tok::l_paren))
566 goto DoneWithDeclSpec;
567
Douglas Gregorb696ea32009-02-04 17:00:24 +0000568 TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
569 Next.getLocation(), CurScope, &SS);
Douglas Gregor55f6b142009-02-09 18:46:07 +0000570
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000571 if (TypeRep == 0)
572 goto DoneWithDeclSpec;
Douglas Gregore4e5b052009-03-19 00:18:19 +0000573
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000574 ConsumeToken(); // The C++ scope.
575
Douglas Gregor1a51b4a2009-02-09 15:09:02 +0000576 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000577 TypeRep);
578 if (isInvalid)
579 break;
580
581 DS.SetRangeEnd(Tok.getLocation());
582 ConsumeToken(); // The typename.
583
584 continue;
585 }
Chris Lattner80d0c892009-01-21 19:48:37 +0000586
587 case tok::annot_typename: {
Douglas Gregor31a19b62009-04-01 21:51:26 +0000588 if (Tok.getAnnotationValue())
589 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
590 Tok.getAnnotationValue());
591 else
592 DS.SetTypeSpecError();
Chris Lattner80d0c892009-01-21 19:48:37 +0000593 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
594 ConsumeToken(); // The typename
595
596 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
597 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
598 // Objective-C interface. If we don't have Objective-C or a '<', this is
599 // just a normal reference to a typedef name.
600 if (!Tok.is(tok::less) || !getLang().ObjC1)
601 continue;
602
603 SourceLocation EndProtoLoc;
Chris Lattnerb28317a2009-03-28 19:18:32 +0000604 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Chris Lattner80d0c892009-01-21 19:48:37 +0000605 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
606 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
607
608 DS.SetRangeEnd(EndProtoLoc);
609 continue;
610 }
611
Chris Lattner3bd934a2008-07-26 01:18:38 +0000612 // typedef-name
613 case tok::identifier: {
Chris Lattner5e02c472009-01-05 00:07:25 +0000614 // In C++, check to see if this is a scope specifier like foo::bar::, if
615 // so handle it as such. This is important for ctor parsing.
Chris Lattner837acd02009-01-21 19:19:26 +0000616 if (getLang().CPlusPlus && TryAnnotateCXXScopeToken())
617 continue;
Chris Lattner5e02c472009-01-05 00:07:25 +0000618
Chris Lattner3bd934a2008-07-26 01:18:38 +0000619 // This identifier can only be a typedef name if we haven't already seen
620 // a type-specifier. Without this check we misparse:
621 // typedef int X; struct Y { short X; }; as 'short int'.
622 if (DS.hasTypeSpecifier())
623 goto DoneWithDeclSpec;
624
625 // It has to be available as a typedef too!
Douglas Gregorb696ea32009-02-04 17:00:24 +0000626 TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(),
627 Tok.getLocation(), CurScope);
Douglas Gregor55f6b142009-02-09 18:46:07 +0000628
Chris Lattnerc199ab32009-04-12 20:42:31 +0000629 // If this is not a typedef name, don't parse it as part of the declspec,
630 // it must be an implicit int or an error.
631 if (TypeRep == 0) {
632 // If we see an identifier that is not a type name, we normally would
633 // parse it as the identifer being declared. However, when a typename
634 // is typo'd or the definition is not included, this will incorrectly
635 // parse the typename as the identifier name and fall over misparsing
636 // later parts of the diagnostic.
637 //
638 // As such, we try to do some look-ahead in cases where this would
639 // otherwise be an "implicit-int" case to see if this is invalid. For
640 // example: "static foo_t x = 4;" In this case, if we parsed foo_t as
641 // an identifier with implicit int, we'd get a parse error because the
642 // next token is obviously invalid for a type. Parse these as a case
643 // with an invalid type specifier.
644 assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
645
646 // Since we know that this either implicit int (which is rare) or an
647 // error, we'd do lookahead to try to do better recovery.
648 if (isValidAfterIdentifierInDeclarator(NextToken())) {
649 // If this token is valid for implicit int, e.g. "static x = 4", then
650 // we just avoid eating the identifier, so it will be parsed as the
651 // identifier in the declarator.
652 goto DoneWithDeclSpec;
653 }
654
655 // Otherwise, if we don't consume this token, we are going to emit an
Chris Lattner4c97d762009-04-12 21:49:30 +0000656 // error anyway. Try to recover from various common problems. Check
657 // to see if this was a reference to a tag name without a tag specified.
Chris Lattner51172d12009-04-12 22:30:22 +0000658 // This is a common problem in C (saying 'foo' instead of 'struct foo').
Chris Lattner4c97d762009-04-12 21:49:30 +0000659 const char *TagName = 0;
660 tok::TokenKind TagKind = tok::unknown;
661
662 switch (Actions.isTagName(*Tok.getIdentifierInfo(), CurScope)) {
663 default: break;
664 case DeclSpec::TST_enum: TagName="enum" ;TagKind=tok::kw_enum ;break;
665 case DeclSpec::TST_union: TagName="union" ;TagKind=tok::kw_union ;break;
666 case DeclSpec::TST_struct:TagName="struct";TagKind=tok::kw_struct;break;
667 case DeclSpec::TST_class: TagName="class" ;TagKind=tok::kw_class ;break;
668 }
669 if (TagName) {
670 Diag(Loc, diag::err_use_of_tag_name_without_tag)
671 << Tok.getIdentifierInfo() << TagName
672 << CodeModificationHint::CreateInsertion(Tok.getLocation(),TagName);
673
674 // Parse this as a tag as if the missing tag were present.
675 if (TagKind == tok::kw_enum)
676 ParseEnumSpecifier(Loc, DS, AS);
677 else
678 ParseClassSpecifier(TagKind, Loc, DS, TemplateParams, AS);
679 continue;
680 }
681
682 // Since this is almost certainly an invalid type name, emit a
Chris Lattner33c6ebe2009-04-12 22:12:26 +0000683 // diagnostic that says it, eat the token, and mark the declspec as
684 // invalid.
Chris Lattnerc199ab32009-04-12 20:42:31 +0000685 Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo();
Chris Lattner33c6ebe2009-04-12 22:12:26 +0000686 DS.SetTypeSpecType(DeclSpec::TST_error, Loc, PrevSpec);
Chris Lattnerc199ab32009-04-12 20:42:31 +0000687 DS.SetRangeEnd(Tok.getLocation());
688 ConsumeToken();
689
Chris Lattnerc199ab32009-04-12 20:42:31 +0000690 // TODO: Could inject an invalid typedef decl in an enclosing scope to
691 // avoid rippling error messages on subsequent uses of the same type,
692 // could be useful if #include was forgotten.
693
Chris Lattner3bd934a2008-07-26 01:18:38 +0000694 goto DoneWithDeclSpec;
Chris Lattnerc199ab32009-04-12 20:42:31 +0000695 }
Douglas Gregor55f6b142009-02-09 18:46:07 +0000696
Douglas Gregorb48fe382008-10-31 09:07:45 +0000697 // C++: If the identifier is actually the name of the class type
698 // being defined and the next token is a '(', then this is a
699 // constructor declaration. We're done with the decl-specifiers
700 // and will treat this token as an identifier.
Chris Lattnerc199ab32009-04-12 20:42:31 +0000701 if (getLang().CPlusPlus && CurScope->isClassScope() &&
Douglas Gregorb48fe382008-10-31 09:07:45 +0000702 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) &&
703 NextToken().getKind() == tok::l_paren)
704 goto DoneWithDeclSpec;
705
Douglas Gregor1a51b4a2009-02-09 15:09:02 +0000706 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Chris Lattner3bd934a2008-07-26 01:18:38 +0000707 TypeRep);
708 if (isInvalid)
709 break;
710
711 DS.SetRangeEnd(Tok.getLocation());
712 ConsumeToken(); // The identifier
713
714 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
715 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
716 // Objective-C interface. If we don't have Objective-C or a '<', this is
717 // just a normal reference to a typedef name.
718 if (!Tok.is(tok::less) || !getLang().ObjC1)
719 continue;
720
721 SourceLocation EndProtoLoc;
Chris Lattnerb28317a2009-03-28 19:18:32 +0000722 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Chris Lattnere13b9592008-07-26 04:03:38 +0000723 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Chris Lattnerae4da612008-07-26 01:53:50 +0000724 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
Chris Lattner3bd934a2008-07-26 01:18:38 +0000725
726 DS.SetRangeEnd(EndProtoLoc);
727
Steve Naroff4f9b9f12008-09-22 10:28:57 +0000728 // Need to support trailing type qualifiers (e.g. "id<p> const").
729 // If a type specifier follows, it will be diagnosed elsewhere.
730 continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +0000731 }
Douglas Gregor39a8de12009-02-25 19:37:18 +0000732
733 // type-name
734 case tok::annot_template_id: {
735 TemplateIdAnnotation *TemplateId
736 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
Douglas Gregorc45c2322009-03-31 00:43:58 +0000737 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor39a8de12009-02-25 19:37:18 +0000738 // This template-id does not refer to a type name, so we're
739 // done with the type-specifiers.
740 goto DoneWithDeclSpec;
741 }
742
743 // Turn the template-id annotation token into a type annotation
744 // token, then try again to parse it as a type-specifier.
Douglas Gregor31a19b62009-04-01 21:51:26 +0000745 AnnotateTemplateIdTokenAsType();
Douglas Gregor39a8de12009-02-25 19:37:18 +0000746 continue;
747 }
748
Reid Spencer5f016e22007-07-11 17:01:13 +0000749 // GNU attributes support.
750 case tok::kw___attribute:
751 DS.AddAttributes(ParseAttributes());
752 continue;
Steve Narofff59e17e2008-12-24 20:59:21 +0000753
754 // Microsoft declspec support.
755 case tok::kw___declspec:
756 if (!PP.getLangOptions().Microsoft)
757 goto DoneWithDeclSpec;
758 FuzzyParseMicrosoftDeclSpec();
759 continue;
Reid Spencer5f016e22007-07-11 17:01:13 +0000760
Steve Naroff239f0732008-12-25 14:16:32 +0000761 // Microsoft single token adornments.
Steve Naroff86bc6cf2008-12-25 14:41:26 +0000762 case tok::kw___forceinline:
763 case tok::kw___w64:
Steve Naroff239f0732008-12-25 14:16:32 +0000764 case tok::kw___cdecl:
765 case tok::kw___stdcall:
766 case tok::kw___fastcall:
767 if (!PP.getLangOptions().Microsoft)
768 goto DoneWithDeclSpec;
769 // Just ignore it.
770 break;
771
Reid Spencer5f016e22007-07-11 17:01:13 +0000772 // storage-class-specifier
773 case tok::kw_typedef:
774 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
775 break;
776 case tok::kw_extern:
777 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +0000778 Diag(Tok, diag::ext_thread_before) << "extern";
Reid Spencer5f016e22007-07-11 17:01:13 +0000779 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec);
780 break;
Steve Naroff8d54bf22007-12-18 00:16:02 +0000781 case tok::kw___private_extern__:
Chris Lattnerf97409f2008-04-06 06:57:35 +0000782 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
783 PrevSpec);
Steve Naroff8d54bf22007-12-18 00:16:02 +0000784 break;
Reid Spencer5f016e22007-07-11 17:01:13 +0000785 case tok::kw_static:
786 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +0000787 Diag(Tok, diag::ext_thread_before) << "static";
Reid Spencer5f016e22007-07-11 17:01:13 +0000788 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
789 break;
790 case tok::kw_auto:
791 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
792 break;
793 case tok::kw_register:
794 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
795 break;
Sebastian Redl669d5d72008-11-14 23:42:31 +0000796 case tok::kw_mutable:
797 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec);
798 break;
Reid Spencer5f016e22007-07-11 17:01:13 +0000799 case tok::kw___thread:
800 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec)*2;
801 break;
Douglas Gregor12e083c2008-11-07 15:42:26 +0000802
Reid Spencer5f016e22007-07-11 17:01:13 +0000803 // function-specifier
804 case tok::kw_inline:
805 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec);
806 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +0000807 case tok::kw_virtual:
808 isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec);
809 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +0000810 case tok::kw_explicit:
811 isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec);
812 break;
Chris Lattner80d0c892009-01-21 19:48:37 +0000813
814 // type-specifier
815 case tok::kw_short:
816 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
817 break;
818 case tok::kw_long:
819 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
820 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
821 else
822 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
823 break;
824 case tok::kw_signed:
825 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
826 break;
827 case tok::kw_unsigned:
828 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
829 break;
830 case tok::kw__Complex:
831 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
832 break;
833 case tok::kw__Imaginary:
834 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
835 break;
836 case tok::kw_void:
837 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
838 break;
839 case tok::kw_char:
840 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
841 break;
842 case tok::kw_int:
843 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
844 break;
845 case tok::kw_float:
846 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
847 break;
848 case tok::kw_double:
849 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
850 break;
851 case tok::kw_wchar_t:
852 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
853 break;
854 case tok::kw_bool:
855 case tok::kw__Bool:
856 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
857 break;
858 case tok::kw__Decimal32:
859 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
860 break;
861 case tok::kw__Decimal64:
862 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
863 break;
864 case tok::kw__Decimal128:
865 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
866 break;
867
868 // class-specifier:
869 case tok::kw_class:
870 case tok::kw_struct:
Chris Lattner4c97d762009-04-12 21:49:30 +0000871 case tok::kw_union: {
872 tok::TokenKind Kind = Tok.getKind();
873 ConsumeToken();
874 ParseClassSpecifier(Kind, Loc, DS, TemplateParams, AS);
Chris Lattner80d0c892009-01-21 19:48:37 +0000875 continue;
Chris Lattner4c97d762009-04-12 21:49:30 +0000876 }
Chris Lattner80d0c892009-01-21 19:48:37 +0000877
878 // enum-specifier:
879 case tok::kw_enum:
Chris Lattner4c97d762009-04-12 21:49:30 +0000880 ConsumeToken();
881 ParseEnumSpecifier(Loc, DS, AS);
Chris Lattner80d0c892009-01-21 19:48:37 +0000882 continue;
883
884 // cv-qualifier:
885 case tok::kw_const:
886 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec,getLang())*2;
887 break;
888 case tok::kw_volatile:
889 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
890 getLang())*2;
891 break;
892 case tok::kw_restrict:
893 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
894 getLang())*2;
895 break;
896
Douglas Gregord57959a2009-03-27 23:10:48 +0000897 // C++ typename-specifier:
898 case tok::kw_typename:
899 if (TryAnnotateTypeOrScopeToken())
900 continue;
901 break;
902
Chris Lattner80d0c892009-01-21 19:48:37 +0000903 // GNU typeof support.
904 case tok::kw_typeof:
905 ParseTypeofSpecifier(DS);
906 continue;
907
Steve Naroffd3ded1f2008-06-05 00:02:44 +0000908 case tok::less:
Chris Lattner3bd934a2008-07-26 01:18:38 +0000909 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerbce61352008-07-26 00:20:22 +0000910 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
911 // but we support it.
Chris Lattner3bd934a2008-07-26 01:18:38 +0000912 if (DS.hasTypeSpecifier() || !getLang().ObjC1)
Chris Lattnerbce61352008-07-26 00:20:22 +0000913 goto DoneWithDeclSpec;
914
915 {
916 SourceLocation EndProtoLoc;
Chris Lattnerb28317a2009-03-28 19:18:32 +0000917 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Chris Lattnere13b9592008-07-26 04:03:38 +0000918 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Chris Lattnerae4da612008-07-26 01:53:50 +0000919 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
Chris Lattner3bd934a2008-07-26 01:18:38 +0000920 DS.SetRangeEnd(EndProtoLoc);
921
Chris Lattner1ab3b962008-11-18 07:48:38 +0000922 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
Chris Lattner75e36062009-04-03 18:38:42 +0000923 << CodeModificationHint::CreateInsertion(Loc, "id")
Chris Lattner1ab3b962008-11-18 07:48:38 +0000924 << SourceRange(Loc, EndProtoLoc);
Steve Naroff4f9b9f12008-09-22 10:28:57 +0000925 // Need to support trailing type qualifiers (e.g. "id<p> const").
926 // If a type specifier follows, it will be diagnosed elsewhere.
927 continue;
Steve Naroffd3ded1f2008-06-05 00:02:44 +0000928 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000929 }
930 // If the specifier combination wasn't legal, issue a diagnostic.
931 if (isInvalid) {
932 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +0000933 // Pick between error or extwarn.
934 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
935 : diag::ext_duplicate_declspec;
936 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +0000937 }
Chris Lattner81c018d2008-03-13 06:29:04 +0000938 DS.SetRangeEnd(Tok.getLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +0000939 ConsumeToken();
940 }
941}
Douglas Gregoradcac882008-12-01 23:54:00 +0000942
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000943/// ParseOptionalTypeSpecifier - Try to parse a single type-specifier. We
Douglas Gregor12e083c2008-11-07 15:42:26 +0000944/// primarily follow the C++ grammar with additions for C99 and GNU,
945/// which together subsume the C grammar. Note that the C++
946/// type-specifier also includes the C type-qualifier (for const,
947/// volatile, and C99 restrict). Returns true if a type-specifier was
948/// found (and parsed), false otherwise.
949///
950/// type-specifier: [C++ 7.1.5]
951/// simple-type-specifier
952/// class-specifier
953/// enum-specifier
954/// elaborated-type-specifier [TODO]
955/// cv-qualifier
956///
957/// cv-qualifier: [C++ 7.1.5.1]
958/// 'const'
959/// 'volatile'
960/// [C99] 'restrict'
961///
962/// simple-type-specifier: [ C++ 7.1.5.2]
963/// '::'[opt] nested-name-specifier[opt] type-name [TODO]
964/// '::'[opt] nested-name-specifier 'template' template-id [TODO]
965/// 'char'
966/// 'wchar_t'
967/// 'bool'
968/// 'short'
969/// 'int'
970/// 'long'
971/// 'signed'
972/// 'unsigned'
973/// 'float'
974/// 'double'
975/// 'void'
976/// [C99] '_Bool'
977/// [C99] '_Complex'
978/// [C99] '_Imaginary' // Removed in TC2?
979/// [GNU] '_Decimal32'
980/// [GNU] '_Decimal64'
981/// [GNU] '_Decimal128'
982/// [GNU] typeof-specifier
983/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
984/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000985bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
986 const char *&PrevSpec,
987 TemplateParameterLists *TemplateParams){
Douglas Gregor12e083c2008-11-07 15:42:26 +0000988 SourceLocation Loc = Tok.getLocation();
989
990 switch (Tok.getKind()) {
Chris Lattner166a8fc2009-01-04 23:41:41 +0000991 case tok::identifier: // foo::bar
Douglas Gregord57959a2009-03-27 23:10:48 +0000992 case tok::kw_typename: // typename foo::bar
Chris Lattner166a8fc2009-01-04 23:41:41 +0000993 // Annotate typenames and C++ scope specifiers. If we get one, just
994 // recurse to handle whatever we get.
995 if (TryAnnotateTypeOrScopeToken())
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000996 return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec,TemplateParams);
Chris Lattner166a8fc2009-01-04 23:41:41 +0000997 // Otherwise, not a type specifier.
998 return false;
999 case tok::coloncolon: // ::foo::bar
1000 if (NextToken().is(tok::kw_new) || // ::new
1001 NextToken().is(tok::kw_delete)) // ::delete
1002 return false;
1003
1004 // Annotate typenames and C++ scope specifiers. If we get one, just
1005 // recurse to handle whatever we get.
1006 if (TryAnnotateTypeOrScopeToken())
Chris Lattner7a0ab5f2009-01-06 06:59:53 +00001007 return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec,TemplateParams);
Chris Lattner166a8fc2009-01-04 23:41:41 +00001008 // Otherwise, not a type specifier.
1009 return false;
1010
Douglas Gregor12e083c2008-11-07 15:42:26 +00001011 // simple-type-specifier:
Chris Lattnerb31757b2009-01-06 05:06:21 +00001012 case tok::annot_typename: {
Douglas Gregor31a19b62009-04-01 21:51:26 +00001013 if (Tok.getAnnotationValue())
1014 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
1015 Tok.getAnnotationValue());
1016 else
1017 DS.SetTypeSpecError();
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001018 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
1019 ConsumeToken(); // The typename
Douglas Gregor12e083c2008-11-07 15:42:26 +00001020
1021 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
1022 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
1023 // Objective-C interface. If we don't have Objective-C or a '<', this is
1024 // just a normal reference to a typedef name.
1025 if (!Tok.is(tok::less) || !getLang().ObjC1)
1026 return true;
1027
1028 SourceLocation EndProtoLoc;
Chris Lattnerb28317a2009-03-28 19:18:32 +00001029 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Douglas Gregor12e083c2008-11-07 15:42:26 +00001030 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
1031 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
1032
1033 DS.SetRangeEnd(EndProtoLoc);
1034 return true;
1035 }
1036
1037 case tok::kw_short:
1038 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
1039 break;
1040 case tok::kw_long:
1041 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
1042 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
1043 else
1044 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
1045 break;
1046 case tok::kw_signed:
1047 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
1048 break;
1049 case tok::kw_unsigned:
1050 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
1051 break;
1052 case tok::kw__Complex:
1053 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
1054 break;
1055 case tok::kw__Imaginary:
1056 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
1057 break;
1058 case tok::kw_void:
1059 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
1060 break;
1061 case tok::kw_char:
1062 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
1063 break;
1064 case tok::kw_int:
1065 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
1066 break;
1067 case tok::kw_float:
1068 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
1069 break;
1070 case tok::kw_double:
1071 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
1072 break;
1073 case tok::kw_wchar_t:
1074 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
1075 break;
1076 case tok::kw_bool:
1077 case tok::kw__Bool:
1078 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
1079 break;
1080 case tok::kw__Decimal32:
1081 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
1082 break;
1083 case tok::kw__Decimal64:
1084 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
1085 break;
1086 case tok::kw__Decimal128:
1087 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
1088 break;
1089
1090 // class-specifier:
1091 case tok::kw_class:
1092 case tok::kw_struct:
Chris Lattner4c97d762009-04-12 21:49:30 +00001093 case tok::kw_union: {
1094 tok::TokenKind Kind = Tok.getKind();
1095 ConsumeToken();
1096 ParseClassSpecifier(Kind, Loc, DS, TemplateParams);
Douglas Gregor12e083c2008-11-07 15:42:26 +00001097 return true;
Chris Lattner4c97d762009-04-12 21:49:30 +00001098 }
Douglas Gregor12e083c2008-11-07 15:42:26 +00001099
1100 // enum-specifier:
1101 case tok::kw_enum:
Chris Lattner4c97d762009-04-12 21:49:30 +00001102 ConsumeToken();
1103 ParseEnumSpecifier(Loc, DS);
Douglas Gregor12e083c2008-11-07 15:42:26 +00001104 return true;
1105
1106 // cv-qualifier:
1107 case tok::kw_const:
1108 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
1109 getLang())*2;
1110 break;
1111 case tok::kw_volatile:
1112 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
1113 getLang())*2;
1114 break;
1115 case tok::kw_restrict:
1116 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
1117 getLang())*2;
1118 break;
1119
1120 // GNU typeof support.
1121 case tok::kw_typeof:
1122 ParseTypeofSpecifier(DS);
1123 return true;
1124
Steve Naroff239f0732008-12-25 14:16:32 +00001125 case tok::kw___cdecl:
1126 case tok::kw___stdcall:
1127 case tok::kw___fastcall:
Chris Lattner837acd02009-01-21 19:19:26 +00001128 if (!PP.getLangOptions().Microsoft) return false;
1129 ConsumeToken();
1130 return true;
Steve Naroff239f0732008-12-25 14:16:32 +00001131
Douglas Gregor12e083c2008-11-07 15:42:26 +00001132 default:
1133 // Not a type-specifier; do nothing.
1134 return false;
1135 }
1136
1137 // If the specifier combination wasn't legal, issue a diagnostic.
1138 if (isInvalid) {
1139 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +00001140 // Pick between error or extwarn.
1141 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
1142 : diag::ext_duplicate_declspec;
1143 Diag(Tok, DiagID) << PrevSpec;
Douglas Gregor12e083c2008-11-07 15:42:26 +00001144 }
1145 DS.SetRangeEnd(Tok.getLocation());
1146 ConsumeToken(); // whatever we parsed above.
1147 return true;
1148}
Reid Spencer5f016e22007-07-11 17:01:13 +00001149
Chris Lattnercd4b83c2007-10-29 04:42:53 +00001150/// ParseStructDeclaration - Parse a struct declaration without the terminating
1151/// semicolon.
1152///
Reid Spencer5f016e22007-07-11 17:01:13 +00001153/// struct-declaration:
Chris Lattnercd4b83c2007-10-29 04:42:53 +00001154/// specifier-qualifier-list struct-declarator-list
Reid Spencer5f016e22007-07-11 17:01:13 +00001155/// [GNU] __extension__ struct-declaration
Chris Lattnercd4b83c2007-10-29 04:42:53 +00001156/// [GNU] specifier-qualifier-list
Reid Spencer5f016e22007-07-11 17:01:13 +00001157/// struct-declarator-list:
1158/// struct-declarator
1159/// struct-declarator-list ',' struct-declarator
1160/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
1161/// struct-declarator:
1162/// declarator
1163/// [GNU] declarator attributes[opt]
1164/// declarator[opt] ':' constant-expression
1165/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
1166///
Chris Lattnere1359422008-04-10 06:46:29 +00001167void Parser::
1168ParseStructDeclaration(DeclSpec &DS,
1169 llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
Chris Lattnerc46d1a12008-10-20 06:45:43 +00001170 if (Tok.is(tok::kw___extension__)) {
1171 // __extension__ silences extension warnings in the subexpression.
1172 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroff28a7ca82007-08-20 22:28:22 +00001173 ConsumeToken();
Chris Lattnerc46d1a12008-10-20 06:45:43 +00001174 return ParseStructDeclaration(DS, Fields);
1175 }
Steve Naroff28a7ca82007-08-20 22:28:22 +00001176
1177 // Parse the common specifier-qualifiers-list piece.
Chris Lattner60b1e3e2008-04-10 06:15:14 +00001178 SourceLocation DSStart = Tok.getLocation();
Steve Naroff28a7ca82007-08-20 22:28:22 +00001179 ParseSpecifierQualifierList(DS);
Steve Naroff28a7ca82007-08-20 22:28:22 +00001180
Douglas Gregor4920f1f2009-01-12 22:49:06 +00001181 // If there are no declarators, this is a free-standing declaration
1182 // specifier. Let the actions module cope with it.
Chris Lattner04d66662007-10-09 17:33:22 +00001183 if (Tok.is(tok::semi)) {
Douglas Gregor4920f1f2009-01-12 22:49:06 +00001184 Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
Steve Naroff28a7ca82007-08-20 22:28:22 +00001185 return;
1186 }
1187
1188 // Read struct-declarators until we find the semicolon.
Chris Lattnerebe457c2008-04-10 16:37:40 +00001189 Fields.push_back(FieldDeclarator(DS));
Steve Naroff28a7ca82007-08-20 22:28:22 +00001190 while (1) {
Chris Lattnere1359422008-04-10 06:46:29 +00001191 FieldDeclarator &DeclaratorInfo = Fields.back();
1192
Steve Naroff28a7ca82007-08-20 22:28:22 +00001193 /// struct-declarator: declarator
1194 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattner04d66662007-10-09 17:33:22 +00001195 if (Tok.isNot(tok::colon))
Chris Lattnere1359422008-04-10 06:46:29 +00001196 ParseDeclarator(DeclaratorInfo.D);
Steve Naroff28a7ca82007-08-20 22:28:22 +00001197
Chris Lattner04d66662007-10-09 17:33:22 +00001198 if (Tok.is(tok::colon)) {
Steve Naroff28a7ca82007-08-20 22:28:22 +00001199 ConsumeToken();
Sebastian Redl2f7ece72008-12-11 21:36:32 +00001200 OwningExprResult Res(ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001201 if (Res.isInvalid())
Steve Naroff28a7ca82007-08-20 22:28:22 +00001202 SkipUntil(tok::semi, true, true);
Chris Lattner60b1e3e2008-04-10 06:15:14 +00001203 else
Sebastian Redleffa8d12008-12-10 00:02:53 +00001204 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroff28a7ca82007-08-20 22:28:22 +00001205 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00001206
Steve Naroff28a7ca82007-08-20 22:28:22 +00001207 // If attributes exist after the declarator, parse them.
Sebastian Redlab197ba2009-02-09 18:23:29 +00001208 if (Tok.is(tok::kw___attribute)) {
1209 SourceLocation Loc;
1210 AttributeList *AttrList = ParseAttributes(&Loc);
1211 DeclaratorInfo.D.AddAttributes(AttrList, Loc);
1212 }
1213
Steve Naroff28a7ca82007-08-20 22:28:22 +00001214 // If we don't have a comma, it is either the end of the list (a ';')
1215 // or an error, bail out.
Chris Lattner04d66662007-10-09 17:33:22 +00001216 if (Tok.isNot(tok::comma))
Chris Lattnercd4b83c2007-10-29 04:42:53 +00001217 return;
Sebastian Redlab197ba2009-02-09 18:23:29 +00001218
Steve Naroff28a7ca82007-08-20 22:28:22 +00001219 // Consume the comma.
1220 ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00001221
Steve Naroff28a7ca82007-08-20 22:28:22 +00001222 // Parse the next declarator.
Chris Lattnerebe457c2008-04-10 16:37:40 +00001223 Fields.push_back(FieldDeclarator(DS));
Sebastian Redlab197ba2009-02-09 18:23:29 +00001224
Steve Naroff28a7ca82007-08-20 22:28:22 +00001225 // Attributes are only allowed on the second declarator.
Sebastian Redlab197ba2009-02-09 18:23:29 +00001226 if (Tok.is(tok::kw___attribute)) {
1227 SourceLocation Loc;
1228 AttributeList *AttrList = ParseAttributes(&Loc);
1229 Fields.back().D.AddAttributes(AttrList, Loc);
1230 }
Steve Naroff28a7ca82007-08-20 22:28:22 +00001231 }
Steve Naroff28a7ca82007-08-20 22:28:22 +00001232}
1233
1234/// ParseStructUnionBody
1235/// struct-contents:
1236/// struct-declaration-list
1237/// [EXT] empty
1238/// [GNU] "struct-declaration-list" without terminatoring ';'
1239/// struct-declaration-list:
1240/// struct-declaration
1241/// struct-declaration-list struct-declaration
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00001242/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroff28a7ca82007-08-20 22:28:22 +00001243///
Reid Spencer5f016e22007-07-11 17:01:13 +00001244void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +00001245 unsigned TagType, DeclPtrTy TagDecl) {
Chris Lattner49f28ca2009-03-05 08:00:35 +00001246 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
1247 PP.getSourceManager(),
1248 "parsing struct/union body");
Chris Lattner27b7f102009-03-05 02:25:03 +00001249
Reid Spencer5f016e22007-07-11 17:01:13 +00001250 SourceLocation LBraceLoc = ConsumeBrace();
1251
Douglas Gregor3218c4b2009-01-09 22:42:13 +00001252 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregor72de6672009-01-08 20:45:30 +00001253 Actions.ActOnTagStartDefinition(CurScope, TagDecl);
1254
Reid Spencer5f016e22007-07-11 17:01:13 +00001255 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
1256 // C++.
Douglas Gregore37ac4f2008-04-13 21:30:24 +00001257 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattner1ab3b962008-11-18 07:48:38 +00001258 Diag(Tok, diag::ext_empty_struct_union_enum)
1259 << DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
Reid Spencer5f016e22007-07-11 17:01:13 +00001260
Chris Lattnerb28317a2009-03-28 19:18:32 +00001261 llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
Chris Lattnere1359422008-04-10 06:46:29 +00001262 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
1263
Reid Spencer5f016e22007-07-11 17:01:13 +00001264 // While we still have something to read, read the declarations in the struct.
Chris Lattner04d66662007-10-09 17:33:22 +00001265 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001266 // Each iteration of this loop reads one struct-declaration.
1267
1268 // Check for extraneous top-level semicolon.
Chris Lattner04d66662007-10-09 17:33:22 +00001269 if (Tok.is(tok::semi)) {
Douglas Gregor9b3064b2009-04-01 22:41:11 +00001270 Diag(Tok, diag::ext_extra_struct_semi)
1271 << CodeModificationHint::CreateRemoval(SourceRange(Tok.getLocation()));
Reid Spencer5f016e22007-07-11 17:01:13 +00001272 ConsumeToken();
1273 continue;
1274 }
Chris Lattnere1359422008-04-10 06:46:29 +00001275
1276 // Parse all the comma separated declarators.
1277 DeclSpec DS;
1278 FieldDeclarators.clear();
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00001279 if (!Tok.is(tok::at)) {
1280 ParseStructDeclaration(DS, FieldDeclarators);
1281
1282 // Convert them all to fields.
1283 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
1284 FieldDeclarator &FD = FieldDeclarators[i];
1285 // Install the declarator into the current TagDecl.
Chris Lattnerb28317a2009-03-28 19:18:32 +00001286 DeclPtrTy Field = Actions.ActOnField(CurScope, TagDecl,
1287 DS.getSourceRange().getBegin(),
1288 FD.D, FD.BitfieldSize);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00001289 FieldDecls.push_back(Field);
1290 }
1291 } else { // Handle @defs
1292 ConsumeToken();
1293 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
1294 Diag(Tok, diag::err_unexpected_at);
1295 SkipUntil(tok::semi, true, true);
1296 continue;
1297 }
1298 ConsumeToken();
1299 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
1300 if (!Tok.is(tok::identifier)) {
1301 Diag(Tok, diag::err_expected_ident);
1302 SkipUntil(tok::semi, true, true);
1303 continue;
1304 }
Chris Lattnerb28317a2009-03-28 19:18:32 +00001305 llvm::SmallVector<DeclPtrTy, 16> Fields;
Douglas Gregor44b43212008-12-11 16:49:14 +00001306 Actions.ActOnDefs(CurScope, TagDecl, Tok.getLocation(),
1307 Tok.getIdentifierInfo(), Fields);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00001308 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
1309 ConsumeToken();
1310 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
1311 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001312
Chris Lattner04d66662007-10-09 17:33:22 +00001313 if (Tok.is(tok::semi)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001314 ConsumeToken();
Chris Lattner04d66662007-10-09 17:33:22 +00001315 } else if (Tok.is(tok::r_brace)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00001316 Diag(Tok, diag::ext_expected_semi_decl_list);
Reid Spencer5f016e22007-07-11 17:01:13 +00001317 break;
1318 } else {
1319 Diag(Tok, diag::err_expected_semi_decl_list);
1320 // Skip to end of block or statement
1321 SkipUntil(tok::r_brace, true, true);
1322 }
1323 }
1324
Steve Naroff60fccee2007-10-29 21:38:07 +00001325 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +00001326
Reid Spencer5f016e22007-07-11 17:01:13 +00001327 AttributeList *AttrList = 0;
1328 // If attributes exist after struct contents, parse them.
Chris Lattner04d66662007-10-09 17:33:22 +00001329 if (Tok.is(tok::kw___attribute))
Daniel Dunbar5e592d82008-10-03 16:42:10 +00001330 AttrList = ParseAttributes();
Daniel Dunbar1bfe1c22008-10-03 02:03:53 +00001331
1332 Actions.ActOnFields(CurScope,
1333 RecordLoc,TagDecl,&FieldDecls[0],FieldDecls.size(),
1334 LBraceLoc, RBraceLoc,
Douglas Gregor72de6672009-01-08 20:45:30 +00001335 AttrList);
1336 StructScope.Exit();
1337 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +00001338}
1339
1340
1341/// ParseEnumSpecifier
1342/// enum-specifier: [C99 6.7.2.2]
1343/// 'enum' identifier[opt] '{' enumerator-list '}'
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001344///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00001345/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
1346/// '}' attributes[opt]
1347/// 'enum' identifier
1348/// [GNU] 'enum' attributes[opt] identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001349///
1350/// [C++] elaborated-type-specifier:
1351/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
1352///
Chris Lattner4c97d762009-04-12 21:49:30 +00001353void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
1354 AccessSpecifier AS) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001355 // Parse the tag portion of this.
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00001356
1357 AttributeList *Attr = 0;
1358 // If attributes exist after tag, parse them.
1359 if (Tok.is(tok::kw___attribute))
1360 Attr = ParseAttributes();
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001361
1362 CXXScopeSpec SS;
Chris Lattner7a0ab5f2009-01-06 06:59:53 +00001363 if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS)) {
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001364 if (Tok.isNot(tok::identifier)) {
1365 Diag(Tok, diag::err_expected_ident);
1366 if (Tok.isNot(tok::l_brace)) {
1367 // Has no name and is not a definition.
1368 // Skip the rest of this declarator, up until the comma or semicolon.
1369 SkipUntil(tok::comma, true);
1370 return;
1371 }
1372 }
1373 }
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00001374
1375 // Must have either 'enum name' or 'enum {...}'.
1376 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) {
1377 Diag(Tok, diag::err_expected_ident_lbrace);
1378
1379 // Skip the rest of this declarator, up until the comma or semicolon.
1380 SkipUntil(tok::comma, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00001381 return;
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00001382 }
1383
1384 // If an identifier is present, consume and remember it.
1385 IdentifierInfo *Name = 0;
1386 SourceLocation NameLoc;
1387 if (Tok.is(tok::identifier)) {
1388 Name = Tok.getIdentifierInfo();
1389 NameLoc = ConsumeToken();
1390 }
1391
1392 // There are three options here. If we have 'enum foo;', then this is a
1393 // forward declaration. If we have 'enum foo {...' then this is a
1394 // definition. Otherwise we have something like 'enum foo xyz', a reference.
1395 //
1396 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
1397 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
1398 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
1399 //
1400 Action::TagKind TK;
1401 if (Tok.is(tok::l_brace))
1402 TK = Action::TK_Definition;
1403 else if (Tok.is(tok::semi))
1404 TK = Action::TK_Declaration;
1405 else
1406 TK = Action::TK_Reference;
Chris Lattnerb28317a2009-03-28 19:18:32 +00001407 DeclPtrTy TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK,
1408 StartLoc, SS, Name, NameLoc, Attr, AS);
Reid Spencer5f016e22007-07-11 17:01:13 +00001409
Chris Lattner04d66662007-10-09 17:33:22 +00001410 if (Tok.is(tok::l_brace))
Reid Spencer5f016e22007-07-11 17:01:13 +00001411 ParseEnumBody(StartLoc, TagDecl);
1412
1413 // TODO: semantic analysis on the declspec for enums.
1414 const char *PrevSpec = 0;
Chris Lattnerb28317a2009-03-28 19:18:32 +00001415 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec,
1416 TagDecl.getAs<void>()))
Chris Lattner1ab3b962008-11-18 07:48:38 +00001417 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00001418}
1419
1420/// ParseEnumBody - Parse a {} enclosed enumerator-list.
1421/// enumerator-list:
1422/// enumerator
1423/// enumerator-list ',' enumerator
1424/// enumerator:
1425/// enumeration-constant
1426/// enumeration-constant '=' constant-expression
1427/// enumeration-constant:
1428/// identifier
1429///
Chris Lattnerb28317a2009-03-28 19:18:32 +00001430void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) {
Douglas Gregor074149e2009-01-05 19:45:36 +00001431 // Enter the scope of the enum body and start the definition.
1432 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregor72de6672009-01-08 20:45:30 +00001433 Actions.ActOnTagStartDefinition(CurScope, EnumDecl);
Douglas Gregor074149e2009-01-05 19:45:36 +00001434
Reid Spencer5f016e22007-07-11 17:01:13 +00001435 SourceLocation LBraceLoc = ConsumeBrace();
1436
Chris Lattner7946dd32007-08-27 17:24:30 +00001437 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
Chris Lattner04d66662007-10-09 17:33:22 +00001438 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattner1ab3b962008-11-18 07:48:38 +00001439 Diag(Tok, diag::ext_empty_struct_union_enum) << "enum";
Reid Spencer5f016e22007-07-11 17:01:13 +00001440
Chris Lattnerb28317a2009-03-28 19:18:32 +00001441 llvm::SmallVector<DeclPtrTy, 32> EnumConstantDecls;
Reid Spencer5f016e22007-07-11 17:01:13 +00001442
Chris Lattnerb28317a2009-03-28 19:18:32 +00001443 DeclPtrTy LastEnumConstDecl;
Reid Spencer5f016e22007-07-11 17:01:13 +00001444
1445 // Parse the enumerator-list.
Chris Lattner04d66662007-10-09 17:33:22 +00001446 while (Tok.is(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001447 IdentifierInfo *Ident = Tok.getIdentifierInfo();
1448 SourceLocation IdentLoc = ConsumeToken();
1449
1450 SourceLocation EqualLoc;
Sebastian Redl15faa7f2008-12-09 20:22:58 +00001451 OwningExprResult AssignedVal(Actions);
Chris Lattner04d66662007-10-09 17:33:22 +00001452 if (Tok.is(tok::equal)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001453 EqualLoc = ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00001454 AssignedVal = ParseConstantExpression();
1455 if (AssignedVal.isInvalid())
Reid Spencer5f016e22007-07-11 17:01:13 +00001456 SkipUntil(tok::comma, tok::r_brace, true, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00001457 }
1458
1459 // Install the enumerator constant into EnumDecl.
Chris Lattnerb28317a2009-03-28 19:18:32 +00001460 DeclPtrTy EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
1461 LastEnumConstDecl,
1462 IdentLoc, Ident,
1463 EqualLoc,
1464 AssignedVal.release());
Reid Spencer5f016e22007-07-11 17:01:13 +00001465 EnumConstantDecls.push_back(EnumConstDecl);
1466 LastEnumConstDecl = EnumConstDecl;
1467
Chris Lattner04d66662007-10-09 17:33:22 +00001468 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +00001469 break;
1470 SourceLocation CommaLoc = ConsumeToken();
1471
Douglas Gregor9b3064b2009-04-01 22:41:11 +00001472 if (Tok.isNot(tok::identifier) &&
1473 !(getLang().C99 || getLang().CPlusPlus0x))
1474 Diag(CommaLoc, diag::ext_enumerator_list_comma)
1475 << getLang().CPlusPlus
1476 << CodeModificationHint::CreateRemoval((SourceRange(CommaLoc)));
Reid Spencer5f016e22007-07-11 17:01:13 +00001477 }
1478
1479 // Eat the }.
1480 MatchRHSPunctuation(tok::r_brace, LBraceLoc);
1481
Steve Naroff08d92e42007-09-15 18:49:24 +00001482 Actions.ActOnEnumBody(StartLoc, EnumDecl, &EnumConstantDecls[0],
Reid Spencer5f016e22007-07-11 17:01:13 +00001483 EnumConstantDecls.size());
1484
Chris Lattnerb28317a2009-03-28 19:18:32 +00001485 Action::AttrTy *AttrList = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +00001486 // If attributes exist after the identifier list, parse them.
Chris Lattner04d66662007-10-09 17:33:22 +00001487 if (Tok.is(tok::kw___attribute))
Reid Spencer5f016e22007-07-11 17:01:13 +00001488 AttrList = ParseAttributes(); // FIXME: where do they do?
Douglas Gregor72de6672009-01-08 20:45:30 +00001489
1490 EnumScope.Exit();
1491 Actions.ActOnTagFinishDefinition(CurScope, EnumDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +00001492}
1493
1494/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff5f8aa692008-02-11 23:15:56 +00001495/// start of a type-qualifier-list.
1496bool Parser::isTypeQualifier() const {
1497 switch (Tok.getKind()) {
1498 default: return false;
1499 // type-qualifier
1500 case tok::kw_const:
1501 case tok::kw_volatile:
1502 case tok::kw_restrict:
1503 return true;
1504 }
1505}
1506
1507/// isTypeSpecifierQualifier - Return true if the current token could be the
Reid Spencer5f016e22007-07-11 17:01:13 +00001508/// start of a specifier-qualifier-list.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001509bool Parser::isTypeSpecifierQualifier() {
Reid Spencer5f016e22007-07-11 17:01:13 +00001510 switch (Tok.getKind()) {
1511 default: return false;
Chris Lattner166a8fc2009-01-04 23:41:41 +00001512
1513 case tok::identifier: // foo::bar
Douglas Gregord57959a2009-03-27 23:10:48 +00001514 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00001515 // Annotate typenames and C++ scope specifiers. If we get one, just
1516 // recurse to handle whatever we get.
1517 if (TryAnnotateTypeOrScopeToken())
1518 return isTypeSpecifierQualifier();
1519 // Otherwise, not a type specifier.
1520 return false;
Douglas Gregord57959a2009-03-27 23:10:48 +00001521
Chris Lattner166a8fc2009-01-04 23:41:41 +00001522 case tok::coloncolon: // ::foo::bar
1523 if (NextToken().is(tok::kw_new) || // ::new
1524 NextToken().is(tok::kw_delete)) // ::delete
1525 return false;
1526
1527 // Annotate typenames and C++ scope specifiers. If we get one, just
1528 // recurse to handle whatever we get.
1529 if (TryAnnotateTypeOrScopeToken())
1530 return isTypeSpecifierQualifier();
1531 // Otherwise, not a type specifier.
1532 return false;
1533
Reid Spencer5f016e22007-07-11 17:01:13 +00001534 // GNU attributes support.
1535 case tok::kw___attribute:
Steve Naroffd1861fd2007-07-31 12:34:36 +00001536 // GNU typeof support.
1537 case tok::kw_typeof:
1538
Reid Spencer5f016e22007-07-11 17:01:13 +00001539 // type-specifiers
1540 case tok::kw_short:
1541 case tok::kw_long:
1542 case tok::kw_signed:
1543 case tok::kw_unsigned:
1544 case tok::kw__Complex:
1545 case tok::kw__Imaginary:
1546 case tok::kw_void:
1547 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00001548 case tok::kw_wchar_t:
Reid Spencer5f016e22007-07-11 17:01:13 +00001549 case tok::kw_int:
1550 case tok::kw_float:
1551 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00001552 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00001553 case tok::kw__Bool:
1554 case tok::kw__Decimal32:
1555 case tok::kw__Decimal64:
1556 case tok::kw__Decimal128:
1557
Chris Lattner99dc9142008-04-13 18:59:07 +00001558 // struct-or-union-specifier (C99) or class-specifier (C++)
1559 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00001560 case tok::kw_struct:
1561 case tok::kw_union:
1562 // enum-specifier
1563 case tok::kw_enum:
1564
1565 // type-qualifier
1566 case tok::kw_const:
1567 case tok::kw_volatile:
1568 case tok::kw_restrict:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001569
1570 // typedef-name
Chris Lattnerb31757b2009-01-06 05:06:21 +00001571 case tok::annot_typename:
Reid Spencer5f016e22007-07-11 17:01:13 +00001572 return true;
Chris Lattner7c186be2008-10-20 00:25:30 +00001573
1574 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
1575 case tok::less:
1576 return getLang().ObjC1;
Steve Naroff239f0732008-12-25 14:16:32 +00001577
1578 case tok::kw___cdecl:
1579 case tok::kw___stdcall:
1580 case tok::kw___fastcall:
1581 return PP.getLangOptions().Microsoft;
Reid Spencer5f016e22007-07-11 17:01:13 +00001582 }
1583}
1584
1585/// isDeclarationSpecifier() - Return true if the current token is part of a
1586/// declaration specifier.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001587bool Parser::isDeclarationSpecifier() {
Reid Spencer5f016e22007-07-11 17:01:13 +00001588 switch (Tok.getKind()) {
1589 default: return false;
Chris Lattner166a8fc2009-01-04 23:41:41 +00001590
1591 case tok::identifier: // foo::bar
Steve Naroff61f72cb2009-03-09 21:12:44 +00001592 // Unfortunate hack to support "Class.factoryMethod" notation.
1593 if (getLang().ObjC1 && NextToken().is(tok::period))
1594 return false;
Douglas Gregord57959a2009-03-27 23:10:48 +00001595 // Fall through
Steve Naroff61f72cb2009-03-09 21:12:44 +00001596
Douglas Gregord57959a2009-03-27 23:10:48 +00001597 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00001598 // Annotate typenames and C++ scope specifiers. If we get one, just
1599 // recurse to handle whatever we get.
1600 if (TryAnnotateTypeOrScopeToken())
1601 return isDeclarationSpecifier();
1602 // Otherwise, not a declaration specifier.
1603 return false;
1604 case tok::coloncolon: // ::foo::bar
1605 if (NextToken().is(tok::kw_new) || // ::new
1606 NextToken().is(tok::kw_delete)) // ::delete
1607 return false;
1608
1609 // Annotate typenames and C++ scope specifiers. If we get one, just
1610 // recurse to handle whatever we get.
1611 if (TryAnnotateTypeOrScopeToken())
1612 return isDeclarationSpecifier();
1613 // Otherwise, not a declaration specifier.
1614 return false;
1615
Reid Spencer5f016e22007-07-11 17:01:13 +00001616 // storage-class-specifier
1617 case tok::kw_typedef:
1618 case tok::kw_extern:
Steve Naroff8d54bf22007-12-18 00:16:02 +00001619 case tok::kw___private_extern__:
Reid Spencer5f016e22007-07-11 17:01:13 +00001620 case tok::kw_static:
1621 case tok::kw_auto:
1622 case tok::kw_register:
1623 case tok::kw___thread:
1624
1625 // type-specifiers
1626 case tok::kw_short:
1627 case tok::kw_long:
1628 case tok::kw_signed:
1629 case tok::kw_unsigned:
1630 case tok::kw__Complex:
1631 case tok::kw__Imaginary:
1632 case tok::kw_void:
1633 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00001634 case tok::kw_wchar_t:
Reid Spencer5f016e22007-07-11 17:01:13 +00001635 case tok::kw_int:
1636 case tok::kw_float:
1637 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00001638 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00001639 case tok::kw__Bool:
1640 case tok::kw__Decimal32:
1641 case tok::kw__Decimal64:
1642 case tok::kw__Decimal128:
1643
Chris Lattner99dc9142008-04-13 18:59:07 +00001644 // struct-or-union-specifier (C99) or class-specifier (C++)
1645 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00001646 case tok::kw_struct:
1647 case tok::kw_union:
1648 // enum-specifier
1649 case tok::kw_enum:
1650
1651 // type-qualifier
1652 case tok::kw_const:
1653 case tok::kw_volatile:
1654 case tok::kw_restrict:
Steve Naroffd1861fd2007-07-31 12:34:36 +00001655
Reid Spencer5f016e22007-07-11 17:01:13 +00001656 // function-specifier
1657 case tok::kw_inline:
Douglas Gregorb48fe382008-10-31 09:07:45 +00001658 case tok::kw_virtual:
1659 case tok::kw_explicit:
Chris Lattnerd6c7c182007-08-09 16:40:21 +00001660
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001661 // typedef-name
Chris Lattnerb31757b2009-01-06 05:06:21 +00001662 case tok::annot_typename:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001663
Chris Lattner1ef08762007-08-09 17:01:07 +00001664 // GNU typeof support.
1665 case tok::kw_typeof:
1666
1667 // GNU attributes.
Chris Lattnerd6c7c182007-08-09 16:40:21 +00001668 case tok::kw___attribute:
Reid Spencer5f016e22007-07-11 17:01:13 +00001669 return true;
Chris Lattnerf3948c42008-07-26 03:38:44 +00001670
1671 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
1672 case tok::less:
1673 return getLang().ObjC1;
Steve Naroff239f0732008-12-25 14:16:32 +00001674
Steve Naroff47f52092009-01-06 19:34:12 +00001675 case tok::kw___declspec:
Steve Naroff239f0732008-12-25 14:16:32 +00001676 case tok::kw___cdecl:
1677 case tok::kw___stdcall:
1678 case tok::kw___fastcall:
1679 return PP.getLangOptions().Microsoft;
Reid Spencer5f016e22007-07-11 17:01:13 +00001680 }
1681}
1682
1683
1684/// ParseTypeQualifierListOpt
1685/// type-qualifier-list: [C99 6.7.5]
1686/// type-qualifier
Chris Lattner5a69d1c2008-12-18 07:02:59 +00001687/// [GNU] attributes [ only if AttributesAllowed=true ]
Reid Spencer5f016e22007-07-11 17:01:13 +00001688/// type-qualifier-list type-qualifier
Chris Lattner5a69d1c2008-12-18 07:02:59 +00001689/// [GNU] type-qualifier-list attributes [ only if AttributesAllowed=true ]
Reid Spencer5f016e22007-07-11 17:01:13 +00001690///
Chris Lattner5a69d1c2008-12-18 07:02:59 +00001691void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001692 while (1) {
1693 int isInvalid = false;
1694 const char *PrevSpec = 0;
1695 SourceLocation Loc = Tok.getLocation();
1696
1697 switch (Tok.getKind()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001698 case tok::kw_const:
1699 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
1700 getLang())*2;
1701 break;
1702 case tok::kw_volatile:
1703 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
1704 getLang())*2;
1705 break;
1706 case tok::kw_restrict:
1707 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
1708 getLang())*2;
1709 break;
Steve Naroff86bc6cf2008-12-25 14:41:26 +00001710 case tok::kw___ptr64:
Steve Naroff239f0732008-12-25 14:16:32 +00001711 case tok::kw___cdecl:
1712 case tok::kw___stdcall:
1713 case tok::kw___fastcall:
1714 if (!PP.getLangOptions().Microsoft)
1715 goto DoneWithTypeQuals;
1716 // Just ignore it.
1717 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00001718 case tok::kw___attribute:
Chris Lattner5a69d1c2008-12-18 07:02:59 +00001719 if (AttributesAllowed) {
1720 DS.AddAttributes(ParseAttributes());
1721 continue; // do *not* consume the next token!
1722 }
1723 // otherwise, FALL THROUGH!
1724 default:
Steve Naroff239f0732008-12-25 14:16:32 +00001725 DoneWithTypeQuals:
Chris Lattner5a69d1c2008-12-18 07:02:59 +00001726 // If this is not a type-qualifier token, we're done reading type
1727 // qualifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00001728 DS.Finish(Diags, PP);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00001729 return;
Reid Spencer5f016e22007-07-11 17:01:13 +00001730 }
Chris Lattnera1fcbad2008-12-18 06:50:14 +00001731
Reid Spencer5f016e22007-07-11 17:01:13 +00001732 // If the specifier combination wasn't legal, issue a diagnostic.
1733 if (isInvalid) {
1734 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +00001735 // Pick between error or extwarn.
1736 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
1737 : diag::ext_duplicate_declspec;
1738 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00001739 }
1740 ConsumeToken();
1741 }
1742}
1743
1744
1745/// ParseDeclarator - Parse and verify a newly-initialized declarator.
1746///
1747void Parser::ParseDeclarator(Declarator &D) {
1748 /// This implements the 'declarator' production in the C grammar, then checks
1749 /// for well-formedness and issues diagnostics.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001750 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Reid Spencer5f016e22007-07-11 17:01:13 +00001751}
1752
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001753/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
1754/// is parsed by the function passed to it. Pass null, and the direct-declarator
1755/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001756/// ptr-operator production.
1757///
Sebastian Redlf30208a2009-01-24 21:16:55 +00001758/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
1759/// [C] pointer[opt] direct-declarator
1760/// [C++] direct-declarator
1761/// [C++] ptr-operator declarator
Reid Spencer5f016e22007-07-11 17:01:13 +00001762///
1763/// pointer: [C99 6.7.5]
1764/// '*' type-qualifier-list[opt]
1765/// '*' type-qualifier-list[opt] pointer
1766///
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001767/// ptr-operator:
1768/// '*' cv-qualifier-seq[opt]
1769/// '&'
Sebastian Redl05532f22009-03-15 22:02:01 +00001770/// [C++0x] '&&'
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001771/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redl05532f22009-03-15 22:02:01 +00001772/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redlf30208a2009-01-24 21:16:55 +00001773/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001774void Parser::ParseDeclaratorInternal(Declarator &D,
1775 DirectDeclParseFunction DirectDeclParser) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001776
Sebastian Redlf30208a2009-01-24 21:16:55 +00001777 // C++ member pointers start with a '::' or a nested-name.
1778 // Member pointers get special handling, since there's no place for the
1779 // scope spec in the generic path below.
Chris Lattnerf919bfe2009-03-24 17:04:48 +00001780 if (getLang().CPlusPlus &&
1781 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
1782 Tok.is(tok::annot_cxxscope))) {
Sebastian Redlf30208a2009-01-24 21:16:55 +00001783 CXXScopeSpec SS;
1784 if (ParseOptionalCXXScopeSpecifier(SS)) {
1785 if(Tok.isNot(tok::star)) {
1786 // The scope spec really belongs to the direct-declarator.
1787 D.getCXXScopeSpec() = SS;
1788 if (DirectDeclParser)
1789 (this->*DirectDeclParser)(D);
1790 return;
1791 }
1792
1793 SourceLocation Loc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00001794 D.SetRangeEnd(Loc);
Sebastian Redlf30208a2009-01-24 21:16:55 +00001795 DeclSpec DS;
1796 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001797 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00001798
1799 // Recurse to parse whatever is left.
1800 ParseDeclaratorInternal(D, DirectDeclParser);
1801
1802 // Sema will have to catch (syntactically invalid) pointers into global
1803 // scope. It has to catch pointers into namespace scope anyway.
1804 D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00001805 Loc, DS.TakeAttributes()),
1806 /* Don't replace range end. */SourceLocation());
Sebastian Redlf30208a2009-01-24 21:16:55 +00001807 return;
1808 }
1809 }
1810
1811 tok::TokenKind Kind = Tok.getKind();
Steve Naroff5618bd42008-08-27 16:04:49 +00001812 // Not a pointer, C++ reference, or block.
Chris Lattner9af55002009-03-27 04:18:06 +00001813 if (Kind != tok::star && Kind != tok::caret &&
Chris Lattnerf919bfe2009-03-24 17:04:48 +00001814 (Kind != tok::amp || !getLang().CPlusPlus) &&
Sebastian Redl743de1f2009-03-23 00:00:23 +00001815 // We parse rvalue refs in C++03, because otherwise the errors are scary.
Chris Lattner9af55002009-03-27 04:18:06 +00001816 (Kind != tok::ampamp || !getLang().CPlusPlus)) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001817 if (DirectDeclParser)
1818 (this->*DirectDeclParser)(D);
Douglas Gregor2f1bc522008-11-07 20:08:42 +00001819 return;
1820 }
Sebastian Redlf30208a2009-01-24 21:16:55 +00001821
Sebastian Redl05532f22009-03-15 22:02:01 +00001822 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
1823 // '&&' -> rvalue reference
Sebastian Redl743de1f2009-03-23 00:00:23 +00001824 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redlab197ba2009-02-09 18:23:29 +00001825 D.SetRangeEnd(Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +00001826
Chris Lattner9af55002009-03-27 04:18:06 +00001827 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner76549142008-02-21 01:32:26 +00001828 // Is a pointer.
Reid Spencer5f016e22007-07-11 17:01:13 +00001829 DeclSpec DS;
Sebastian Redlf30208a2009-01-24 21:16:55 +00001830
Reid Spencer5f016e22007-07-11 17:01:13 +00001831 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001832 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00001833
Reid Spencer5f016e22007-07-11 17:01:13 +00001834 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001835 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff5618bd42008-08-27 16:04:49 +00001836 if (Kind == tok::star)
1837 // Remember that we parsed a pointer type, and remember the type-quals.
1838 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
Sebastian Redlab197ba2009-02-09 18:23:29 +00001839 DS.TakeAttributes()),
1840 SourceLocation());
Steve Naroff5618bd42008-08-27 16:04:49 +00001841 else
1842 // Remember that we parsed a Block type, and remember the type-quals.
1843 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00001844 Loc),
1845 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00001846 } else {
1847 // Is a reference
1848 DeclSpec DS;
1849
Sebastian Redl743de1f2009-03-23 00:00:23 +00001850 // Complain about rvalue references in C++03, but then go on and build
1851 // the declarator.
1852 if (Kind == tok::ampamp && !getLang().CPlusPlus0x)
1853 Diag(Loc, diag::err_rvalue_reference);
1854
Reid Spencer5f016e22007-07-11 17:01:13 +00001855 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
1856 // cv-qualifiers are introduced through the use of a typedef or of a
1857 // template type argument, in which case the cv-qualifiers are ignored.
1858 //
1859 // [GNU] Retricted references are allowed.
1860 // [GNU] Attributes on references are allowed.
1861 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001862 D.ExtendWithDeclSpec(DS);
Reid Spencer5f016e22007-07-11 17:01:13 +00001863
1864 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
1865 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
1866 Diag(DS.getConstSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00001867 diag::err_invalid_reference_qualifier_application) << "const";
Reid Spencer5f016e22007-07-11 17:01:13 +00001868 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
1869 Diag(DS.getVolatileSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00001870 diag::err_invalid_reference_qualifier_application) << "volatile";
Reid Spencer5f016e22007-07-11 17:01:13 +00001871 }
1872
1873 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001874 ParseDeclaratorInternal(D, DirectDeclParser);
Reid Spencer5f016e22007-07-11 17:01:13 +00001875
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00001876 if (D.getNumTypeObjects() > 0) {
1877 // C++ [dcl.ref]p4: There shall be no references to references.
1878 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
1879 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattnerda83bac2008-11-19 07:37:42 +00001880 if (const IdentifierInfo *II = D.getIdentifier())
1881 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
1882 << II;
1883 else
1884 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
1885 << "type name";
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00001886
Sebastian Redl4c5d3202008-11-21 19:14:01 +00001887 // Once we've complained about the reference-to-reference, we
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00001888 // can go ahead and build the (technically ill-formed)
1889 // declarator: reference collapsing will take care of it.
1890 }
1891 }
1892
Reid Spencer5f016e22007-07-11 17:01:13 +00001893 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner76549142008-02-21 01:32:26 +00001894 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redl05532f22009-03-15 22:02:01 +00001895 DS.TakeAttributes(),
1896 Kind == tok::amp),
Sebastian Redlab197ba2009-02-09 18:23:29 +00001897 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00001898 }
1899}
1900
1901/// ParseDirectDeclarator
1902/// direct-declarator: [C99 6.7.5]
Douglas Gregor42a552f2008-11-05 20:51:48 +00001903/// [C99] identifier
Reid Spencer5f016e22007-07-11 17:01:13 +00001904/// '(' declarator ')'
1905/// [GNU] '(' attributes declarator ')'
1906/// [C90] direct-declarator '[' constant-expression[opt] ']'
1907/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
1908/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
1909/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
1910/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
1911/// direct-declarator '(' parameter-type-list ')'
1912/// direct-declarator '(' identifier-list[opt] ')'
1913/// [GNU] direct-declarator '(' parameter-forward-declarations
1914/// parameter-type-list[opt] ')'
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00001915/// [C++] direct-declarator '(' parameter-declaration-clause ')'
1916/// cv-qualifier-seq[opt] exception-specification[opt]
Douglas Gregorb48fe382008-10-31 09:07:45 +00001917/// [C++] declarator-id
Douglas Gregor42a552f2008-11-05 20:51:48 +00001918///
1919/// declarator-id: [C++ 8]
1920/// id-expression
1921/// '::'[opt] nested-name-specifier[opt] type-name
1922///
1923/// id-expression: [C++ 5.1]
1924/// unqualified-id
1925/// qualified-id [TODO]
1926///
1927/// unqualified-id: [C++ 5.1]
1928/// identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001929/// operator-function-id
Douglas Gregor42a552f2008-11-05 20:51:48 +00001930/// conversion-function-id [TODO]
1931/// '~' class-name
Douglas Gregor39a8de12009-02-25 19:37:18 +00001932/// template-id
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +00001933///
Reid Spencer5f016e22007-07-11 17:01:13 +00001934void Parser::ParseDirectDeclarator(Declarator &D) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00001935 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001936
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00001937 if (getLang().CPlusPlus) {
1938 if (D.mayHaveIdentifier()) {
Sebastian Redlf30208a2009-01-24 21:16:55 +00001939 // ParseDeclaratorInternal might already have parsed the scope.
1940 bool afterCXXScope = D.getCXXScopeSpec().isSet() ||
1941 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec());
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00001942 if (afterCXXScope) {
1943 // Change the declaration context for name lookup, until this function
1944 // is exited (and the declarator has been parsed).
1945 DeclScopeObj.EnterDeclaratorScope();
1946 }
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00001947
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00001948 if (Tok.is(tok::identifier)) {
1949 assert(Tok.getIdentifierInfo() && "Not an identifier?");
Douglas Gregord6fb7ef2008-12-18 19:37:40 +00001950
Douglas Gregord6fb7ef2008-12-18 19:37:40 +00001951 // If this identifier is the name of the current class, it's a
1952 // constructor name.
Douglas Gregor39a8de12009-02-25 19:37:18 +00001953 if (Actions.isCurrentClassName(*Tok.getIdentifierInfo(),CurScope)){
Steve Naroffb43a50f2009-01-28 19:39:02 +00001954 D.setConstructor(Actions.getTypeName(*Tok.getIdentifierInfo(),
Douglas Gregorb696ea32009-02-04 17:00:24 +00001955 Tok.getLocation(), CurScope),
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00001956 Tok.getLocation());
Douglas Gregord6fb7ef2008-12-18 19:37:40 +00001957 // This is a normal identifier.
Sebastian Redlab197ba2009-02-09 18:23:29 +00001958 } else
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00001959 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1960 ConsumeToken();
1961 goto PastIdentifier;
Douglas Gregor39a8de12009-02-25 19:37:18 +00001962 } else if (Tok.is(tok::annot_template_id)) {
1963 TemplateIdAnnotation *TemplateId
1964 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
1965
1966 // FIXME: Could this template-id name a constructor?
1967
1968 // FIXME: This is an egregious hack, where we silently ignore
1969 // the specialization (which should be a function template
1970 // specialization name) and use the name instead. This hack
1971 // will go away when we have support for function
1972 // specializations.
1973 D.SetIdentifier(TemplateId->Name, Tok.getLocation());
1974 TemplateId->Destroy();
1975 ConsumeToken();
1976 goto PastIdentifier;
Douglas Gregor70316a02008-12-26 15:00:45 +00001977 } else if (Tok.is(tok::kw_operator)) {
1978 SourceLocation OperatorLoc = Tok.getLocation();
Sebastian Redlab197ba2009-02-09 18:23:29 +00001979 SourceLocation EndLoc;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00001980
Douglas Gregor70316a02008-12-26 15:00:45 +00001981 // First try the name of an overloaded operator
Sebastian Redlab197ba2009-02-09 18:23:29 +00001982 if (OverloadedOperatorKind Op = TryParseOperatorFunctionId(&EndLoc)) {
1983 D.setOverloadedOperator(Op, OperatorLoc, EndLoc);
Douglas Gregor70316a02008-12-26 15:00:45 +00001984 } else {
1985 // This must be a conversion function (C++ [class.conv.fct]).
Sebastian Redlab197ba2009-02-09 18:23:29 +00001986 if (TypeTy *ConvType = ParseConversionFunctionId(&EndLoc))
1987 D.setConversionFunction(ConvType, OperatorLoc, EndLoc);
1988 else {
Douglas Gregor70316a02008-12-26 15:00:45 +00001989 D.SetIdentifier(0, Tok.getLocation());
Sebastian Redlab197ba2009-02-09 18:23:29 +00001990 }
Douglas Gregor70316a02008-12-26 15:00:45 +00001991 }
1992 goto PastIdentifier;
1993 } else if (Tok.is(tok::tilde)) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00001994 // This should be a C++ destructor.
1995 SourceLocation TildeLoc = ConsumeToken();
1996 if (Tok.is(tok::identifier)) {
Sebastian Redlab197ba2009-02-09 18:23:29 +00001997 // FIXME: Inaccurate.
1998 SourceLocation NameLoc = Tok.getLocation();
Douglas Gregor7f43d672009-02-25 23:52:28 +00001999 SourceLocation EndLoc;
Douglas Gregor31a19b62009-04-01 21:51:26 +00002000 TypeResult Type = ParseClassName(EndLoc);
2001 if (Type.isInvalid())
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00002002 D.SetIdentifier(0, TildeLoc);
Douglas Gregor31a19b62009-04-01 21:51:26 +00002003 else
2004 D.setDestructor(Type.get(), TildeLoc, NameLoc);
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00002005 } else {
2006 Diag(Tok, diag::err_expected_class_name);
2007 D.SetIdentifier(0, TildeLoc);
2008 }
2009 goto PastIdentifier;
2010 }
2011
2012 // If we reached this point, token is not identifier and not '~'.
2013
2014 if (afterCXXScope) {
2015 Diag(Tok, diag::err_expected_unqualified_id);
2016 D.SetIdentifier(0, Tok.getLocation());
2017 D.setInvalidType(true);
2018 goto PastIdentifier;
Douglas Gregor2f1bc522008-11-07 20:08:42 +00002019 }
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00002020 }
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00002021 }
2022
2023 // If we reached this point, we are either in C/ObjC or the token didn't
2024 // satisfy any of the C++-specific checks.
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00002025 if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
2026 assert(!getLang().CPlusPlus &&
2027 "There's a C++-specific check for tok::identifier above");
2028 assert(Tok.getIdentifierInfo() && "Not an identifier?");
2029 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
2030 ConsumeToken();
2031 } else if (Tok.is(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002032 // direct-declarator: '(' declarator ')'
2033 // direct-declarator: '(' attributes declarator ')'
2034 // Example: 'char (*X)' or 'int (*XX)(void)'
2035 ParseParenDeclarator(D);
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00002036 } else if (D.mayOmitIdentifier()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002037 // This could be something simple like "int" (in which case the declarator
2038 // portion is empty), if an abstract-declarator is allowed.
2039 D.SetIdentifier(0, Tok.getLocation());
2040 } else {
Douglas Gregore950d4b2009-03-06 23:28:18 +00002041 if (D.getContext() == Declarator::MemberContext)
2042 Diag(Tok, diag::err_expected_member_name_or_semi)
2043 << D.getDeclSpec().getSourceRange();
2044 else if (getLang().CPlusPlus)
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002045 Diag(Tok, diag::err_expected_unqualified_id);
2046 else
Chris Lattner1ab3b962008-11-18 07:48:38 +00002047 Diag(Tok, diag::err_expected_ident_lparen);
Reid Spencer5f016e22007-07-11 17:01:13 +00002048 D.SetIdentifier(0, Tok.getLocation());
Chris Lattner1f6f54b2008-11-11 06:13:16 +00002049 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00002050 }
2051
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00002052 PastIdentifier:
Reid Spencer5f016e22007-07-11 17:01:13 +00002053 assert(D.isPastIdentifier() &&
2054 "Haven't past the location of the identifier yet?");
2055
2056 while (1) {
Chris Lattner04d66662007-10-09 17:33:22 +00002057 if (Tok.is(tok::l_paren)) {
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00002058 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
2059 // In such a case, check if we actually have a function declarator; if it
2060 // is not, the declarator has been fully parsed.
Chris Lattner7399ee02008-10-20 02:05:46 +00002061 if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
2062 // When not in file scope, warn for ambiguous function declarators, just
2063 // in case the author intended it as a variable definition.
2064 bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
2065 if (!isCXXFunctionDeclarator(warnIfAmbiguous))
2066 break;
2067 }
Chris Lattneref4715c2008-04-06 05:45:57 +00002068 ParseFunctionDeclarator(ConsumeParen(), D);
Chris Lattner04d66662007-10-09 17:33:22 +00002069 } else if (Tok.is(tok::l_square)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002070 ParseBracketDeclarator(D);
2071 } else {
2072 break;
2073 }
2074 }
2075}
2076
Chris Lattneref4715c2008-04-06 05:45:57 +00002077/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
2078/// only called before the identifier, so these are most likely just grouping
2079/// parens for precedence. If we find that these are actually function
2080/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
2081///
2082/// direct-declarator:
2083/// '(' declarator ')'
2084/// [GNU] '(' attributes declarator ')'
Chris Lattner7399ee02008-10-20 02:05:46 +00002085/// direct-declarator '(' parameter-type-list ')'
2086/// direct-declarator '(' identifier-list[opt] ')'
2087/// [GNU] direct-declarator '(' parameter-forward-declarations
2088/// parameter-type-list[opt] ')'
Chris Lattneref4715c2008-04-06 05:45:57 +00002089///
2090void Parser::ParseParenDeclarator(Declarator &D) {
2091 SourceLocation StartLoc = ConsumeParen();
2092 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
2093
Chris Lattner7399ee02008-10-20 02:05:46 +00002094 // Eat any attributes before we look at whether this is a grouping or function
2095 // declarator paren. If this is a grouping paren, the attribute applies to
2096 // the type being built up, for example:
2097 // int (__attribute__(()) *x)(long y)
2098 // If this ends up not being a grouping paren, the attribute applies to the
2099 // first argument, for example:
2100 // int (__attribute__(()) int x)
2101 // In either case, we need to eat any attributes to be able to determine what
2102 // sort of paren this is.
2103 //
2104 AttributeList *AttrList = 0;
2105 bool RequiresArg = false;
2106 if (Tok.is(tok::kw___attribute)) {
2107 AttrList = ParseAttributes();
2108
2109 // We require that the argument list (if this is a non-grouping paren) be
2110 // present even if the attribute list was empty.
2111 RequiresArg = true;
2112 }
Steve Naroff239f0732008-12-25 14:16:32 +00002113 // Eat any Microsoft extensions.
Douglas Gregor5a2f5d32009-01-10 00:48:18 +00002114 while ((Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
2115 (Tok.is(tok::kw___fastcall))) && PP.getLangOptions().Microsoft)
Steve Naroff239f0732008-12-25 14:16:32 +00002116 ConsumeToken();
Chris Lattner7399ee02008-10-20 02:05:46 +00002117
Chris Lattneref4715c2008-04-06 05:45:57 +00002118 // If we haven't past the identifier yet (or where the identifier would be
2119 // stored, if this is an abstract declarator), then this is probably just
2120 // grouping parens. However, if this could be an abstract-declarator, then
2121 // this could also be the start of function arguments (consider 'void()').
2122 bool isGrouping;
2123
2124 if (!D.mayOmitIdentifier()) {
2125 // If this can't be an abstract-declarator, this *must* be a grouping
2126 // paren, because we haven't seen the identifier yet.
2127 isGrouping = true;
2128 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Argyrios Kyrtzidise25d2702008-10-06 00:07:55 +00002129 (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
Chris Lattneref4715c2008-04-06 05:45:57 +00002130 isDeclarationSpecifier()) { // 'int(int)' is a function.
2131 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
2132 // considered to be a type, not a K&R identifier-list.
2133 isGrouping = false;
2134 } else {
2135 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
2136 isGrouping = true;
2137 }
2138
2139 // If this is a grouping paren, handle:
2140 // direct-declarator: '(' declarator ')'
2141 // direct-declarator: '(' attributes declarator ')'
2142 if (isGrouping) {
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00002143 bool hadGroupingParens = D.hasGroupingParens();
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00002144 D.setGroupingParens(true);
Chris Lattner7399ee02008-10-20 02:05:46 +00002145 if (AttrList)
Sebastian Redlab197ba2009-02-09 18:23:29 +00002146 D.AddAttributes(AttrList, SourceLocation());
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00002147
Sebastian Redl4c5d3202008-11-21 19:14:01 +00002148 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattneref4715c2008-04-06 05:45:57 +00002149 // Match the ')'.
Sebastian Redlab197ba2009-02-09 18:23:29 +00002150 SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, StartLoc);
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00002151
2152 D.setGroupingParens(hadGroupingParens);
Sebastian Redlab197ba2009-02-09 18:23:29 +00002153 D.SetRangeEnd(Loc);
Chris Lattneref4715c2008-04-06 05:45:57 +00002154 return;
2155 }
2156
2157 // Okay, if this wasn't a grouping paren, it must be the start of a function
2158 // argument list. Recognize that this declarator will never have an
Chris Lattner7399ee02008-10-20 02:05:46 +00002159 // identifier (and remember where it would have been), then call into
2160 // ParseFunctionDeclarator to handle of argument list.
Chris Lattneref4715c2008-04-06 05:45:57 +00002161 D.SetIdentifier(0, Tok.getLocation());
2162
Chris Lattner7399ee02008-10-20 02:05:46 +00002163 ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
Chris Lattneref4715c2008-04-06 05:45:57 +00002164}
2165
2166/// ParseFunctionDeclarator - We are after the identifier and have parsed the
2167/// declarator D up to a paren, which indicates that we are parsing function
2168/// arguments.
Reid Spencer5f016e22007-07-11 17:01:13 +00002169///
Chris Lattner7399ee02008-10-20 02:05:46 +00002170/// If AttrList is non-null, then the caller parsed those arguments immediately
2171/// after the open paren - they should be considered to be the first argument of
2172/// a parameter. If RequiresArg is true, then the first argument of the
2173/// function is required to be present and required to not be an identifier
2174/// list.
2175///
Reid Spencer5f016e22007-07-11 17:01:13 +00002176/// This method also handles this portion of the grammar:
2177/// parameter-type-list: [C99 6.7.5]
2178/// parameter-list
2179/// parameter-list ',' '...'
2180///
2181/// parameter-list: [C99 6.7.5]
2182/// parameter-declaration
2183/// parameter-list ',' parameter-declaration
2184///
2185/// parameter-declaration: [C99 6.7.5]
2186/// declaration-specifiers declarator
Chris Lattner04421082008-04-08 04:40:51 +00002187/// [C++] declaration-specifiers declarator '=' assignment-expression
Reid Spencer5f016e22007-07-11 17:01:13 +00002188/// [GNU] declaration-specifiers declarator attributes
Sebastian Redl50de12f2009-03-24 22:27:57 +00002189/// declaration-specifiers abstract-declarator[opt]
2190/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner8123a952008-04-10 02:22:51 +00002191/// '=' assignment-expression
Reid Spencer5f016e22007-07-11 17:01:13 +00002192/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
2193///
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002194/// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
Sebastian Redl50de12f2009-03-24 22:27:57 +00002195/// and "exception-specification[opt]".
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002196///
Chris Lattner7399ee02008-10-20 02:05:46 +00002197void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
2198 AttributeList *AttrList,
2199 bool RequiresArg) {
Chris Lattneref4715c2008-04-06 05:45:57 +00002200 // lparen is already consumed!
2201 assert(D.isPastIdentifier() && "Should not call before identifier!");
Reid Spencer5f016e22007-07-11 17:01:13 +00002202
Chris Lattner7399ee02008-10-20 02:05:46 +00002203 // This parameter list may be empty.
Chris Lattner04d66662007-10-09 17:33:22 +00002204 if (Tok.is(tok::r_paren)) {
Chris Lattner7399ee02008-10-20 02:05:46 +00002205 if (RequiresArg) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00002206 Diag(Tok, diag::err_argument_required_after_attribute);
Chris Lattner7399ee02008-10-20 02:05:46 +00002207 delete AttrList;
2208 }
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002209
Sebastian Redlab197ba2009-02-09 18:23:29 +00002210 SourceLocation Loc = ConsumeParen(); // Eat the closing ')'.
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002211
2212 // cv-qualifier-seq[opt].
2213 DeclSpec DS;
2214 if (getLang().CPlusPlus) {
Chris Lattner5a69d1c2008-12-18 07:02:59 +00002215 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Sebastian Redlab197ba2009-02-09 18:23:29 +00002216 if (!DS.getSourceRange().getEnd().isInvalid())
2217 Loc = DS.getSourceRange().getEnd();
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00002218
2219 // Parse exception-specification[opt].
2220 if (Tok.is(tok::kw_throw))
Sebastian Redlab197ba2009-02-09 18:23:29 +00002221 ParseExceptionSpecification(Loc);
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002222 }
2223
Chris Lattnerf97409f2008-04-06 06:57:35 +00002224 // Remember that we parsed a function type, and remember the attributes.
Reid Spencer5f016e22007-07-11 17:01:13 +00002225 // int() -> no prototype, no '...'.
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002226 D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
Chris Lattnerf97409f2008-04-06 06:57:35 +00002227 /*variadic*/ false,
Douglas Gregor965acbb2009-02-18 07:07:28 +00002228 SourceLocation(),
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002229 /*arglist*/ 0, 0,
2230 DS.getTypeQualifiers(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00002231 LParenLoc, D),
2232 Loc);
Chris Lattnerf97409f2008-04-06 06:57:35 +00002233 return;
Chris Lattner7399ee02008-10-20 02:05:46 +00002234 }
2235
2236 // Alternatively, this parameter list may be an identifier list form for a
2237 // K&R-style function: void foo(a,b,c)
Steve Naroff2d081c42009-01-28 19:16:40 +00002238 if (!getLang().CPlusPlus && Tok.is(tok::identifier)) {
Steve Narofff64ef622009-01-30 14:23:32 +00002239 if (!TryAnnotateTypeOrScopeToken()) {
Chris Lattner7399ee02008-10-20 02:05:46 +00002240 // K&R identifier lists can't have typedefs as identifiers, per
2241 // C99 6.7.5.3p11.
Steve Naroff2d081c42009-01-28 19:16:40 +00002242 if (RequiresArg) {
2243 Diag(Tok, diag::err_argument_required_after_attribute);
2244 delete AttrList;
2245 }
Steve Naroff2d081c42009-01-28 19:16:40 +00002246 // Identifier list. Note that '(' identifier-list ')' is only allowed for
2247 // normal declarators, not for abstract-declarators.
2248 return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
Chris Lattner7399ee02008-10-20 02:05:46 +00002249 }
Chris Lattnerf97409f2008-04-06 06:57:35 +00002250 }
2251
2252 // Finally, a normal, non-empty parameter type list.
2253
2254 // Build up an array of information about the parsed arguments.
2255 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Chris Lattner04421082008-04-08 04:40:51 +00002256
2257 // Enter function-declaration scope, limiting any declarators to the
2258 // function prototype scope, including parameter declarators.
Chris Lattnerae50fa02009-03-05 00:00:31 +00002259 ParseScope PrototypeScope(this,
2260 Scope::FunctionPrototypeScope|Scope::DeclScope);
Chris Lattnerf97409f2008-04-06 06:57:35 +00002261
2262 bool IsVariadic = false;
Douglas Gregor965acbb2009-02-18 07:07:28 +00002263 SourceLocation EllipsisLoc;
Chris Lattnerf97409f2008-04-06 06:57:35 +00002264 while (1) {
2265 if (Tok.is(tok::ellipsis)) {
2266 IsVariadic = true;
Douglas Gregor965acbb2009-02-18 07:07:28 +00002267 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattnerf97409f2008-04-06 06:57:35 +00002268 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002269 }
2270
Chris Lattnerf97409f2008-04-06 06:57:35 +00002271 SourceLocation DSStart = Tok.getLocation();
Reid Spencer5f016e22007-07-11 17:01:13 +00002272
Chris Lattnerf97409f2008-04-06 06:57:35 +00002273 // Parse the declaration-specifiers.
2274 DeclSpec DS;
Chris Lattner7399ee02008-10-20 02:05:46 +00002275
2276 // If the caller parsed attributes for the first argument, add them now.
2277 if (AttrList) {
2278 DS.AddAttributes(AttrList);
2279 AttrList = 0; // Only apply the attributes to the first parameter.
2280 }
Chris Lattnere64c5492009-02-27 18:38:20 +00002281 ParseDeclarationSpecifiers(DS);
2282
Chris Lattnerf97409f2008-04-06 06:57:35 +00002283 // Parse the declarator. This is "PrototypeContext", because we must
2284 // accept either 'declarator' or 'abstract-declarator' here.
2285 Declarator ParmDecl(DS, Declarator::PrototypeContext);
2286 ParseDeclarator(ParmDecl);
2287
2288 // Parse GNU attributes, if present.
Sebastian Redlab197ba2009-02-09 18:23:29 +00002289 if (Tok.is(tok::kw___attribute)) {
2290 SourceLocation Loc;
2291 AttributeList *AttrList = ParseAttributes(&Loc);
2292 ParmDecl.AddAttributes(AttrList, Loc);
2293 }
Chris Lattnerf97409f2008-04-06 06:57:35 +00002294
Chris Lattnerf97409f2008-04-06 06:57:35 +00002295 // Remember this parsed parameter in ParamInfo.
2296 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
2297
Douglas Gregor72b505b2008-12-16 21:30:33 +00002298 // DefArgToks is used when the parsing of default arguments needs
2299 // to be delayed.
2300 CachedTokens *DefArgToks = 0;
2301
Chris Lattnerf97409f2008-04-06 06:57:35 +00002302 // If no parameter was specified, verify that *something* was specified,
2303 // otherwise we have a missing type and identifier.
Chris Lattnere64c5492009-02-27 18:38:20 +00002304 if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
2305 ParmDecl.getNumTypeObjects() == 0) {
Chris Lattnerf97409f2008-04-06 06:57:35 +00002306 // Completely missing, emit error.
2307 Diag(DSStart, diag::err_missing_param);
2308 } else {
2309 // Otherwise, we have something. Add it and let semantic analysis try
2310 // to grok it and add the result to the ParamInfo we are building.
2311
2312 // Inform the actions module about the parameter declarator, so it gets
2313 // added to the current scope.
Chris Lattnerb28317a2009-03-28 19:18:32 +00002314 DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
Chris Lattner04421082008-04-08 04:40:51 +00002315
2316 // Parse the default argument, if any. We parse the default
2317 // arguments in all dialects; the semantic analysis in
2318 // ActOnParamDefaultArgument will reject the default argument in
2319 // C.
2320 if (Tok.is(tok::equal)) {
Douglas Gregor61366e92008-12-24 00:01:03 +00002321 SourceLocation EqualLoc = Tok.getLocation();
2322
Chris Lattner04421082008-04-08 04:40:51 +00002323 // Parse the default argument
Douglas Gregor72b505b2008-12-16 21:30:33 +00002324 if (D.getContext() == Declarator::MemberContext) {
2325 // If we're inside a class definition, cache the tokens
2326 // corresponding to the default argument. We'll actually parse
2327 // them when we see the end of the class definition.
2328 // FIXME: Templates will require something similar.
2329 // FIXME: Can we use a smart pointer for Toks?
2330 DefArgToks = new CachedTokens;
2331
2332 if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
2333 tok::semi, false)) {
2334 delete DefArgToks;
2335 DefArgToks = 0;
Douglas Gregor61366e92008-12-24 00:01:03 +00002336 Actions.ActOnParamDefaultArgumentError(Param);
2337 } else
2338 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc);
Chris Lattner04421082008-04-08 04:40:51 +00002339 } else {
Douglas Gregor72b505b2008-12-16 21:30:33 +00002340 // Consume the '='.
Douglas Gregor61366e92008-12-24 00:01:03 +00002341 ConsumeToken();
Douglas Gregor72b505b2008-12-16 21:30:33 +00002342
2343 OwningExprResult DefArgResult(ParseAssignmentExpression());
2344 if (DefArgResult.isInvalid()) {
2345 Actions.ActOnParamDefaultArgumentError(Param);
2346 SkipUntil(tok::comma, tok::r_paren, true, true);
2347 } else {
2348 // Inform the actions module about the default argument
2349 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
Sebastian Redlf53597f2009-03-15 17:47:39 +00002350 move(DefArgResult));
Douglas Gregor72b505b2008-12-16 21:30:33 +00002351 }
Chris Lattner04421082008-04-08 04:40:51 +00002352 }
2353 }
Chris Lattnerf97409f2008-04-06 06:57:35 +00002354
2355 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Douglas Gregor72b505b2008-12-16 21:30:33 +00002356 ParmDecl.getIdentifierLoc(), Param,
2357 DefArgToks));
Chris Lattnerf97409f2008-04-06 06:57:35 +00002358 }
2359
2360 // If the next token is a comma, consume it and keep reading arguments.
2361 if (Tok.isNot(tok::comma)) break;
2362
2363 // Consume the comma.
2364 ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00002365 }
2366
Chris Lattnerf97409f2008-04-06 06:57:35 +00002367 // Leave prototype scope.
Douglas Gregor8935b8b2008-12-10 06:34:36 +00002368 PrototypeScope.Exit();
Chris Lattnerf97409f2008-04-06 06:57:35 +00002369
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002370 // If we have the closing ')', eat it.
Sebastian Redlab197ba2009-02-09 18:23:29 +00002371 SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002372
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002373 DeclSpec DS;
2374 if (getLang().CPlusPlus) {
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00002375 // Parse cv-qualifier-seq[opt].
Chris Lattner5a69d1c2008-12-18 07:02:59 +00002376 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Sebastian Redlab197ba2009-02-09 18:23:29 +00002377 if (!DS.getSourceRange().getEnd().isInvalid())
2378 Loc = DS.getSourceRange().getEnd();
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00002379
2380 // Parse exception-specification[opt].
2381 if (Tok.is(tok::kw_throw))
Sebastian Redlab197ba2009-02-09 18:23:29 +00002382 ParseExceptionSpecification(Loc);
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002383 }
2384
Reid Spencer5f016e22007-07-11 17:01:13 +00002385 // Remember that we parsed a function type, and remember the attributes.
Chris Lattnerf97409f2008-04-06 06:57:35 +00002386 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
Douglas Gregor965acbb2009-02-18 07:07:28 +00002387 EllipsisLoc,
Chris Lattnerf97409f2008-04-06 06:57:35 +00002388 &ParamInfo[0], ParamInfo.size(),
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00002389 DS.getTypeQualifiers(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00002390 LParenLoc, D),
2391 Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +00002392}
2393
Chris Lattner66d28652008-04-06 06:34:08 +00002394/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
2395/// we found a K&R-style identifier list instead of a type argument list. The
2396/// current token is known to be the first identifier in the list.
2397///
2398/// identifier-list: [C99 6.7.5]
2399/// identifier
2400/// identifier-list ',' identifier
2401///
2402void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
2403 Declarator &D) {
2404 // Build up an array of information about the parsed arguments.
2405 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
2406 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
2407
2408 // If there was no identifier specified for the declarator, either we are in
2409 // an abstract-declarator, or we are in a parameter declarator which was found
2410 // to be abstract. In abstract-declarators, identifier lists are not valid:
2411 // diagnose this.
2412 if (!D.getIdentifier())
2413 Diag(Tok, diag::ext_ident_list_in_param);
2414
2415 // Tok is known to be the first identifier in the list. Remember this
2416 // identifier in ParamInfo.
Chris Lattner3825c2e2008-04-06 06:50:56 +00002417 ParamsSoFar.insert(Tok.getIdentifierInfo());
Chris Lattner66d28652008-04-06 06:34:08 +00002418 ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
Chris Lattnerb28317a2009-03-28 19:18:32 +00002419 Tok.getLocation(),
2420 DeclPtrTy()));
Chris Lattner66d28652008-04-06 06:34:08 +00002421
Chris Lattner50c64772008-04-06 06:39:19 +00002422 ConsumeToken(); // eat the first identifier.
Chris Lattner66d28652008-04-06 06:34:08 +00002423
2424 while (Tok.is(tok::comma)) {
2425 // Eat the comma.
2426 ConsumeToken();
2427
Chris Lattner50c64772008-04-06 06:39:19 +00002428 // If this isn't an identifier, report the error and skip until ')'.
Chris Lattner66d28652008-04-06 06:34:08 +00002429 if (Tok.isNot(tok::identifier)) {
2430 Diag(Tok, diag::err_expected_ident);
Chris Lattner50c64772008-04-06 06:39:19 +00002431 SkipUntil(tok::r_paren);
2432 return;
Chris Lattner66d28652008-04-06 06:34:08 +00002433 }
Chris Lattneraaf9ddb2008-04-06 06:47:48 +00002434
Chris Lattner66d28652008-04-06 06:34:08 +00002435 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
Chris Lattneraaf9ddb2008-04-06 06:47:48 +00002436
2437 // Reject 'typedef int y; int test(x, y)', but continue parsing.
Douglas Gregorb696ea32009-02-04 17:00:24 +00002438 if (Actions.getTypeName(*ParmII, Tok.getLocation(), CurScope))
Chris Lattnerda83bac2008-11-19 07:37:42 +00002439 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
Chris Lattner66d28652008-04-06 06:34:08 +00002440
2441 // Verify that the argument identifier has not already been mentioned.
2442 if (!ParamsSoFar.insert(ParmII)) {
Chris Lattnerda83bac2008-11-19 07:37:42 +00002443 Diag(Tok, diag::err_param_redefinition) << ParmII;
Chris Lattner50c64772008-04-06 06:39:19 +00002444 } else {
2445 // Remember this identifier in ParamInfo.
Chris Lattner66d28652008-04-06 06:34:08 +00002446 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Chris Lattnerb28317a2009-03-28 19:18:32 +00002447 Tok.getLocation(),
2448 DeclPtrTy()));
Chris Lattner50c64772008-04-06 06:39:19 +00002449 }
Chris Lattner66d28652008-04-06 06:34:08 +00002450
2451 // Eat the identifier.
2452 ConsumeToken();
2453 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00002454
2455 // If we have the closing ')', eat it and we're done.
2456 SourceLocation RLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2457
Chris Lattner50c64772008-04-06 06:39:19 +00002458 // Remember that we parsed a function type, and remember the attributes. This
2459 // function type is always a K&R style function type, which is not varargs and
2460 // has no prototype.
2461 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
Douglas Gregor965acbb2009-02-18 07:07:28 +00002462 SourceLocation(),
Chris Lattner50c64772008-04-06 06:39:19 +00002463 &ParamInfo[0], ParamInfo.size(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00002464 /*TypeQuals*/0, LParenLoc, D),
2465 RLoc);
Chris Lattner66d28652008-04-06 06:34:08 +00002466}
Chris Lattneref4715c2008-04-06 05:45:57 +00002467
Reid Spencer5f016e22007-07-11 17:01:13 +00002468/// [C90] direct-declarator '[' constant-expression[opt] ']'
2469/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
2470/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
2471/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
2472/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
2473void Parser::ParseBracketDeclarator(Declarator &D) {
2474 SourceLocation StartLoc = ConsumeBracket();
2475
Chris Lattner378c7e42008-12-18 07:27:21 +00002476 // C array syntax has many features, but by-far the most common is [] and [4].
2477 // This code does a fast path to handle some of the most obvious cases.
2478 if (Tok.getKind() == tok::r_square) {
Sebastian Redlab197ba2009-02-09 18:23:29 +00002479 SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
Chris Lattner378c7e42008-12-18 07:27:21 +00002480 // Remember that we parsed the empty array type.
2481 OwningExprResult NumElements(Actions);
Sebastian Redlab197ba2009-02-09 18:23:29 +00002482 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, StartLoc),
2483 EndLoc);
Chris Lattner378c7e42008-12-18 07:27:21 +00002484 return;
2485 } else if (Tok.getKind() == tok::numeric_constant &&
2486 GetLookAheadToken(1).is(tok::r_square)) {
2487 // [4] is very common. Parse the numeric constant expression.
Sebastian Redlcd965b92009-01-18 18:53:16 +00002488 OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
Chris Lattner378c7e42008-12-18 07:27:21 +00002489 ConsumeToken();
2490
Sebastian Redlab197ba2009-02-09 18:23:29 +00002491 SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
Chris Lattner378c7e42008-12-18 07:27:21 +00002492
2493 // If there was an error parsing the assignment-expression, recover.
2494 if (ExprRes.isInvalid())
2495 ExprRes.release(); // Deallocate expr, just use [].
2496
2497 // Remember that we parsed a array type, and remember its features.
2498 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
Sebastian Redlab197ba2009-02-09 18:23:29 +00002499 ExprRes.release(), StartLoc),
2500 EndLoc);
Chris Lattner378c7e42008-12-18 07:27:21 +00002501 return;
2502 }
2503
Reid Spencer5f016e22007-07-11 17:01:13 +00002504 // If valid, this location is the position where we read the 'static' keyword.
2505 SourceLocation StaticLoc;
Chris Lattner04d66662007-10-09 17:33:22 +00002506 if (Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00002507 StaticLoc = ConsumeToken();
2508
2509 // If there is a type-qualifier-list, read it now.
Chris Lattnera1fcbad2008-12-18 06:50:14 +00002510 // Type qualifiers in an array subscript are a C99 feature.
Reid Spencer5f016e22007-07-11 17:01:13 +00002511 DeclSpec DS;
Chris Lattner5a69d1c2008-12-18 07:02:59 +00002512 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Reid Spencer5f016e22007-07-11 17:01:13 +00002513
2514 // If we haven't already read 'static', check to see if there is one after the
2515 // type-qualifier-list.
Chris Lattner04d66662007-10-09 17:33:22 +00002516 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00002517 StaticLoc = ConsumeToken();
2518
2519 // Handle "direct-declarator [ type-qual-list[opt] * ]".
2520 bool isStar = false;
Sebastian Redl15faa7f2008-12-09 20:22:58 +00002521 OwningExprResult NumElements(Actions);
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00002522
2523 // Handle the case where we have '[*]' as the array size. However, a leading
2524 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
2525 // the the token after the star is a ']'. Since stars in arrays are
2526 // infrequent, use of lookahead is not costly here.
2527 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattnera711dd02008-04-06 05:27:21 +00002528 ConsumeToken(); // Eat the '*'.
Reid Spencer5f016e22007-07-11 17:01:13 +00002529
Chris Lattnera1fcbad2008-12-18 06:50:14 +00002530 if (StaticLoc.isValid()) {
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00002531 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattnera1fcbad2008-12-18 06:50:14 +00002532 StaticLoc = SourceLocation(); // Drop the static.
2533 }
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00002534 isStar = true;
Chris Lattner04d66662007-10-09 17:33:22 +00002535 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner378c7e42008-12-18 07:27:21 +00002536 // Note, in C89, this production uses the constant-expr production instead
2537 // of assignment-expr. The only difference is that assignment-expr allows
2538 // things like '=' and '*='. Sema rejects these in C89 mode because they
2539 // are not i-c-e's, so we don't need to distinguish between the two here.
2540
Reid Spencer5f016e22007-07-11 17:01:13 +00002541 // Parse the assignment-expression now.
2542 NumElements = ParseAssignmentExpression();
2543 }
2544
2545 // If there was an error parsing the assignment-expression, recover.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00002546 if (NumElements.isInvalid()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002547 // If the expression was invalid, skip it.
2548 SkipUntil(tok::r_square);
2549 return;
2550 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00002551
2552 SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
2553
Chris Lattner378c7e42008-12-18 07:27:21 +00002554 // Remember that we parsed a array type, and remember its features.
Reid Spencer5f016e22007-07-11 17:01:13 +00002555 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
2556 StaticLoc.isValid(), isStar,
Sebastian Redlab197ba2009-02-09 18:23:29 +00002557 NumElements.release(), StartLoc),
2558 EndLoc);
Reid Spencer5f016e22007-07-11 17:01:13 +00002559}
2560
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00002561/// [GNU] typeof-specifier:
2562/// typeof ( expressions )
2563/// typeof ( type-name )
2564/// [GNU/C++] typeof unary-expression
Steve Naroffd1861fd2007-07-31 12:34:36 +00002565///
2566void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner04d66662007-10-09 17:33:22 +00002567 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Steve Naroff9dfa7b42007-08-02 02:53:48 +00002568 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
Steve Naroffd1861fd2007-07-31 12:34:36 +00002569 SourceLocation StartLoc = ConsumeToken();
2570
Chris Lattner04d66662007-10-09 17:33:22 +00002571 if (Tok.isNot(tok::l_paren)) {
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00002572 if (!getLang().CPlusPlus) {
Chris Lattner08631c52008-11-23 21:45:46 +00002573 Diag(Tok, diag::err_expected_lparen_after_id) << BuiltinII;
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00002574 return;
2575 }
2576
Sebastian Redl2f7ece72008-12-11 21:36:32 +00002577 OwningExprResult Result(ParseCastExpression(true/*isUnaryExpression*/));
Douglas Gregor809070a2009-02-18 17:45:20 +00002578 if (Result.isInvalid()) {
2579 DS.SetTypeSpecError();
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00002580 return;
Douglas Gregor809070a2009-02-18 17:45:20 +00002581 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00002582
2583 const char *PrevSpec = 0;
2584 // Check for duplicate type specifiers.
2585 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
Sebastian Redleffa8d12008-12-10 00:02:53 +00002586 Result.release()))
Chris Lattner1ab3b962008-11-18 07:48:38 +00002587 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00002588
2589 // FIXME: Not accurate, the range gets one token more than it should.
2590 DS.SetRangeEnd(Tok.getLocation());
Steve Naroff9dfa7b42007-08-02 02:53:48 +00002591 return;
Steve Naroffd1861fd2007-07-31 12:34:36 +00002592 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00002593
Steve Naroffd1861fd2007-07-31 12:34:36 +00002594 SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
2595
Argyrios Kyrtzidis78c8d802008-10-05 19:56:22 +00002596 if (isTypeIdInParens()) {
Douglas Gregor809070a2009-02-18 17:45:20 +00002597 Action::TypeResult Ty = ParseTypeName();
Steve Naroffd1861fd2007-07-31 12:34:36 +00002598
Douglas Gregor809070a2009-02-18 17:45:20 +00002599 assert((Ty.isInvalid() || Ty.get()) &&
2600 "Parser::ParseTypeofSpecifier(): missing type");
Steve Naroff2cb64ec2007-07-31 23:56:32 +00002601
Chris Lattner04d66662007-10-09 17:33:22 +00002602 if (Tok.isNot(tok::r_paren)) {
Steve Naroff2cb64ec2007-07-31 23:56:32 +00002603 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Steve Naroff9dfa7b42007-08-02 02:53:48 +00002604 return;
2605 }
2606 RParenLoc = ConsumeParen();
Douglas Gregor809070a2009-02-18 17:45:20 +00002607
2608 if (Ty.isInvalid())
2609 DS.SetTypeSpecError();
2610 else {
2611 const char *PrevSpec = 0;
2612 // Check for duplicate type specifiers (e.g. "int typeof(int)").
2613 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
2614 Ty.get()))
2615 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
2616 }
Steve Naroffd1861fd2007-07-31 12:34:36 +00002617 } else { // we have an expression.
Sebastian Redl2f7ece72008-12-11 21:36:32 +00002618 OwningExprResult Result(ParseExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00002619
2620 if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
Steve Naroff2cb64ec2007-07-31 23:56:32 +00002621 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor809070a2009-02-18 17:45:20 +00002622 DS.SetTypeSpecError();
Steve Naroff9dfa7b42007-08-02 02:53:48 +00002623 return;
2624 }
2625 RParenLoc = ConsumeParen();
2626 const char *PrevSpec = 0;
2627 // Check for duplicate type specifiers (e.g. "int typeof(int)").
2628 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
Sebastian Redleffa8d12008-12-10 00:02:53 +00002629 Result.release()))
Chris Lattner1ab3b962008-11-18 07:48:38 +00002630 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Steve Naroffd1861fd2007-07-31 12:34:36 +00002631 }
Argyrios Kyrtzidis0919f9e2008-08-16 10:21:33 +00002632 DS.SetRangeEnd(RParenLoc);
Steve Naroffd1861fd2007-07-31 12:34:36 +00002633}
2634
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +00002635