blob: eaf9f8b0f98a91bced3bf188de2e69b7ad804ce7 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner4b009652007-07-25 00:24:17 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
Daniel Dunbarcc7b1602008-08-11 03:45:03 +000015#include "clang/Basic/Diagnostic.h"
Chris Lattnera7549902007-08-26 06:24:45 +000016#include "clang/Parse/Scope.h"
Chris Lattnerdaa5c002008-10-20 06:45:43 +000017#include "ExtensionRAIIObject.h"
Chris Lattner4b009652007-07-25 00:24:17 +000018#include "llvm/ADT/SmallSet.h"
19using namespace clang;
20
21//===----------------------------------------------------------------------===//
22// C99 6.7: Declarations.
23//===----------------------------------------------------------------------===//
24
25/// ParseTypeName
26/// type-name: [C99 6.7.6]
27/// specifier-qualifier-list abstract-declarator[opt]
Sebastian Redl19fec9d2008-11-21 19:14:01 +000028///
29/// Called type-id in C++.
30/// CXXNewMode is a special flag used by the parser of C++ new-expressions. It
31/// is simply passed on to ActOnTypeName.
32Parser::TypeTy *Parser::ParseTypeName(bool CXXNewMode) {
Chris Lattner4b009652007-07-25 00:24:17 +000033 // Parse the common declaration-specifiers piece.
34 DeclSpec DS;
35 ParseSpecifierQualifierList(DS);
36
37 // Parse the abstract-declarator, if present.
38 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
39 ParseDeclarator(DeclaratorInfo);
40
Sebastian Redl19fec9d2008-11-21 19:14:01 +000041 return Actions.ActOnTypeName(CurScope, DeclaratorInfo, CXXNewMode).Val;
Chris Lattner4b009652007-07-25 00:24:17 +000042}
43
44/// ParseAttributes - Parse a non-empty attributes list.
45///
46/// [GNU] attributes:
47/// attribute
48/// attributes attribute
49///
50/// [GNU] attribute:
51/// '__attribute__' '(' '(' attribute-list ')' ')'
52///
53/// [GNU] attribute-list:
54/// attrib
55/// attribute_list ',' attrib
56///
57/// [GNU] attrib:
58/// empty
59/// attrib-name
60/// attrib-name '(' identifier ')'
61/// attrib-name '(' identifier ',' nonempty-expr-list ')'
62/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
63///
64/// [GNU] attrib-name:
65/// identifier
66/// typespec
67/// typequal
68/// storageclass
69///
70/// FIXME: The GCC grammar/code for this construct implies we need two
71/// token lookahead. Comment from gcc: "If they start with an identifier
72/// which is followed by a comma or close parenthesis, then the arguments
73/// start with that identifier; otherwise they are an expression list."
74///
75/// At the moment, I am not doing 2 token lookahead. I am also unaware of
76/// any attributes that don't work (based on my limited testing). Most
77/// attributes are very simple in practice. Until we find a bug, I don't see
78/// a pressing need to implement the 2 token lookahead.
79
80AttributeList *Parser::ParseAttributes() {
Chris Lattner34a01ad2007-10-09 17:33:22 +000081 assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
Chris Lattner4b009652007-07-25 00:24:17 +000082
83 AttributeList *CurrAttr = 0;
84
Chris Lattner34a01ad2007-10-09 17:33:22 +000085 while (Tok.is(tok::kw___attribute)) {
Chris Lattner4b009652007-07-25 00:24:17 +000086 ConsumeToken();
87 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
88 "attribute")) {
89 SkipUntil(tok::r_paren, true); // skip until ) or ;
90 return CurrAttr;
91 }
92 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
93 SkipUntil(tok::r_paren, true); // skip until ) or ;
94 return CurrAttr;
95 }
96 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner34a01ad2007-10-09 17:33:22 +000097 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
98 Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +000099
Chris Lattner34a01ad2007-10-09 17:33:22 +0000100 if (Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000101 // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
102 ConsumeToken();
103 continue;
104 }
105 // we have an identifier or declaration specifier (const, int, etc.)
106 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
107 SourceLocation AttrNameLoc = ConsumeToken();
108
109 // check if we have a "paramterized" attribute
Chris Lattner34a01ad2007-10-09 17:33:22 +0000110 if (Tok.is(tok::l_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000111 ConsumeParen(); // ignore the left paren loc for now
112
Chris Lattner34a01ad2007-10-09 17:33:22 +0000113 if (Tok.is(tok::identifier)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000114 IdentifierInfo *ParmName = Tok.getIdentifierInfo();
115 SourceLocation ParmLoc = ConsumeToken();
116
Chris Lattner34a01ad2007-10-09 17:33:22 +0000117 if (Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000118 // __attribute__(( mode(byte) ))
119 ConsumeParen(); // ignore the right paren loc for now
120 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
121 ParmName, ParmLoc, 0, 0, CurrAttr);
Chris Lattner34a01ad2007-10-09 17:33:22 +0000122 } else if (Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000123 ConsumeToken();
124 // __attribute__(( format(printf, 1, 2) ))
125 llvm::SmallVector<ExprTy*, 8> ArgExprs;
126 bool ArgExprsOk = true;
127
128 // now parse the non-empty comma separated list of expressions
129 while (1) {
130 ExprResult ArgExpr = ParseAssignmentExpression();
131 if (ArgExpr.isInvalid) {
132 ArgExprsOk = false;
133 SkipUntil(tok::r_paren);
134 break;
135 } else {
136 ArgExprs.push_back(ArgExpr.Val);
137 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000138 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000139 break;
140 ConsumeToken(); // Eat the comma, move to the next argument
141 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000142 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000143 ConsumeParen(); // ignore the right paren loc for now
144 CurrAttr = new AttributeList(AttrName, AttrNameLoc, ParmName,
145 ParmLoc, &ArgExprs[0], ArgExprs.size(), CurrAttr);
146 }
147 }
148 } else { // not an identifier
149 // parse a possibly empty comma separated list of expressions
Chris Lattner34a01ad2007-10-09 17:33:22 +0000150 if (Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000151 // __attribute__(( nonnull() ))
152 ConsumeParen(); // ignore the right paren loc for now
153 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
154 0, SourceLocation(), 0, 0, CurrAttr);
155 } else {
156 // __attribute__(( aligned(16) ))
157 llvm::SmallVector<ExprTy*, 8> ArgExprs;
158 bool ArgExprsOk = true;
159
160 // now parse the list of expressions
161 while (1) {
162 ExprResult ArgExpr = ParseAssignmentExpression();
163 if (ArgExpr.isInvalid) {
164 ArgExprsOk = false;
165 SkipUntil(tok::r_paren);
166 break;
167 } else {
168 ArgExprs.push_back(ArgExpr.Val);
169 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000170 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000171 break;
172 ConsumeToken(); // Eat the comma, move to the next argument
173 }
174 // Match the ')'.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000175 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000176 ConsumeParen(); // ignore the right paren loc for now
177 CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
178 SourceLocation(), &ArgExprs[0], ArgExprs.size(),
179 CurrAttr);
180 }
181 }
182 }
183 } else {
184 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
185 0, SourceLocation(), 0, 0, CurrAttr);
186 }
187 }
188 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
189 SkipUntil(tok::r_paren, false);
190 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
191 SkipUntil(tok::r_paren, false);
192 }
193 return CurrAttr;
194}
195
196/// ParseDeclaration - Parse a full 'declaration', which consists of
197/// declaration-specifiers, some number of declarators, and a semicolon.
198/// 'Context' should be a Declarator::TheContext value.
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000199///
200/// declaration: [C99 6.7]
201/// block-declaration ->
202/// simple-declaration
203/// others [FIXME]
204/// [C++] namespace-definition
205/// others... [FIXME]
206///
Chris Lattner4b009652007-07-25 00:24:17 +0000207Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000208 switch (Tok.getKind()) {
209 case tok::kw_namespace:
210 return ParseNamespace(Context);
211 default:
212 return ParseSimpleDeclaration(Context);
213 }
214}
215
216/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
217/// declaration-specifiers init-declarator-list[opt] ';'
218///[C90/C++]init-declarator-list ';' [TODO]
219/// [OMP] threadprivate-directive [TODO]
220Parser::DeclTy *Parser::ParseSimpleDeclaration(unsigned Context) {
Chris Lattner4b009652007-07-25 00:24:17 +0000221 // Parse the common declaration-specifiers piece.
222 DeclSpec DS;
223 ParseDeclarationSpecifiers(DS);
224
225 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
226 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner34a01ad2007-10-09 17:33:22 +0000227 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000228 ConsumeToken();
229 return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
230 }
231
232 Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
233 ParseDeclarator(DeclaratorInfo);
234
235 return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
236}
237
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000238
Chris Lattner4b009652007-07-25 00:24:17 +0000239/// ParseInitDeclaratorListAfterFirstDeclarator - Parse 'declaration' after
240/// parsing 'declaration-specifiers declarator'. This method is split out this
241/// way to handle the ambiguity between top-level function-definitions and
242/// declarations.
243///
Chris Lattner4b009652007-07-25 00:24:17 +0000244/// init-declarator-list: [C99 6.7]
245/// init-declarator
246/// init-declarator-list ',' init-declarator
247/// init-declarator: [C99 6.7]
248/// declarator
249/// declarator '=' initializer
250/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
251/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +0000252/// [C++] declarator initializer[opt]
253///
254/// [C++] initializer:
255/// [C++] '=' initializer-clause
256/// [C++] '(' expression-list ')'
Chris Lattner4b009652007-07-25 00:24:17 +0000257///
258Parser::DeclTy *Parser::
259ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
260
261 // Declarators may be grouped together ("int X, *Y, Z();"). Provide info so
262 // that they can be chained properly if the actions want this.
263 Parser::DeclTy *LastDeclInGroup = 0;
264
265 // At this point, we know that it is not a function definition. Parse the
266 // rest of the init-declarator-list.
267 while (1) {
268 // If a simple-asm-expr is present, parse it.
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000269 if (Tok.is(tok::kw_asm)) {
Daniel Dunbar72eaf8a2008-08-05 16:28:08 +0000270 ExprResult AsmLabel = ParseSimpleAsm();
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000271 if (AsmLabel.isInvalid) {
272 SkipUntil(tok::semi);
273 return 0;
274 }
Daniel Dunbar72eaf8a2008-08-05 16:28:08 +0000275
276 D.setAsmLabel(AsmLabel.Val);
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000277 }
Chris Lattner4b009652007-07-25 00:24:17 +0000278
279 // If attributes are present, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000280 if (Tok.is(tok::kw___attribute))
Chris Lattner4b009652007-07-25 00:24:17 +0000281 D.AddAttributes(ParseAttributes());
Steve Naroff6a0e2092007-09-12 14:07:44 +0000282
283 // Inform the current actions module that we just parsed this declarator.
Daniel Dunbar72eaf8a2008-08-05 16:28:08 +0000284 LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
Steve Naroff6a0e2092007-09-12 14:07:44 +0000285
Chris Lattner4b009652007-07-25 00:24:17 +0000286 // Parse declarator '=' initializer.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000287 if (Tok.is(tok::equal)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000288 ConsumeToken();
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000289 ExprResult Init = ParseInitializer();
Chris Lattner4b009652007-07-25 00:24:17 +0000290 if (Init.isInvalid) {
291 SkipUntil(tok::semi);
292 return 0;
293 }
Steve Naroff6a0e2092007-09-12 14:07:44 +0000294 Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val);
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +0000295 } else if (Tok.is(tok::l_paren)) {
296 // Parse C++ direct initializer: '(' expression-list ')'
297 SourceLocation LParenLoc = ConsumeParen();
298 ExprListTy Exprs;
299 CommaLocsTy CommaLocs;
300
301 bool InvalidExpr = false;
302 if (ParseExpressionList(Exprs, CommaLocs)) {
303 SkipUntil(tok::r_paren);
304 InvalidExpr = true;
305 }
306 // Match the ')'.
307 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
308
309 if (!InvalidExpr) {
310 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
311 "Unexpected number of commas!");
312 Actions.AddCXXDirectInitializerToDecl(LastDeclInGroup, LParenLoc,
313 &Exprs[0], Exprs.size(),
314 &CommaLocs[0], RParenLoc);
315 }
Douglas Gregor81c29152008-10-29 00:13:59 +0000316 } else {
317 Actions.ActOnUninitializedDecl(LastDeclInGroup);
Chris Lattner4b009652007-07-25 00:24:17 +0000318 }
319
Chris Lattner4b009652007-07-25 00:24:17 +0000320 // If we don't have a comma, it is either the end of the list (a ';') or an
321 // error, bail out.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000322 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000323 break;
324
325 // Consume the comma.
326 ConsumeToken();
327
328 // Parse the next declarator.
329 D.clear();
Chris Lattner926cf542008-10-20 04:57:38 +0000330
331 // Accept attributes in an init-declarator. In the first declarator in a
332 // declaration, these would be part of the declspec. In subsequent
333 // declarators, they become part of the declarator itself, so that they
334 // don't apply to declarators after *this* one. Examples:
335 // short __attribute__((common)) var; -> declspec
336 // short var __attribute__((common)); -> declarator
337 // short x, __attribute__((common)) var; -> declarator
338 if (Tok.is(tok::kw___attribute))
339 D.AddAttributes(ParseAttributes());
340
Chris Lattner4b009652007-07-25 00:24:17 +0000341 ParseDeclarator(D);
342 }
343
Chris Lattner34a01ad2007-10-09 17:33:22 +0000344 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000345 ConsumeToken();
346 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
347 }
Fariborz Jahanian6e9c2b12008-01-04 23:23:46 +0000348 // If this is an ObjC2 for-each loop, this is a successful declarator
349 // parse. The syntax for these looks like:
350 // 'for' '(' declaration 'in' expr ')' statement
Fariborz Jahaniancadb0702008-01-04 23:04:08 +0000351 if (D.getContext() == Declarator::ForContext && isTokIdentifier_in()) {
Fariborz Jahanian1300bc72008-01-03 17:55:25 +0000352 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
353 }
Chris Lattner4b009652007-07-25 00:24:17 +0000354 Diag(Tok, diag::err_parse_error);
355 // Skip to end of block or statement
Chris Lattnerf491b412007-08-21 18:36:18 +0000356 SkipUntil(tok::r_brace, true, true);
Chris Lattner34a01ad2007-10-09 17:33:22 +0000357 if (Tok.is(tok::semi))
Chris Lattner4b009652007-07-25 00:24:17 +0000358 ConsumeToken();
359 return 0;
360}
361
362/// ParseSpecifierQualifierList
363/// specifier-qualifier-list:
364/// type-specifier specifier-qualifier-list[opt]
365/// type-qualifier specifier-qualifier-list[opt]
366/// [GNU] attributes specifier-qualifier-list[opt]
367///
368void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
369 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
370 /// parse declaration-specifiers and complain about extra stuff.
371 ParseDeclarationSpecifiers(DS);
372
373 // Validate declspec for type-name.
374 unsigned Specs = DS.getParsedSpecifiers();
Steve Naroff5f0466b2008-06-05 00:02:44 +0000375 if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers())
Chris Lattner4b009652007-07-25 00:24:17 +0000376 Diag(Tok, diag::err_typename_requires_specqual);
377
378 // Issue diagnostic and remove storage class if present.
379 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
380 if (DS.getStorageClassSpecLoc().isValid())
381 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
382 else
383 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
384 DS.ClearStorageClassSpecs();
385 }
386
387 // Issue diagnostic and remove function specfier if present.
388 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000389 if (DS.isInlineSpecified())
390 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
391 if (DS.isVirtualSpecified())
392 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
393 if (DS.isExplicitSpecified())
394 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
Chris Lattner4b009652007-07-25 00:24:17 +0000395 DS.ClearFunctionSpecs();
396 }
397}
398
399/// ParseDeclarationSpecifiers
400/// declaration-specifiers: [C99 6.7]
401/// storage-class-specifier declaration-specifiers[opt]
402/// type-specifier declaration-specifiers[opt]
Chris Lattner4b009652007-07-25 00:24:17 +0000403/// [C99] function-specifier declaration-specifiers[opt]
404/// [GNU] attributes declaration-specifiers[opt]
405///
406/// storage-class-specifier: [C99 6.7.1]
407/// 'typedef'
408/// 'extern'
409/// 'static'
410/// 'auto'
411/// 'register'
Sebastian Redl9f5337b2008-11-14 23:42:31 +0000412/// [C++] 'mutable'
Chris Lattner4b009652007-07-25 00:24:17 +0000413/// [GNU] '__thread'
Chris Lattner4b009652007-07-25 00:24:17 +0000414/// function-specifier: [C99 6.7.4]
415/// [C99] 'inline'
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000416/// [C++] 'virtual'
417/// [C++] 'explicit'
Chris Lattner4b009652007-07-25 00:24:17 +0000418///
419void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
Chris Lattnera4ff4272008-03-13 06:29:04 +0000420 DS.SetRangeStart(Tok.getLocation());
Chris Lattner4b009652007-07-25 00:24:17 +0000421 while (1) {
422 int isInvalid = false;
423 const char *PrevSpec = 0;
424 SourceLocation Loc = Tok.getLocation();
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000425
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000426 // Only annotate C++ scope. Allow class-name as an identifier in case
427 // it's a constructor.
428 TryAnnotateScopeToken();
429
Chris Lattner4b009652007-07-25 00:24:17 +0000430 switch (Tok.getKind()) {
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000431 default:
432 // Try to parse a type-specifier; if we found one, continue.
433 if (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec))
434 continue;
435
Chris Lattnerb99d7492008-07-26 00:20:22 +0000436 DoneWithDeclSpec:
Chris Lattner4b009652007-07-25 00:24:17 +0000437 // If this is not a declaration specifier token, we're done reading decl
438 // specifiers. First verify that DeclSpec's are consistent.
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000439 DS.Finish(Diags, PP.getSourceManager(), getLang());
Chris Lattner4b009652007-07-25 00:24:17 +0000440 return;
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000441
442 case tok::annot_cxxscope: {
443 if (DS.hasTypeSpecifier())
444 goto DoneWithDeclSpec;
445
446 // We are looking for a qualified typename.
447 if (NextToken().isNot(tok::identifier))
448 goto DoneWithDeclSpec;
449
450 CXXScopeSpec SS;
451 SS.setScopeRep(Tok.getAnnotationValue());
452 SS.setRange(Tok.getAnnotationRange());
453
454 // If the next token is the name of the class type that the C++ scope
455 // denotes, followed by a '(', then this is a constructor declaration.
456 // We're done with the decl-specifiers.
457 if (Actions.isCurrentClassName(*NextToken().getIdentifierInfo(),
458 CurScope, &SS) &&
459 GetLookAheadToken(2).is(tok::l_paren))
460 goto DoneWithDeclSpec;
461
462 TypeTy *TypeRep = Actions.isTypeName(*NextToken().getIdentifierInfo(),
463 CurScope, &SS);
464 if (TypeRep == 0)
465 goto DoneWithDeclSpec;
466
467 ConsumeToken(); // The C++ scope.
468
469 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
470 TypeRep);
471 if (isInvalid)
472 break;
473
474 DS.SetRangeEnd(Tok.getLocation());
475 ConsumeToken(); // The typename.
476
477 continue;
478 }
479
Chris Lattnerfda18db2008-07-26 01:18:38 +0000480 // typedef-name
481 case tok::identifier: {
482 // This identifier can only be a typedef name if we haven't already seen
483 // a type-specifier. Without this check we misparse:
484 // typedef int X; struct Y { short X; }; as 'short int'.
485 if (DS.hasTypeSpecifier())
486 goto DoneWithDeclSpec;
487
488 // It has to be available as a typedef too!
Argiris Kirtzidis46403632008-08-01 10:35:27 +0000489 TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
Chris Lattnerfda18db2008-07-26 01:18:38 +0000490 if (TypeRep == 0)
491 goto DoneWithDeclSpec;
492
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000493 // C++: If the identifier is actually the name of the class type
494 // being defined and the next token is a '(', then this is a
495 // constructor declaration. We're done with the decl-specifiers
496 // and will treat this token as an identifier.
497 if (getLang().CPlusPlus &&
498 CurScope->isCXXClassScope() &&
499 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) &&
500 NextToken().getKind() == tok::l_paren)
501 goto DoneWithDeclSpec;
502
Chris Lattnerfda18db2008-07-26 01:18:38 +0000503 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
504 TypeRep);
505 if (isInvalid)
506 break;
507
508 DS.SetRangeEnd(Tok.getLocation());
509 ConsumeToken(); // The identifier
510
511 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
512 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
513 // Objective-C interface. If we don't have Objective-C or a '<', this is
514 // just a normal reference to a typedef name.
515 if (!Tok.is(tok::less) || !getLang().ObjC1)
516 continue;
517
518 SourceLocation EndProtoLoc;
Chris Lattnerada63792008-07-26 01:53:50 +0000519 llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
Chris Lattner2bdedd62008-07-26 04:03:38 +0000520 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Chris Lattnerada63792008-07-26 01:53:50 +0000521 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
Chris Lattnerfda18db2008-07-26 01:18:38 +0000522
523 DS.SetRangeEnd(EndProtoLoc);
524
Steve Narofff7683302008-09-22 10:28:57 +0000525 // Need to support trailing type qualifiers (e.g. "id<p> const").
526 // If a type specifier follows, it will be diagnosed elsewhere.
527 continue;
Chris Lattnerfda18db2008-07-26 01:18:38 +0000528 }
Chris Lattner4b009652007-07-25 00:24:17 +0000529 // GNU attributes support.
530 case tok::kw___attribute:
531 DS.AddAttributes(ParseAttributes());
532 continue;
533
534 // storage-class-specifier
535 case tok::kw_typedef:
536 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
537 break;
538 case tok::kw_extern:
539 if (DS.isThreadSpecified())
Chris Lattnerf006a222008-11-18 07:48:38 +0000540 Diag(Tok, diag::ext_thread_before) << "extern";
Chris Lattner4b009652007-07-25 00:24:17 +0000541 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec);
542 break;
Steve Narofff258a0f2007-12-18 00:16:02 +0000543 case tok::kw___private_extern__:
Chris Lattner9f7564b2008-04-06 06:57:35 +0000544 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
545 PrevSpec);
Steve Narofff258a0f2007-12-18 00:16:02 +0000546 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000547 case tok::kw_static:
548 if (DS.isThreadSpecified())
Chris Lattnerf006a222008-11-18 07:48:38 +0000549 Diag(Tok, diag::ext_thread_before) << "static";
Chris Lattner4b009652007-07-25 00:24:17 +0000550 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
551 break;
552 case tok::kw_auto:
553 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
554 break;
555 case tok::kw_register:
556 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
557 break;
Sebastian Redl9f5337b2008-11-14 23:42:31 +0000558 case tok::kw_mutable:
559 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec);
560 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000561 case tok::kw___thread:
562 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec)*2;
563 break;
564
Chris Lattner4b009652007-07-25 00:24:17 +0000565 continue;
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000566
Chris Lattner4b009652007-07-25 00:24:17 +0000567 // function-specifier
568 case tok::kw_inline:
569 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec);
570 break;
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000571
572 case tok::kw_virtual:
573 isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec);
574 break;
575
576 case tok::kw_explicit:
577 isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec);
578 break;
Steve Naroff5f0466b2008-06-05 00:02:44 +0000579
Steve Naroff5f0466b2008-06-05 00:02:44 +0000580 case tok::less:
Chris Lattnerfda18db2008-07-26 01:18:38 +0000581 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerb99d7492008-07-26 00:20:22 +0000582 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
583 // but we support it.
Chris Lattnerfda18db2008-07-26 01:18:38 +0000584 if (DS.hasTypeSpecifier() || !getLang().ObjC1)
Chris Lattnerb99d7492008-07-26 00:20:22 +0000585 goto DoneWithDeclSpec;
586
587 {
588 SourceLocation EndProtoLoc;
Chris Lattnerada63792008-07-26 01:53:50 +0000589 llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
Chris Lattner2bdedd62008-07-26 04:03:38 +0000590 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Chris Lattnerada63792008-07-26 01:53:50 +0000591 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
Chris Lattnerfda18db2008-07-26 01:18:38 +0000592 DS.SetRangeEnd(EndProtoLoc);
593
Chris Lattnerf006a222008-11-18 07:48:38 +0000594 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
595 << SourceRange(Loc, EndProtoLoc);
Steve Narofff7683302008-09-22 10:28:57 +0000596 // Need to support trailing type qualifiers (e.g. "id<p> const").
597 // If a type specifier follows, it will be diagnosed elsewhere.
598 continue;
Steve Naroff5f0466b2008-06-05 00:02:44 +0000599 }
Chris Lattner4b009652007-07-25 00:24:17 +0000600 }
601 // If the specifier combination wasn't legal, issue a diagnostic.
602 if (isInvalid) {
603 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattnerf006a222008-11-18 07:48:38 +0000604 // Pick between error or extwarn.
605 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
606 : diag::ext_duplicate_declspec;
607 Diag(Tok, DiagID) << PrevSpec;
Chris Lattner4b009652007-07-25 00:24:17 +0000608 }
Chris Lattnera4ff4272008-03-13 06:29:04 +0000609 DS.SetRangeEnd(Tok.getLocation());
Chris Lattner4b009652007-07-25 00:24:17 +0000610 ConsumeToken();
611 }
612}
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000613/// MaybeParseTypeSpecifier - Try to parse a single type-specifier. We
614/// primarily follow the C++ grammar with additions for C99 and GNU,
615/// which together subsume the C grammar. Note that the C++
616/// type-specifier also includes the C type-qualifier (for const,
617/// volatile, and C99 restrict). Returns true if a type-specifier was
618/// found (and parsed), false otherwise.
619///
620/// type-specifier: [C++ 7.1.5]
621/// simple-type-specifier
622/// class-specifier
623/// enum-specifier
624/// elaborated-type-specifier [TODO]
625/// cv-qualifier
626///
627/// cv-qualifier: [C++ 7.1.5.1]
628/// 'const'
629/// 'volatile'
630/// [C99] 'restrict'
631///
632/// simple-type-specifier: [ C++ 7.1.5.2]
633/// '::'[opt] nested-name-specifier[opt] type-name [TODO]
634/// '::'[opt] nested-name-specifier 'template' template-id [TODO]
635/// 'char'
636/// 'wchar_t'
637/// 'bool'
638/// 'short'
639/// 'int'
640/// 'long'
641/// 'signed'
642/// 'unsigned'
643/// 'float'
644/// 'double'
645/// 'void'
646/// [C99] '_Bool'
647/// [C99] '_Complex'
648/// [C99] '_Imaginary' // Removed in TC2?
649/// [GNU] '_Decimal32'
650/// [GNU] '_Decimal64'
651/// [GNU] '_Decimal128'
652/// [GNU] typeof-specifier
653/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
654/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
655bool Parser::MaybeParseTypeSpecifier(DeclSpec &DS, int& isInvalid,
656 const char *&PrevSpec) {
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000657 // Annotate typenames and C++ scope specifiers.
658 TryAnnotateTypeOrScopeToken();
659
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000660 SourceLocation Loc = Tok.getLocation();
661
662 switch (Tok.getKind()) {
663 // simple-type-specifier:
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000664 case tok::annot_qualtypename: {
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000665 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000666 Tok.getAnnotationValue());
667 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
668 ConsumeToken(); // The typename
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000669
670 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
671 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
672 // Objective-C interface. If we don't have Objective-C or a '<', this is
673 // just a normal reference to a typedef name.
674 if (!Tok.is(tok::less) || !getLang().ObjC1)
675 return true;
676
677 SourceLocation EndProtoLoc;
678 llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
679 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
680 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
681
682 DS.SetRangeEnd(EndProtoLoc);
683 return true;
684 }
685
686 case tok::kw_short:
687 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
688 break;
689 case tok::kw_long:
690 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
691 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
692 else
693 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
694 break;
695 case tok::kw_signed:
696 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
697 break;
698 case tok::kw_unsigned:
699 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
700 break;
701 case tok::kw__Complex:
702 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
703 break;
704 case tok::kw__Imaginary:
705 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
706 break;
707 case tok::kw_void:
708 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
709 break;
710 case tok::kw_char:
711 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
712 break;
713 case tok::kw_int:
714 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
715 break;
716 case tok::kw_float:
717 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
718 break;
719 case tok::kw_double:
720 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
721 break;
722 case tok::kw_wchar_t:
723 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
724 break;
725 case tok::kw_bool:
726 case tok::kw__Bool:
727 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
728 break;
729 case tok::kw__Decimal32:
730 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
731 break;
732 case tok::kw__Decimal64:
733 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
734 break;
735 case tok::kw__Decimal128:
736 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
737 break;
738
739 // class-specifier:
740 case tok::kw_class:
741 case tok::kw_struct:
742 case tok::kw_union:
743 ParseClassSpecifier(DS);
744 return true;
745
746 // enum-specifier:
747 case tok::kw_enum:
748 ParseEnumSpecifier(DS);
749 return true;
750
751 // cv-qualifier:
752 case tok::kw_const:
753 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
754 getLang())*2;
755 break;
756 case tok::kw_volatile:
757 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
758 getLang())*2;
759 break;
760 case tok::kw_restrict:
761 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
762 getLang())*2;
763 break;
764
765 // GNU typeof support.
766 case tok::kw_typeof:
767 ParseTypeofSpecifier(DS);
768 return true;
769
770 default:
771 // Not a type-specifier; do nothing.
772 return false;
773 }
774
775 // If the specifier combination wasn't legal, issue a diagnostic.
776 if (isInvalid) {
777 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattnerf006a222008-11-18 07:48:38 +0000778 // Pick between error or extwarn.
779 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
780 : diag::ext_duplicate_declspec;
781 Diag(Tok, DiagID) << PrevSpec;
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000782 }
783 DS.SetRangeEnd(Tok.getLocation());
784 ConsumeToken(); // whatever we parsed above.
785 return true;
786}
Chris Lattner4b009652007-07-25 00:24:17 +0000787
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000788/// ParseStructDeclaration - Parse a struct declaration without the terminating
789/// semicolon.
790///
Chris Lattner4b009652007-07-25 00:24:17 +0000791/// struct-declaration:
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000792/// specifier-qualifier-list struct-declarator-list
Chris Lattner4b009652007-07-25 00:24:17 +0000793/// [GNU] __extension__ struct-declaration
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000794/// [GNU] specifier-qualifier-list
Chris Lattner4b009652007-07-25 00:24:17 +0000795/// struct-declarator-list:
796/// struct-declarator
797/// struct-declarator-list ',' struct-declarator
798/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
799/// struct-declarator:
800/// declarator
801/// [GNU] declarator attributes[opt]
802/// declarator[opt] ':' constant-expression
803/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
804///
Chris Lattner3dd8d392008-04-10 06:46:29 +0000805void Parser::
806ParseStructDeclaration(DeclSpec &DS,
807 llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
Chris Lattnerdaa5c002008-10-20 06:45:43 +0000808 if (Tok.is(tok::kw___extension__)) {
809 // __extension__ silences extension warnings in the subexpression.
810 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroffa9adf112007-08-20 22:28:22 +0000811 ConsumeToken();
Chris Lattnerdaa5c002008-10-20 06:45:43 +0000812 return ParseStructDeclaration(DS, Fields);
813 }
Steve Naroffa9adf112007-08-20 22:28:22 +0000814
815 // Parse the common specifier-qualifiers-list piece.
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000816 SourceLocation DSStart = Tok.getLocation();
Steve Naroffa9adf112007-08-20 22:28:22 +0000817 ParseSpecifierQualifierList(DS);
Steve Naroffa9adf112007-08-20 22:28:22 +0000818
819 // If there are no declarators, issue a warning.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000820 if (Tok.is(tok::semi)) {
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000821 Diag(DSStart, diag::w_no_declarators);
Steve Naroffa9adf112007-08-20 22:28:22 +0000822 return;
823 }
824
825 // Read struct-declarators until we find the semicolon.
Chris Lattnerf62fb732008-04-10 16:37:40 +0000826 Fields.push_back(FieldDeclarator(DS));
Steve Naroffa9adf112007-08-20 22:28:22 +0000827 while (1) {
Chris Lattner3dd8d392008-04-10 06:46:29 +0000828 FieldDeclarator &DeclaratorInfo = Fields.back();
829
Steve Naroffa9adf112007-08-20 22:28:22 +0000830 /// struct-declarator: declarator
831 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattner34a01ad2007-10-09 17:33:22 +0000832 if (Tok.isNot(tok::colon))
Chris Lattner3dd8d392008-04-10 06:46:29 +0000833 ParseDeclarator(DeclaratorInfo.D);
Steve Naroffa9adf112007-08-20 22:28:22 +0000834
Chris Lattner34a01ad2007-10-09 17:33:22 +0000835 if (Tok.is(tok::colon)) {
Steve Naroffa9adf112007-08-20 22:28:22 +0000836 ConsumeToken();
837 ExprResult Res = ParseConstantExpression();
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000838 if (Res.isInvalid)
Steve Naroffa9adf112007-08-20 22:28:22 +0000839 SkipUntil(tok::semi, true, true);
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000840 else
Chris Lattner3dd8d392008-04-10 06:46:29 +0000841 DeclaratorInfo.BitfieldSize = Res.Val;
Steve Naroffa9adf112007-08-20 22:28:22 +0000842 }
843
844 // If attributes exist after the declarator, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000845 if (Tok.is(tok::kw___attribute))
Chris Lattner3dd8d392008-04-10 06:46:29 +0000846 DeclaratorInfo.D.AddAttributes(ParseAttributes());
Steve Naroffa9adf112007-08-20 22:28:22 +0000847
848 // If we don't have a comma, it is either the end of the list (a ';')
849 // or an error, bail out.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000850 if (Tok.isNot(tok::comma))
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000851 return;
Steve Naroffa9adf112007-08-20 22:28:22 +0000852
853 // Consume the comma.
854 ConsumeToken();
855
856 // Parse the next declarator.
Chris Lattnerf62fb732008-04-10 16:37:40 +0000857 Fields.push_back(FieldDeclarator(DS));
Steve Naroffa9adf112007-08-20 22:28:22 +0000858
859 // Attributes are only allowed on the second declarator.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000860 if (Tok.is(tok::kw___attribute))
Chris Lattner3dd8d392008-04-10 06:46:29 +0000861 Fields.back().D.AddAttributes(ParseAttributes());
Steve Naroffa9adf112007-08-20 22:28:22 +0000862 }
Steve Naroffa9adf112007-08-20 22:28:22 +0000863}
864
865/// ParseStructUnionBody
866/// struct-contents:
867/// struct-declaration-list
868/// [EXT] empty
869/// [GNU] "struct-declaration-list" without terminatoring ';'
870/// struct-declaration-list:
871/// struct-declaration
872/// struct-declaration-list struct-declaration
Chris Lattner1bf58f62008-06-21 19:39:06 +0000873/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroffa9adf112007-08-20 22:28:22 +0000874///
Chris Lattner4b009652007-07-25 00:24:17 +0000875void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
876 unsigned TagType, DeclTy *TagDecl) {
877 SourceLocation LBraceLoc = ConsumeBrace();
878
879 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
880 // C++.
Douglas Gregorec93f442008-04-13 21:30:24 +0000881 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattnerf006a222008-11-18 07:48:38 +0000882 Diag(Tok, diag::ext_empty_struct_union_enum)
883 << DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
Chris Lattner4b009652007-07-25 00:24:17 +0000884
885 llvm::SmallVector<DeclTy*, 32> FieldDecls;
Chris Lattner3dd8d392008-04-10 06:46:29 +0000886 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
887
Chris Lattner4b009652007-07-25 00:24:17 +0000888 // While we still have something to read, read the declarations in the struct.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000889 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000890 // Each iteration of this loop reads one struct-declaration.
891
892 // Check for extraneous top-level semicolon.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000893 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000894 Diag(Tok, diag::ext_extra_struct_semi);
895 ConsumeToken();
896 continue;
897 }
Chris Lattner3dd8d392008-04-10 06:46:29 +0000898
899 // Parse all the comma separated declarators.
900 DeclSpec DS;
901 FieldDeclarators.clear();
Chris Lattner1bf58f62008-06-21 19:39:06 +0000902 if (!Tok.is(tok::at)) {
903 ParseStructDeclaration(DS, FieldDeclarators);
904
905 // Convert them all to fields.
906 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
907 FieldDeclarator &FD = FieldDeclarators[i];
908 // Install the declarator into the current TagDecl.
909 DeclTy *Field = Actions.ActOnField(CurScope,
910 DS.getSourceRange().getBegin(),
911 FD.D, FD.BitfieldSize);
912 FieldDecls.push_back(Field);
913 }
914 } else { // Handle @defs
915 ConsumeToken();
916 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
917 Diag(Tok, diag::err_unexpected_at);
918 SkipUntil(tok::semi, true, true);
919 continue;
920 }
921 ConsumeToken();
922 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
923 if (!Tok.is(tok::identifier)) {
924 Diag(Tok, diag::err_expected_ident);
925 SkipUntil(tok::semi, true, true);
926 continue;
927 }
928 llvm::SmallVector<DeclTy*, 16> Fields;
929 Actions.ActOnDefs(CurScope, Tok.getLocation(), Tok.getIdentifierInfo(),
930 Fields);
931 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
932 ConsumeToken();
933 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
934 }
Chris Lattner4b009652007-07-25 00:24:17 +0000935
Chris Lattner34a01ad2007-10-09 17:33:22 +0000936 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000937 ConsumeToken();
Chris Lattner34a01ad2007-10-09 17:33:22 +0000938 } else if (Tok.is(tok::r_brace)) {
Chris Lattnerf006a222008-11-18 07:48:38 +0000939 Diag(Tok, diag::ext_expected_semi_decl_list);
Chris Lattner4b009652007-07-25 00:24:17 +0000940 break;
941 } else {
942 Diag(Tok, diag::err_expected_semi_decl_list);
943 // Skip to end of block or statement
944 SkipUntil(tok::r_brace, true, true);
945 }
946 }
947
Steve Naroff1a7fa7b2007-10-29 21:38:07 +0000948 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
Chris Lattner4b009652007-07-25 00:24:17 +0000949
Chris Lattner4b009652007-07-25 00:24:17 +0000950 AttributeList *AttrList = 0;
951 // If attributes exist after struct contents, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000952 if (Tok.is(tok::kw___attribute))
Daniel Dunbar3b908072008-10-03 16:42:10 +0000953 AttrList = ParseAttributes();
Daniel Dunbarf3944442008-10-03 02:03:53 +0000954
955 Actions.ActOnFields(CurScope,
956 RecordLoc,TagDecl,&FieldDecls[0],FieldDecls.size(),
957 LBraceLoc, RBraceLoc,
958 AttrList);
Chris Lattner4b009652007-07-25 00:24:17 +0000959}
960
961
962/// ParseEnumSpecifier
963/// enum-specifier: [C99 6.7.2.2]
964/// 'enum' identifier[opt] '{' enumerator-list '}'
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000965///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Chris Lattner4b009652007-07-25 00:24:17 +0000966/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
967/// '}' attributes[opt]
968/// 'enum' identifier
969/// [GNU] 'enum' attributes[opt] identifier
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000970///
971/// [C++] elaborated-type-specifier:
972/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
973///
Chris Lattner4b009652007-07-25 00:24:17 +0000974void Parser::ParseEnumSpecifier(DeclSpec &DS) {
Chris Lattner34a01ad2007-10-09 17:33:22 +0000975 assert(Tok.is(tok::kw_enum) && "Not an enum specifier");
Chris Lattner4b009652007-07-25 00:24:17 +0000976 SourceLocation StartLoc = ConsumeToken();
977
978 // Parse the tag portion of this.
Argiris Kirtzidis2298f012008-09-11 00:21:41 +0000979
980 AttributeList *Attr = 0;
981 // If attributes exist after tag, parse them.
982 if (Tok.is(tok::kw___attribute))
983 Attr = ParseAttributes();
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000984
985 CXXScopeSpec SS;
986 if (isTokenCXXScopeSpecifier()) {
987 ParseCXXScopeSpecifier(SS);
988 if (Tok.isNot(tok::identifier)) {
989 Diag(Tok, diag::err_expected_ident);
990 if (Tok.isNot(tok::l_brace)) {
991 // Has no name and is not a definition.
992 // Skip the rest of this declarator, up until the comma or semicolon.
993 SkipUntil(tok::comma, true);
994 return;
995 }
996 }
997 }
Argiris Kirtzidis2298f012008-09-11 00:21:41 +0000998
999 // Must have either 'enum name' or 'enum {...}'.
1000 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) {
1001 Diag(Tok, diag::err_expected_ident_lbrace);
1002
1003 // Skip the rest of this declarator, up until the comma or semicolon.
1004 SkipUntil(tok::comma, true);
Chris Lattner4b009652007-07-25 00:24:17 +00001005 return;
Argiris Kirtzidis2298f012008-09-11 00:21:41 +00001006 }
1007
1008 // If an identifier is present, consume and remember it.
1009 IdentifierInfo *Name = 0;
1010 SourceLocation NameLoc;
1011 if (Tok.is(tok::identifier)) {
1012 Name = Tok.getIdentifierInfo();
1013 NameLoc = ConsumeToken();
1014 }
1015
1016 // There are three options here. If we have 'enum foo;', then this is a
1017 // forward declaration. If we have 'enum foo {...' then this is a
1018 // definition. Otherwise we have something like 'enum foo xyz', a reference.
1019 //
1020 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
1021 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
1022 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
1023 //
1024 Action::TagKind TK;
1025 if (Tok.is(tok::l_brace))
1026 TK = Action::TK_Definition;
1027 else if (Tok.is(tok::semi))
1028 TK = Action::TK_Declaration;
1029 else
1030 TK = Action::TK_Reference;
1031 DeclTy *TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK, StartLoc,
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001032 SS, Name, NameLoc, Attr);
Chris Lattner4b009652007-07-25 00:24:17 +00001033
Chris Lattner34a01ad2007-10-09 17:33:22 +00001034 if (Tok.is(tok::l_brace))
Chris Lattner4b009652007-07-25 00:24:17 +00001035 ParseEnumBody(StartLoc, TagDecl);
1036
1037 // TODO: semantic analysis on the declspec for enums.
1038 const char *PrevSpec = 0;
1039 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, TagDecl))
Chris Lattnerf006a222008-11-18 07:48:38 +00001040 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Chris Lattner4b009652007-07-25 00:24:17 +00001041}
1042
1043/// ParseEnumBody - Parse a {} enclosed enumerator-list.
1044/// enumerator-list:
1045/// enumerator
1046/// enumerator-list ',' enumerator
1047/// enumerator:
1048/// enumeration-constant
1049/// enumeration-constant '=' constant-expression
1050/// enumeration-constant:
1051/// identifier
1052///
1053void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
1054 SourceLocation LBraceLoc = ConsumeBrace();
1055
Chris Lattnerc9a92452007-08-27 17:24:30 +00001056 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
Chris Lattner34a01ad2007-10-09 17:33:22 +00001057 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattnerf006a222008-11-18 07:48:38 +00001058 Diag(Tok, diag::ext_empty_struct_union_enum) << "enum";
Chris Lattner4b009652007-07-25 00:24:17 +00001059
1060 llvm::SmallVector<DeclTy*, 32> EnumConstantDecls;
1061
1062 DeclTy *LastEnumConstDecl = 0;
1063
1064 // Parse the enumerator-list.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001065 while (Tok.is(tok::identifier)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001066 IdentifierInfo *Ident = Tok.getIdentifierInfo();
1067 SourceLocation IdentLoc = ConsumeToken();
1068
1069 SourceLocation EqualLoc;
1070 ExprTy *AssignedVal = 0;
Chris Lattner34a01ad2007-10-09 17:33:22 +00001071 if (Tok.is(tok::equal)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001072 EqualLoc = ConsumeToken();
1073 ExprResult Res = ParseConstantExpression();
1074 if (Res.isInvalid)
1075 SkipUntil(tok::comma, tok::r_brace, true, true);
1076 else
1077 AssignedVal = Res.Val;
1078 }
1079
1080 // Install the enumerator constant into EnumDecl.
Steve Naroff0acc9c92007-09-15 18:49:24 +00001081 DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
Chris Lattner4b009652007-07-25 00:24:17 +00001082 LastEnumConstDecl,
1083 IdentLoc, Ident,
1084 EqualLoc, AssignedVal);
1085 EnumConstantDecls.push_back(EnumConstDecl);
1086 LastEnumConstDecl = EnumConstDecl;
1087
Chris Lattner34a01ad2007-10-09 17:33:22 +00001088 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +00001089 break;
1090 SourceLocation CommaLoc = ConsumeToken();
1091
Chris Lattner34a01ad2007-10-09 17:33:22 +00001092 if (Tok.isNot(tok::identifier) && !getLang().C99)
Chris Lattner4b009652007-07-25 00:24:17 +00001093 Diag(CommaLoc, diag::ext_c99_enumerator_list_comma);
1094 }
1095
1096 // Eat the }.
1097 MatchRHSPunctuation(tok::r_brace, LBraceLoc);
1098
Steve Naroff0acc9c92007-09-15 18:49:24 +00001099 Actions.ActOnEnumBody(StartLoc, EnumDecl, &EnumConstantDecls[0],
Chris Lattner4b009652007-07-25 00:24:17 +00001100 EnumConstantDecls.size());
1101
1102 DeclTy *AttrList = 0;
1103 // If attributes exist after the identifier list, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001104 if (Tok.is(tok::kw___attribute))
Chris Lattner4b009652007-07-25 00:24:17 +00001105 AttrList = ParseAttributes(); // FIXME: where do they do?
1106}
1107
1108/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff6f9f9552008-02-11 23:15:56 +00001109/// start of a type-qualifier-list.
1110bool Parser::isTypeQualifier() const {
1111 switch (Tok.getKind()) {
1112 default: return false;
1113 // type-qualifier
1114 case tok::kw_const:
1115 case tok::kw_volatile:
1116 case tok::kw_restrict:
1117 return true;
1118 }
1119}
1120
1121/// isTypeSpecifierQualifier - Return true if the current token could be the
Chris Lattner4b009652007-07-25 00:24:17 +00001122/// start of a specifier-qualifier-list.
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001123bool Parser::isTypeSpecifierQualifier() {
1124 // Annotate typenames and C++ scope specifiers.
1125 TryAnnotateTypeOrScopeToken();
1126
Chris Lattner4b009652007-07-25 00:24:17 +00001127 switch (Tok.getKind()) {
1128 default: return false;
1129 // GNU attributes support.
1130 case tok::kw___attribute:
Steve Naroff7cbb1462007-07-31 12:34:36 +00001131 // GNU typeof support.
1132 case tok::kw_typeof:
1133
Chris Lattner4b009652007-07-25 00:24:17 +00001134 // type-specifiers
1135 case tok::kw_short:
1136 case tok::kw_long:
1137 case tok::kw_signed:
1138 case tok::kw_unsigned:
1139 case tok::kw__Complex:
1140 case tok::kw__Imaginary:
1141 case tok::kw_void:
1142 case tok::kw_char:
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +00001143 case tok::kw_wchar_t:
Chris Lattner4b009652007-07-25 00:24:17 +00001144 case tok::kw_int:
1145 case tok::kw_float:
1146 case tok::kw_double:
Chris Lattner2baef2e2007-11-15 05:25:19 +00001147 case tok::kw_bool:
Chris Lattner4b009652007-07-25 00:24:17 +00001148 case tok::kw__Bool:
1149 case tok::kw__Decimal32:
1150 case tok::kw__Decimal64:
1151 case tok::kw__Decimal128:
1152
Chris Lattner2e78db32008-04-13 18:59:07 +00001153 // struct-or-union-specifier (C99) or class-specifier (C++)
1154 case tok::kw_class:
Chris Lattner4b009652007-07-25 00:24:17 +00001155 case tok::kw_struct:
1156 case tok::kw_union:
1157 // enum-specifier
1158 case tok::kw_enum:
1159
1160 // type-qualifier
1161 case tok::kw_const:
1162 case tok::kw_volatile:
1163 case tok::kw_restrict:
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001164
1165 // typedef-name
1166 case tok::annot_qualtypename:
Chris Lattner4b009652007-07-25 00:24:17 +00001167 return true;
Chris Lattner9aefe722008-10-20 00:25:30 +00001168
1169 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
1170 case tok::less:
1171 return getLang().ObjC1;
Chris Lattner4b009652007-07-25 00:24:17 +00001172 }
1173}
1174
1175/// isDeclarationSpecifier() - Return true if the current token is part of a
1176/// declaration specifier.
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001177bool Parser::isDeclarationSpecifier() {
1178 // Annotate typenames and C++ scope specifiers.
1179 TryAnnotateTypeOrScopeToken();
1180
Chris Lattner4b009652007-07-25 00:24:17 +00001181 switch (Tok.getKind()) {
1182 default: return false;
1183 // storage-class-specifier
1184 case tok::kw_typedef:
1185 case tok::kw_extern:
Steve Narofff258a0f2007-12-18 00:16:02 +00001186 case tok::kw___private_extern__:
Chris Lattner4b009652007-07-25 00:24:17 +00001187 case tok::kw_static:
1188 case tok::kw_auto:
1189 case tok::kw_register:
1190 case tok::kw___thread:
1191
1192 // type-specifiers
1193 case tok::kw_short:
1194 case tok::kw_long:
1195 case tok::kw_signed:
1196 case tok::kw_unsigned:
1197 case tok::kw__Complex:
1198 case tok::kw__Imaginary:
1199 case tok::kw_void:
1200 case tok::kw_char:
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +00001201 case tok::kw_wchar_t:
Chris Lattner4b009652007-07-25 00:24:17 +00001202 case tok::kw_int:
1203 case tok::kw_float:
1204 case tok::kw_double:
Chris Lattner2baef2e2007-11-15 05:25:19 +00001205 case tok::kw_bool:
Chris Lattner4b009652007-07-25 00:24:17 +00001206 case tok::kw__Bool:
1207 case tok::kw__Decimal32:
1208 case tok::kw__Decimal64:
1209 case tok::kw__Decimal128:
1210
Chris Lattner2e78db32008-04-13 18:59:07 +00001211 // struct-or-union-specifier (C99) or class-specifier (C++)
1212 case tok::kw_class:
Chris Lattner4b009652007-07-25 00:24:17 +00001213 case tok::kw_struct:
1214 case tok::kw_union:
1215 // enum-specifier
1216 case tok::kw_enum:
1217
1218 // type-qualifier
1219 case tok::kw_const:
1220 case tok::kw_volatile:
1221 case tok::kw_restrict:
Steve Naroff7cbb1462007-07-31 12:34:36 +00001222
Chris Lattner4b009652007-07-25 00:24:17 +00001223 // function-specifier
1224 case tok::kw_inline:
Douglas Gregorf15ac4b2008-10-31 09:07:45 +00001225 case tok::kw_virtual:
1226 case tok::kw_explicit:
Chris Lattnere35d2582007-08-09 16:40:21 +00001227
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001228 // typedef-name
1229 case tok::annot_qualtypename:
1230
Chris Lattnerb707a7a2007-08-09 17:01:07 +00001231 // GNU typeof support.
1232 case tok::kw_typeof:
1233
1234 // GNU attributes.
Chris Lattnere35d2582007-08-09 16:40:21 +00001235 case tok::kw___attribute:
Chris Lattner4b009652007-07-25 00:24:17 +00001236 return true;
Chris Lattner1b2251c2008-07-26 03:38:44 +00001237
1238 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
1239 case tok::less:
1240 return getLang().ObjC1;
Chris Lattner4b009652007-07-25 00:24:17 +00001241 }
1242}
1243
1244
1245/// ParseTypeQualifierListOpt
1246/// type-qualifier-list: [C99 6.7.5]
1247/// type-qualifier
1248/// [GNU] attributes
1249/// type-qualifier-list type-qualifier
1250/// [GNU] type-qualifier-list attributes
1251///
1252void Parser::ParseTypeQualifierListOpt(DeclSpec &DS) {
1253 while (1) {
1254 int isInvalid = false;
1255 const char *PrevSpec = 0;
1256 SourceLocation Loc = Tok.getLocation();
1257
1258 switch (Tok.getKind()) {
1259 default:
1260 // If this is not a type-qualifier token, we're done reading type
1261 // qualifiers. First verify that DeclSpec's are consistent.
Ted Kremenekb3ee1932007-12-11 21:27:55 +00001262 DS.Finish(Diags, PP.getSourceManager(), getLang());
Chris Lattner4b009652007-07-25 00:24:17 +00001263 return;
1264 case tok::kw_const:
1265 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
1266 getLang())*2;
1267 break;
1268 case tok::kw_volatile:
1269 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
1270 getLang())*2;
1271 break;
1272 case tok::kw_restrict:
1273 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
1274 getLang())*2;
1275 break;
1276 case tok::kw___attribute:
1277 DS.AddAttributes(ParseAttributes());
1278 continue; // do *not* consume the next token!
1279 }
1280
1281 // If the specifier combination wasn't legal, issue a diagnostic.
1282 if (isInvalid) {
1283 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattnerf006a222008-11-18 07:48:38 +00001284 // Pick between error or extwarn.
1285 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
1286 : diag::ext_duplicate_declspec;
1287 Diag(Tok, DiagID) << PrevSpec;
Chris Lattner4b009652007-07-25 00:24:17 +00001288 }
1289 ConsumeToken();
1290 }
1291}
1292
1293
1294/// ParseDeclarator - Parse and verify a newly-initialized declarator.
1295///
1296void Parser::ParseDeclarator(Declarator &D) {
1297 /// This implements the 'declarator' production in the C grammar, then checks
1298 /// for well-formedness and issues diagnostics.
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001299 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattner4b009652007-07-25 00:24:17 +00001300}
1301
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001302/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
1303/// is parsed by the function passed to it. Pass null, and the direct-declarator
1304/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001305/// ptr-operator production.
1306///
Chris Lattner4b009652007-07-25 00:24:17 +00001307/// declarator: [C99 6.7.5]
1308/// pointer[opt] direct-declarator
1309/// [C++] '&' declarator [C++ 8p4, dcl.decl]
1310/// [GNU] '&' restrict[opt] attributes[opt] declarator
1311///
1312/// pointer: [C99 6.7.5]
1313/// '*' type-qualifier-list[opt]
1314/// '*' type-qualifier-list[opt] pointer
1315///
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001316/// ptr-operator:
1317/// '*' cv-qualifier-seq[opt]
1318/// '&'
1319/// [GNU] '&' restrict[opt] attributes[opt]
1320/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] [TODO]
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001321void Parser::ParseDeclaratorInternal(Declarator &D,
1322 DirectDeclParseFunction DirectDeclParser) {
Chris Lattner4b009652007-07-25 00:24:17 +00001323 tok::TokenKind Kind = Tok.getKind();
1324
Steve Naroff7aa54752008-08-27 16:04:49 +00001325 // Not a pointer, C++ reference, or block.
1326 if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus) &&
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001327 (Kind != tok::caret || !getLang().Blocks)) {
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001328 if (DirectDeclParser)
1329 (this->*DirectDeclParser)(D);
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001330 return;
1331 }
Chris Lattner4b009652007-07-25 00:24:17 +00001332
Steve Naroffdc22f212008-08-28 10:07:06 +00001333 // Otherwise, '*' -> pointer, '^' -> block, '&' -> reference.
Chris Lattner4b009652007-07-25 00:24:17 +00001334 SourceLocation Loc = ConsumeToken(); // Eat the * or &.
1335
Steve Naroffdc22f212008-08-28 10:07:06 +00001336 if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) {
Chris Lattner69f01932008-02-21 01:32:26 +00001337 // Is a pointer.
Chris Lattner4b009652007-07-25 00:24:17 +00001338 DeclSpec DS;
1339
1340 ParseTypeQualifierListOpt(DS);
1341
1342 // Recursively parse the declarator.
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001343 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff7aa54752008-08-27 16:04:49 +00001344 if (Kind == tok::star)
1345 // Remember that we parsed a pointer type, and remember the type-quals.
1346 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
1347 DS.TakeAttributes()));
1348 else
1349 // Remember that we parsed a Block type, and remember the type-quals.
1350 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
1351 Loc));
Chris Lattner4b009652007-07-25 00:24:17 +00001352 } else {
1353 // Is a reference
1354 DeclSpec DS;
1355
1356 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
1357 // cv-qualifiers are introduced through the use of a typedef or of a
1358 // template type argument, in which case the cv-qualifiers are ignored.
1359 //
1360 // [GNU] Retricted references are allowed.
1361 // [GNU] Attributes on references are allowed.
1362 ParseTypeQualifierListOpt(DS);
1363
1364 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
1365 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
1366 Diag(DS.getConstSpecLoc(),
Chris Lattnerf006a222008-11-18 07:48:38 +00001367 diag::err_invalid_reference_qualifier_application) << "const";
Chris Lattner4b009652007-07-25 00:24:17 +00001368 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
1369 Diag(DS.getVolatileSpecLoc(),
Chris Lattnerf006a222008-11-18 07:48:38 +00001370 diag::err_invalid_reference_qualifier_application) << "volatile";
Chris Lattner4b009652007-07-25 00:24:17 +00001371 }
1372
1373 // Recursively parse the declarator.
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001374 ParseDeclaratorInternal(D, DirectDeclParser);
Chris Lattner4b009652007-07-25 00:24:17 +00001375
Douglas Gregorb7b28a22008-11-03 15:51:28 +00001376 if (D.getNumTypeObjects() > 0) {
1377 // C++ [dcl.ref]p4: There shall be no references to references.
1378 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
1379 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattner8f7db152008-11-19 07:37:42 +00001380 if (const IdentifierInfo *II = D.getIdentifier())
1381 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
1382 << II;
1383 else
1384 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
1385 << "type name";
Douglas Gregorb7b28a22008-11-03 15:51:28 +00001386
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001387 // Once we've complained about the reference-to-reference, we
Douglas Gregorb7b28a22008-11-03 15:51:28 +00001388 // can go ahead and build the (technically ill-formed)
1389 // declarator: reference collapsing will take care of it.
1390 }
1391 }
1392
Chris Lattner4b009652007-07-25 00:24:17 +00001393 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner69f01932008-02-21 01:32:26 +00001394 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
1395 DS.TakeAttributes()));
Chris Lattner4b009652007-07-25 00:24:17 +00001396 }
1397}
1398
1399/// ParseDirectDeclarator
1400/// direct-declarator: [C99 6.7.5]
Douglas Gregor8210a8e2008-11-05 20:51:48 +00001401/// [C99] identifier
Chris Lattner4b009652007-07-25 00:24:17 +00001402/// '(' declarator ')'
1403/// [GNU] '(' attributes declarator ')'
1404/// [C90] direct-declarator '[' constant-expression[opt] ']'
1405/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
1406/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
1407/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
1408/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
1409/// direct-declarator '(' parameter-type-list ')'
1410/// direct-declarator '(' identifier-list[opt] ')'
1411/// [GNU] direct-declarator '(' parameter-forward-declarations
1412/// parameter-type-list[opt] ')'
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001413/// [C++] direct-declarator '(' parameter-declaration-clause ')'
1414/// cv-qualifier-seq[opt] exception-specification[opt]
Douglas Gregorf15ac4b2008-10-31 09:07:45 +00001415/// [C++] declarator-id
Douglas Gregor8210a8e2008-11-05 20:51:48 +00001416///
1417/// declarator-id: [C++ 8]
1418/// id-expression
1419/// '::'[opt] nested-name-specifier[opt] type-name
1420///
1421/// id-expression: [C++ 5.1]
1422/// unqualified-id
1423/// qualified-id [TODO]
1424///
1425/// unqualified-id: [C++ 5.1]
1426/// identifier
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001427/// operator-function-id
Douglas Gregor8210a8e2008-11-05 20:51:48 +00001428/// conversion-function-id [TODO]
1429/// '~' class-name
1430/// template-id [TODO]
Argiris Kirtzidisc9e909c2008-11-07 22:02:30 +00001431///
Chris Lattner4b009652007-07-25 00:24:17 +00001432void Parser::ParseDirectDeclarator(Declarator &D) {
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001433 CXXScopeSpec &SS = D.getCXXScopeSpec();
1434 DeclaratorScopeObj DeclScopeObj(*this, SS);
1435
1436 if (D.mayHaveIdentifier() && isTokenCXXScopeSpecifier()) {
1437 ParseCXXScopeSpecifier(SS);
1438 // Change the declaration context for name lookup, until this function is
1439 // exited (and the declarator has been parsed).
1440 DeclScopeObj.EnterDeclaratorScope();
1441 }
1442
Chris Lattner4b009652007-07-25 00:24:17 +00001443 // Parse the first direct-declarator seen.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001444 if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
Chris Lattner4b009652007-07-25 00:24:17 +00001445 assert(Tok.getIdentifierInfo() && "Not an identifier?");
Douglas Gregor8210a8e2008-11-05 20:51:48 +00001446 // Determine whether this identifier is a C++ constructor name or
1447 // a normal identifier.
1448 if (getLang().CPlusPlus &&
Argiris Kirtzidis78207a72008-11-08 12:02:25 +00001449 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope))
Douglas Gregor6704b312008-11-17 22:58:34 +00001450 D.setConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope),
Douglas Gregorcbcb4c22008-11-12 23:21:09 +00001451 Tok.getLocation());
Douglas Gregor8210a8e2008-11-05 20:51:48 +00001452 else
1453 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
Chris Lattner4b009652007-07-25 00:24:17 +00001454 ConsumeToken();
Argiris Kirtzidisc9e909c2008-11-07 22:02:30 +00001455 } else if (getLang().CPlusPlus &&
1456 Tok.is(tok::tilde) && D.mayHaveIdentifier()) {
Douglas Gregor8210a8e2008-11-05 20:51:48 +00001457 // This should be a C++ destructor.
1458 SourceLocation TildeLoc = ConsumeToken();
Argiris Kirtzidisc9e909c2008-11-07 22:02:30 +00001459 if (Tok.is(tok::identifier)) {
Argiris Kirtzidisc9e909c2008-11-07 22:02:30 +00001460 if (TypeTy *Type = ParseClassName())
Douglas Gregor6704b312008-11-17 22:58:34 +00001461 D.setDestructor(Type, TildeLoc);
Argiris Kirtzidisc9e909c2008-11-07 22:02:30 +00001462 else
1463 D.SetIdentifier(0, TildeLoc);
1464 } else {
1465 Diag(Tok, diag::err_expected_class_name);
1466 D.SetIdentifier(0, TildeLoc);
1467 }
Douglas Gregore60e5d32008-11-06 22:13:31 +00001468 } else if (Tok.is(tok::kw_operator)) {
1469 SourceLocation OperatorLoc = Tok.getLocation();
1470
1471 // First try the name of an overloaded operator
Douglas Gregor96a32dd2008-11-18 14:39:36 +00001472 if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) {
1473 D.setOverloadedOperator(Op, OperatorLoc);
Douglas Gregore60e5d32008-11-06 22:13:31 +00001474 } else {
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001475 // This must be a conversion function (C++ [class.conv.fct]).
1476 if (TypeTy *ConvType = ParseConversionFunctionId()) {
Douglas Gregor6704b312008-11-17 22:58:34 +00001477 D.setConversionFunction(ConvType, OperatorLoc);
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001478 }
Douglas Gregore60e5d32008-11-06 22:13:31 +00001479 }
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001480 } else if (Tok.is(tok::l_paren) && SS.isEmpty()) {
Chris Lattner4b009652007-07-25 00:24:17 +00001481 // direct-declarator: '(' declarator ')'
1482 // direct-declarator: '(' attributes declarator ')'
1483 // Example: 'char (*X)' or 'int (*XX)(void)'
1484 ParseParenDeclarator(D);
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001485 } else if (D.mayOmitIdentifier() && SS.isEmpty()) {
Chris Lattner4b009652007-07-25 00:24:17 +00001486 // This could be something simple like "int" (in which case the declarator
1487 // portion is empty), if an abstract-declarator is allowed.
1488 D.SetIdentifier(0, Tok.getLocation());
1489 } else {
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001490 if (getLang().CPlusPlus)
1491 Diag(Tok, diag::err_expected_unqualified_id);
1492 else
Chris Lattnerf006a222008-11-18 07:48:38 +00001493 Diag(Tok, diag::err_expected_ident_lparen);
Chris Lattner4b009652007-07-25 00:24:17 +00001494 D.SetIdentifier(0, Tok.getLocation());
Chris Lattnercd61d592008-11-11 06:13:16 +00001495 D.setInvalidType(true);
Chris Lattner4b009652007-07-25 00:24:17 +00001496 }
1497
1498 assert(D.isPastIdentifier() &&
1499 "Haven't past the location of the identifier yet?");
1500
1501 while (1) {
Chris Lattner34a01ad2007-10-09 17:33:22 +00001502 if (Tok.is(tok::l_paren)) {
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00001503 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
1504 // In such a case, check if we actually have a function declarator; if it
1505 // is not, the declarator has been fully parsed.
Chris Lattner1f185292008-10-20 02:05:46 +00001506 if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
1507 // When not in file scope, warn for ambiguous function declarators, just
1508 // in case the author intended it as a variable definition.
1509 bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
1510 if (!isCXXFunctionDeclarator(warnIfAmbiguous))
1511 break;
1512 }
Chris Lattnera0d056d2008-04-06 05:45:57 +00001513 ParseFunctionDeclarator(ConsumeParen(), D);
Chris Lattner34a01ad2007-10-09 17:33:22 +00001514 } else if (Tok.is(tok::l_square)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001515 ParseBracketDeclarator(D);
1516 } else {
1517 break;
1518 }
1519 }
1520}
1521
Chris Lattnera0d056d2008-04-06 05:45:57 +00001522/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
1523/// only called before the identifier, so these are most likely just grouping
1524/// parens for precedence. If we find that these are actually function
1525/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
1526///
1527/// direct-declarator:
1528/// '(' declarator ')'
1529/// [GNU] '(' attributes declarator ')'
Chris Lattner1f185292008-10-20 02:05:46 +00001530/// direct-declarator '(' parameter-type-list ')'
1531/// direct-declarator '(' identifier-list[opt] ')'
1532/// [GNU] direct-declarator '(' parameter-forward-declarations
1533/// parameter-type-list[opt] ')'
Chris Lattnera0d056d2008-04-06 05:45:57 +00001534///
1535void Parser::ParseParenDeclarator(Declarator &D) {
1536 SourceLocation StartLoc = ConsumeParen();
1537 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
1538
Chris Lattner1f185292008-10-20 02:05:46 +00001539 // Eat any attributes before we look at whether this is a grouping or function
1540 // declarator paren. If this is a grouping paren, the attribute applies to
1541 // the type being built up, for example:
1542 // int (__attribute__(()) *x)(long y)
1543 // If this ends up not being a grouping paren, the attribute applies to the
1544 // first argument, for example:
1545 // int (__attribute__(()) int x)
1546 // In either case, we need to eat any attributes to be able to determine what
1547 // sort of paren this is.
1548 //
1549 AttributeList *AttrList = 0;
1550 bool RequiresArg = false;
1551 if (Tok.is(tok::kw___attribute)) {
1552 AttrList = ParseAttributes();
1553
1554 // We require that the argument list (if this is a non-grouping paren) be
1555 // present even if the attribute list was empty.
1556 RequiresArg = true;
1557 }
1558
Chris Lattnera0d056d2008-04-06 05:45:57 +00001559 // If we haven't past the identifier yet (or where the identifier would be
1560 // stored, if this is an abstract declarator), then this is probably just
1561 // grouping parens. However, if this could be an abstract-declarator, then
1562 // this could also be the start of function arguments (consider 'void()').
1563 bool isGrouping;
1564
1565 if (!D.mayOmitIdentifier()) {
1566 // If this can't be an abstract-declarator, this *must* be a grouping
1567 // paren, because we haven't seen the identifier yet.
1568 isGrouping = true;
1569 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Argiris Kirtzidis1c64fdc2008-10-06 00:07:55 +00001570 (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
Chris Lattnera0d056d2008-04-06 05:45:57 +00001571 isDeclarationSpecifier()) { // 'int(int)' is a function.
1572 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
1573 // considered to be a type, not a K&R identifier-list.
1574 isGrouping = false;
1575 } else {
1576 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
1577 isGrouping = true;
1578 }
1579
1580 // If this is a grouping paren, handle:
1581 // direct-declarator: '(' declarator ')'
1582 // direct-declarator: '(' attributes declarator ')'
1583 if (isGrouping) {
Argiris Kirtzidis0941ff42008-10-07 10:21:57 +00001584 bool hadGroupingParens = D.hasGroupingParens();
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00001585 D.setGroupingParens(true);
Chris Lattner1f185292008-10-20 02:05:46 +00001586 if (AttrList)
1587 D.AddAttributes(AttrList);
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00001588
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001589 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattnera0d056d2008-04-06 05:45:57 +00001590 // Match the ')'.
1591 MatchRHSPunctuation(tok::r_paren, StartLoc);
Argiris Kirtzidis0941ff42008-10-07 10:21:57 +00001592
1593 D.setGroupingParens(hadGroupingParens);
Chris Lattnera0d056d2008-04-06 05:45:57 +00001594 return;
1595 }
1596
1597 // Okay, if this wasn't a grouping paren, it must be the start of a function
1598 // argument list. Recognize that this declarator will never have an
Chris Lattner1f185292008-10-20 02:05:46 +00001599 // identifier (and remember where it would have been), then call into
1600 // ParseFunctionDeclarator to handle of argument list.
Chris Lattnera0d056d2008-04-06 05:45:57 +00001601 D.SetIdentifier(0, Tok.getLocation());
1602
Chris Lattner1f185292008-10-20 02:05:46 +00001603 ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
Chris Lattnera0d056d2008-04-06 05:45:57 +00001604}
1605
1606/// ParseFunctionDeclarator - We are after the identifier and have parsed the
1607/// declarator D up to a paren, which indicates that we are parsing function
1608/// arguments.
Chris Lattner4b009652007-07-25 00:24:17 +00001609///
Chris Lattner1f185292008-10-20 02:05:46 +00001610/// If AttrList is non-null, then the caller parsed those arguments immediately
1611/// after the open paren - they should be considered to be the first argument of
1612/// a parameter. If RequiresArg is true, then the first argument of the
1613/// function is required to be present and required to not be an identifier
1614/// list.
1615///
Chris Lattner4b009652007-07-25 00:24:17 +00001616/// This method also handles this portion of the grammar:
1617/// parameter-type-list: [C99 6.7.5]
1618/// parameter-list
1619/// parameter-list ',' '...'
1620///
1621/// parameter-list: [C99 6.7.5]
1622/// parameter-declaration
1623/// parameter-list ',' parameter-declaration
1624///
1625/// parameter-declaration: [C99 6.7.5]
1626/// declaration-specifiers declarator
Chris Lattner3e254fb2008-04-08 04:40:51 +00001627/// [C++] declaration-specifiers declarator '=' assignment-expression
Chris Lattner4b009652007-07-25 00:24:17 +00001628/// [GNU] declaration-specifiers declarator attributes
1629/// declaration-specifiers abstract-declarator[opt]
Chris Lattner97316c02008-04-10 02:22:51 +00001630/// [C++] declaration-specifiers abstract-declarator[opt]
1631/// '=' assignment-expression
Chris Lattner4b009652007-07-25 00:24:17 +00001632/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
1633///
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001634/// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
1635/// and "exception-specification[opt]"(TODO).
1636///
Chris Lattner1f185292008-10-20 02:05:46 +00001637void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
1638 AttributeList *AttrList,
1639 bool RequiresArg) {
Chris Lattnera0d056d2008-04-06 05:45:57 +00001640 // lparen is already consumed!
1641 assert(D.isPastIdentifier() && "Should not call before identifier!");
Chris Lattner4b009652007-07-25 00:24:17 +00001642
Chris Lattner1f185292008-10-20 02:05:46 +00001643 // This parameter list may be empty.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001644 if (Tok.is(tok::r_paren)) {
Chris Lattner1f185292008-10-20 02:05:46 +00001645 if (RequiresArg) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001646 Diag(Tok, diag::err_argument_required_after_attribute);
Chris Lattner1f185292008-10-20 02:05:46 +00001647 delete AttrList;
1648 }
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001649
1650 ConsumeParen(); // Eat the closing ')'.
1651
1652 // cv-qualifier-seq[opt].
1653 DeclSpec DS;
1654 if (getLang().CPlusPlus) {
1655 ParseTypeQualifierListOpt(DS);
Douglas Gregor90a2c972008-11-25 03:22:00 +00001656
1657 // Parse exception-specification[opt].
1658 if (Tok.is(tok::kw_throw))
1659 ParseExceptionSpecification();
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001660 }
1661
Chris Lattner9f7564b2008-04-06 06:57:35 +00001662 // Remember that we parsed a function type, and remember the attributes.
Chris Lattner4b009652007-07-25 00:24:17 +00001663 // int() -> no prototype, no '...'.
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001664 D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
Chris Lattner9f7564b2008-04-06 06:57:35 +00001665 /*variadic*/ false,
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001666 /*arglist*/ 0, 0,
1667 DS.getTypeQualifiers(),
1668 LParenLoc));
Chris Lattner9f7564b2008-04-06 06:57:35 +00001669 return;
Chris Lattner1f185292008-10-20 02:05:46 +00001670 }
1671
1672 // Alternatively, this parameter list may be an identifier list form for a
1673 // K&R-style function: void foo(a,b,c)
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001674 if (!getLang().CPlusPlus && Tok.is(tok::identifier) &&
Chris Lattner1f185292008-10-20 02:05:46 +00001675 // K&R identifier lists can't have typedefs as identifiers, per
1676 // C99 6.7.5.3p11.
1677 !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
1678 if (RequiresArg) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001679 Diag(Tok, diag::err_argument_required_after_attribute);
Chris Lattner1f185292008-10-20 02:05:46 +00001680 delete AttrList;
1681 }
1682
Chris Lattner4b009652007-07-25 00:24:17 +00001683 // Identifier list. Note that '(' identifier-list ')' is only allowed for
1684 // normal declarators, not for abstract-declarators.
Chris Lattner35d9c912008-04-06 06:34:08 +00001685 return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
Chris Lattner9f7564b2008-04-06 06:57:35 +00001686 }
1687
1688 // Finally, a normal, non-empty parameter type list.
1689
1690 // Build up an array of information about the parsed arguments.
1691 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Chris Lattner3e254fb2008-04-08 04:40:51 +00001692
1693 // Enter function-declaration scope, limiting any declarators to the
1694 // function prototype scope, including parameter declarators.
Argiris Kirtzidis59a9afb2008-05-09 23:39:43 +00001695 EnterScope(Scope::FnScope|Scope::DeclScope);
Chris Lattner9f7564b2008-04-06 06:57:35 +00001696
1697 bool IsVariadic = false;
1698 while (1) {
1699 if (Tok.is(tok::ellipsis)) {
1700 IsVariadic = true;
Chris Lattner4b009652007-07-25 00:24:17 +00001701
Chris Lattner9f7564b2008-04-06 06:57:35 +00001702 // Check to see if this is "void(...)" which is not allowed.
Argiris Kirtzidis1c64fdc2008-10-06 00:07:55 +00001703 if (!getLang().CPlusPlus && ParamInfo.empty()) {
Chris Lattner9f7564b2008-04-06 06:57:35 +00001704 // Otherwise, parse parameter type list. If it starts with an
1705 // ellipsis, diagnose the malformed function.
1706 Diag(Tok, diag::err_ellipsis_first_arg);
1707 IsVariadic = false; // Treat this like 'void()'.
Chris Lattner4b009652007-07-25 00:24:17 +00001708 }
Chris Lattnere5db29f2008-01-31 06:10:07 +00001709
Chris Lattner9f7564b2008-04-06 06:57:35 +00001710 ConsumeToken(); // Consume the ellipsis.
1711 break;
Chris Lattner4b009652007-07-25 00:24:17 +00001712 }
1713
Chris Lattner9f7564b2008-04-06 06:57:35 +00001714 SourceLocation DSStart = Tok.getLocation();
Chris Lattner4b009652007-07-25 00:24:17 +00001715
Chris Lattner9f7564b2008-04-06 06:57:35 +00001716 // Parse the declaration-specifiers.
1717 DeclSpec DS;
Chris Lattner1f185292008-10-20 02:05:46 +00001718
1719 // If the caller parsed attributes for the first argument, add them now.
1720 if (AttrList) {
1721 DS.AddAttributes(AttrList);
1722 AttrList = 0; // Only apply the attributes to the first parameter.
1723 }
Chris Lattner9f7564b2008-04-06 06:57:35 +00001724 ParseDeclarationSpecifiers(DS);
1725
1726 // Parse the declarator. This is "PrototypeContext", because we must
1727 // accept either 'declarator' or 'abstract-declarator' here.
1728 Declarator ParmDecl(DS, Declarator::PrototypeContext);
1729 ParseDeclarator(ParmDecl);
1730
1731 // Parse GNU attributes, if present.
1732 if (Tok.is(tok::kw___attribute))
1733 ParmDecl.AddAttributes(ParseAttributes());
1734
Chris Lattner9f7564b2008-04-06 06:57:35 +00001735 // Remember this parsed parameter in ParamInfo.
1736 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
1737
Chris Lattner9f7564b2008-04-06 06:57:35 +00001738 // If no parameter was specified, verify that *something* was specified,
1739 // otherwise we have a missing type and identifier.
1740 if (DS.getParsedSpecifiers() == DeclSpec::PQ_None &&
1741 ParmDecl.getIdentifier() == 0 && ParmDecl.getNumTypeObjects() == 0) {
1742 // Completely missing, emit error.
1743 Diag(DSStart, diag::err_missing_param);
1744 } else {
1745 // Otherwise, we have something. Add it and let semantic analysis try
1746 // to grok it and add the result to the ParamInfo we are building.
1747
1748 // Inform the actions module about the parameter declarator, so it gets
1749 // added to the current scope.
Chris Lattner3e254fb2008-04-08 04:40:51 +00001750 DeclTy *Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
1751
1752 // Parse the default argument, if any. We parse the default
1753 // arguments in all dialects; the semantic analysis in
1754 // ActOnParamDefaultArgument will reject the default argument in
1755 // C.
1756 if (Tok.is(tok::equal)) {
1757 SourceLocation EqualLoc = Tok.getLocation();
1758
1759 // Consume the '='.
1760 ConsumeToken();
1761
1762 // Parse the default argument
Chris Lattner3e254fb2008-04-08 04:40:51 +00001763 ExprResult DefArgResult = ParseAssignmentExpression();
1764 if (DefArgResult.isInvalid) {
1765 SkipUntil(tok::comma, tok::r_paren, true, true);
1766 } else {
1767 // Inform the actions module about the default argument
1768 Actions.ActOnParamDefaultArgument(Param, EqualLoc, DefArgResult.Val);
1769 }
1770 }
Chris Lattner9f7564b2008-04-06 06:57:35 +00001771
1772 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Chris Lattner3e254fb2008-04-08 04:40:51 +00001773 ParmDecl.getIdentifierLoc(), Param));
Chris Lattner9f7564b2008-04-06 06:57:35 +00001774 }
1775
1776 // If the next token is a comma, consume it and keep reading arguments.
1777 if (Tok.isNot(tok::comma)) break;
1778
1779 // Consume the comma.
1780 ConsumeToken();
Chris Lattner4b009652007-07-25 00:24:17 +00001781 }
1782
Chris Lattner9f7564b2008-04-06 06:57:35 +00001783 // Leave prototype scope.
1784 ExitScope();
1785
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001786 // If we have the closing ')', eat it.
1787 MatchRHSPunctuation(tok::r_paren, LParenLoc);
1788
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001789 DeclSpec DS;
1790 if (getLang().CPlusPlus) {
Douglas Gregor90a2c972008-11-25 03:22:00 +00001791 // Parse cv-qualifier-seq[opt].
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001792 ParseTypeQualifierListOpt(DS);
Douglas Gregor90a2c972008-11-25 03:22:00 +00001793
1794 // Parse exception-specification[opt].
1795 if (Tok.is(tok::kw_throw))
1796 ParseExceptionSpecification();
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001797 }
1798
Chris Lattner4b009652007-07-25 00:24:17 +00001799 // Remember that we parsed a function type, and remember the attributes.
Chris Lattner9f7564b2008-04-06 06:57:35 +00001800 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
1801 &ParamInfo[0], ParamInfo.size(),
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001802 DS.getTypeQualifiers(),
Chris Lattner9f7564b2008-04-06 06:57:35 +00001803 LParenLoc));
Chris Lattner4b009652007-07-25 00:24:17 +00001804}
1805
Chris Lattner35d9c912008-04-06 06:34:08 +00001806/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
1807/// we found a K&R-style identifier list instead of a type argument list. The
1808/// current token is known to be the first identifier in the list.
1809///
1810/// identifier-list: [C99 6.7.5]
1811/// identifier
1812/// identifier-list ',' identifier
1813///
1814void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
1815 Declarator &D) {
1816 // Build up an array of information about the parsed arguments.
1817 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
1818 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
1819
1820 // If there was no identifier specified for the declarator, either we are in
1821 // an abstract-declarator, or we are in a parameter declarator which was found
1822 // to be abstract. In abstract-declarators, identifier lists are not valid:
1823 // diagnose this.
1824 if (!D.getIdentifier())
1825 Diag(Tok, diag::ext_ident_list_in_param);
1826
1827 // Tok is known to be the first identifier in the list. Remember this
1828 // identifier in ParamInfo.
Chris Lattnerc337fa22008-04-06 06:50:56 +00001829 ParamsSoFar.insert(Tok.getIdentifierInfo());
Chris Lattner35d9c912008-04-06 06:34:08 +00001830 ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
1831 Tok.getLocation(), 0));
1832
Chris Lattner113a56b2008-04-06 06:39:19 +00001833 ConsumeToken(); // eat the first identifier.
Chris Lattner35d9c912008-04-06 06:34:08 +00001834
1835 while (Tok.is(tok::comma)) {
1836 // Eat the comma.
1837 ConsumeToken();
1838
Chris Lattner113a56b2008-04-06 06:39:19 +00001839 // If this isn't an identifier, report the error and skip until ')'.
Chris Lattner35d9c912008-04-06 06:34:08 +00001840 if (Tok.isNot(tok::identifier)) {
1841 Diag(Tok, diag::err_expected_ident);
Chris Lattner113a56b2008-04-06 06:39:19 +00001842 SkipUntil(tok::r_paren);
1843 return;
Chris Lattner35d9c912008-04-06 06:34:08 +00001844 }
Chris Lattneracb67d92008-04-06 06:47:48 +00001845
Chris Lattner35d9c912008-04-06 06:34:08 +00001846 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
Chris Lattneracb67d92008-04-06 06:47:48 +00001847
1848 // Reject 'typedef int y; int test(x, y)', but continue parsing.
1849 if (Actions.isTypeName(*ParmII, CurScope))
Chris Lattner8f7db152008-11-19 07:37:42 +00001850 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
Chris Lattner35d9c912008-04-06 06:34:08 +00001851
1852 // Verify that the argument identifier has not already been mentioned.
1853 if (!ParamsSoFar.insert(ParmII)) {
Chris Lattner8f7db152008-11-19 07:37:42 +00001854 Diag(Tok, diag::err_param_redefinition) << ParmII;
Chris Lattner113a56b2008-04-06 06:39:19 +00001855 } else {
1856 // Remember this identifier in ParamInfo.
Chris Lattner35d9c912008-04-06 06:34:08 +00001857 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
1858 Tok.getLocation(), 0));
Chris Lattner113a56b2008-04-06 06:39:19 +00001859 }
Chris Lattner35d9c912008-04-06 06:34:08 +00001860
1861 // Eat the identifier.
1862 ConsumeToken();
1863 }
1864
Chris Lattner113a56b2008-04-06 06:39:19 +00001865 // Remember that we parsed a function type, and remember the attributes. This
1866 // function type is always a K&R style function type, which is not varargs and
1867 // has no prototype.
1868 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
1869 &ParamInfo[0], ParamInfo.size(),
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00001870 /*TypeQuals*/0, LParenLoc));
Chris Lattner35d9c912008-04-06 06:34:08 +00001871
1872 // If we have the closing ')', eat it and we're done.
Chris Lattner113a56b2008-04-06 06:39:19 +00001873 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Chris Lattner35d9c912008-04-06 06:34:08 +00001874}
Chris Lattnera0d056d2008-04-06 05:45:57 +00001875
Chris Lattner4b009652007-07-25 00:24:17 +00001876/// [C90] direct-declarator '[' constant-expression[opt] ']'
1877/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
1878/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
1879/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
1880/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
1881void Parser::ParseBracketDeclarator(Declarator &D) {
1882 SourceLocation StartLoc = ConsumeBracket();
1883
1884 // If valid, this location is the position where we read the 'static' keyword.
1885 SourceLocation StaticLoc;
Chris Lattner34a01ad2007-10-09 17:33:22 +00001886 if (Tok.is(tok::kw_static))
Chris Lattner4b009652007-07-25 00:24:17 +00001887 StaticLoc = ConsumeToken();
1888
1889 // If there is a type-qualifier-list, read it now.
1890 DeclSpec DS;
1891 ParseTypeQualifierListOpt(DS);
1892
1893 // If we haven't already read 'static', check to see if there is one after the
1894 // type-qualifier-list.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001895 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Chris Lattner4b009652007-07-25 00:24:17 +00001896 StaticLoc = ConsumeToken();
1897
1898 // Handle "direct-declarator [ type-qual-list[opt] * ]".
1899 bool isStar = false;
1900 ExprResult NumElements(false);
Chris Lattner44f6d9d2008-04-06 05:26:30 +00001901
1902 // Handle the case where we have '[*]' as the array size. However, a leading
1903 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
1904 // the the token after the star is a ']'. Since stars in arrays are
1905 // infrequent, use of lookahead is not costly here.
1906 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattner1bb39512008-04-06 05:27:21 +00001907 ConsumeToken(); // Eat the '*'.
Chris Lattner4b009652007-07-25 00:24:17 +00001908
Chris Lattner44f6d9d2008-04-06 05:26:30 +00001909 if (StaticLoc.isValid())
1910 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
1911 StaticLoc = SourceLocation(); // Drop the static.
1912 isStar = true;
Chris Lattner34a01ad2007-10-09 17:33:22 +00001913 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001914 // Parse the assignment-expression now.
1915 NumElements = ParseAssignmentExpression();
1916 }
1917
1918 // If there was an error parsing the assignment-expression, recover.
1919 if (NumElements.isInvalid) {
1920 // If the expression was invalid, skip it.
1921 SkipUntil(tok::r_square);
1922 return;
1923 }
1924
1925 MatchRHSPunctuation(tok::r_square, StartLoc);
1926
1927 // If C99 isn't enabled, emit an ext-warn if the arg list wasn't empty and if
1928 // it was not a constant expression.
1929 if (!getLang().C99) {
1930 // TODO: check C90 array constant exprness.
1931 if (isStar || StaticLoc.isValid() ||
1932 0/*TODO: NumElts is not a C90 constantexpr */)
1933 Diag(StartLoc, diag::ext_c99_array_usage);
1934 }
1935
1936 // Remember that we parsed a pointer type, and remember the type-quals.
1937 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
1938 StaticLoc.isValid(), isStar,
1939 NumElements.Val, StartLoc));
1940}
1941
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001942/// [GNU] typeof-specifier:
1943/// typeof ( expressions )
1944/// typeof ( type-name )
1945/// [GNU/C++] typeof unary-expression
Steve Naroff7cbb1462007-07-31 12:34:36 +00001946///
1947void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner34a01ad2007-10-09 17:33:22 +00001948 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Steve Naroff14bbce82007-08-02 02:53:48 +00001949 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
Steve Naroff7cbb1462007-07-31 12:34:36 +00001950 SourceLocation StartLoc = ConsumeToken();
1951
Chris Lattner34a01ad2007-10-09 17:33:22 +00001952 if (Tok.isNot(tok::l_paren)) {
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001953 if (!getLang().CPlusPlus) {
Chris Lattnerb1753422008-11-23 21:45:46 +00001954 Diag(Tok, diag::err_expected_lparen_after_id) << BuiltinII;
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001955 return;
1956 }
1957
1958 ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/);
1959 if (Result.isInvalid)
1960 return;
1961
1962 const char *PrevSpec = 0;
1963 // Check for duplicate type specifiers.
1964 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
1965 Result.Val))
Chris Lattnerf006a222008-11-18 07:48:38 +00001966 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001967
1968 // FIXME: Not accurate, the range gets one token more than it should.
1969 DS.SetRangeEnd(Tok.getLocation());
Steve Naroff14bbce82007-08-02 02:53:48 +00001970 return;
Steve Naroff7cbb1462007-07-31 12:34:36 +00001971 }
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001972
Steve Naroff7cbb1462007-07-31 12:34:36 +00001973 SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
1974
Argiris Kirtzidis3276cbc2008-10-05 19:56:22 +00001975 if (isTypeIdInParens()) {
Steve Naroff7cbb1462007-07-31 12:34:36 +00001976 TypeTy *Ty = ParseTypeName();
1977
Steve Naroff4c255ab2007-07-31 23:56:32 +00001978 assert(Ty && "Parser::ParseTypeofSpecifier(): missing type");
1979
Chris Lattner34a01ad2007-10-09 17:33:22 +00001980 if (Tok.isNot(tok::r_paren)) {
Steve Naroff4c255ab2007-07-31 23:56:32 +00001981 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Steve Naroff14bbce82007-08-02 02:53:48 +00001982 return;
1983 }
1984 RParenLoc = ConsumeParen();
1985 const char *PrevSpec = 0;
1986 // Check for duplicate type specifiers (e.g. "int typeof(int)").
1987 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
Chris Lattnerf006a222008-11-18 07:48:38 +00001988 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Steve Naroff7cbb1462007-07-31 12:34:36 +00001989 } else { // we have an expression.
1990 ExprResult Result = ParseExpression();
Steve Naroff4c255ab2007-07-31 23:56:32 +00001991
Chris Lattner34a01ad2007-10-09 17:33:22 +00001992 if (Result.isInvalid || Tok.isNot(tok::r_paren)) {
Steve Naroff4c255ab2007-07-31 23:56:32 +00001993 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Steve Naroff14bbce82007-08-02 02:53:48 +00001994 return;
1995 }
1996 RParenLoc = ConsumeParen();
1997 const char *PrevSpec = 0;
1998 // Check for duplicate type specifiers (e.g. "int typeof(int)").
1999 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
2000 Result.Val))
Chris Lattnerf006a222008-11-18 07:48:38 +00002001 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Steve Naroff7cbb1462007-07-31 12:34:36 +00002002 }
Argiris Kirtzidis4d923942008-08-16 10:21:33 +00002003 DS.SetRangeEnd(RParenLoc);
Steve Naroff7cbb1462007-07-31 12:34:36 +00002004}
2005
Argiris Kirtzidis59a9afb2008-05-09 23:39:43 +00002006