blob: 041d876f56709480de35b8e3767420c868ebaa44 [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 Lattner4b009652007-07-25 00:24:17 +000016#include "clang/Parse/DeclSpec.h"
Chris Lattnera7549902007-08-26 06:24:45 +000017#include "clang/Parse/Scope.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]
28Parser::TypeTy *Parser::ParseTypeName() {
29 // Parse the common declaration-specifiers piece.
30 DeclSpec DS;
31 ParseSpecifierQualifierList(DS);
32
33 // Parse the abstract-declarator, if present.
34 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
35 ParseDeclarator(DeclaratorInfo);
36
Steve Naroff0acc9c92007-09-15 18:49:24 +000037 return Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val;
Chris Lattner4b009652007-07-25 00:24:17 +000038}
39
40/// ParseAttributes - Parse a non-empty attributes list.
41///
42/// [GNU] attributes:
43/// attribute
44/// attributes attribute
45///
46/// [GNU] attribute:
47/// '__attribute__' '(' '(' attribute-list ')' ')'
48///
49/// [GNU] attribute-list:
50/// attrib
51/// attribute_list ',' attrib
52///
53/// [GNU] attrib:
54/// empty
55/// attrib-name
56/// attrib-name '(' identifier ')'
57/// attrib-name '(' identifier ',' nonempty-expr-list ')'
58/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
59///
60/// [GNU] attrib-name:
61/// identifier
62/// typespec
63/// typequal
64/// storageclass
65///
66/// FIXME: The GCC grammar/code for this construct implies we need two
67/// token lookahead. Comment from gcc: "If they start with an identifier
68/// which is followed by a comma or close parenthesis, then the arguments
69/// start with that identifier; otherwise they are an expression list."
70///
71/// At the moment, I am not doing 2 token lookahead. I am also unaware of
72/// any attributes that don't work (based on my limited testing). Most
73/// attributes are very simple in practice. Until we find a bug, I don't see
74/// a pressing need to implement the 2 token lookahead.
75
76AttributeList *Parser::ParseAttributes() {
Chris Lattner34a01ad2007-10-09 17:33:22 +000077 assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
Chris Lattner4b009652007-07-25 00:24:17 +000078
79 AttributeList *CurrAttr = 0;
80
Chris Lattner34a01ad2007-10-09 17:33:22 +000081 while (Tok.is(tok::kw___attribute)) {
Chris Lattner4b009652007-07-25 00:24:17 +000082 ConsumeToken();
83 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
84 "attribute")) {
85 SkipUntil(tok::r_paren, true); // skip until ) or ;
86 return CurrAttr;
87 }
88 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
89 SkipUntil(tok::r_paren, true); // skip until ) or ;
90 return CurrAttr;
91 }
92 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner34a01ad2007-10-09 17:33:22 +000093 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
94 Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +000095
Chris Lattner34a01ad2007-10-09 17:33:22 +000096 if (Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +000097 // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
98 ConsumeToken();
99 continue;
100 }
101 // we have an identifier or declaration specifier (const, int, etc.)
102 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
103 SourceLocation AttrNameLoc = ConsumeToken();
104
105 // check if we have a "paramterized" attribute
Chris Lattner34a01ad2007-10-09 17:33:22 +0000106 if (Tok.is(tok::l_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000107 ConsumeParen(); // ignore the left paren loc for now
108
Chris Lattner34a01ad2007-10-09 17:33:22 +0000109 if (Tok.is(tok::identifier)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000110 IdentifierInfo *ParmName = Tok.getIdentifierInfo();
111 SourceLocation ParmLoc = ConsumeToken();
112
Chris Lattner34a01ad2007-10-09 17:33:22 +0000113 if (Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000114 // __attribute__(( mode(byte) ))
115 ConsumeParen(); // ignore the right paren loc for now
116 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
117 ParmName, ParmLoc, 0, 0, CurrAttr);
Chris Lattner34a01ad2007-10-09 17:33:22 +0000118 } else if (Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000119 ConsumeToken();
120 // __attribute__(( format(printf, 1, 2) ))
121 llvm::SmallVector<ExprTy*, 8> ArgExprs;
122 bool ArgExprsOk = true;
123
124 // now parse the non-empty comma separated list of expressions
125 while (1) {
126 ExprResult ArgExpr = ParseAssignmentExpression();
127 if (ArgExpr.isInvalid) {
128 ArgExprsOk = false;
129 SkipUntil(tok::r_paren);
130 break;
131 } else {
132 ArgExprs.push_back(ArgExpr.Val);
133 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000134 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000135 break;
136 ConsumeToken(); // Eat the comma, move to the next argument
137 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000138 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000139 ConsumeParen(); // ignore the right paren loc for now
140 CurrAttr = new AttributeList(AttrName, AttrNameLoc, ParmName,
141 ParmLoc, &ArgExprs[0], ArgExprs.size(), CurrAttr);
142 }
143 }
144 } else { // not an identifier
145 // parse a possibly empty comma separated list of expressions
Chris Lattner34a01ad2007-10-09 17:33:22 +0000146 if (Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000147 // __attribute__(( nonnull() ))
148 ConsumeParen(); // ignore the right paren loc for now
149 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
150 0, SourceLocation(), 0, 0, CurrAttr);
151 } else {
152 // __attribute__(( aligned(16) ))
153 llvm::SmallVector<ExprTy*, 8> ArgExprs;
154 bool ArgExprsOk = true;
155
156 // now parse the list of expressions
157 while (1) {
158 ExprResult ArgExpr = ParseAssignmentExpression();
159 if (ArgExpr.isInvalid) {
160 ArgExprsOk = false;
161 SkipUntil(tok::r_paren);
162 break;
163 } else {
164 ArgExprs.push_back(ArgExpr.Val);
165 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000166 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000167 break;
168 ConsumeToken(); // Eat the comma, move to the next argument
169 }
170 // Match the ')'.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000171 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000172 ConsumeParen(); // ignore the right paren loc for now
173 CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
174 SourceLocation(), &ArgExprs[0], ArgExprs.size(),
175 CurrAttr);
176 }
177 }
178 }
179 } else {
180 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
181 0, SourceLocation(), 0, 0, CurrAttr);
182 }
183 }
184 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
185 SkipUntil(tok::r_paren, false);
186 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
187 SkipUntil(tok::r_paren, false);
188 }
189 return CurrAttr;
190}
191
192/// ParseDeclaration - Parse a full 'declaration', which consists of
193/// declaration-specifiers, some number of declarators, and a semicolon.
194/// 'Context' should be a Declarator::TheContext value.
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000195///
196/// declaration: [C99 6.7]
197/// block-declaration ->
198/// simple-declaration
199/// others [FIXME]
200/// [C++] namespace-definition
201/// others... [FIXME]
202///
Chris Lattner4b009652007-07-25 00:24:17 +0000203Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000204 switch (Tok.getKind()) {
205 case tok::kw_namespace:
206 return ParseNamespace(Context);
207 default:
208 return ParseSimpleDeclaration(Context);
209 }
210}
211
212/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
213/// declaration-specifiers init-declarator-list[opt] ';'
214///[C90/C++]init-declarator-list ';' [TODO]
215/// [OMP] threadprivate-directive [TODO]
216Parser::DeclTy *Parser::ParseSimpleDeclaration(unsigned Context) {
Chris Lattner4b009652007-07-25 00:24:17 +0000217 // Parse the common declaration-specifiers piece.
218 DeclSpec DS;
219 ParseDeclarationSpecifiers(DS);
220
221 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
222 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner34a01ad2007-10-09 17:33:22 +0000223 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000224 ConsumeToken();
225 return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
226 }
227
228 Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
229 ParseDeclarator(DeclaratorInfo);
230
231 return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
232}
233
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000234
Chris Lattner4b009652007-07-25 00:24:17 +0000235/// ParseInitDeclaratorListAfterFirstDeclarator - Parse 'declaration' after
236/// parsing 'declaration-specifiers declarator'. This method is split out this
237/// way to handle the ambiguity between top-level function-definitions and
238/// declarations.
239///
Chris Lattner4b009652007-07-25 00:24:17 +0000240/// init-declarator-list: [C99 6.7]
241/// init-declarator
242/// init-declarator-list ',' init-declarator
243/// init-declarator: [C99 6.7]
244/// declarator
245/// declarator '=' initializer
246/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
247/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +0000248/// [C++] declarator initializer[opt]
249///
250/// [C++] initializer:
251/// [C++] '=' initializer-clause
252/// [C++] '(' expression-list ')'
Chris Lattner4b009652007-07-25 00:24:17 +0000253///
254Parser::DeclTy *Parser::
255ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
256
257 // Declarators may be grouped together ("int X, *Y, Z();"). Provide info so
258 // that they can be chained properly if the actions want this.
259 Parser::DeclTy *LastDeclInGroup = 0;
260
261 // At this point, we know that it is not a function definition. Parse the
262 // rest of the init-declarator-list.
263 while (1) {
264 // If a simple-asm-expr is present, parse it.
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000265 if (Tok.is(tok::kw_asm)) {
Daniel Dunbar72eaf8a2008-08-05 16:28:08 +0000266 ExprResult AsmLabel = ParseSimpleAsm();
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000267 if (AsmLabel.isInvalid) {
268 SkipUntil(tok::semi);
269 return 0;
270 }
Daniel Dunbar72eaf8a2008-08-05 16:28:08 +0000271
272 D.setAsmLabel(AsmLabel.Val);
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000273 }
Chris Lattner4b009652007-07-25 00:24:17 +0000274
275 // If attributes are present, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000276 if (Tok.is(tok::kw___attribute))
Chris Lattner4b009652007-07-25 00:24:17 +0000277 D.AddAttributes(ParseAttributes());
Steve Naroff6a0e2092007-09-12 14:07:44 +0000278
279 // Inform the current actions module that we just parsed this declarator.
Daniel Dunbar72eaf8a2008-08-05 16:28:08 +0000280 LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
Steve Naroff6a0e2092007-09-12 14:07:44 +0000281
Chris Lattner4b009652007-07-25 00:24:17 +0000282 // Parse declarator '=' initializer.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000283 if (Tok.is(tok::equal)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000284 ConsumeToken();
Daniel Dunbarc3540ff2008-08-05 01:35:17 +0000285 ExprResult Init = ParseInitializer();
Chris Lattner4b009652007-07-25 00:24:17 +0000286 if (Init.isInvalid) {
287 SkipUntil(tok::semi);
288 return 0;
289 }
Steve Naroff6a0e2092007-09-12 14:07:44 +0000290 Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val);
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +0000291 } else if (Tok.is(tok::l_paren)) {
292 // Parse C++ direct initializer: '(' expression-list ')'
293 SourceLocation LParenLoc = ConsumeParen();
294 ExprListTy Exprs;
295 CommaLocsTy CommaLocs;
296
297 bool InvalidExpr = false;
298 if (ParseExpressionList(Exprs, CommaLocs)) {
299 SkipUntil(tok::r_paren);
300 InvalidExpr = true;
301 }
302 // Match the ')'.
303 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
304
305 if (!InvalidExpr) {
306 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
307 "Unexpected number of commas!");
308 Actions.AddCXXDirectInitializerToDecl(LastDeclInGroup, LParenLoc,
309 &Exprs[0], Exprs.size(),
310 &CommaLocs[0], RParenLoc);
311 }
Chris Lattner4b009652007-07-25 00:24:17 +0000312 }
313
Chris Lattner4b009652007-07-25 00:24:17 +0000314 // If we don't have a comma, it is either the end of the list (a ';') or an
315 // error, bail out.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000316 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000317 break;
318
319 // Consume the comma.
320 ConsumeToken();
321
322 // Parse the next declarator.
323 D.clear();
Chris Lattner926cf542008-10-20 04:57:38 +0000324
325 // Accept attributes in an init-declarator. In the first declarator in a
326 // declaration, these would be part of the declspec. In subsequent
327 // declarators, they become part of the declarator itself, so that they
328 // don't apply to declarators after *this* one. Examples:
329 // short __attribute__((common)) var; -> declspec
330 // short var __attribute__((common)); -> declarator
331 // short x, __attribute__((common)) var; -> declarator
332 if (Tok.is(tok::kw___attribute))
333 D.AddAttributes(ParseAttributes());
334
Chris Lattner4b009652007-07-25 00:24:17 +0000335 ParseDeclarator(D);
336 }
337
Chris Lattner34a01ad2007-10-09 17:33:22 +0000338 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000339 ConsumeToken();
340 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
341 }
Fariborz Jahanian6e9c2b12008-01-04 23:23:46 +0000342 // If this is an ObjC2 for-each loop, this is a successful declarator
343 // parse. The syntax for these looks like:
344 // 'for' '(' declaration 'in' expr ')' statement
Fariborz Jahaniancadb0702008-01-04 23:04:08 +0000345 if (D.getContext() == Declarator::ForContext && isTokIdentifier_in()) {
Fariborz Jahanian1300bc72008-01-03 17:55:25 +0000346 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
347 }
Chris Lattner4b009652007-07-25 00:24:17 +0000348 Diag(Tok, diag::err_parse_error);
349 // Skip to end of block or statement
Chris Lattnerf491b412007-08-21 18:36:18 +0000350 SkipUntil(tok::r_brace, true, true);
Chris Lattner34a01ad2007-10-09 17:33:22 +0000351 if (Tok.is(tok::semi))
Chris Lattner4b009652007-07-25 00:24:17 +0000352 ConsumeToken();
353 return 0;
354}
355
356/// ParseSpecifierQualifierList
357/// specifier-qualifier-list:
358/// type-specifier specifier-qualifier-list[opt]
359/// type-qualifier specifier-qualifier-list[opt]
360/// [GNU] attributes specifier-qualifier-list[opt]
361///
362void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
363 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
364 /// parse declaration-specifiers and complain about extra stuff.
365 ParseDeclarationSpecifiers(DS);
366
367 // Validate declspec for type-name.
368 unsigned Specs = DS.getParsedSpecifiers();
Steve Naroff5f0466b2008-06-05 00:02:44 +0000369 if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers())
Chris Lattner4b009652007-07-25 00:24:17 +0000370 Diag(Tok, diag::err_typename_requires_specqual);
371
372 // Issue diagnostic and remove storage class if present.
373 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
374 if (DS.getStorageClassSpecLoc().isValid())
375 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
376 else
377 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
378 DS.ClearStorageClassSpecs();
379 }
380
381 // Issue diagnostic and remove function specfier if present.
382 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
383 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
384 DS.ClearFunctionSpecs();
385 }
386}
387
388/// ParseDeclarationSpecifiers
389/// declaration-specifiers: [C99 6.7]
390/// storage-class-specifier declaration-specifiers[opt]
391/// type-specifier declaration-specifiers[opt]
392/// type-qualifier declaration-specifiers[opt]
393/// [C99] function-specifier declaration-specifiers[opt]
394/// [GNU] attributes declaration-specifiers[opt]
395///
396/// storage-class-specifier: [C99 6.7.1]
397/// 'typedef'
398/// 'extern'
399/// 'static'
400/// 'auto'
401/// 'register'
402/// [GNU] '__thread'
403/// type-specifier: [C99 6.7.2]
404/// 'void'
405/// 'char'
406/// 'short'
407/// 'int'
408/// 'long'
409/// 'float'
410/// 'double'
411/// 'signed'
412/// 'unsigned'
413/// struct-or-union-specifier
414/// enum-specifier
415/// typedef-name
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +0000416/// [C++] 'wchar_t'
Chris Lattner4b009652007-07-25 00:24:17 +0000417/// [C++] 'bool'
418/// [C99] '_Bool'
419/// [C99] '_Complex'
420/// [C99] '_Imaginary' // Removed in TC2?
421/// [GNU] '_Decimal32'
422/// [GNU] '_Decimal64'
423/// [GNU] '_Decimal128'
Steve Naroff4c255ab2007-07-31 23:56:32 +0000424/// [GNU] typeof-specifier
Chris Lattner4b009652007-07-25 00:24:17 +0000425/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
Steve Naroffa8ee2262007-08-22 23:18:22 +0000426/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
Chris Lattner4b009652007-07-25 00:24:17 +0000427/// type-qualifier:
428/// 'const'
429/// 'volatile'
430/// [C99] 'restrict'
431/// function-specifier: [C99 6.7.4]
432/// [C99] 'inline'
433///
434void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
Chris Lattnera4ff4272008-03-13 06:29:04 +0000435 DS.SetRangeStart(Tok.getLocation());
Chris Lattner4b009652007-07-25 00:24:17 +0000436 while (1) {
437 int isInvalid = false;
438 const char *PrevSpec = 0;
439 SourceLocation Loc = Tok.getLocation();
440
441 switch (Tok.getKind()) {
Chris Lattner4b009652007-07-25 00:24:17 +0000442 default:
Chris Lattnerb99d7492008-07-26 00:20:22 +0000443 DoneWithDeclSpec:
Chris Lattner4b009652007-07-25 00:24:17 +0000444 // If this is not a declaration specifier token, we're done reading decl
445 // specifiers. First verify that DeclSpec's are consistent.
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000446 DS.Finish(Diags, PP.getSourceManager(), getLang());
Chris Lattner4b009652007-07-25 00:24:17 +0000447 return;
Chris Lattnerfda18db2008-07-26 01:18:38 +0000448
449 // typedef-name
450 case tok::identifier: {
451 // This identifier can only be a typedef name if we haven't already seen
452 // a type-specifier. Without this check we misparse:
453 // typedef int X; struct Y { short X; }; as 'short int'.
454 if (DS.hasTypeSpecifier())
455 goto DoneWithDeclSpec;
456
457 // It has to be available as a typedef too!
Argiris Kirtzidis46403632008-08-01 10:35:27 +0000458 TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
Chris Lattnerfda18db2008-07-26 01:18:38 +0000459 if (TypeRep == 0)
460 goto DoneWithDeclSpec;
461
462 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
463 TypeRep);
464 if (isInvalid)
465 break;
466
467 DS.SetRangeEnd(Tok.getLocation());
468 ConsumeToken(); // The identifier
469
470 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
471 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
472 // Objective-C interface. If we don't have Objective-C or a '<', this is
473 // just a normal reference to a typedef name.
474 if (!Tok.is(tok::less) || !getLang().ObjC1)
475 continue;
476
477 SourceLocation EndProtoLoc;
Chris Lattnerada63792008-07-26 01:53:50 +0000478 llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
Chris Lattner2bdedd62008-07-26 04:03:38 +0000479 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Chris Lattnerada63792008-07-26 01:53:50 +0000480 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
Chris Lattnerfda18db2008-07-26 01:18:38 +0000481
482 DS.SetRangeEnd(EndProtoLoc);
483
Steve Narofff7683302008-09-22 10:28:57 +0000484 // Need to support trailing type qualifiers (e.g. "id<p> const").
485 // If a type specifier follows, it will be diagnosed elsewhere.
486 continue;
Chris Lattnerfda18db2008-07-26 01:18:38 +0000487 }
Chris Lattner4b009652007-07-25 00:24:17 +0000488 // GNU attributes support.
489 case tok::kw___attribute:
490 DS.AddAttributes(ParseAttributes());
491 continue;
492
493 // storage-class-specifier
494 case tok::kw_typedef:
495 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
496 break;
497 case tok::kw_extern:
498 if (DS.isThreadSpecified())
499 Diag(Tok, diag::ext_thread_before, "extern");
500 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec);
501 break;
Steve Narofff258a0f2007-12-18 00:16:02 +0000502 case tok::kw___private_extern__:
Chris Lattner9f7564b2008-04-06 06:57:35 +0000503 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
504 PrevSpec);
Steve Narofff258a0f2007-12-18 00:16:02 +0000505 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000506 case tok::kw_static:
507 if (DS.isThreadSpecified())
508 Diag(Tok, diag::ext_thread_before, "static");
509 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
510 break;
511 case tok::kw_auto:
512 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
513 break;
514 case tok::kw_register:
515 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
516 break;
517 case tok::kw___thread:
518 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec)*2;
519 break;
520
521 // type-specifiers
522 case tok::kw_short:
523 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
524 break;
525 case tok::kw_long:
526 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
527 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
528 else
529 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
530 break;
531 case tok::kw_signed:
532 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
533 break;
534 case tok::kw_unsigned:
535 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
536 break;
537 case tok::kw__Complex:
538 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
539 break;
540 case tok::kw__Imaginary:
541 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
542 break;
543 case tok::kw_void:
544 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
545 break;
546 case tok::kw_char:
547 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
548 break;
549 case tok::kw_int:
550 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
551 break;
552 case tok::kw_float:
553 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
554 break;
555 case tok::kw_double:
556 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
557 break;
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +0000558 case tok::kw_wchar_t: // [C++ 2.11p1]
559 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
560 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000561 case tok::kw_bool: // [C++ 2.11p1]
562 case tok::kw__Bool:
563 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
564 break;
565 case tok::kw__Decimal32:
566 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
567 break;
568 case tok::kw__Decimal64:
569 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
570 break;
571 case tok::kw__Decimal128:
572 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
573 break;
Chris Lattner2e78db32008-04-13 18:59:07 +0000574
575 case tok::kw_class:
Chris Lattner4b009652007-07-25 00:24:17 +0000576 case tok::kw_struct:
577 case tok::kw_union:
Douglas Gregorec93f442008-04-13 21:30:24 +0000578 ParseClassSpecifier(DS);
Chris Lattner4b009652007-07-25 00:24:17 +0000579 continue;
580 case tok::kw_enum:
581 ParseEnumSpecifier(DS);
582 continue;
583
Steve Naroff7cbb1462007-07-31 12:34:36 +0000584 // GNU typeof support.
585 case tok::kw_typeof:
586 ParseTypeofSpecifier(DS);
587 continue;
588
Chris Lattner4b009652007-07-25 00:24:17 +0000589 // type-qualifier
590 case tok::kw_const:
591 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
592 getLang())*2;
593 break;
594 case tok::kw_volatile:
595 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
596 getLang())*2;
597 break;
598 case tok::kw_restrict:
599 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
600 getLang())*2;
601 break;
602
603 // function-specifier
604 case tok::kw_inline:
605 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec);
606 break;
Steve Naroff5f0466b2008-06-05 00:02:44 +0000607
Steve Naroff5f0466b2008-06-05 00:02:44 +0000608 case tok::less:
Chris Lattnerfda18db2008-07-26 01:18:38 +0000609 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerb99d7492008-07-26 00:20:22 +0000610 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
611 // but we support it.
Chris Lattnerfda18db2008-07-26 01:18:38 +0000612 if (DS.hasTypeSpecifier() || !getLang().ObjC1)
Chris Lattnerb99d7492008-07-26 00:20:22 +0000613 goto DoneWithDeclSpec;
614
615 {
616 SourceLocation EndProtoLoc;
Chris Lattnerada63792008-07-26 01:53:50 +0000617 llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
Chris Lattner2bdedd62008-07-26 04:03:38 +0000618 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Chris Lattnerada63792008-07-26 01:53:50 +0000619 DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
Chris Lattnerfda18db2008-07-26 01:18:38 +0000620 DS.SetRangeEnd(EndProtoLoc);
621
Chris Lattnerb99d7492008-07-26 00:20:22 +0000622 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id,
623 SourceRange(Loc, EndProtoLoc));
Steve Narofff7683302008-09-22 10:28:57 +0000624 // Need to support trailing type qualifiers (e.g. "id<p> const").
625 // If a type specifier follows, it will be diagnosed elsewhere.
626 continue;
Steve Naroff5f0466b2008-06-05 00:02:44 +0000627 }
Chris Lattner4b009652007-07-25 00:24:17 +0000628 }
629 // If the specifier combination wasn't legal, issue a diagnostic.
630 if (isInvalid) {
631 assert(PrevSpec && "Method did not return previous specifier!");
632 if (isInvalid == 1) // Error.
633 Diag(Tok, diag::err_invalid_decl_spec_combination, PrevSpec);
634 else // extwarn.
635 Diag(Tok, diag::ext_duplicate_declspec, PrevSpec);
636 }
Chris Lattnera4ff4272008-03-13 06:29:04 +0000637 DS.SetRangeEnd(Tok.getLocation());
Chris Lattner4b009652007-07-25 00:24:17 +0000638 ConsumeToken();
639 }
640}
641
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000642/// ParseStructDeclaration - Parse a struct declaration without the terminating
643/// semicolon.
644///
Chris Lattner4b009652007-07-25 00:24:17 +0000645/// struct-declaration:
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000646/// specifier-qualifier-list struct-declarator-list
Chris Lattner4b009652007-07-25 00:24:17 +0000647/// [GNU] __extension__ struct-declaration
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000648/// [GNU] specifier-qualifier-list
Chris Lattner4b009652007-07-25 00:24:17 +0000649/// struct-declarator-list:
650/// struct-declarator
651/// struct-declarator-list ',' struct-declarator
652/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
653/// struct-declarator:
654/// declarator
655/// [GNU] declarator attributes[opt]
656/// declarator[opt] ':' constant-expression
657/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
658///
Chris Lattner3dd8d392008-04-10 06:46:29 +0000659void Parser::
660ParseStructDeclaration(DeclSpec &DS,
661 llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
Steve Naroffa9adf112007-08-20 22:28:22 +0000662 // FIXME: When __extension__ is specified, disable extension diagnostics.
Chris Lattner3dd8d392008-04-10 06:46:29 +0000663 while (Tok.is(tok::kw___extension__))
Steve Naroffa9adf112007-08-20 22:28:22 +0000664 ConsumeToken();
665
666 // Parse the common specifier-qualifiers-list piece.
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000667 SourceLocation DSStart = Tok.getLocation();
Steve Naroffa9adf112007-08-20 22:28:22 +0000668 ParseSpecifierQualifierList(DS);
669 // TODO: Does specifier-qualifier list correctly check that *something* is
670 // specified?
671
672 // If there are no declarators, issue a warning.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000673 if (Tok.is(tok::semi)) {
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000674 Diag(DSStart, diag::w_no_declarators);
Steve Naroffa9adf112007-08-20 22:28:22 +0000675 return;
676 }
677
678 // Read struct-declarators until we find the semicolon.
Chris Lattnerf62fb732008-04-10 16:37:40 +0000679 Fields.push_back(FieldDeclarator(DS));
Steve Naroffa9adf112007-08-20 22:28:22 +0000680 while (1) {
Chris Lattner3dd8d392008-04-10 06:46:29 +0000681 FieldDeclarator &DeclaratorInfo = Fields.back();
682
Steve Naroffa9adf112007-08-20 22:28:22 +0000683 /// struct-declarator: declarator
684 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattner34a01ad2007-10-09 17:33:22 +0000685 if (Tok.isNot(tok::colon))
Chris Lattner3dd8d392008-04-10 06:46:29 +0000686 ParseDeclarator(DeclaratorInfo.D);
Steve Naroffa9adf112007-08-20 22:28:22 +0000687
Chris Lattner34a01ad2007-10-09 17:33:22 +0000688 if (Tok.is(tok::colon)) {
Steve Naroffa9adf112007-08-20 22:28:22 +0000689 ConsumeToken();
690 ExprResult Res = ParseConstantExpression();
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000691 if (Res.isInvalid)
Steve Naroffa9adf112007-08-20 22:28:22 +0000692 SkipUntil(tok::semi, true, true);
Chris Lattner12e8a4c2008-04-10 06:15:14 +0000693 else
Chris Lattner3dd8d392008-04-10 06:46:29 +0000694 DeclaratorInfo.BitfieldSize = Res.Val;
Steve Naroffa9adf112007-08-20 22:28:22 +0000695 }
696
697 // If attributes exist after the declarator, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000698 if (Tok.is(tok::kw___attribute))
Chris Lattner3dd8d392008-04-10 06:46:29 +0000699 DeclaratorInfo.D.AddAttributes(ParseAttributes());
Steve Naroffa9adf112007-08-20 22:28:22 +0000700
701 // If we don't have a comma, it is either the end of the list (a ';')
702 // or an error, bail out.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000703 if (Tok.isNot(tok::comma))
Chris Lattnerced5b4f2007-10-29 04:42:53 +0000704 return;
Steve Naroffa9adf112007-08-20 22:28:22 +0000705
706 // Consume the comma.
707 ConsumeToken();
708
709 // Parse the next declarator.
Chris Lattnerf62fb732008-04-10 16:37:40 +0000710 Fields.push_back(FieldDeclarator(DS));
Steve Naroffa9adf112007-08-20 22:28:22 +0000711
712 // Attributes are only allowed on the second declarator.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000713 if (Tok.is(tok::kw___attribute))
Chris Lattner3dd8d392008-04-10 06:46:29 +0000714 Fields.back().D.AddAttributes(ParseAttributes());
Steve Naroffa9adf112007-08-20 22:28:22 +0000715 }
Steve Naroffa9adf112007-08-20 22:28:22 +0000716}
717
718/// ParseStructUnionBody
719/// struct-contents:
720/// struct-declaration-list
721/// [EXT] empty
722/// [GNU] "struct-declaration-list" without terminatoring ';'
723/// struct-declaration-list:
724/// struct-declaration
725/// struct-declaration-list struct-declaration
Chris Lattner1bf58f62008-06-21 19:39:06 +0000726/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroffa9adf112007-08-20 22:28:22 +0000727///
Chris Lattner4b009652007-07-25 00:24:17 +0000728void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
729 unsigned TagType, DeclTy *TagDecl) {
730 SourceLocation LBraceLoc = ConsumeBrace();
731
732 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
733 // C++.
Douglas Gregorec93f442008-04-13 21:30:24 +0000734 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattner4b009652007-07-25 00:24:17 +0000735 Diag(Tok, diag::ext_empty_struct_union_enum,
736 DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
737
738 llvm::SmallVector<DeclTy*, 32> FieldDecls;
Chris Lattner3dd8d392008-04-10 06:46:29 +0000739 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
740
Chris Lattner4b009652007-07-25 00:24:17 +0000741 // While we still have something to read, read the declarations in the struct.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000742 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000743 // Each iteration of this loop reads one struct-declaration.
744
745 // Check for extraneous top-level semicolon.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000746 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000747 Diag(Tok, diag::ext_extra_struct_semi);
748 ConsumeToken();
749 continue;
750 }
Chris Lattner3dd8d392008-04-10 06:46:29 +0000751
752 // Parse all the comma separated declarators.
753 DeclSpec DS;
754 FieldDeclarators.clear();
Chris Lattner1bf58f62008-06-21 19:39:06 +0000755 if (!Tok.is(tok::at)) {
756 ParseStructDeclaration(DS, FieldDeclarators);
757
758 // Convert them all to fields.
759 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
760 FieldDeclarator &FD = FieldDeclarators[i];
761 // Install the declarator into the current TagDecl.
762 DeclTy *Field = Actions.ActOnField(CurScope,
763 DS.getSourceRange().getBegin(),
764 FD.D, FD.BitfieldSize);
765 FieldDecls.push_back(Field);
766 }
767 } else { // Handle @defs
768 ConsumeToken();
769 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
770 Diag(Tok, diag::err_unexpected_at);
771 SkipUntil(tok::semi, true, true);
772 continue;
773 }
774 ConsumeToken();
775 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
776 if (!Tok.is(tok::identifier)) {
777 Diag(Tok, diag::err_expected_ident);
778 SkipUntil(tok::semi, true, true);
779 continue;
780 }
781 llvm::SmallVector<DeclTy*, 16> Fields;
782 Actions.ActOnDefs(CurScope, Tok.getLocation(), Tok.getIdentifierInfo(),
783 Fields);
784 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
785 ConsumeToken();
786 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
787 }
Chris Lattner4b009652007-07-25 00:24:17 +0000788
Chris Lattner34a01ad2007-10-09 17:33:22 +0000789 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000790 ConsumeToken();
Chris Lattner34a01ad2007-10-09 17:33:22 +0000791 } else if (Tok.is(tok::r_brace)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000792 Diag(Tok.getLocation(), diag::ext_expected_semi_decl_list);
793 break;
794 } else {
795 Diag(Tok, diag::err_expected_semi_decl_list);
796 // Skip to end of block or statement
797 SkipUntil(tok::r_brace, true, true);
798 }
799 }
800
Steve Naroff1a7fa7b2007-10-29 21:38:07 +0000801 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
Chris Lattner4b009652007-07-25 00:24:17 +0000802
Chris Lattner4b009652007-07-25 00:24:17 +0000803 AttributeList *AttrList = 0;
804 // If attributes exist after struct contents, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000805 if (Tok.is(tok::kw___attribute))
Daniel Dunbar3b908072008-10-03 16:42:10 +0000806 AttrList = ParseAttributes();
Daniel Dunbarf3944442008-10-03 02:03:53 +0000807
808 Actions.ActOnFields(CurScope,
809 RecordLoc,TagDecl,&FieldDecls[0],FieldDecls.size(),
810 LBraceLoc, RBraceLoc,
811 AttrList);
Chris Lattner4b009652007-07-25 00:24:17 +0000812}
813
814
815/// ParseEnumSpecifier
816/// enum-specifier: [C99 6.7.2.2]
817/// 'enum' identifier[opt] '{' enumerator-list '}'
818/// [C99] 'enum' identifier[opt] '{' enumerator-list ',' '}'
819/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
820/// '}' attributes[opt]
821/// 'enum' identifier
822/// [GNU] 'enum' attributes[opt] identifier
823void Parser::ParseEnumSpecifier(DeclSpec &DS) {
Chris Lattner34a01ad2007-10-09 17:33:22 +0000824 assert(Tok.is(tok::kw_enum) && "Not an enum specifier");
Chris Lattner4b009652007-07-25 00:24:17 +0000825 SourceLocation StartLoc = ConsumeToken();
826
827 // Parse the tag portion of this.
Argiris Kirtzidis2298f012008-09-11 00:21:41 +0000828
829 AttributeList *Attr = 0;
830 // If attributes exist after tag, parse them.
831 if (Tok.is(tok::kw___attribute))
832 Attr = ParseAttributes();
833
834 // Must have either 'enum name' or 'enum {...}'.
835 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) {
836 Diag(Tok, diag::err_expected_ident_lbrace);
837
838 // Skip the rest of this declarator, up until the comma or semicolon.
839 SkipUntil(tok::comma, true);
Chris Lattner4b009652007-07-25 00:24:17 +0000840 return;
Argiris Kirtzidis2298f012008-09-11 00:21:41 +0000841 }
842
843 // If an identifier is present, consume and remember it.
844 IdentifierInfo *Name = 0;
845 SourceLocation NameLoc;
846 if (Tok.is(tok::identifier)) {
847 Name = Tok.getIdentifierInfo();
848 NameLoc = ConsumeToken();
849 }
850
851 // There are three options here. If we have 'enum foo;', then this is a
852 // forward declaration. If we have 'enum foo {...' then this is a
853 // definition. Otherwise we have something like 'enum foo xyz', a reference.
854 //
855 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
856 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
857 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
858 //
859 Action::TagKind TK;
860 if (Tok.is(tok::l_brace))
861 TK = Action::TK_Definition;
862 else if (Tok.is(tok::semi))
863 TK = Action::TK_Declaration;
864 else
865 TK = Action::TK_Reference;
866 DeclTy *TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK, StartLoc,
867 Name, NameLoc, Attr);
Chris Lattner4b009652007-07-25 00:24:17 +0000868
Chris Lattner34a01ad2007-10-09 17:33:22 +0000869 if (Tok.is(tok::l_brace))
Chris Lattner4b009652007-07-25 00:24:17 +0000870 ParseEnumBody(StartLoc, TagDecl);
871
872 // TODO: semantic analysis on the declspec for enums.
873 const char *PrevSpec = 0;
874 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, TagDecl))
875 Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
876}
877
878/// ParseEnumBody - Parse a {} enclosed enumerator-list.
879/// enumerator-list:
880/// enumerator
881/// enumerator-list ',' enumerator
882/// enumerator:
883/// enumeration-constant
884/// enumeration-constant '=' constant-expression
885/// enumeration-constant:
886/// identifier
887///
888void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
889 SourceLocation LBraceLoc = ConsumeBrace();
890
Chris Lattnerc9a92452007-08-27 17:24:30 +0000891 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
Chris Lattner34a01ad2007-10-09 17:33:22 +0000892 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattner4b009652007-07-25 00:24:17 +0000893 Diag(Tok, diag::ext_empty_struct_union_enum, "enum");
894
895 llvm::SmallVector<DeclTy*, 32> EnumConstantDecls;
896
897 DeclTy *LastEnumConstDecl = 0;
898
899 // Parse the enumerator-list.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000900 while (Tok.is(tok::identifier)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000901 IdentifierInfo *Ident = Tok.getIdentifierInfo();
902 SourceLocation IdentLoc = ConsumeToken();
903
904 SourceLocation EqualLoc;
905 ExprTy *AssignedVal = 0;
Chris Lattner34a01ad2007-10-09 17:33:22 +0000906 if (Tok.is(tok::equal)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000907 EqualLoc = ConsumeToken();
908 ExprResult Res = ParseConstantExpression();
909 if (Res.isInvalid)
910 SkipUntil(tok::comma, tok::r_brace, true, true);
911 else
912 AssignedVal = Res.Val;
913 }
914
915 // Install the enumerator constant into EnumDecl.
Steve Naroff0acc9c92007-09-15 18:49:24 +0000916 DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
Chris Lattner4b009652007-07-25 00:24:17 +0000917 LastEnumConstDecl,
918 IdentLoc, Ident,
919 EqualLoc, AssignedVal);
920 EnumConstantDecls.push_back(EnumConstDecl);
921 LastEnumConstDecl = EnumConstDecl;
922
Chris Lattner34a01ad2007-10-09 17:33:22 +0000923 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000924 break;
925 SourceLocation CommaLoc = ConsumeToken();
926
Chris Lattner34a01ad2007-10-09 17:33:22 +0000927 if (Tok.isNot(tok::identifier) && !getLang().C99)
Chris Lattner4b009652007-07-25 00:24:17 +0000928 Diag(CommaLoc, diag::ext_c99_enumerator_list_comma);
929 }
930
931 // Eat the }.
932 MatchRHSPunctuation(tok::r_brace, LBraceLoc);
933
Steve Naroff0acc9c92007-09-15 18:49:24 +0000934 Actions.ActOnEnumBody(StartLoc, EnumDecl, &EnumConstantDecls[0],
Chris Lattner4b009652007-07-25 00:24:17 +0000935 EnumConstantDecls.size());
936
937 DeclTy *AttrList = 0;
938 // If attributes exist after the identifier list, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000939 if (Tok.is(tok::kw___attribute))
Chris Lattner4b009652007-07-25 00:24:17 +0000940 AttrList = ParseAttributes(); // FIXME: where do they do?
941}
942
943/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff6f9f9552008-02-11 23:15:56 +0000944/// start of a type-qualifier-list.
945bool Parser::isTypeQualifier() const {
946 switch (Tok.getKind()) {
947 default: return false;
948 // type-qualifier
949 case tok::kw_const:
950 case tok::kw_volatile:
951 case tok::kw_restrict:
952 return true;
953 }
954}
955
956/// isTypeSpecifierQualifier - Return true if the current token could be the
Chris Lattner4b009652007-07-25 00:24:17 +0000957/// start of a specifier-qualifier-list.
958bool Parser::isTypeSpecifierQualifier() const {
959 switch (Tok.getKind()) {
960 default: return false;
961 // GNU attributes support.
962 case tok::kw___attribute:
Steve Naroff7cbb1462007-07-31 12:34:36 +0000963 // GNU typeof support.
964 case tok::kw_typeof:
965
Chris Lattner4b009652007-07-25 00:24:17 +0000966 // type-specifiers
967 case tok::kw_short:
968 case tok::kw_long:
969 case tok::kw_signed:
970 case tok::kw_unsigned:
971 case tok::kw__Complex:
972 case tok::kw__Imaginary:
973 case tok::kw_void:
974 case tok::kw_char:
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +0000975 case tok::kw_wchar_t:
Chris Lattner4b009652007-07-25 00:24:17 +0000976 case tok::kw_int:
977 case tok::kw_float:
978 case tok::kw_double:
Chris Lattner2baef2e2007-11-15 05:25:19 +0000979 case tok::kw_bool:
Chris Lattner4b009652007-07-25 00:24:17 +0000980 case tok::kw__Bool:
981 case tok::kw__Decimal32:
982 case tok::kw__Decimal64:
983 case tok::kw__Decimal128:
984
Chris Lattner2e78db32008-04-13 18:59:07 +0000985 // struct-or-union-specifier (C99) or class-specifier (C++)
986 case tok::kw_class:
Chris Lattner4b009652007-07-25 00:24:17 +0000987 case tok::kw_struct:
988 case tok::kw_union:
989 // enum-specifier
990 case tok::kw_enum:
991
992 // type-qualifier
993 case tok::kw_const:
994 case tok::kw_volatile:
995 case tok::kw_restrict:
996 return true;
Chris Lattner9aefe722008-10-20 00:25:30 +0000997
998 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
999 case tok::less:
1000 return getLang().ObjC1;
Chris Lattner4b009652007-07-25 00:24:17 +00001001
1002 // typedef-name
1003 case tok::identifier:
1004 return Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope) != 0;
Chris Lattner4b009652007-07-25 00:24:17 +00001005 }
1006}
1007
1008/// isDeclarationSpecifier() - Return true if the current token is part of a
1009/// declaration specifier.
1010bool Parser::isDeclarationSpecifier() const {
1011 switch (Tok.getKind()) {
1012 default: return false;
1013 // storage-class-specifier
1014 case tok::kw_typedef:
1015 case tok::kw_extern:
Steve Narofff258a0f2007-12-18 00:16:02 +00001016 case tok::kw___private_extern__:
Chris Lattner4b009652007-07-25 00:24:17 +00001017 case tok::kw_static:
1018 case tok::kw_auto:
1019 case tok::kw_register:
1020 case tok::kw___thread:
1021
1022 // type-specifiers
1023 case tok::kw_short:
1024 case tok::kw_long:
1025 case tok::kw_signed:
1026 case tok::kw_unsigned:
1027 case tok::kw__Complex:
1028 case tok::kw__Imaginary:
1029 case tok::kw_void:
1030 case tok::kw_char:
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +00001031 case tok::kw_wchar_t:
Chris Lattner4b009652007-07-25 00:24:17 +00001032 case tok::kw_int:
1033 case tok::kw_float:
1034 case tok::kw_double:
Chris Lattner2baef2e2007-11-15 05:25:19 +00001035 case tok::kw_bool:
Chris Lattner4b009652007-07-25 00:24:17 +00001036 case tok::kw__Bool:
1037 case tok::kw__Decimal32:
1038 case tok::kw__Decimal64:
1039 case tok::kw__Decimal128:
1040
Chris Lattner2e78db32008-04-13 18:59:07 +00001041 // struct-or-union-specifier (C99) or class-specifier (C++)
1042 case tok::kw_class:
Chris Lattner4b009652007-07-25 00:24:17 +00001043 case tok::kw_struct:
1044 case tok::kw_union:
1045 // enum-specifier
1046 case tok::kw_enum:
1047
1048 // type-qualifier
1049 case tok::kw_const:
1050 case tok::kw_volatile:
1051 case tok::kw_restrict:
Steve Naroff7cbb1462007-07-31 12:34:36 +00001052
Chris Lattner4b009652007-07-25 00:24:17 +00001053 // function-specifier
1054 case tok::kw_inline:
Chris Lattnere35d2582007-08-09 16:40:21 +00001055
Chris Lattnerb707a7a2007-08-09 17:01:07 +00001056 // GNU typeof support.
1057 case tok::kw_typeof:
1058
1059 // GNU attributes.
Chris Lattnere35d2582007-08-09 16:40:21 +00001060 case tok::kw___attribute:
Chris Lattner4b009652007-07-25 00:24:17 +00001061 return true;
Chris Lattner1b2251c2008-07-26 03:38:44 +00001062
1063 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
1064 case tok::less:
1065 return getLang().ObjC1;
Chris Lattner4b009652007-07-25 00:24:17 +00001066
1067 // typedef-name
1068 case tok::identifier:
1069 return Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope) != 0;
Chris Lattner4b009652007-07-25 00:24:17 +00001070 }
1071}
1072
1073
1074/// ParseTypeQualifierListOpt
1075/// type-qualifier-list: [C99 6.7.5]
1076/// type-qualifier
1077/// [GNU] attributes
1078/// type-qualifier-list type-qualifier
1079/// [GNU] type-qualifier-list attributes
1080///
1081void Parser::ParseTypeQualifierListOpt(DeclSpec &DS) {
1082 while (1) {
1083 int isInvalid = false;
1084 const char *PrevSpec = 0;
1085 SourceLocation Loc = Tok.getLocation();
1086
1087 switch (Tok.getKind()) {
1088 default:
1089 // If this is not a type-qualifier token, we're done reading type
1090 // qualifiers. First verify that DeclSpec's are consistent.
Ted Kremenekb3ee1932007-12-11 21:27:55 +00001091 DS.Finish(Diags, PP.getSourceManager(), getLang());
Chris Lattner4b009652007-07-25 00:24:17 +00001092 return;
1093 case tok::kw_const:
1094 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
1095 getLang())*2;
1096 break;
1097 case tok::kw_volatile:
1098 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
1099 getLang())*2;
1100 break;
1101 case tok::kw_restrict:
1102 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
1103 getLang())*2;
1104 break;
1105 case tok::kw___attribute:
1106 DS.AddAttributes(ParseAttributes());
1107 continue; // do *not* consume the next token!
1108 }
1109
1110 // If the specifier combination wasn't legal, issue a diagnostic.
1111 if (isInvalid) {
1112 assert(PrevSpec && "Method did not return previous specifier!");
1113 if (isInvalid == 1) // Error.
1114 Diag(Tok, diag::err_invalid_decl_spec_combination, PrevSpec);
1115 else // extwarn.
1116 Diag(Tok, diag::ext_duplicate_declspec, PrevSpec);
1117 }
1118 ConsumeToken();
1119 }
1120}
1121
1122
1123/// ParseDeclarator - Parse and verify a newly-initialized declarator.
1124///
1125void Parser::ParseDeclarator(Declarator &D) {
1126 /// This implements the 'declarator' production in the C grammar, then checks
1127 /// for well-formedness and issues diagnostics.
1128 ParseDeclaratorInternal(D);
Chris Lattner4b009652007-07-25 00:24:17 +00001129}
1130
1131/// ParseDeclaratorInternal
1132/// declarator: [C99 6.7.5]
1133/// pointer[opt] direct-declarator
1134/// [C++] '&' declarator [C++ 8p4, dcl.decl]
1135/// [GNU] '&' restrict[opt] attributes[opt] declarator
1136///
1137/// pointer: [C99 6.7.5]
1138/// '*' type-qualifier-list[opt]
1139/// '*' type-qualifier-list[opt] pointer
1140///
1141void Parser::ParseDeclaratorInternal(Declarator &D) {
1142 tok::TokenKind Kind = Tok.getKind();
1143
Steve Naroff7aa54752008-08-27 16:04:49 +00001144 // Not a pointer, C++ reference, or block.
1145 if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus) &&
1146 (Kind != tok::caret || !getLang().Blocks))
Chris Lattner4b009652007-07-25 00:24:17 +00001147 return ParseDirectDeclarator(D);
1148
Steve Naroffdc22f212008-08-28 10:07:06 +00001149 // Otherwise, '*' -> pointer, '^' -> block, '&' -> reference.
Chris Lattner4b009652007-07-25 00:24:17 +00001150 SourceLocation Loc = ConsumeToken(); // Eat the * or &.
1151
Steve Naroffdc22f212008-08-28 10:07:06 +00001152 if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) {
Chris Lattner69f01932008-02-21 01:32:26 +00001153 // Is a pointer.
Chris Lattner4b009652007-07-25 00:24:17 +00001154 DeclSpec DS;
1155
1156 ParseTypeQualifierListOpt(DS);
1157
1158 // Recursively parse the declarator.
1159 ParseDeclaratorInternal(D);
Steve Naroff7aa54752008-08-27 16:04:49 +00001160 if (Kind == tok::star)
1161 // Remember that we parsed a pointer type, and remember the type-quals.
1162 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
1163 DS.TakeAttributes()));
1164 else
1165 // Remember that we parsed a Block type, and remember the type-quals.
1166 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
1167 Loc));
Chris Lattner4b009652007-07-25 00:24:17 +00001168 } else {
1169 // Is a reference
1170 DeclSpec DS;
1171
1172 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
1173 // cv-qualifiers are introduced through the use of a typedef or of a
1174 // template type argument, in which case the cv-qualifiers are ignored.
1175 //
1176 // [GNU] Retricted references are allowed.
1177 // [GNU] Attributes on references are allowed.
1178 ParseTypeQualifierListOpt(DS);
1179
1180 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
1181 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
1182 Diag(DS.getConstSpecLoc(),
1183 diag::err_invalid_reference_qualifier_application,
1184 "const");
1185 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
1186 Diag(DS.getVolatileSpecLoc(),
1187 diag::err_invalid_reference_qualifier_application,
1188 "volatile");
1189 }
1190
1191 // Recursively parse the declarator.
1192 ParseDeclaratorInternal(D);
1193
1194 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner69f01932008-02-21 01:32:26 +00001195 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
1196 DS.TakeAttributes()));
Chris Lattner4b009652007-07-25 00:24:17 +00001197 }
1198}
1199
1200/// ParseDirectDeclarator
1201/// direct-declarator: [C99 6.7.5]
1202/// identifier
1203/// '(' declarator ')'
1204/// [GNU] '(' attributes declarator ')'
1205/// [C90] direct-declarator '[' constant-expression[opt] ']'
1206/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
1207/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
1208/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
1209/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
1210/// direct-declarator '(' parameter-type-list ')'
1211/// direct-declarator '(' identifier-list[opt] ')'
1212/// [GNU] direct-declarator '(' parameter-forward-declarations
1213/// parameter-type-list[opt] ')'
1214///
1215void Parser::ParseDirectDeclarator(Declarator &D) {
1216 // Parse the first direct-declarator seen.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001217 if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
Chris Lattner4b009652007-07-25 00:24:17 +00001218 assert(Tok.getIdentifierInfo() && "Not an identifier?");
1219 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
1220 ConsumeToken();
Chris Lattner34a01ad2007-10-09 17:33:22 +00001221 } else if (Tok.is(tok::l_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001222 // direct-declarator: '(' declarator ')'
1223 // direct-declarator: '(' attributes declarator ')'
1224 // Example: 'char (*X)' or 'int (*XX)(void)'
1225 ParseParenDeclarator(D);
1226 } else if (D.mayOmitIdentifier()) {
1227 // This could be something simple like "int" (in which case the declarator
1228 // portion is empty), if an abstract-declarator is allowed.
1229 D.SetIdentifier(0, Tok.getLocation());
1230 } else {
1231 // Expected identifier or '('.
1232 Diag(Tok, diag::err_expected_ident_lparen);
1233 D.SetIdentifier(0, Tok.getLocation());
1234 }
1235
1236 assert(D.isPastIdentifier() &&
1237 "Haven't past the location of the identifier yet?");
1238
1239 while (1) {
Chris Lattner34a01ad2007-10-09 17:33:22 +00001240 if (Tok.is(tok::l_paren)) {
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00001241 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
1242 // In such a case, check if we actually have a function declarator; if it
1243 // is not, the declarator has been fully parsed.
Chris Lattner1f185292008-10-20 02:05:46 +00001244 if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
1245 // When not in file scope, warn for ambiguous function declarators, just
1246 // in case the author intended it as a variable definition.
1247 bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
1248 if (!isCXXFunctionDeclarator(warnIfAmbiguous))
1249 break;
1250 }
Chris Lattnera0d056d2008-04-06 05:45:57 +00001251 ParseFunctionDeclarator(ConsumeParen(), D);
Chris Lattner34a01ad2007-10-09 17:33:22 +00001252 } else if (Tok.is(tok::l_square)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001253 ParseBracketDeclarator(D);
1254 } else {
1255 break;
1256 }
1257 }
1258}
1259
Chris Lattnera0d056d2008-04-06 05:45:57 +00001260/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
1261/// only called before the identifier, so these are most likely just grouping
1262/// parens for precedence. If we find that these are actually function
1263/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
1264///
1265/// direct-declarator:
1266/// '(' declarator ')'
1267/// [GNU] '(' attributes declarator ')'
Chris Lattner1f185292008-10-20 02:05:46 +00001268/// direct-declarator '(' parameter-type-list ')'
1269/// direct-declarator '(' identifier-list[opt] ')'
1270/// [GNU] direct-declarator '(' parameter-forward-declarations
1271/// parameter-type-list[opt] ')'
Chris Lattnera0d056d2008-04-06 05:45:57 +00001272///
1273void Parser::ParseParenDeclarator(Declarator &D) {
1274 SourceLocation StartLoc = ConsumeParen();
1275 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
1276
Chris Lattner1f185292008-10-20 02:05:46 +00001277 // Eat any attributes before we look at whether this is a grouping or function
1278 // declarator paren. If this is a grouping paren, the attribute applies to
1279 // the type being built up, for example:
1280 // int (__attribute__(()) *x)(long y)
1281 // If this ends up not being a grouping paren, the attribute applies to the
1282 // first argument, for example:
1283 // int (__attribute__(()) int x)
1284 // In either case, we need to eat any attributes to be able to determine what
1285 // sort of paren this is.
1286 //
1287 AttributeList *AttrList = 0;
1288 bool RequiresArg = false;
1289 if (Tok.is(tok::kw___attribute)) {
1290 AttrList = ParseAttributes();
1291
1292 // We require that the argument list (if this is a non-grouping paren) be
1293 // present even if the attribute list was empty.
1294 RequiresArg = true;
1295 }
1296
Chris Lattnera0d056d2008-04-06 05:45:57 +00001297 // If we haven't past the identifier yet (or where the identifier would be
1298 // stored, if this is an abstract declarator), then this is probably just
1299 // grouping parens. However, if this could be an abstract-declarator, then
1300 // this could also be the start of function arguments (consider 'void()').
1301 bool isGrouping;
1302
1303 if (!D.mayOmitIdentifier()) {
1304 // If this can't be an abstract-declarator, this *must* be a grouping
1305 // paren, because we haven't seen the identifier yet.
1306 isGrouping = true;
1307 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Argiris Kirtzidis1c64fdc2008-10-06 00:07:55 +00001308 (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
Chris Lattnera0d056d2008-04-06 05:45:57 +00001309 isDeclarationSpecifier()) { // 'int(int)' is a function.
1310 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
1311 // considered to be a type, not a K&R identifier-list.
1312 isGrouping = false;
1313 } else {
1314 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
1315 isGrouping = true;
1316 }
1317
1318 // If this is a grouping paren, handle:
1319 // direct-declarator: '(' declarator ')'
1320 // direct-declarator: '(' attributes declarator ')'
1321 if (isGrouping) {
Argiris Kirtzidis0941ff42008-10-07 10:21:57 +00001322 bool hadGroupingParens = D.hasGroupingParens();
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00001323 D.setGroupingParens(true);
Chris Lattner1f185292008-10-20 02:05:46 +00001324 if (AttrList)
1325 D.AddAttributes(AttrList);
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00001326
Chris Lattnera0d056d2008-04-06 05:45:57 +00001327 ParseDeclaratorInternal(D);
1328 // Match the ')'.
1329 MatchRHSPunctuation(tok::r_paren, StartLoc);
Argiris Kirtzidis0941ff42008-10-07 10:21:57 +00001330
1331 D.setGroupingParens(hadGroupingParens);
Chris Lattnera0d056d2008-04-06 05:45:57 +00001332 return;
1333 }
1334
1335 // Okay, if this wasn't a grouping paren, it must be the start of a function
1336 // argument list. Recognize that this declarator will never have an
Chris Lattner1f185292008-10-20 02:05:46 +00001337 // identifier (and remember where it would have been), then call into
1338 // ParseFunctionDeclarator to handle of argument list.
Chris Lattnera0d056d2008-04-06 05:45:57 +00001339 D.SetIdentifier(0, Tok.getLocation());
1340
Chris Lattner1f185292008-10-20 02:05:46 +00001341 ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
Chris Lattnera0d056d2008-04-06 05:45:57 +00001342}
1343
1344/// ParseFunctionDeclarator - We are after the identifier and have parsed the
1345/// declarator D up to a paren, which indicates that we are parsing function
1346/// arguments.
Chris Lattner4b009652007-07-25 00:24:17 +00001347///
Chris Lattner1f185292008-10-20 02:05:46 +00001348/// If AttrList is non-null, then the caller parsed those arguments immediately
1349/// after the open paren - they should be considered to be the first argument of
1350/// a parameter. If RequiresArg is true, then the first argument of the
1351/// function is required to be present and required to not be an identifier
1352/// list.
1353///
Chris Lattner4b009652007-07-25 00:24:17 +00001354/// This method also handles this portion of the grammar:
1355/// parameter-type-list: [C99 6.7.5]
1356/// parameter-list
1357/// parameter-list ',' '...'
1358///
1359/// parameter-list: [C99 6.7.5]
1360/// parameter-declaration
1361/// parameter-list ',' parameter-declaration
1362///
1363/// parameter-declaration: [C99 6.7.5]
1364/// declaration-specifiers declarator
Chris Lattner3e254fb2008-04-08 04:40:51 +00001365/// [C++] declaration-specifiers declarator '=' assignment-expression
Chris Lattner4b009652007-07-25 00:24:17 +00001366/// [GNU] declaration-specifiers declarator attributes
1367/// declaration-specifiers abstract-declarator[opt]
Chris Lattner97316c02008-04-10 02:22:51 +00001368/// [C++] declaration-specifiers abstract-declarator[opt]
1369/// '=' assignment-expression
Chris Lattner4b009652007-07-25 00:24:17 +00001370/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
1371///
Chris Lattner1f185292008-10-20 02:05:46 +00001372void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
1373 AttributeList *AttrList,
1374 bool RequiresArg) {
Chris Lattnera0d056d2008-04-06 05:45:57 +00001375 // lparen is already consumed!
1376 assert(D.isPastIdentifier() && "Should not call before identifier!");
Chris Lattner4b009652007-07-25 00:24:17 +00001377
Chris Lattner1f185292008-10-20 02:05:46 +00001378 // This parameter list may be empty.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001379 if (Tok.is(tok::r_paren)) {
Chris Lattner1f185292008-10-20 02:05:46 +00001380 if (RequiresArg) {
1381 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1382 delete AttrList;
1383 }
1384
Chris Lattner9f7564b2008-04-06 06:57:35 +00001385 // Remember that we parsed a function type, and remember the attributes.
Chris Lattner4b009652007-07-25 00:24:17 +00001386 // int() -> no prototype, no '...'.
Chris Lattner9f7564b2008-04-06 06:57:35 +00001387 D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/ false,
1388 /*variadic*/ false,
1389 /*arglist*/ 0, 0, LParenLoc));
1390
1391 ConsumeParen(); // Eat the closing ')'.
1392 return;
Chris Lattner1f185292008-10-20 02:05:46 +00001393 }
1394
1395 // Alternatively, this parameter list may be an identifier list form for a
1396 // K&R-style function: void foo(a,b,c)
1397 if (Tok.is(tok::identifier) &&
1398 // K&R identifier lists can't have typedefs as identifiers, per
1399 // C99 6.7.5.3p11.
1400 !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
1401 if (RequiresArg) {
1402 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1403 delete AttrList;
1404 }
1405
Chris Lattner4b009652007-07-25 00:24:17 +00001406 // Identifier list. Note that '(' identifier-list ')' is only allowed for
1407 // normal declarators, not for abstract-declarators.
Chris Lattner35d9c912008-04-06 06:34:08 +00001408 return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
Chris Lattner9f7564b2008-04-06 06:57:35 +00001409 }
1410
1411 // Finally, a normal, non-empty parameter type list.
1412
1413 // Build up an array of information about the parsed arguments.
1414 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Chris Lattner3e254fb2008-04-08 04:40:51 +00001415
1416 // Enter function-declaration scope, limiting any declarators to the
1417 // function prototype scope, including parameter declarators.
Argiris Kirtzidis59a9afb2008-05-09 23:39:43 +00001418 EnterScope(Scope::FnScope|Scope::DeclScope);
Chris Lattner9f7564b2008-04-06 06:57:35 +00001419
1420 bool IsVariadic = false;
1421 while (1) {
1422 if (Tok.is(tok::ellipsis)) {
1423 IsVariadic = true;
Chris Lattner4b009652007-07-25 00:24:17 +00001424
Chris Lattner9f7564b2008-04-06 06:57:35 +00001425 // Check to see if this is "void(...)" which is not allowed.
Argiris Kirtzidis1c64fdc2008-10-06 00:07:55 +00001426 if (!getLang().CPlusPlus && ParamInfo.empty()) {
Chris Lattner9f7564b2008-04-06 06:57:35 +00001427 // Otherwise, parse parameter type list. If it starts with an
1428 // ellipsis, diagnose the malformed function.
1429 Diag(Tok, diag::err_ellipsis_first_arg);
1430 IsVariadic = false; // Treat this like 'void()'.
Chris Lattner4b009652007-07-25 00:24:17 +00001431 }
Chris Lattnere5db29f2008-01-31 06:10:07 +00001432
Chris Lattner9f7564b2008-04-06 06:57:35 +00001433 ConsumeToken(); // Consume the ellipsis.
1434 break;
Chris Lattner4b009652007-07-25 00:24:17 +00001435 }
1436
Chris Lattner9f7564b2008-04-06 06:57:35 +00001437 SourceLocation DSStart = Tok.getLocation();
Chris Lattner4b009652007-07-25 00:24:17 +00001438
Chris Lattner9f7564b2008-04-06 06:57:35 +00001439 // Parse the declaration-specifiers.
1440 DeclSpec DS;
Chris Lattner1f185292008-10-20 02:05:46 +00001441
1442 // If the caller parsed attributes for the first argument, add them now.
1443 if (AttrList) {
1444 DS.AddAttributes(AttrList);
1445 AttrList = 0; // Only apply the attributes to the first parameter.
1446 }
Chris Lattner9f7564b2008-04-06 06:57:35 +00001447 ParseDeclarationSpecifiers(DS);
1448
1449 // Parse the declarator. This is "PrototypeContext", because we must
1450 // accept either 'declarator' or 'abstract-declarator' here.
1451 Declarator ParmDecl(DS, Declarator::PrototypeContext);
1452 ParseDeclarator(ParmDecl);
1453
1454 // Parse GNU attributes, if present.
1455 if (Tok.is(tok::kw___attribute))
1456 ParmDecl.AddAttributes(ParseAttributes());
1457
Chris Lattner9f7564b2008-04-06 06:57:35 +00001458 // Remember this parsed parameter in ParamInfo.
1459 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
1460
Chris Lattner9f7564b2008-04-06 06:57:35 +00001461 // If no parameter was specified, verify that *something* was specified,
1462 // otherwise we have a missing type and identifier.
1463 if (DS.getParsedSpecifiers() == DeclSpec::PQ_None &&
1464 ParmDecl.getIdentifier() == 0 && ParmDecl.getNumTypeObjects() == 0) {
1465 // Completely missing, emit error.
1466 Diag(DSStart, diag::err_missing_param);
1467 } else {
1468 // Otherwise, we have something. Add it and let semantic analysis try
1469 // to grok it and add the result to the ParamInfo we are building.
1470
1471 // Inform the actions module about the parameter declarator, so it gets
1472 // added to the current scope.
Chris Lattner3e254fb2008-04-08 04:40:51 +00001473 DeclTy *Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
1474
1475 // Parse the default argument, if any. We parse the default
1476 // arguments in all dialects; the semantic analysis in
1477 // ActOnParamDefaultArgument will reject the default argument in
1478 // C.
1479 if (Tok.is(tok::equal)) {
1480 SourceLocation EqualLoc = Tok.getLocation();
1481
1482 // Consume the '='.
1483 ConsumeToken();
1484
1485 // Parse the default argument
Chris Lattner3e254fb2008-04-08 04:40:51 +00001486 ExprResult DefArgResult = ParseAssignmentExpression();
1487 if (DefArgResult.isInvalid) {
1488 SkipUntil(tok::comma, tok::r_paren, true, true);
1489 } else {
1490 // Inform the actions module about the default argument
1491 Actions.ActOnParamDefaultArgument(Param, EqualLoc, DefArgResult.Val);
1492 }
1493 }
Chris Lattner9f7564b2008-04-06 06:57:35 +00001494
1495 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Chris Lattner3e254fb2008-04-08 04:40:51 +00001496 ParmDecl.getIdentifierLoc(), Param));
Chris Lattner9f7564b2008-04-06 06:57:35 +00001497 }
1498
1499 // If the next token is a comma, consume it and keep reading arguments.
1500 if (Tok.isNot(tok::comma)) break;
1501
1502 // Consume the comma.
1503 ConsumeToken();
Chris Lattner4b009652007-07-25 00:24:17 +00001504 }
1505
Chris Lattner9f7564b2008-04-06 06:57:35 +00001506 // Leave prototype scope.
1507 ExitScope();
1508
Chris Lattner4b009652007-07-25 00:24:17 +00001509 // Remember that we parsed a function type, and remember the attributes.
Chris Lattner9f7564b2008-04-06 06:57:35 +00001510 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
1511 &ParamInfo[0], ParamInfo.size(),
1512 LParenLoc));
Chris Lattner4b009652007-07-25 00:24:17 +00001513
1514 // If we have the closing ')', eat it and we're done.
Chris Lattner9f7564b2008-04-06 06:57:35 +00001515 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Chris Lattner4b009652007-07-25 00:24:17 +00001516}
1517
Chris Lattner35d9c912008-04-06 06:34:08 +00001518/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
1519/// we found a K&R-style identifier list instead of a type argument list. The
1520/// current token is known to be the first identifier in the list.
1521///
1522/// identifier-list: [C99 6.7.5]
1523/// identifier
1524/// identifier-list ',' identifier
1525///
1526void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
1527 Declarator &D) {
1528 // Build up an array of information about the parsed arguments.
1529 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
1530 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
1531
1532 // If there was no identifier specified for the declarator, either we are in
1533 // an abstract-declarator, or we are in a parameter declarator which was found
1534 // to be abstract. In abstract-declarators, identifier lists are not valid:
1535 // diagnose this.
1536 if (!D.getIdentifier())
1537 Diag(Tok, diag::ext_ident_list_in_param);
1538
1539 // Tok is known to be the first identifier in the list. Remember this
1540 // identifier in ParamInfo.
Chris Lattnerc337fa22008-04-06 06:50:56 +00001541 ParamsSoFar.insert(Tok.getIdentifierInfo());
Chris Lattner35d9c912008-04-06 06:34:08 +00001542 ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
1543 Tok.getLocation(), 0));
1544
Chris Lattner113a56b2008-04-06 06:39:19 +00001545 ConsumeToken(); // eat the first identifier.
Chris Lattner35d9c912008-04-06 06:34:08 +00001546
1547 while (Tok.is(tok::comma)) {
1548 // Eat the comma.
1549 ConsumeToken();
1550
Chris Lattner113a56b2008-04-06 06:39:19 +00001551 // If this isn't an identifier, report the error and skip until ')'.
Chris Lattner35d9c912008-04-06 06:34:08 +00001552 if (Tok.isNot(tok::identifier)) {
1553 Diag(Tok, diag::err_expected_ident);
Chris Lattner113a56b2008-04-06 06:39:19 +00001554 SkipUntil(tok::r_paren);
1555 return;
Chris Lattner35d9c912008-04-06 06:34:08 +00001556 }
Chris Lattneracb67d92008-04-06 06:47:48 +00001557
Chris Lattner35d9c912008-04-06 06:34:08 +00001558 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
Chris Lattneracb67d92008-04-06 06:47:48 +00001559
1560 // Reject 'typedef int y; int test(x, y)', but continue parsing.
1561 if (Actions.isTypeName(*ParmII, CurScope))
1562 Diag(Tok, diag::err_unexpected_typedef_ident, ParmII->getName());
Chris Lattner35d9c912008-04-06 06:34:08 +00001563
1564 // Verify that the argument identifier has not already been mentioned.
1565 if (!ParamsSoFar.insert(ParmII)) {
Chris Lattner113a56b2008-04-06 06:39:19 +00001566 Diag(Tok.getLocation(), diag::err_param_redefinition, ParmII->getName());
1567 } else {
1568 // Remember this identifier in ParamInfo.
Chris Lattner35d9c912008-04-06 06:34:08 +00001569 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
1570 Tok.getLocation(), 0));
Chris Lattner113a56b2008-04-06 06:39:19 +00001571 }
Chris Lattner35d9c912008-04-06 06:34:08 +00001572
1573 // Eat the identifier.
1574 ConsumeToken();
1575 }
1576
Chris Lattner113a56b2008-04-06 06:39:19 +00001577 // Remember that we parsed a function type, and remember the attributes. This
1578 // function type is always a K&R style function type, which is not varargs and
1579 // has no prototype.
1580 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
1581 &ParamInfo[0], ParamInfo.size(),
1582 LParenLoc));
Chris Lattner35d9c912008-04-06 06:34:08 +00001583
1584 // If we have the closing ')', eat it and we're done.
Chris Lattner113a56b2008-04-06 06:39:19 +00001585 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Chris Lattner35d9c912008-04-06 06:34:08 +00001586}
Chris Lattnera0d056d2008-04-06 05:45:57 +00001587
Chris Lattner4b009652007-07-25 00:24:17 +00001588/// [C90] direct-declarator '[' constant-expression[opt] ']'
1589/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
1590/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
1591/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
1592/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
1593void Parser::ParseBracketDeclarator(Declarator &D) {
1594 SourceLocation StartLoc = ConsumeBracket();
1595
1596 // If valid, this location is the position where we read the 'static' keyword.
1597 SourceLocation StaticLoc;
Chris Lattner34a01ad2007-10-09 17:33:22 +00001598 if (Tok.is(tok::kw_static))
Chris Lattner4b009652007-07-25 00:24:17 +00001599 StaticLoc = ConsumeToken();
1600
1601 // If there is a type-qualifier-list, read it now.
1602 DeclSpec DS;
1603 ParseTypeQualifierListOpt(DS);
1604
1605 // If we haven't already read 'static', check to see if there is one after the
1606 // type-qualifier-list.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001607 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Chris Lattner4b009652007-07-25 00:24:17 +00001608 StaticLoc = ConsumeToken();
1609
1610 // Handle "direct-declarator [ type-qual-list[opt] * ]".
1611 bool isStar = false;
1612 ExprResult NumElements(false);
Chris Lattner44f6d9d2008-04-06 05:26:30 +00001613
1614 // Handle the case where we have '[*]' as the array size. However, a leading
1615 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
1616 // the the token after the star is a ']'. Since stars in arrays are
1617 // infrequent, use of lookahead is not costly here.
1618 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattner1bb39512008-04-06 05:27:21 +00001619 ConsumeToken(); // Eat the '*'.
Chris Lattner4b009652007-07-25 00:24:17 +00001620
Chris Lattner44f6d9d2008-04-06 05:26:30 +00001621 if (StaticLoc.isValid())
1622 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
1623 StaticLoc = SourceLocation(); // Drop the static.
1624 isStar = true;
Chris Lattner34a01ad2007-10-09 17:33:22 +00001625 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001626 // Parse the assignment-expression now.
1627 NumElements = ParseAssignmentExpression();
1628 }
1629
1630 // If there was an error parsing the assignment-expression, recover.
1631 if (NumElements.isInvalid) {
1632 // If the expression was invalid, skip it.
1633 SkipUntil(tok::r_square);
1634 return;
1635 }
1636
1637 MatchRHSPunctuation(tok::r_square, StartLoc);
1638
1639 // If C99 isn't enabled, emit an ext-warn if the arg list wasn't empty and if
1640 // it was not a constant expression.
1641 if (!getLang().C99) {
1642 // TODO: check C90 array constant exprness.
1643 if (isStar || StaticLoc.isValid() ||
1644 0/*TODO: NumElts is not a C90 constantexpr */)
1645 Diag(StartLoc, diag::ext_c99_array_usage);
1646 }
1647
1648 // Remember that we parsed a pointer type, and remember the type-quals.
1649 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
1650 StaticLoc.isValid(), isStar,
1651 NumElements.Val, StartLoc));
1652}
1653
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001654/// [GNU] typeof-specifier:
1655/// typeof ( expressions )
1656/// typeof ( type-name )
1657/// [GNU/C++] typeof unary-expression
Steve Naroff7cbb1462007-07-31 12:34:36 +00001658///
1659void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner34a01ad2007-10-09 17:33:22 +00001660 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Steve Naroff14bbce82007-08-02 02:53:48 +00001661 const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
Steve Naroff7cbb1462007-07-31 12:34:36 +00001662 SourceLocation StartLoc = ConsumeToken();
1663
Chris Lattner34a01ad2007-10-09 17:33:22 +00001664 if (Tok.isNot(tok::l_paren)) {
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001665 if (!getLang().CPlusPlus) {
1666 Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
1667 return;
1668 }
1669
1670 ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/);
1671 if (Result.isInvalid)
1672 return;
1673
1674 const char *PrevSpec = 0;
1675 // Check for duplicate type specifiers.
1676 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
1677 Result.Val))
1678 Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
1679
1680 // FIXME: Not accurate, the range gets one token more than it should.
1681 DS.SetRangeEnd(Tok.getLocation());
Steve Naroff14bbce82007-08-02 02:53:48 +00001682 return;
Steve Naroff7cbb1462007-07-31 12:34:36 +00001683 }
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00001684
Steve Naroff7cbb1462007-07-31 12:34:36 +00001685 SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
1686
Argiris Kirtzidis3276cbc2008-10-05 19:56:22 +00001687 if (isTypeIdInParens()) {
Steve Naroff7cbb1462007-07-31 12:34:36 +00001688 TypeTy *Ty = ParseTypeName();
1689
Steve Naroff4c255ab2007-07-31 23:56:32 +00001690 assert(Ty && "Parser::ParseTypeofSpecifier(): missing type");
1691
Chris Lattner34a01ad2007-10-09 17:33:22 +00001692 if (Tok.isNot(tok::r_paren)) {
Steve Naroff4c255ab2007-07-31 23:56:32 +00001693 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Steve Naroff14bbce82007-08-02 02:53:48 +00001694 return;
1695 }
1696 RParenLoc = ConsumeParen();
1697 const char *PrevSpec = 0;
1698 // Check for duplicate type specifiers (e.g. "int typeof(int)").
1699 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
1700 Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
Steve Naroff7cbb1462007-07-31 12:34:36 +00001701 } else { // we have an expression.
1702 ExprResult Result = ParseExpression();
Steve Naroff4c255ab2007-07-31 23:56:32 +00001703
Chris Lattner34a01ad2007-10-09 17:33:22 +00001704 if (Result.isInvalid || Tok.isNot(tok::r_paren)) {
Steve Naroff4c255ab2007-07-31 23:56:32 +00001705 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Steve Naroff14bbce82007-08-02 02:53:48 +00001706 return;
1707 }
1708 RParenLoc = ConsumeParen();
1709 const char *PrevSpec = 0;
1710 // Check for duplicate type specifiers (e.g. "int typeof(int)").
1711 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
1712 Result.Val))
1713 Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
Steve Naroff7cbb1462007-07-31 12:34:36 +00001714 }
Argiris Kirtzidis4d923942008-08-16 10:21:33 +00001715 DS.SetRangeEnd(RParenLoc);
Steve Naroff7cbb1462007-07-31 12:34:36 +00001716}
1717
Argiris Kirtzidis59a9afb2008-05-09 23:39:43 +00001718