blob: 1ddd20a9ecbf82253fc1fe100b1b646ed6bc29cf [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"
Chris Lattner545f39e2009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.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++.
Sebastian Redlaaacda92009-05-29 18:02:33 +000030Action::TypeResult Parser::ParseTypeName(SourceRange *Range) {
Chris Lattner4b009652007-07-25 00:24:17 +000031 // Parse the common declaration-specifiers piece.
32 DeclSpec DS;
33 ParseSpecifierQualifierList(DS);
Sebastian Redlaaacda92009-05-29 18:02:33 +000034
Chris Lattner4b009652007-07-25 00:24:17 +000035 // Parse the abstract-declarator, if present.
36 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
37 ParseDeclarator(DeclaratorInfo);
Sebastian Redlaaacda92009-05-29 18:02:33 +000038 if (Range)
39 *Range = DeclaratorInfo.getSourceRange();
40
Chris Lattner34c61332009-04-25 08:06:05 +000041 if (DeclaratorInfo.isInvalidType())
Douglas Gregor6c0f4062009-02-18 17:45:20 +000042 return true;
43
44 return Actions.ActOnTypeName(CurScope, DeclaratorInfo);
Chris Lattner4b009652007-07-25 00:24:17 +000045}
46
47/// ParseAttributes - Parse a non-empty attributes list.
48///
49/// [GNU] attributes:
50/// attribute
51/// attributes attribute
52///
53/// [GNU] attribute:
54/// '__attribute__' '(' '(' attribute-list ')' ')'
55///
56/// [GNU] attribute-list:
57/// attrib
58/// attribute_list ',' attrib
59///
60/// [GNU] attrib:
61/// empty
62/// attrib-name
63/// attrib-name '(' identifier ')'
64/// attrib-name '(' identifier ',' nonempty-expr-list ')'
65/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
66///
67/// [GNU] attrib-name:
68/// identifier
69/// typespec
70/// typequal
71/// storageclass
72///
73/// FIXME: The GCC grammar/code for this construct implies we need two
74/// token lookahead. Comment from gcc: "If they start with an identifier
75/// which is followed by a comma or close parenthesis, then the arguments
76/// start with that identifier; otherwise they are an expression list."
77///
78/// At the moment, I am not doing 2 token lookahead. I am also unaware of
79/// any attributes that don't work (based on my limited testing). Most
80/// attributes are very simple in practice. Until we find a bug, I don't see
81/// a pressing need to implement the 2 token lookahead.
82
Sebastian Redl0c986032009-02-09 18:23:29 +000083AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
Chris Lattner34a01ad2007-10-09 17:33:22 +000084 assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
Chris Lattner4b009652007-07-25 00:24:17 +000085
86 AttributeList *CurrAttr = 0;
87
Chris Lattner34a01ad2007-10-09 17:33:22 +000088 while (Tok.is(tok::kw___attribute)) {
Chris Lattner4b009652007-07-25 00:24:17 +000089 ConsumeToken();
90 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
91 "attribute")) {
92 SkipUntil(tok::r_paren, true); // skip until ) or ;
93 return CurrAttr;
94 }
95 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
96 SkipUntil(tok::r_paren, true); // skip until ) or ;
97 return CurrAttr;
98 }
99 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner34a01ad2007-10-09 17:33:22 +0000100 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
101 Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000102
Chris Lattner34a01ad2007-10-09 17:33:22 +0000103 if (Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000104 // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
105 ConsumeToken();
106 continue;
107 }
108 // we have an identifier or declaration specifier (const, int, etc.)
109 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
110 SourceLocation AttrNameLoc = ConsumeToken();
111
112 // check if we have a "paramterized" attribute
Chris Lattner34a01ad2007-10-09 17:33:22 +0000113 if (Tok.is(tok::l_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000114 ConsumeParen(); // ignore the left paren loc for now
115
Chris Lattner34a01ad2007-10-09 17:33:22 +0000116 if (Tok.is(tok::identifier)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000117 IdentifierInfo *ParmName = Tok.getIdentifierInfo();
118 SourceLocation ParmLoc = ConsumeToken();
119
Chris Lattner34a01ad2007-10-09 17:33:22 +0000120 if (Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000121 // __attribute__(( mode(byte) ))
122 ConsumeParen(); // ignore the right paren loc for now
123 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
124 ParmName, ParmLoc, 0, 0, CurrAttr);
Chris Lattner34a01ad2007-10-09 17:33:22 +0000125 } else if (Tok.is(tok::comma)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000126 ConsumeToken();
127 // __attribute__(( format(printf, 1, 2) ))
Sebastian Redl6008ac32008-11-25 22:21:31 +0000128 ExprVector ArgExprs(Actions);
Chris Lattner4b009652007-07-25 00:24:17 +0000129 bool ArgExprsOk = true;
130
131 // now parse the non-empty comma separated list of expressions
132 while (1) {
Sebastian Redl14ca7412008-12-11 21:36:32 +0000133 OwningExprResult ArgExpr(ParseAssignmentExpression());
Sebastian Redlbb4dae72008-12-09 13:15:23 +0000134 if (ArgExpr.isInvalid()) {
Chris Lattner4b009652007-07-25 00:24:17 +0000135 ArgExprsOk = false;
136 SkipUntil(tok::r_paren);
137 break;
138 } else {
Sebastian Redl6f1ee232008-12-10 00:02:53 +0000139 ArgExprs.push_back(ArgExpr.release());
Chris Lattner4b009652007-07-25 00:24:17 +0000140 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000141 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000142 break;
143 ConsumeToken(); // Eat the comma, move to the next argument
144 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000145 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000146 ConsumeParen(); // ignore the right paren loc for now
147 CurrAttr = new AttributeList(AttrName, AttrNameLoc, ParmName,
Sebastian Redl6008ac32008-11-25 22:21:31 +0000148 ParmLoc, ArgExprs.take(), ArgExprs.size(), CurrAttr);
Chris Lattner4b009652007-07-25 00:24:17 +0000149 }
150 }
151 } else { // not an identifier
Nate Begeman60702162009-06-26 06:32:41 +0000152 switch (Tok.getKind()) {
153 case tok::r_paren:
Chris Lattner4b009652007-07-25 00:24:17 +0000154 // parse a possibly empty comma separated list of expressions
Chris Lattner4b009652007-07-25 00:24:17 +0000155 // __attribute__(( nonnull() ))
156 ConsumeParen(); // ignore the right paren loc for now
157 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
158 0, SourceLocation(), 0, 0, CurrAttr);
Nate Begeman60702162009-06-26 06:32:41 +0000159 break;
160 case tok::kw_char:
161 case tok::kw_wchar_t:
162 case tok::kw_bool:
163 case tok::kw_short:
164 case tok::kw_int:
165 case tok::kw_long:
166 case tok::kw_signed:
167 case tok::kw_unsigned:
168 case tok::kw_float:
169 case tok::kw_double:
170 case tok::kw_void:
171 case tok::kw_typeof:
172 // If it's a builtin type name, eat it and expect a rparen
173 // __attribute__(( vec_type_hint(char) ))
174 ConsumeToken();
175 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
176 0, SourceLocation(), 0, 0, CurrAttr);
177 if (Tok.is(tok::r_paren))
178 ConsumeParen();
179 break;
180 default:
Chris Lattner4b009652007-07-25 00:24:17 +0000181 // __attribute__(( aligned(16) ))
Sebastian Redl6008ac32008-11-25 22:21:31 +0000182 ExprVector ArgExprs(Actions);
Chris Lattner4b009652007-07-25 00:24:17 +0000183 bool ArgExprsOk = true;
184
185 // now parse the list of expressions
186 while (1) {
Sebastian Redl14ca7412008-12-11 21:36:32 +0000187 OwningExprResult ArgExpr(ParseAssignmentExpression());
Sebastian Redlbb4dae72008-12-09 13:15:23 +0000188 if (ArgExpr.isInvalid()) {
Chris Lattner4b009652007-07-25 00:24:17 +0000189 ArgExprsOk = false;
190 SkipUntil(tok::r_paren);
191 break;
192 } else {
Sebastian Redl6f1ee232008-12-10 00:02:53 +0000193 ArgExprs.push_back(ArgExpr.release());
Chris Lattner4b009652007-07-25 00:24:17 +0000194 }
Chris Lattner34a01ad2007-10-09 17:33:22 +0000195 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000196 break;
197 ConsumeToken(); // Eat the comma, move to the next argument
198 }
199 // Match the ')'.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000200 if (ArgExprsOk && Tok.is(tok::r_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000201 ConsumeParen(); // ignore the right paren loc for now
Sebastian Redl6008ac32008-11-25 22:21:31 +0000202 CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
203 SourceLocation(), ArgExprs.take(), ArgExprs.size(),
Chris Lattner4b009652007-07-25 00:24:17 +0000204 CurrAttr);
205 }
Nate Begeman60702162009-06-26 06:32:41 +0000206 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000207 }
208 }
209 } else {
210 CurrAttr = new AttributeList(AttrName, AttrNameLoc,
211 0, SourceLocation(), 0, 0, CurrAttr);
212 }
213 }
214 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
Chris Lattner4b009652007-07-25 00:24:17 +0000215 SkipUntil(tok::r_paren, false);
Sebastian Redl0c986032009-02-09 18:23:29 +0000216 SourceLocation Loc = Tok.getLocation();;
217 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
218 SkipUntil(tok::r_paren, false);
219 }
220 if (EndLoc)
221 *EndLoc = Loc;
Chris Lattner4b009652007-07-25 00:24:17 +0000222 }
223 return CurrAttr;
224}
225
Eli Friedmancd231842009-06-08 07:21:15 +0000226/// ParseMicrosoftDeclSpec - Parse an __declspec construct
227///
228/// [MS] decl-specifier:
229/// __declspec ( extended-decl-modifier-seq )
230///
231/// [MS] extended-decl-modifier-seq:
232/// extended-decl-modifier[opt]
233/// extended-decl-modifier extended-decl-modifier-seq
234
Eli Friedman891d82f2009-06-08 23:27:34 +0000235AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
Steve Naroffc5ab14f2008-12-24 20:59:21 +0000236 assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
Eli Friedmancd231842009-06-08 07:21:15 +0000237
Steve Naroffc5ab14f2008-12-24 20:59:21 +0000238 ConsumeToken();
Eli Friedmancd231842009-06-08 07:21:15 +0000239 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
240 "declspec")) {
241 SkipUntil(tok::r_paren, true); // skip until ) or ;
242 return CurrAttr;
243 }
Eli Friedman891d82f2009-06-08 23:27:34 +0000244 while (Tok.getIdentifierInfo()) {
Eli Friedmancd231842009-06-08 07:21:15 +0000245 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
246 SourceLocation AttrNameLoc = ConsumeToken();
247 if (Tok.is(tok::l_paren)) {
248 ConsumeParen();
249 // FIXME: This doesn't parse __declspec(property(get=get_func_name))
250 // correctly.
251 OwningExprResult ArgExpr(ParseAssignmentExpression());
252 if (!ArgExpr.isInvalid()) {
253 ExprTy* ExprList = ArgExpr.take();
254 CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
255 SourceLocation(), &ExprList, 1,
256 CurrAttr, true);
257 }
258 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
259 SkipUntil(tok::r_paren, false);
260 } else {
261 CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, SourceLocation(),
262 0, 0, CurrAttr, true);
263 }
264 }
265 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
266 SkipUntil(tok::r_paren, false);
Eli Friedman891d82f2009-06-08 23:27:34 +0000267 return CurrAttr;
268}
269
270AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
271 // Treat these like attributes
272 // FIXME: Allow Sema to distinguish between these and real attributes!
273 while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
274 Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___ptr64) ||
275 Tok.is(tok::kw___w64)) {
276 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
277 SourceLocation AttrNameLoc = ConsumeToken();
278 if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
279 // FIXME: Support these properly!
280 continue;
281 CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
282 SourceLocation(), 0, 0, CurrAttr, true);
283 }
284 return CurrAttr;
Steve Naroffc5ab14f2008-12-24 20:59:21 +0000285}
286
Chris Lattner4b009652007-07-25 00:24:17 +0000287/// ParseDeclaration - Parse a full 'declaration', which consists of
288/// declaration-specifiers, some number of declarators, and a semicolon.
Chris Lattner9802a0a2009-04-02 04:16:50 +0000289/// 'Context' should be a Declarator::TheContext value. This returns the
290/// location of the semicolon in DeclEnd.
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000291///
292/// declaration: [C99 6.7]
293/// block-declaration ->
294/// simple-declaration
295/// others [FIXME]
Douglas Gregorb3bec712008-12-01 23:54:00 +0000296/// [C++] template-declaration
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000297/// [C++] namespace-definition
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000298/// [C++] using-directive
Douglas Gregorcad27f62009-06-22 23:06:13 +0000299/// [C++] using-declaration
Sebastian Redla8cecf62009-03-24 22:27:57 +0000300/// [C++0x] static_assert-declaration
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000301/// others... [FIXME]
302///
Chris Lattner9802a0a2009-04-02 04:16:50 +0000303Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
304 SourceLocation &DeclEnd) {
Chris Lattnera17991f2009-03-29 16:50:03 +0000305 DeclPtrTy SingleDecl;
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000306 switch (Tok.getKind()) {
Douglas Gregorb3bec712008-12-01 23:54:00 +0000307 case tok::kw_template:
Douglas Gregore3298aa2009-05-12 21:31:51 +0000308 case tok::kw_export:
Douglas Gregora9db0fa2009-05-12 23:25:50 +0000309 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
Chris Lattnera17991f2009-03-29 16:50:03 +0000310 break;
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000311 case tok::kw_namespace:
Chris Lattner9802a0a2009-04-02 04:16:50 +0000312 SingleDecl = ParseNamespace(Context, DeclEnd);
Chris Lattnera17991f2009-03-29 16:50:03 +0000313 break;
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000314 case tok::kw_using:
Chris Lattner9802a0a2009-04-02 04:16:50 +0000315 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd);
Chris Lattnera17991f2009-03-29 16:50:03 +0000316 break;
Anders Carlssonab041982009-03-11 16:27:10 +0000317 case tok::kw_static_assert:
Chris Lattner9802a0a2009-04-02 04:16:50 +0000318 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
Chris Lattnera17991f2009-03-29 16:50:03 +0000319 break;
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000320 default:
Chris Lattner9802a0a2009-04-02 04:16:50 +0000321 return ParseSimpleDeclaration(Context, DeclEnd);
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000322 }
Chris Lattnera17991f2009-03-29 16:50:03 +0000323
324 // This routine returns a DeclGroup, if the thing we parsed only contains a
325 // single decl, convert it now.
326 return Actions.ConvertDeclToDeclGroup(SingleDecl);
Chris Lattnerf7b2e552007-08-25 06:57:03 +0000327}
328
329/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
330/// declaration-specifiers init-declarator-list[opt] ';'
331///[C90/C++]init-declarator-list ';' [TODO]
332/// [OMP] threadprivate-directive [TODO]
Chris Lattnerf8016042009-03-29 17:27:48 +0000333///
334/// If RequireSemi is false, this does not check for a ';' at the end of the
335/// declaration.
336Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
Chris Lattner9802a0a2009-04-02 04:16:50 +0000337 SourceLocation &DeclEnd,
Chris Lattnerf8016042009-03-29 17:27:48 +0000338 bool RequireSemi) {
Chris Lattner4b009652007-07-25 00:24:17 +0000339 // Parse the common declaration-specifiers piece.
340 DeclSpec DS;
341 ParseDeclarationSpecifiers(DS);
342
343 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
344 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner34a01ad2007-10-09 17:33:22 +0000345 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +0000346 ConsumeToken();
Chris Lattnera17991f2009-03-29 16:50:03 +0000347 DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
348 return Actions.ConvertDeclToDeclGroup(TheDecl);
Chris Lattner4b009652007-07-25 00:24:17 +0000349 }
350
351 Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
352 ParseDeclarator(DeclaratorInfo);
353
Chris Lattner2c41d482009-03-29 17:18:04 +0000354 DeclGroupPtrTy DG =
355 ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
Chris Lattnerf8016042009-03-29 17:27:48 +0000356
Chris Lattner9802a0a2009-04-02 04:16:50 +0000357 DeclEnd = Tok.getLocation();
358
Chris Lattnerf8016042009-03-29 17:27:48 +0000359 // If the client wants to check what comes after the declaration, just return
360 // immediately without checking anything!
361 if (!RequireSemi) return DG;
Chris Lattner2c41d482009-03-29 17:18:04 +0000362
363 if (Tok.is(tok::semi)) {
364 ConsumeToken();
Chris Lattner2c41d482009-03-29 17:18:04 +0000365 return DG;
366 }
367
Chris Lattner2c41d482009-03-29 17:18:04 +0000368 Diag(Tok, diag::err_expected_semi_declation);
369 // Skip to end of block or statement
370 SkipUntil(tok::r_brace, true, true);
371 if (Tok.is(tok::semi))
372 ConsumeToken();
373 return DG;
Chris Lattner4b009652007-07-25 00:24:17 +0000374}
375
Douglas Gregore3298aa2009-05-12 21:31:51 +0000376/// \brief Parse 'declaration' after parsing 'declaration-specifiers
377/// declarator'. This method parses the remainder of the declaration
378/// (including any attributes or initializer, among other things) and
379/// finalizes the declaration.
Chris Lattner4b009652007-07-25 00:24:17 +0000380///
Chris Lattner4b009652007-07-25 00:24:17 +0000381/// init-declarator: [C99 6.7]
382/// declarator
383/// declarator '=' initializer
384/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
385/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +0000386/// [C++] declarator initializer[opt]
387///
388/// [C++] initializer:
389/// [C++] '=' initializer-clause
390/// [C++] '(' expression-list ')'
Sebastian Redla8cecf62009-03-24 22:27:57 +0000391/// [C++0x] '=' 'default' [TODO]
392/// [C++0x] '=' 'delete'
393///
394/// According to the standard grammar, =default and =delete are function
395/// definitions, but that definitely doesn't fit with the parser here.
Chris Lattner4b009652007-07-25 00:24:17 +0000396///
Douglas Gregor2ae1d772009-06-23 23:11:28 +0000397Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
398 const ParsedTemplateInfo &TemplateInfo) {
Douglas Gregore3298aa2009-05-12 21:31:51 +0000399 // If a simple-asm-expr is present, parse it.
400 if (Tok.is(tok::kw_asm)) {
401 SourceLocation Loc;
402 OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
403 if (AsmLabel.isInvalid()) {
404 SkipUntil(tok::semi, true, true);
405 return DeclPtrTy();
406 }
407
408 D.setAsmLabel(AsmLabel.release());
409 D.SetRangeEnd(Loc);
410 }
411
412 // If attributes are present, parse them.
413 if (Tok.is(tok::kw___attribute)) {
414 SourceLocation Loc;
415 AttributeList *AttrList = ParseAttributes(&Loc);
416 D.AddAttributes(AttrList, Loc);
417 }
418
419 // Inform the current actions module that we just parsed this declarator.
Douglas Gregor2ae1d772009-06-23 23:11:28 +0000420 DeclPtrTy ThisDecl = TemplateInfo.TemplateParams?
421 Actions.ActOnTemplateDeclarator(CurScope,
422 Action::MultiTemplateParamsArg(Actions,
423 TemplateInfo.TemplateParams->data(),
424 TemplateInfo.TemplateParams->size()),
425 D)
426 : Actions.ActOnDeclarator(CurScope, D);
Douglas Gregore3298aa2009-05-12 21:31:51 +0000427
428 // Parse declarator '=' initializer.
429 if (Tok.is(tok::equal)) {
430 ConsumeToken();
431 if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
432 SourceLocation DelLoc = ConsumeToken();
433 Actions.SetDeclDeleted(ThisDecl, DelLoc);
434 } else {
Argiris Kirtzidis68370592009-06-17 22:50:06 +0000435 if (getLang().CPlusPlus)
436 Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl);
437
Douglas Gregore3298aa2009-05-12 21:31:51 +0000438 OwningExprResult Init(ParseInitializer());
Argiris Kirtzidis68370592009-06-17 22:50:06 +0000439
440 if (getLang().CPlusPlus)
441 Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl);
442
Douglas Gregore3298aa2009-05-12 21:31:51 +0000443 if (Init.isInvalid()) {
444 SkipUntil(tok::semi, true, true);
445 return DeclPtrTy();
446 }
Anders Carlssonf9f05b82009-05-30 21:37:25 +0000447 Actions.AddInitializerToDecl(ThisDecl, Actions.FullExpr(Init));
Douglas Gregore3298aa2009-05-12 21:31:51 +0000448 }
449 } else if (Tok.is(tok::l_paren)) {
450 // Parse C++ direct initializer: '(' expression-list ')'
451 SourceLocation LParenLoc = ConsumeParen();
452 ExprVector Exprs(Actions);
453 CommaLocsTy CommaLocs;
454
455 if (ParseExpressionList(Exprs, CommaLocs)) {
456 SkipUntil(tok::r_paren);
457 } else {
458 // Match the ')'.
459 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
460
461 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
462 "Unexpected number of commas!");
463 Actions.AddCXXDirectInitializerToDecl(ThisDecl, LParenLoc,
464 move_arg(Exprs),
Jay Foad9e6bef42009-05-21 09:52:38 +0000465 CommaLocs.data(), RParenLoc);
Douglas Gregore3298aa2009-05-12 21:31:51 +0000466 }
467 } else {
Anders Carlsson68acecb2009-07-11 00:34:39 +0000468 bool TypeContainsUndeducedAuto =
469 D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
470 Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsUndeducedAuto);
Douglas Gregore3298aa2009-05-12 21:31:51 +0000471 }
472
473 return ThisDecl;
474}
475
476/// ParseInitDeclaratorListAfterFirstDeclarator - Parse 'declaration' after
477/// parsing 'declaration-specifiers declarator'. This method is split out this
478/// way to handle the ambiguity between top-level function-definitions and
479/// declarations.
480///
481/// init-declarator-list: [C99 6.7]
482/// init-declarator
483/// init-declarator-list ',' init-declarator
484///
485/// According to the standard grammar, =default and =delete are function
486/// definitions, but that definitely doesn't fit with the parser here.
487///
Chris Lattnera17991f2009-03-29 16:50:03 +0000488Parser::DeclGroupPtrTy Parser::
Chris Lattner4b009652007-07-25 00:24:17 +0000489ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
Chris Lattnera17991f2009-03-29 16:50:03 +0000490 // Declarators may be grouped together ("int X, *Y, Z();"). Remember the decls
491 // that we parse together here.
492 llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
Chris Lattner4b009652007-07-25 00:24:17 +0000493
494 // At this point, we know that it is not a function definition. Parse the
495 // rest of the init-declarator-list.
496 while (1) {
Douglas Gregore3298aa2009-05-12 21:31:51 +0000497 DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(D);
498 if (ThisDecl.get())
499 DeclsInGroup.push_back(ThisDecl);
Chris Lattner4b009652007-07-25 00:24:17 +0000500
Chris Lattner4b009652007-07-25 00:24:17 +0000501 // If we don't have a comma, it is either the end of the list (a ';') or an
502 // error, bail out.
Chris Lattner34a01ad2007-10-09 17:33:22 +0000503 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +0000504 break;
505
506 // Consume the comma.
507 ConsumeToken();
508
509 // Parse the next declarator.
510 D.clear();
Chris Lattner926cf542008-10-20 04:57:38 +0000511
512 // Accept attributes in an init-declarator. In the first declarator in a
513 // declaration, these would be part of the declspec. In subsequent
514 // declarators, they become part of the declarator itself, so that they
515 // don't apply to declarators after *this* one. Examples:
516 // short __attribute__((common)) var; -> declspec
517 // short var __attribute__((common)); -> declarator
518 // short x, __attribute__((common)) var; -> declarator
Sebastian Redl0c986032009-02-09 18:23:29 +0000519 if (Tok.is(tok::kw___attribute)) {
520 SourceLocation Loc;
521 AttributeList *AttrList = ParseAttributes(&Loc);
522 D.AddAttributes(AttrList, Loc);
523 }
Chris Lattner926cf542008-10-20 04:57:38 +0000524
Chris Lattner4b009652007-07-25 00:24:17 +0000525 ParseDeclarator(D);
526 }
527
Eli Friedman4d57af22009-05-29 01:49:24 +0000528 return Actions.FinalizeDeclaratorGroup(CurScope, D.getDeclSpec(),
529 DeclsInGroup.data(),
Chris Lattner2c41d482009-03-29 17:18:04 +0000530 DeclsInGroup.size());
Chris Lattner4b009652007-07-25 00:24:17 +0000531}
532
533/// ParseSpecifierQualifierList
534/// specifier-qualifier-list:
535/// type-specifier specifier-qualifier-list[opt]
536/// type-qualifier specifier-qualifier-list[opt]
537/// [GNU] attributes specifier-qualifier-list[opt]
538///
539void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
540 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
541 /// parse declaration-specifiers and complain about extra stuff.
542 ParseDeclarationSpecifiers(DS);
543
544 // Validate declspec for type-name.
545 unsigned Specs = DS.getParsedSpecifiers();
Chris Lattnera52aec42009-04-14 21:16:09 +0000546 if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
547 !DS.getAttributes())
Chris Lattner4b009652007-07-25 00:24:17 +0000548 Diag(Tok, diag::err_typename_requires_specqual);
549
550 // Issue diagnostic and remove storage class if present.
551 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
552 if (DS.getStorageClassSpecLoc().isValid())
553 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
554 else
555 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
556 DS.ClearStorageClassSpecs();
557 }
558
559 // Issue diagnostic and remove function specfier if present.
560 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000561 if (DS.isInlineSpecified())
562 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
563 if (DS.isVirtualSpecified())
564 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
565 if (DS.isExplicitSpecified())
566 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
Chris Lattner4b009652007-07-25 00:24:17 +0000567 DS.ClearFunctionSpecs();
568 }
569}
570
Chris Lattnercc98d8c2009-04-12 20:42:31 +0000571/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
572/// specified token is valid after the identifier in a declarator which
573/// immediately follows the declspec. For example, these things are valid:
574///
575/// int x [ 4]; // direct-declarator
576/// int x ( int y); // direct-declarator
577/// int(int x ) // direct-declarator
578/// int x ; // simple-declaration
579/// int x = 17; // init-declarator-list
580/// int x , y; // init-declarator-list
581/// int x __asm__ ("foo"); // init-declarator-list
Chris Lattnera52aec42009-04-14 21:16:09 +0000582/// int x : 4; // struct-declarator
Chris Lattnerca6cc362009-04-12 22:29:43 +0000583/// int x { 5}; // C++'0x unified initializers
Chris Lattnercc98d8c2009-04-12 20:42:31 +0000584///
585/// This is not, because 'x' does not immediately follow the declspec (though
586/// ')' happens to be valid anyway).
587/// int (x)
588///
589static bool isValidAfterIdentifierInDeclarator(const Token &T) {
590 return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
591 T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
Chris Lattnera52aec42009-04-14 21:16:09 +0000592 T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
Chris Lattnercc98d8c2009-04-12 20:42:31 +0000593}
594
Chris Lattner82353c62009-04-14 21:34:55 +0000595
596/// ParseImplicitInt - This method is called when we have an non-typename
597/// identifier in a declspec (which normally terminates the decl spec) when
598/// the declspec has no type specifier. In this case, the declspec is either
599/// malformed or is "implicit int" (in K&R and C89).
600///
601/// This method handles diagnosing this prettily and returns false if the
602/// declspec is done being processed. If it recovers and thinks there may be
603/// other pieces of declspec after it, it returns true.
604///
Chris Lattner52cd7622009-04-14 22:17:06 +0000605bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
Douglas Gregora9db0fa2009-05-12 23:25:50 +0000606 const ParsedTemplateInfo &TemplateInfo,
Chris Lattner82353c62009-04-14 21:34:55 +0000607 AccessSpecifier AS) {
Chris Lattner52cd7622009-04-14 22:17:06 +0000608 assert(Tok.is(tok::identifier) && "should have identifier");
609
Chris Lattner82353c62009-04-14 21:34:55 +0000610 SourceLocation Loc = Tok.getLocation();
611 // If we see an identifier that is not a type name, we normally would
612 // parse it as the identifer being declared. However, when a typename
613 // is typo'd or the definition is not included, this will incorrectly
614 // parse the typename as the identifier name and fall over misparsing
615 // later parts of the diagnostic.
616 //
617 // As such, we try to do some look-ahead in cases where this would
618 // otherwise be an "implicit-int" case to see if this is invalid. For
619 // example: "static foo_t x = 4;" In this case, if we parsed foo_t as
620 // an identifier with implicit int, we'd get a parse error because the
621 // next token is obviously invalid for a type. Parse these as a case
622 // with an invalid type specifier.
623 assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
624
625 // Since we know that this either implicit int (which is rare) or an
626 // error, we'd do lookahead to try to do better recovery.
627 if (isValidAfterIdentifierInDeclarator(NextToken())) {
628 // If this token is valid for implicit int, e.g. "static x = 4", then
629 // we just avoid eating the identifier, so it will be parsed as the
630 // identifier in the declarator.
631 return false;
632 }
633
634 // Otherwise, if we don't consume this token, we are going to emit an
635 // error anyway. Try to recover from various common problems. Check
636 // to see if this was a reference to a tag name without a tag specified.
637 // This is a common problem in C (saying 'foo' instead of 'struct foo').
Chris Lattner52cd7622009-04-14 22:17:06 +0000638 //
639 // C++ doesn't need this, and isTagName doesn't take SS.
640 if (SS == 0) {
641 const char *TagName = 0;
642 tok::TokenKind TagKind = tok::unknown;
Chris Lattner82353c62009-04-14 21:34:55 +0000643
Chris Lattner82353c62009-04-14 21:34:55 +0000644 switch (Actions.isTagName(*Tok.getIdentifierInfo(), CurScope)) {
645 default: break;
646 case DeclSpec::TST_enum: TagName="enum" ;TagKind=tok::kw_enum ;break;
647 case DeclSpec::TST_union: TagName="union" ;TagKind=tok::kw_union ;break;
648 case DeclSpec::TST_struct:TagName="struct";TagKind=tok::kw_struct;break;
649 case DeclSpec::TST_class: TagName="class" ;TagKind=tok::kw_class ;break;
650 }
Chris Lattner82353c62009-04-14 21:34:55 +0000651
Chris Lattner52cd7622009-04-14 22:17:06 +0000652 if (TagName) {
653 Diag(Loc, diag::err_use_of_tag_name_without_tag)
654 << Tok.getIdentifierInfo() << TagName
655 << CodeModificationHint::CreateInsertion(Tok.getLocation(),TagName);
656
657 // Parse this as a tag as if the missing tag were present.
658 if (TagKind == tok::kw_enum)
659 ParseEnumSpecifier(Loc, DS, AS);
660 else
Douglas Gregora9db0fa2009-05-12 23:25:50 +0000661 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS);
Chris Lattner52cd7622009-04-14 22:17:06 +0000662 return true;
663 }
Chris Lattner82353c62009-04-14 21:34:55 +0000664 }
665
666 // Since this is almost certainly an invalid type name, emit a
667 // diagnostic that says it, eat the token, and mark the declspec as
668 // invalid.
Chris Lattner52cd7622009-04-14 22:17:06 +0000669 SourceRange R;
670 if (SS) R = SS->getRange();
671
672 Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
Chris Lattner82353c62009-04-14 21:34:55 +0000673 const char *PrevSpec;
674 DS.SetTypeSpecType(DeclSpec::TST_error, Loc, PrevSpec);
675 DS.SetRangeEnd(Tok.getLocation());
676 ConsumeToken();
677
678 // TODO: Could inject an invalid typedef decl in an enclosing scope to
679 // avoid rippling error messages on subsequent uses of the same type,
680 // could be useful if #include was forgotten.
681 return false;
682}
683
Chris Lattner4b009652007-07-25 00:24:17 +0000684/// ParseDeclarationSpecifiers
685/// declaration-specifiers: [C99 6.7]
686/// storage-class-specifier declaration-specifiers[opt]
687/// type-specifier declaration-specifiers[opt]
Chris Lattner4b009652007-07-25 00:24:17 +0000688/// [C99] function-specifier declaration-specifiers[opt]
689/// [GNU] attributes declaration-specifiers[opt]
690///
691/// storage-class-specifier: [C99 6.7.1]
692/// 'typedef'
693/// 'extern'
694/// 'static'
695/// 'auto'
696/// 'register'
Sebastian Redl9f5337b2008-11-14 23:42:31 +0000697/// [C++] 'mutable'
Chris Lattner4b009652007-07-25 00:24:17 +0000698/// [GNU] '__thread'
Chris Lattner4b009652007-07-25 00:24:17 +0000699/// function-specifier: [C99 6.7.4]
700/// [C99] 'inline'
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000701/// [C++] 'virtual'
702/// [C++] 'explicit'
Anders Carlsson6c2ad5a2009-05-06 04:46:28 +0000703/// 'friend': [C++ dcl.friend]
704
Chris Lattner4b009652007-07-25 00:24:17 +0000705///
Douglas Gregor52473432008-12-24 02:52:09 +0000706void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Douglas Gregora9db0fa2009-05-12 23:25:50 +0000707 const ParsedTemplateInfo &TemplateInfo,
Chris Lattnercc98d8c2009-04-12 20:42:31 +0000708 AccessSpecifier AS) {
Chris Lattnera4ff4272008-03-13 06:29:04 +0000709 DS.SetRangeStart(Tok.getLocation());
Chris Lattner4b009652007-07-25 00:24:17 +0000710 while (1) {
711 int isInvalid = false;
712 const char *PrevSpec = 0;
713 SourceLocation Loc = Tok.getLocation();
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000714
Chris Lattner4b009652007-07-25 00:24:17 +0000715 switch (Tok.getKind()) {
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000716 default:
Chris Lattnerb99d7492008-07-26 00:20:22 +0000717 DoneWithDeclSpec:
Chris Lattner4b009652007-07-25 00:24:17 +0000718 // If this is not a declaration specifier token, we're done reading decl
719 // specifiers. First verify that DeclSpec's are consistent.
Douglas Gregor1ba5cb32009-04-01 22:41:11 +0000720 DS.Finish(Diags, PP);
Chris Lattner4b009652007-07-25 00:24:17 +0000721 return;
Chris Lattner712f9a32009-01-05 00:07:25 +0000722
723 case tok::coloncolon: // ::foo::bar
724 // Annotate C++ scope specifiers. If we get one, loop.
725 if (TryAnnotateCXXScopeToken())
726 continue;
727 goto DoneWithDeclSpec;
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000728
729 case tok::annot_cxxscope: {
730 if (DS.hasTypeSpecifier())
731 goto DoneWithDeclSpec;
732
733 // We are looking for a qualified typename.
Douglas Gregor80b95c52009-03-25 15:40:00 +0000734 Token Next = NextToken();
735 if (Next.is(tok::annot_template_id) &&
736 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
Douglas Gregoraabb8502009-03-31 00:43:58 +0000737 ->Kind == TNK_Type_template) {
Douglas Gregor80b95c52009-03-25 15:40:00 +0000738 // We have a qualified template-id, e.g., N::A<int>
739 CXXScopeSpec SS;
740 ParseOptionalCXXScopeSpecifier(SS);
741 assert(Tok.is(tok::annot_template_id) &&
742 "ParseOptionalCXXScopeSpecifier not working");
743 AnnotateTemplateIdTokenAsType(&SS);
744 continue;
745 }
746
747 if (Next.isNot(tok::identifier))
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000748 goto DoneWithDeclSpec;
749
750 CXXScopeSpec SS;
Douglas Gregor041e9292009-03-26 23:56:24 +0000751 SS.setScopeRep(Tok.getAnnotationValue());
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000752 SS.setRange(Tok.getAnnotationRange());
753
754 // If the next token is the name of the class type that the C++ scope
755 // denotes, followed by a '(', then this is a constructor declaration.
756 // We're done with the decl-specifiers.
Chris Lattner52cd7622009-04-14 22:17:06 +0000757 if (Actions.isCurrentClassName(*Next.getIdentifierInfo(),
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000758 CurScope, &SS) &&
759 GetLookAheadToken(2).is(tok::l_paren))
760 goto DoneWithDeclSpec;
761
Douglas Gregor1075a162009-02-04 17:00:24 +0000762 TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
763 Next.getLocation(), CurScope, &SS);
Douglas Gregor8e458f42009-02-09 18:46:07 +0000764
Chris Lattner52cd7622009-04-14 22:17:06 +0000765 // If the referenced identifier is not a type, then this declspec is
766 // erroneous: We already checked about that it has no type specifier, and
767 // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
768 // typename.
769 if (TypeRep == 0) {
770 ConsumeToken(); // Eat the scope spec so the identifier is current.
Douglas Gregora9db0fa2009-05-12 23:25:50 +0000771 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS)) continue;
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000772 goto DoneWithDeclSpec;
Chris Lattner52cd7622009-04-14 22:17:06 +0000773 }
Douglas Gregor734b4ba2009-03-19 00:18:19 +0000774
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000775 ConsumeToken(); // The C++ scope.
776
Douglas Gregora60c62e2009-02-09 15:09:02 +0000777 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000778 TypeRep);
779 if (isInvalid)
780 break;
781
782 DS.SetRangeEnd(Tok.getLocation());
783 ConsumeToken(); // The typename.
784
785 continue;
786 }
Chris Lattnerc297b722009-01-21 19:48:37 +0000787
788 case tok::annot_typename: {
Douglas Gregord7cb0372009-04-01 21:51:26 +0000789 if (Tok.getAnnotationValue())
790 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
791 Tok.getAnnotationValue());
792 else
793 DS.SetTypeSpecError();
Chris Lattnerc297b722009-01-21 19:48:37 +0000794 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
795 ConsumeToken(); // The typename
796
797 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
798 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
799 // Objective-C interface. If we don't have Objective-C or a '<', this is
800 // just a normal reference to a typedef name.
801 if (!Tok.is(tok::less) || !getLang().ObjC1)
802 continue;
803
804 SourceLocation EndProtoLoc;
Chris Lattner5261d0c2009-03-28 19:18:32 +0000805 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Chris Lattnerc297b722009-01-21 19:48:37 +0000806 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Ted Kremeneka0c6de32009-06-30 22:19:00 +0000807 DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
Chris Lattnerc297b722009-01-21 19:48:37 +0000808
809 DS.SetRangeEnd(EndProtoLoc);
810 continue;
811 }
812
Chris Lattnerfda18db2008-07-26 01:18:38 +0000813 // typedef-name
814 case tok::identifier: {
Chris Lattner712f9a32009-01-05 00:07:25 +0000815 // In C++, check to see if this is a scope specifier like foo::bar::, if
816 // so handle it as such. This is important for ctor parsing.
Chris Lattner5bb837e2009-01-21 19:19:26 +0000817 if (getLang().CPlusPlus && TryAnnotateCXXScopeToken())
818 continue;
Chris Lattner712f9a32009-01-05 00:07:25 +0000819
Chris Lattnerfda18db2008-07-26 01:18:38 +0000820 // This identifier can only be a typedef name if we haven't already seen
821 // a type-specifier. Without this check we misparse:
822 // typedef int X; struct Y { short X; }; as 'short int'.
823 if (DS.hasTypeSpecifier())
824 goto DoneWithDeclSpec;
825
826 // It has to be available as a typedef too!
Douglas Gregor1075a162009-02-04 17:00:24 +0000827 TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(),
828 Tok.getLocation(), CurScope);
Douglas Gregor8e458f42009-02-09 18:46:07 +0000829
Chris Lattnercc98d8c2009-04-12 20:42:31 +0000830 // If this is not a typedef name, don't parse it as part of the declspec,
831 // it must be an implicit int or an error.
832 if (TypeRep == 0) {
Douglas Gregora9db0fa2009-05-12 23:25:50 +0000833 if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue;
Chris Lattnerfda18db2008-07-26 01:18:38 +0000834 goto DoneWithDeclSpec;
Chris Lattnercc98d8c2009-04-12 20:42:31 +0000835 }
Douglas Gregor8e458f42009-02-09 18:46:07 +0000836
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000837 // C++: If the identifier is actually the name of the class type
838 // being defined and the next token is a '(', then this is a
839 // constructor declaration. We're done with the decl-specifiers
840 // and will treat this token as an identifier.
Chris Lattnercc98d8c2009-04-12 20:42:31 +0000841 if (getLang().CPlusPlus && CurScope->isClassScope() &&
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000842 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) &&
843 NextToken().getKind() == tok::l_paren)
844 goto DoneWithDeclSpec;
845
Douglas Gregora60c62e2009-02-09 15:09:02 +0000846 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
Chris Lattnerfda18db2008-07-26 01:18:38 +0000847 TypeRep);
848 if (isInvalid)
849 break;
850
851 DS.SetRangeEnd(Tok.getLocation());
852 ConsumeToken(); // The identifier
853
854 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
855 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
856 // Objective-C interface. If we don't have Objective-C or a '<', this is
857 // just a normal reference to a typedef name.
858 if (!Tok.is(tok::less) || !getLang().ObjC1)
859 continue;
860
861 SourceLocation EndProtoLoc;
Chris Lattner5261d0c2009-03-28 19:18:32 +0000862 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Chris Lattner2bdedd62008-07-26 04:03:38 +0000863 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Ted Kremeneka0c6de32009-06-30 22:19:00 +0000864 DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
Chris Lattnerfda18db2008-07-26 01:18:38 +0000865
866 DS.SetRangeEnd(EndProtoLoc);
867
Steve Narofff7683302008-09-22 10:28:57 +0000868 // Need to support trailing type qualifiers (e.g. "id<p> const").
869 // If a type specifier follows, it will be diagnosed elsewhere.
870 continue;
Chris Lattnerfda18db2008-07-26 01:18:38 +0000871 }
Douglas Gregor0c281a82009-02-25 19:37:18 +0000872
873 // type-name
874 case tok::annot_template_id: {
875 TemplateIdAnnotation *TemplateId
876 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
Douglas Gregoraabb8502009-03-31 00:43:58 +0000877 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor0c281a82009-02-25 19:37:18 +0000878 // This template-id does not refer to a type name, so we're
879 // done with the type-specifiers.
880 goto DoneWithDeclSpec;
881 }
882
883 // Turn the template-id annotation token into a type annotation
884 // token, then try again to parse it as a type-specifier.
Douglas Gregord7cb0372009-04-01 21:51:26 +0000885 AnnotateTemplateIdTokenAsType();
Douglas Gregor0c281a82009-02-25 19:37:18 +0000886 continue;
887 }
888
Chris Lattner4b009652007-07-25 00:24:17 +0000889 // GNU attributes support.
890 case tok::kw___attribute:
891 DS.AddAttributes(ParseAttributes());
892 continue;
Steve Naroffc5ab14f2008-12-24 20:59:21 +0000893
894 // Microsoft declspec support.
895 case tok::kw___declspec:
Eli Friedmancd231842009-06-08 07:21:15 +0000896 DS.AddAttributes(ParseMicrosoftDeclSpec());
Steve Naroffc5ab14f2008-12-24 20:59:21 +0000897 continue;
Chris Lattner4b009652007-07-25 00:24:17 +0000898
Steve Naroffedd04d52008-12-25 14:16:32 +0000899 // Microsoft single token adornments.
Steve Naroffad620402008-12-25 14:41:26 +0000900 case tok::kw___forceinline:
Eli Friedman891d82f2009-06-08 23:27:34 +0000901 // FIXME: Add handling here!
902 break;
903
904 case tok::kw___ptr64:
Steve Naroffad620402008-12-25 14:41:26 +0000905 case tok::kw___w64:
Steve Naroffedd04d52008-12-25 14:16:32 +0000906 case tok::kw___cdecl:
907 case tok::kw___stdcall:
908 case tok::kw___fastcall:
Eli Friedman891d82f2009-06-08 23:27:34 +0000909 DS.AddAttributes(ParseMicrosoftTypeAttributes());
910 continue;
911
Chris Lattner4b009652007-07-25 00:24:17 +0000912 // storage-class-specifier
913 case tok::kw_typedef:
914 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec);
915 break;
916 case tok::kw_extern:
917 if (DS.isThreadSpecified())
Chris Lattnerf006a222008-11-18 07:48:38 +0000918 Diag(Tok, diag::ext_thread_before) << "extern";
Chris Lattner4b009652007-07-25 00:24:17 +0000919 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec);
920 break;
Steve Narofff258a0f2007-12-18 00:16:02 +0000921 case tok::kw___private_extern__:
Chris Lattner9f7564b2008-04-06 06:57:35 +0000922 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
923 PrevSpec);
Steve Narofff258a0f2007-12-18 00:16:02 +0000924 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000925 case tok::kw_static:
926 if (DS.isThreadSpecified())
Chris Lattnerf006a222008-11-18 07:48:38 +0000927 Diag(Tok, diag::ext_thread_before) << "static";
Chris Lattner4b009652007-07-25 00:24:17 +0000928 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
929 break;
930 case tok::kw_auto:
Anders Carlsson4a8498c2009-06-26 18:41:36 +0000931 if (getLang().CPlusPlus0x)
932 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec);
933 else
934 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
Chris Lattner4b009652007-07-25 00:24:17 +0000935 break;
936 case tok::kw_register:
937 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
938 break;
Sebastian Redl9f5337b2008-11-14 23:42:31 +0000939 case tok::kw_mutable:
940 isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec);
941 break;
Chris Lattner4b009652007-07-25 00:24:17 +0000942 case tok::kw___thread:
943 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec)*2;
944 break;
Douglas Gregor3a6a3072008-11-07 15:42:26 +0000945
Chris Lattner4b009652007-07-25 00:24:17 +0000946 // function-specifier
947 case tok::kw_inline:
948 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec);
949 break;
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000950 case tok::kw_virtual:
951 isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec);
952 break;
Douglas Gregorf15ac4b2008-10-31 09:07:45 +0000953 case tok::kw_explicit:
954 isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec);
955 break;
Chris Lattnerc297b722009-01-21 19:48:37 +0000956
Anders Carlsson6c2ad5a2009-05-06 04:46:28 +0000957 // friend
958 case tok::kw_friend:
959 isInvalid = DS.SetFriendSpec(Loc, PrevSpec);
960 break;
961
Chris Lattnerc297b722009-01-21 19:48:37 +0000962 // type-specifier
963 case tok::kw_short:
964 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
965 break;
966 case tok::kw_long:
967 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
968 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
969 else
970 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
971 break;
972 case tok::kw_signed:
973 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
974 break;
975 case tok::kw_unsigned:
976 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
977 break;
978 case tok::kw__Complex:
979 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
980 break;
981 case tok::kw__Imaginary:
982 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
983 break;
984 case tok::kw_void:
985 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
986 break;
987 case tok::kw_char:
988 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
989 break;
990 case tok::kw_int:
991 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
992 break;
993 case tok::kw_float:
994 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
995 break;
996 case tok::kw_double:
997 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
998 break;
999 case tok::kw_wchar_t:
1000 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
1001 break;
1002 case tok::kw_bool:
1003 case tok::kw__Bool:
1004 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
1005 break;
1006 case tok::kw__Decimal32:
1007 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
1008 break;
1009 case tok::kw__Decimal64:
1010 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
1011 break;
1012 case tok::kw__Decimal128:
1013 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
1014 break;
1015
1016 // class-specifier:
1017 case tok::kw_class:
1018 case tok::kw_struct:
Chris Lattner197b4342009-04-12 21:49:30 +00001019 case tok::kw_union: {
1020 tok::TokenKind Kind = Tok.getKind();
1021 ConsumeToken();
Douglas Gregora9db0fa2009-05-12 23:25:50 +00001022 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS);
Chris Lattnerc297b722009-01-21 19:48:37 +00001023 continue;
Chris Lattner197b4342009-04-12 21:49:30 +00001024 }
Chris Lattnerc297b722009-01-21 19:48:37 +00001025
1026 // enum-specifier:
1027 case tok::kw_enum:
Chris Lattner197b4342009-04-12 21:49:30 +00001028 ConsumeToken();
1029 ParseEnumSpecifier(Loc, DS, AS);
Chris Lattnerc297b722009-01-21 19:48:37 +00001030 continue;
1031
1032 // cv-qualifier:
1033 case tok::kw_const:
1034 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec,getLang())*2;
1035 break;
1036 case tok::kw_volatile:
1037 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
1038 getLang())*2;
1039 break;
1040 case tok::kw_restrict:
1041 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
1042 getLang())*2;
1043 break;
1044
Douglas Gregord3022602009-03-27 23:10:48 +00001045 // C++ typename-specifier:
1046 case tok::kw_typename:
1047 if (TryAnnotateTypeOrScopeToken())
1048 continue;
1049 break;
1050
Chris Lattnerc297b722009-01-21 19:48:37 +00001051 // GNU typeof support.
1052 case tok::kw_typeof:
1053 ParseTypeofSpecifier(DS);
1054 continue;
1055
Anders Carlssoneed418b2009-06-24 17:47:40 +00001056 case tok::kw_decltype:
1057 ParseDecltypeSpecifier(DS);
1058 continue;
1059
Steve Naroff5f0466b2008-06-05 00:02:44 +00001060 case tok::less:
Chris Lattnerfda18db2008-07-26 01:18:38 +00001061 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerb99d7492008-07-26 00:20:22 +00001062 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
1063 // but we support it.
Chris Lattnerfda18db2008-07-26 01:18:38 +00001064 if (DS.hasTypeSpecifier() || !getLang().ObjC1)
Chris Lattnerb99d7492008-07-26 00:20:22 +00001065 goto DoneWithDeclSpec;
1066
1067 {
1068 SourceLocation EndProtoLoc;
Chris Lattner5261d0c2009-03-28 19:18:32 +00001069 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Chris Lattner2bdedd62008-07-26 04:03:38 +00001070 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Ted Kremeneka0c6de32009-06-30 22:19:00 +00001071 DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
Chris Lattnerfda18db2008-07-26 01:18:38 +00001072 DS.SetRangeEnd(EndProtoLoc);
1073
Chris Lattnerf006a222008-11-18 07:48:38 +00001074 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
Chris Lattnerb980c732009-04-03 18:38:42 +00001075 << CodeModificationHint::CreateInsertion(Loc, "id")
Chris Lattnerf006a222008-11-18 07:48:38 +00001076 << SourceRange(Loc, EndProtoLoc);
Steve Narofff7683302008-09-22 10:28:57 +00001077 // Need to support trailing type qualifiers (e.g. "id<p> const").
1078 // If a type specifier follows, it will be diagnosed elsewhere.
1079 continue;
Steve Naroff5f0466b2008-06-05 00:02:44 +00001080 }
Chris Lattner4b009652007-07-25 00:24:17 +00001081 }
1082 // If the specifier combination wasn't legal, issue a diagnostic.
1083 if (isInvalid) {
1084 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattnerf006a222008-11-18 07:48:38 +00001085 // Pick between error or extwarn.
1086 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
1087 : diag::ext_duplicate_declspec;
1088 Diag(Tok, DiagID) << PrevSpec;
Chris Lattner4b009652007-07-25 00:24:17 +00001089 }
Chris Lattnera4ff4272008-03-13 06:29:04 +00001090 DS.SetRangeEnd(Tok.getLocation());
Chris Lattner4b009652007-07-25 00:24:17 +00001091 ConsumeToken();
1092 }
1093}
Douglas Gregorb3bec712008-12-01 23:54:00 +00001094
Chris Lattnerd706dc82009-01-06 06:59:53 +00001095/// ParseOptionalTypeSpecifier - Try to parse a single type-specifier. We
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001096/// primarily follow the C++ grammar with additions for C99 and GNU,
1097/// which together subsume the C grammar. Note that the C++
1098/// type-specifier also includes the C type-qualifier (for const,
1099/// volatile, and C99 restrict). Returns true if a type-specifier was
1100/// found (and parsed), false otherwise.
1101///
1102/// type-specifier: [C++ 7.1.5]
1103/// simple-type-specifier
1104/// class-specifier
1105/// enum-specifier
1106/// elaborated-type-specifier [TODO]
1107/// cv-qualifier
1108///
1109/// cv-qualifier: [C++ 7.1.5.1]
1110/// 'const'
1111/// 'volatile'
1112/// [C99] 'restrict'
1113///
1114/// simple-type-specifier: [ C++ 7.1.5.2]
1115/// '::'[opt] nested-name-specifier[opt] type-name [TODO]
1116/// '::'[opt] nested-name-specifier 'template' template-id [TODO]
1117/// 'char'
1118/// 'wchar_t'
1119/// 'bool'
1120/// 'short'
1121/// 'int'
1122/// 'long'
1123/// 'signed'
1124/// 'unsigned'
1125/// 'float'
1126/// 'double'
1127/// 'void'
1128/// [C99] '_Bool'
1129/// [C99] '_Complex'
1130/// [C99] '_Imaginary' // Removed in TC2?
1131/// [GNU] '_Decimal32'
1132/// [GNU] '_Decimal64'
1133/// [GNU] '_Decimal128'
1134/// [GNU] typeof-specifier
1135/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
1136/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
Anders Carlssoneed418b2009-06-24 17:47:40 +00001137/// [C++0x] 'decltype' ( expression )
Chris Lattnerd706dc82009-01-06 06:59:53 +00001138bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
1139 const char *&PrevSpec,
Douglas Gregora9db0fa2009-05-12 23:25:50 +00001140 const ParsedTemplateInfo &TemplateInfo) {
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001141 SourceLocation Loc = Tok.getLocation();
1142
1143 switch (Tok.getKind()) {
Chris Lattnerb75fde62009-01-04 23:41:41 +00001144 case tok::identifier: // foo::bar
Douglas Gregord3022602009-03-27 23:10:48 +00001145 case tok::kw_typename: // typename foo::bar
Chris Lattnerb75fde62009-01-04 23:41:41 +00001146 // Annotate typenames and C++ scope specifiers. If we get one, just
1147 // recurse to handle whatever we get.
1148 if (TryAnnotateTypeOrScopeToken())
Douglas Gregora9db0fa2009-05-12 23:25:50 +00001149 return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, TemplateInfo);
Chris Lattnerb75fde62009-01-04 23:41:41 +00001150 // Otherwise, not a type specifier.
1151 return false;
1152 case tok::coloncolon: // ::foo::bar
1153 if (NextToken().is(tok::kw_new) || // ::new
1154 NextToken().is(tok::kw_delete)) // ::delete
1155 return false;
1156
1157 // Annotate typenames and C++ scope specifiers. If we get one, just
1158 // recurse to handle whatever we get.
1159 if (TryAnnotateTypeOrScopeToken())
Douglas Gregora9db0fa2009-05-12 23:25:50 +00001160 return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, TemplateInfo);
Chris Lattnerb75fde62009-01-04 23:41:41 +00001161 // Otherwise, not a type specifier.
1162 return false;
1163
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001164 // simple-type-specifier:
Chris Lattner5d7eace2009-01-06 05:06:21 +00001165 case tok::annot_typename: {
Douglas Gregord7cb0372009-04-01 21:51:26 +00001166 if (Tok.getAnnotationValue())
1167 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
1168 Tok.getAnnotationValue());
1169 else
1170 DS.SetTypeSpecError();
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001171 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
1172 ConsumeToken(); // The typename
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001173
1174 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
1175 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
1176 // Objective-C interface. If we don't have Objective-C or a '<', this is
1177 // just a normal reference to a typedef name.
1178 if (!Tok.is(tok::less) || !getLang().ObjC1)
1179 return true;
1180
1181 SourceLocation EndProtoLoc;
Chris Lattner5261d0c2009-03-28 19:18:32 +00001182 llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001183 ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
Ted Kremeneka0c6de32009-06-30 22:19:00 +00001184 DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001185
1186 DS.SetRangeEnd(EndProtoLoc);
1187 return true;
1188 }
1189
1190 case tok::kw_short:
1191 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
1192 break;
1193 case tok::kw_long:
1194 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
1195 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec);
1196 else
1197 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec);
1198 break;
1199 case tok::kw_signed:
1200 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec);
1201 break;
1202 case tok::kw_unsigned:
1203 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec);
1204 break;
1205 case tok::kw__Complex:
1206 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec);
1207 break;
1208 case tok::kw__Imaginary:
1209 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec);
1210 break;
1211 case tok::kw_void:
1212 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec);
1213 break;
1214 case tok::kw_char:
1215 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec);
1216 break;
1217 case tok::kw_int:
1218 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec);
1219 break;
1220 case tok::kw_float:
1221 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec);
1222 break;
1223 case tok::kw_double:
1224 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
1225 break;
1226 case tok::kw_wchar_t:
1227 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
1228 break;
1229 case tok::kw_bool:
1230 case tok::kw__Bool:
1231 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
1232 break;
1233 case tok::kw__Decimal32:
1234 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec);
1235 break;
1236 case tok::kw__Decimal64:
1237 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec);
1238 break;
1239 case tok::kw__Decimal128:
1240 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec);
1241 break;
1242
1243 // class-specifier:
1244 case tok::kw_class:
1245 case tok::kw_struct:
Chris Lattner197b4342009-04-12 21:49:30 +00001246 case tok::kw_union: {
1247 tok::TokenKind Kind = Tok.getKind();
1248 ConsumeToken();
Douglas Gregora9db0fa2009-05-12 23:25:50 +00001249 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo);
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001250 return true;
Chris Lattner197b4342009-04-12 21:49:30 +00001251 }
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001252
1253 // enum-specifier:
1254 case tok::kw_enum:
Chris Lattner197b4342009-04-12 21:49:30 +00001255 ConsumeToken();
1256 ParseEnumSpecifier(Loc, DS);
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001257 return true;
1258
1259 // cv-qualifier:
1260 case tok::kw_const:
1261 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
1262 getLang())*2;
1263 break;
1264 case tok::kw_volatile:
1265 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
1266 getLang())*2;
1267 break;
1268 case tok::kw_restrict:
1269 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
1270 getLang())*2;
1271 break;
1272
1273 // GNU typeof support.
1274 case tok::kw_typeof:
1275 ParseTypeofSpecifier(DS);
1276 return true;
1277
Anders Carlssoneed418b2009-06-24 17:47:40 +00001278 // C++0x decltype support.
1279 case tok::kw_decltype:
1280 ParseDecltypeSpecifier(DS);
1281 return true;
1282
Anders Carlsson7e023eb2009-06-26 23:44:14 +00001283 // C++0x auto support.
1284 case tok::kw_auto:
1285 if (!getLang().CPlusPlus0x)
1286 return false;
1287
1288 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec);
1289 break;
Eli Friedman891d82f2009-06-08 23:27:34 +00001290 case tok::kw___ptr64:
1291 case tok::kw___w64:
Steve Naroffedd04d52008-12-25 14:16:32 +00001292 case tok::kw___cdecl:
1293 case tok::kw___stdcall:
1294 case tok::kw___fastcall:
Eli Friedman891d82f2009-06-08 23:27:34 +00001295 DS.AddAttributes(ParseMicrosoftTypeAttributes());
Chris Lattner5bb837e2009-01-21 19:19:26 +00001296 return true;
Steve Naroffedd04d52008-12-25 14:16:32 +00001297
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001298 default:
1299 // Not a type-specifier; do nothing.
1300 return false;
1301 }
1302
1303 // If the specifier combination wasn't legal, issue a diagnostic.
1304 if (isInvalid) {
1305 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattnerf006a222008-11-18 07:48:38 +00001306 // Pick between error or extwarn.
1307 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
1308 : diag::ext_duplicate_declspec;
1309 Diag(Tok, DiagID) << PrevSpec;
Douglas Gregor3a6a3072008-11-07 15:42:26 +00001310 }
1311 DS.SetRangeEnd(Tok.getLocation());
1312 ConsumeToken(); // whatever we parsed above.
1313 return true;
1314}
Chris Lattner4b009652007-07-25 00:24:17 +00001315
Chris Lattnerced5b4f2007-10-29 04:42:53 +00001316/// ParseStructDeclaration - Parse a struct declaration without the terminating
1317/// semicolon.
1318///
Chris Lattner4b009652007-07-25 00:24:17 +00001319/// struct-declaration:
Chris Lattnerced5b4f2007-10-29 04:42:53 +00001320/// specifier-qualifier-list struct-declarator-list
Chris Lattner4b009652007-07-25 00:24:17 +00001321/// [GNU] __extension__ struct-declaration
Chris Lattnerced5b4f2007-10-29 04:42:53 +00001322/// [GNU] specifier-qualifier-list
Chris Lattner4b009652007-07-25 00:24:17 +00001323/// struct-declarator-list:
1324/// struct-declarator
1325/// struct-declarator-list ',' struct-declarator
1326/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
1327/// struct-declarator:
1328/// declarator
1329/// [GNU] declarator attributes[opt]
1330/// declarator[opt] ':' constant-expression
1331/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
1332///
Chris Lattner3dd8d392008-04-10 06:46:29 +00001333void Parser::
1334ParseStructDeclaration(DeclSpec &DS,
1335 llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
Chris Lattnerdaa5c002008-10-20 06:45:43 +00001336 if (Tok.is(tok::kw___extension__)) {
1337 // __extension__ silences extension warnings in the subexpression.
1338 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroffa9adf112007-08-20 22:28:22 +00001339 ConsumeToken();
Chris Lattnerdaa5c002008-10-20 06:45:43 +00001340 return ParseStructDeclaration(DS, Fields);
1341 }
Steve Naroffa9adf112007-08-20 22:28:22 +00001342
1343 // Parse the common specifier-qualifiers-list piece.
Chris Lattner12e8a4c2008-04-10 06:15:14 +00001344 SourceLocation DSStart = Tok.getLocation();
Steve Naroffa9adf112007-08-20 22:28:22 +00001345 ParseSpecifierQualifierList(DS);
Steve Naroffa9adf112007-08-20 22:28:22 +00001346
Douglas Gregorb748fc52009-01-12 22:49:06 +00001347 // If there are no declarators, this is a free-standing declaration
1348 // specifier. Let the actions module cope with it.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001349 if (Tok.is(tok::semi)) {
Douglas Gregorb748fc52009-01-12 22:49:06 +00001350 Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
Steve Naroffa9adf112007-08-20 22:28:22 +00001351 return;
1352 }
1353
1354 // Read struct-declarators until we find the semicolon.
Chris Lattnerf62fb732008-04-10 16:37:40 +00001355 Fields.push_back(FieldDeclarator(DS));
Steve Naroffa9adf112007-08-20 22:28:22 +00001356 while (1) {
Chris Lattner3dd8d392008-04-10 06:46:29 +00001357 FieldDeclarator &DeclaratorInfo = Fields.back();
1358
Steve Naroffa9adf112007-08-20 22:28:22 +00001359 /// struct-declarator: declarator
1360 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattner34a01ad2007-10-09 17:33:22 +00001361 if (Tok.isNot(tok::colon))
Chris Lattner3dd8d392008-04-10 06:46:29 +00001362 ParseDeclarator(DeclaratorInfo.D);
Steve Naroffa9adf112007-08-20 22:28:22 +00001363
Chris Lattner34a01ad2007-10-09 17:33:22 +00001364 if (Tok.is(tok::colon)) {
Steve Naroffa9adf112007-08-20 22:28:22 +00001365 ConsumeToken();
Sebastian Redl14ca7412008-12-11 21:36:32 +00001366 OwningExprResult Res(ParseConstantExpression());
Sebastian Redlbb4dae72008-12-09 13:15:23 +00001367 if (Res.isInvalid())
Steve Naroffa9adf112007-08-20 22:28:22 +00001368 SkipUntil(tok::semi, true, true);
Chris Lattner12e8a4c2008-04-10 06:15:14 +00001369 else
Sebastian Redl6f1ee232008-12-10 00:02:53 +00001370 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroffa9adf112007-08-20 22:28:22 +00001371 }
Sebastian Redl0c986032009-02-09 18:23:29 +00001372
Steve Naroffa9adf112007-08-20 22:28:22 +00001373 // If attributes exist after the declarator, parse them.
Sebastian Redl0c986032009-02-09 18:23:29 +00001374 if (Tok.is(tok::kw___attribute)) {
1375 SourceLocation Loc;
1376 AttributeList *AttrList = ParseAttributes(&Loc);
1377 DeclaratorInfo.D.AddAttributes(AttrList, Loc);
1378 }
1379
Steve Naroffa9adf112007-08-20 22:28:22 +00001380 // If we don't have a comma, it is either the end of the list (a ';')
1381 // or an error, bail out.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001382 if (Tok.isNot(tok::comma))
Chris Lattnerced5b4f2007-10-29 04:42:53 +00001383 return;
Sebastian Redl0c986032009-02-09 18:23:29 +00001384
Steve Naroffa9adf112007-08-20 22:28:22 +00001385 // Consume the comma.
1386 ConsumeToken();
Sebastian Redl0c986032009-02-09 18:23:29 +00001387
Steve Naroffa9adf112007-08-20 22:28:22 +00001388 // Parse the next declarator.
Chris Lattnerf62fb732008-04-10 16:37:40 +00001389 Fields.push_back(FieldDeclarator(DS));
Sebastian Redl0c986032009-02-09 18:23:29 +00001390
Steve Naroffa9adf112007-08-20 22:28:22 +00001391 // Attributes are only allowed on the second declarator.
Sebastian Redl0c986032009-02-09 18:23:29 +00001392 if (Tok.is(tok::kw___attribute)) {
1393 SourceLocation Loc;
1394 AttributeList *AttrList = ParseAttributes(&Loc);
1395 Fields.back().D.AddAttributes(AttrList, Loc);
1396 }
Steve Naroffa9adf112007-08-20 22:28:22 +00001397 }
Steve Naroffa9adf112007-08-20 22:28:22 +00001398}
1399
1400/// ParseStructUnionBody
1401/// struct-contents:
1402/// struct-declaration-list
1403/// [EXT] empty
1404/// [GNU] "struct-declaration-list" without terminatoring ';'
1405/// struct-declaration-list:
1406/// struct-declaration
1407/// struct-declaration-list struct-declaration
Chris Lattner1bf58f62008-06-21 19:39:06 +00001408/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroffa9adf112007-08-20 22:28:22 +00001409///
Chris Lattner4b009652007-07-25 00:24:17 +00001410void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
Chris Lattner5261d0c2009-03-28 19:18:32 +00001411 unsigned TagType, DeclPtrTy TagDecl) {
Chris Lattnerc309ade2009-03-05 08:00:35 +00001412 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
1413 PP.getSourceManager(),
1414 "parsing struct/union body");
Chris Lattner7efd75e2009-03-05 02:25:03 +00001415
Chris Lattner4b009652007-07-25 00:24:17 +00001416 SourceLocation LBraceLoc = ConsumeBrace();
1417
Douglas Gregorcab994d2009-01-09 22:42:13 +00001418 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregordb568cf2009-01-08 20:45:30 +00001419 Actions.ActOnTagStartDefinition(CurScope, TagDecl);
1420
Chris Lattner4b009652007-07-25 00:24:17 +00001421 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
1422 // C++.
Douglas Gregorec93f442008-04-13 21:30:24 +00001423 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattnerf006a222008-11-18 07:48:38 +00001424 Diag(Tok, diag::ext_empty_struct_union_enum)
1425 << DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
Chris Lattner4b009652007-07-25 00:24:17 +00001426
Chris Lattner5261d0c2009-03-28 19:18:32 +00001427 llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
Chris Lattner3dd8d392008-04-10 06:46:29 +00001428 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
1429
Chris Lattner4b009652007-07-25 00:24:17 +00001430 // While we still have something to read, read the declarations in the struct.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001431 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001432 // Each iteration of this loop reads one struct-declaration.
1433
1434 // Check for extraneous top-level semicolon.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001435 if (Tok.is(tok::semi)) {
Douglas Gregor1ba5cb32009-04-01 22:41:11 +00001436 Diag(Tok, diag::ext_extra_struct_semi)
1437 << CodeModificationHint::CreateRemoval(SourceRange(Tok.getLocation()));
Chris Lattner4b009652007-07-25 00:24:17 +00001438 ConsumeToken();
1439 continue;
1440 }
Chris Lattner3dd8d392008-04-10 06:46:29 +00001441
1442 // Parse all the comma separated declarators.
1443 DeclSpec DS;
1444 FieldDeclarators.clear();
Chris Lattner1bf58f62008-06-21 19:39:06 +00001445 if (!Tok.is(tok::at)) {
1446 ParseStructDeclaration(DS, FieldDeclarators);
1447
1448 // Convert them all to fields.
1449 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
1450 FieldDeclarator &FD = FieldDeclarators[i];
1451 // Install the declarator into the current TagDecl.
Chris Lattner5261d0c2009-03-28 19:18:32 +00001452 DeclPtrTy Field = Actions.ActOnField(CurScope, TagDecl,
1453 DS.getSourceRange().getBegin(),
1454 FD.D, FD.BitfieldSize);
Chris Lattner1bf58f62008-06-21 19:39:06 +00001455 FieldDecls.push_back(Field);
1456 }
1457 } else { // Handle @defs
1458 ConsumeToken();
1459 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
1460 Diag(Tok, diag::err_unexpected_at);
1461 SkipUntil(tok::semi, true, true);
1462 continue;
1463 }
1464 ConsumeToken();
1465 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
1466 if (!Tok.is(tok::identifier)) {
1467 Diag(Tok, diag::err_expected_ident);
1468 SkipUntil(tok::semi, true, true);
1469 continue;
1470 }
Chris Lattner5261d0c2009-03-28 19:18:32 +00001471 llvm::SmallVector<DeclPtrTy, 16> Fields;
Douglas Gregor8acb7272008-12-11 16:49:14 +00001472 Actions.ActOnDefs(CurScope, TagDecl, Tok.getLocation(),
1473 Tok.getIdentifierInfo(), Fields);
Chris Lattner1bf58f62008-06-21 19:39:06 +00001474 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
1475 ConsumeToken();
1476 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
1477 }
Chris Lattner4b009652007-07-25 00:24:17 +00001478
Chris Lattner34a01ad2007-10-09 17:33:22 +00001479 if (Tok.is(tok::semi)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001480 ConsumeToken();
Chris Lattner34a01ad2007-10-09 17:33:22 +00001481 } else if (Tok.is(tok::r_brace)) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001482 Diag(Tok, diag::ext_expected_semi_decl_list);
Chris Lattner4b009652007-07-25 00:24:17 +00001483 break;
1484 } else {
1485 Diag(Tok, diag::err_expected_semi_decl_list);
1486 // Skip to end of block or statement
1487 SkipUntil(tok::r_brace, true, true);
1488 }
1489 }
1490
Steve Naroff1a7fa7b2007-10-29 21:38:07 +00001491 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
Chris Lattner4b009652007-07-25 00:24:17 +00001492
Chris Lattner4b009652007-07-25 00:24:17 +00001493 AttributeList *AttrList = 0;
1494 // If attributes exist after struct contents, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001495 if (Tok.is(tok::kw___attribute))
Daniel Dunbar3b908072008-10-03 16:42:10 +00001496 AttrList = ParseAttributes();
Daniel Dunbarf3944442008-10-03 02:03:53 +00001497
1498 Actions.ActOnFields(CurScope,
Jay Foad9e6bef42009-05-21 09:52:38 +00001499 RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
Daniel Dunbarf3944442008-10-03 02:03:53 +00001500 LBraceLoc, RBraceLoc,
Douglas Gregordb568cf2009-01-08 20:45:30 +00001501 AttrList);
1502 StructScope.Exit();
1503 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Chris Lattner4b009652007-07-25 00:24:17 +00001504}
1505
1506
1507/// ParseEnumSpecifier
1508/// enum-specifier: [C99 6.7.2.2]
1509/// 'enum' identifier[opt] '{' enumerator-list '}'
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001510///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Chris Lattner4b009652007-07-25 00:24:17 +00001511/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
1512/// '}' attributes[opt]
1513/// 'enum' identifier
1514/// [GNU] 'enum' attributes[opt] identifier
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001515///
1516/// [C++] elaborated-type-specifier:
1517/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
1518///
Chris Lattner197b4342009-04-12 21:49:30 +00001519void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
1520 AccessSpecifier AS) {
Chris Lattner4b009652007-07-25 00:24:17 +00001521 // Parse the tag portion of this.
Argiris Kirtzidis2298f012008-09-11 00:21:41 +00001522
1523 AttributeList *Attr = 0;
1524 // If attributes exist after tag, parse them.
1525 if (Tok.is(tok::kw___attribute))
1526 Attr = ParseAttributes();
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001527
1528 CXXScopeSpec SS;
Chris Lattnerd706dc82009-01-06 06:59:53 +00001529 if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS)) {
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001530 if (Tok.isNot(tok::identifier)) {
1531 Diag(Tok, diag::err_expected_ident);
1532 if (Tok.isNot(tok::l_brace)) {
1533 // Has no name and is not a definition.
1534 // Skip the rest of this declarator, up until the comma or semicolon.
1535 SkipUntil(tok::comma, true);
1536 return;
1537 }
1538 }
1539 }
Argiris Kirtzidis2298f012008-09-11 00:21:41 +00001540
1541 // Must have either 'enum name' or 'enum {...}'.
1542 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) {
1543 Diag(Tok, diag::err_expected_ident_lbrace);
1544
1545 // Skip the rest of this declarator, up until the comma or semicolon.
1546 SkipUntil(tok::comma, true);
Chris Lattner4b009652007-07-25 00:24:17 +00001547 return;
Argiris Kirtzidis2298f012008-09-11 00:21:41 +00001548 }
1549
1550 // If an identifier is present, consume and remember it.
1551 IdentifierInfo *Name = 0;
1552 SourceLocation NameLoc;
1553 if (Tok.is(tok::identifier)) {
1554 Name = Tok.getIdentifierInfo();
1555 NameLoc = ConsumeToken();
1556 }
1557
1558 // There are three options here. If we have 'enum foo;', then this is a
1559 // forward declaration. If we have 'enum foo {...' then this is a
1560 // definition. Otherwise we have something like 'enum foo xyz', a reference.
1561 //
1562 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
1563 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
1564 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
1565 //
1566 Action::TagKind TK;
1567 if (Tok.is(tok::l_brace))
1568 TK = Action::TK_Definition;
1569 else if (Tok.is(tok::semi))
1570 TK = Action::TK_Declaration;
1571 else
1572 TK = Action::TK_Reference;
Douglas Gregor71f06032009-05-28 23:31:59 +00001573 bool Owned = false;
Chris Lattner5261d0c2009-03-28 19:18:32 +00001574 DeclPtrTy TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK,
Douglas Gregor71f06032009-05-28 23:31:59 +00001575 StartLoc, SS, Name, NameLoc, Attr, AS,
1576 Owned);
Chris Lattner4b009652007-07-25 00:24:17 +00001577
Chris Lattner34a01ad2007-10-09 17:33:22 +00001578 if (Tok.is(tok::l_brace))
Chris Lattner4b009652007-07-25 00:24:17 +00001579 ParseEnumBody(StartLoc, TagDecl);
1580
1581 // TODO: semantic analysis on the declspec for enums.
1582 const char *PrevSpec = 0;
Chris Lattner5261d0c2009-03-28 19:18:32 +00001583 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec,
Douglas Gregor71f06032009-05-28 23:31:59 +00001584 TagDecl.getAs<void>(), Owned))
Chris Lattnerf006a222008-11-18 07:48:38 +00001585 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Chris Lattner4b009652007-07-25 00:24:17 +00001586}
1587
1588/// ParseEnumBody - Parse a {} enclosed enumerator-list.
1589/// enumerator-list:
1590/// enumerator
1591/// enumerator-list ',' enumerator
1592/// enumerator:
1593/// enumeration-constant
1594/// enumeration-constant '=' constant-expression
1595/// enumeration-constant:
1596/// identifier
1597///
Chris Lattner5261d0c2009-03-28 19:18:32 +00001598void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) {
Douglas Gregord8028382009-01-05 19:45:36 +00001599 // Enter the scope of the enum body and start the definition.
1600 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregordb568cf2009-01-08 20:45:30 +00001601 Actions.ActOnTagStartDefinition(CurScope, EnumDecl);
Douglas Gregord8028382009-01-05 19:45:36 +00001602
Chris Lattner4b009652007-07-25 00:24:17 +00001603 SourceLocation LBraceLoc = ConsumeBrace();
1604
Chris Lattnerc9a92452007-08-27 17:24:30 +00001605 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
Chris Lattner34a01ad2007-10-09 17:33:22 +00001606 if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
Chris Lattnerf006a222008-11-18 07:48:38 +00001607 Diag(Tok, diag::ext_empty_struct_union_enum) << "enum";
Chris Lattner4b009652007-07-25 00:24:17 +00001608
Chris Lattner5261d0c2009-03-28 19:18:32 +00001609 llvm::SmallVector<DeclPtrTy, 32> EnumConstantDecls;
Chris Lattner4b009652007-07-25 00:24:17 +00001610
Chris Lattner5261d0c2009-03-28 19:18:32 +00001611 DeclPtrTy LastEnumConstDecl;
Chris Lattner4b009652007-07-25 00:24:17 +00001612
1613 // Parse the enumerator-list.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001614 while (Tok.is(tok::identifier)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001615 IdentifierInfo *Ident = Tok.getIdentifierInfo();
1616 SourceLocation IdentLoc = ConsumeToken();
1617
1618 SourceLocation EqualLoc;
Sebastian Redl62261042008-12-09 20:22:58 +00001619 OwningExprResult AssignedVal(Actions);
Chris Lattner34a01ad2007-10-09 17:33:22 +00001620 if (Tok.is(tok::equal)) {
Chris Lattner4b009652007-07-25 00:24:17 +00001621 EqualLoc = ConsumeToken();
Sebastian Redlbb4dae72008-12-09 13:15:23 +00001622 AssignedVal = ParseConstantExpression();
1623 if (AssignedVal.isInvalid())
Chris Lattner4b009652007-07-25 00:24:17 +00001624 SkipUntil(tok::comma, tok::r_brace, true, true);
Chris Lattner4b009652007-07-25 00:24:17 +00001625 }
1626
1627 // Install the enumerator constant into EnumDecl.
Chris Lattner5261d0c2009-03-28 19:18:32 +00001628 DeclPtrTy EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
1629 LastEnumConstDecl,
1630 IdentLoc, Ident,
1631 EqualLoc,
1632 AssignedVal.release());
Chris Lattner4b009652007-07-25 00:24:17 +00001633 EnumConstantDecls.push_back(EnumConstDecl);
1634 LastEnumConstDecl = EnumConstDecl;
1635
Chris Lattner34a01ad2007-10-09 17:33:22 +00001636 if (Tok.isNot(tok::comma))
Chris Lattner4b009652007-07-25 00:24:17 +00001637 break;
1638 SourceLocation CommaLoc = ConsumeToken();
1639
Douglas Gregor1ba5cb32009-04-01 22:41:11 +00001640 if (Tok.isNot(tok::identifier) &&
1641 !(getLang().C99 || getLang().CPlusPlus0x))
1642 Diag(CommaLoc, diag::ext_enumerator_list_comma)
1643 << getLang().CPlusPlus
1644 << CodeModificationHint::CreateRemoval((SourceRange(CommaLoc)));
Chris Lattner4b009652007-07-25 00:24:17 +00001645 }
1646
1647 // Eat the }.
Mike Stump155750e2009-05-16 07:06:02 +00001648 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
Chris Lattner4b009652007-07-25 00:24:17 +00001649
Mike Stump155750e2009-05-16 07:06:02 +00001650 Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
Jay Foad9e6bef42009-05-21 09:52:38 +00001651 EnumConstantDecls.data(), EnumConstantDecls.size());
Chris Lattner4b009652007-07-25 00:24:17 +00001652
Chris Lattner5261d0c2009-03-28 19:18:32 +00001653 Action::AttrTy *AttrList = 0;
Chris Lattner4b009652007-07-25 00:24:17 +00001654 // If attributes exist after the identifier list, parse them.
Chris Lattner34a01ad2007-10-09 17:33:22 +00001655 if (Tok.is(tok::kw___attribute))
Chris Lattner4b009652007-07-25 00:24:17 +00001656 AttrList = ParseAttributes(); // FIXME: where do they do?
Douglas Gregordb568cf2009-01-08 20:45:30 +00001657
1658 EnumScope.Exit();
1659 Actions.ActOnTagFinishDefinition(CurScope, EnumDecl);
Chris Lattner4b009652007-07-25 00:24:17 +00001660}
1661
1662/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff6f9f9552008-02-11 23:15:56 +00001663/// start of a type-qualifier-list.
1664bool Parser::isTypeQualifier() const {
1665 switch (Tok.getKind()) {
1666 default: return false;
1667 // type-qualifier
1668 case tok::kw_const:
1669 case tok::kw_volatile:
1670 case tok::kw_restrict:
1671 return true;
1672 }
1673}
1674
1675/// isTypeSpecifierQualifier - Return true if the current token could be the
Chris Lattner4b009652007-07-25 00:24:17 +00001676/// start of a specifier-qualifier-list.
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001677bool Parser::isTypeSpecifierQualifier() {
Chris Lattner4b009652007-07-25 00:24:17 +00001678 switch (Tok.getKind()) {
1679 default: return false;
Chris Lattnerb75fde62009-01-04 23:41:41 +00001680
1681 case tok::identifier: // foo::bar
Douglas Gregord3022602009-03-27 23:10:48 +00001682 case tok::kw_typename: // typename T::type
Chris Lattnerb75fde62009-01-04 23:41:41 +00001683 // Annotate typenames and C++ scope specifiers. If we get one, just
1684 // recurse to handle whatever we get.
1685 if (TryAnnotateTypeOrScopeToken())
1686 return isTypeSpecifierQualifier();
1687 // Otherwise, not a type specifier.
1688 return false;
Douglas Gregord3022602009-03-27 23:10:48 +00001689
Chris Lattnerb75fde62009-01-04 23:41:41 +00001690 case tok::coloncolon: // ::foo::bar
1691 if (NextToken().is(tok::kw_new) || // ::new
1692 NextToken().is(tok::kw_delete)) // ::delete
1693 return false;
1694
1695 // Annotate typenames and C++ scope specifiers. If we get one, just
1696 // recurse to handle whatever we get.
1697 if (TryAnnotateTypeOrScopeToken())
1698 return isTypeSpecifierQualifier();
1699 // Otherwise, not a type specifier.
1700 return false;
1701
Chris Lattner4b009652007-07-25 00:24:17 +00001702 // GNU attributes support.
1703 case tok::kw___attribute:
Steve Naroff7cbb1462007-07-31 12:34:36 +00001704 // GNU typeof support.
1705 case tok::kw_typeof:
1706
Chris Lattner4b009652007-07-25 00:24:17 +00001707 // type-specifiers
1708 case tok::kw_short:
1709 case tok::kw_long:
1710 case tok::kw_signed:
1711 case tok::kw_unsigned:
1712 case tok::kw__Complex:
1713 case tok::kw__Imaginary:
1714 case tok::kw_void:
1715 case tok::kw_char:
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +00001716 case tok::kw_wchar_t:
Chris Lattner4b009652007-07-25 00:24:17 +00001717 case tok::kw_int:
1718 case tok::kw_float:
1719 case tok::kw_double:
Chris Lattner2baef2e2007-11-15 05:25:19 +00001720 case tok::kw_bool:
Chris Lattner4b009652007-07-25 00:24:17 +00001721 case tok::kw__Bool:
1722 case tok::kw__Decimal32:
1723 case tok::kw__Decimal64:
1724 case tok::kw__Decimal128:
1725
Chris Lattner2e78db32008-04-13 18:59:07 +00001726 // struct-or-union-specifier (C99) or class-specifier (C++)
1727 case tok::kw_class:
Chris Lattner4b009652007-07-25 00:24:17 +00001728 case tok::kw_struct:
1729 case tok::kw_union:
1730 // enum-specifier
1731 case tok::kw_enum:
1732
1733 // type-qualifier
1734 case tok::kw_const:
1735 case tok::kw_volatile:
1736 case tok::kw_restrict:
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001737
1738 // typedef-name
Chris Lattner5d7eace2009-01-06 05:06:21 +00001739 case tok::annot_typename:
Chris Lattner4b009652007-07-25 00:24:17 +00001740 return true;
Chris Lattner9aefe722008-10-20 00:25:30 +00001741
1742 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
1743 case tok::less:
1744 return getLang().ObjC1;
Steve Naroffedd04d52008-12-25 14:16:32 +00001745
1746 case tok::kw___cdecl:
1747 case tok::kw___stdcall:
1748 case tok::kw___fastcall:
Eli Friedman891d82f2009-06-08 23:27:34 +00001749 case tok::kw___w64:
1750 case tok::kw___ptr64:
1751 return true;
Chris Lattner4b009652007-07-25 00:24:17 +00001752 }
1753}
1754
1755/// isDeclarationSpecifier() - Return true if the current token is part of a
1756/// declaration specifier.
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001757bool Parser::isDeclarationSpecifier() {
Chris Lattner4b009652007-07-25 00:24:17 +00001758 switch (Tok.getKind()) {
1759 default: return false;
Chris Lattnerb75fde62009-01-04 23:41:41 +00001760
1761 case tok::identifier: // foo::bar
Steve Naroff73ec9322009-03-09 21:12:44 +00001762 // Unfortunate hack to support "Class.factoryMethod" notation.
1763 if (getLang().ObjC1 && NextToken().is(tok::period))
1764 return false;
Douglas Gregord3022602009-03-27 23:10:48 +00001765 // Fall through
Steve Naroff73ec9322009-03-09 21:12:44 +00001766
Douglas Gregord3022602009-03-27 23:10:48 +00001767 case tok::kw_typename: // typename T::type
Chris Lattnerb75fde62009-01-04 23:41:41 +00001768 // Annotate typenames and C++ scope specifiers. If we get one, just
1769 // recurse to handle whatever we get.
1770 if (TryAnnotateTypeOrScopeToken())
1771 return isDeclarationSpecifier();
1772 // Otherwise, not a declaration specifier.
1773 return false;
1774 case tok::coloncolon: // ::foo::bar
1775 if (NextToken().is(tok::kw_new) || // ::new
1776 NextToken().is(tok::kw_delete)) // ::delete
1777 return false;
1778
1779 // Annotate typenames and C++ scope specifiers. If we get one, just
1780 // recurse to handle whatever we get.
1781 if (TryAnnotateTypeOrScopeToken())
1782 return isDeclarationSpecifier();
1783 // Otherwise, not a declaration specifier.
1784 return false;
1785
Chris Lattner4b009652007-07-25 00:24:17 +00001786 // storage-class-specifier
1787 case tok::kw_typedef:
1788 case tok::kw_extern:
Steve Narofff258a0f2007-12-18 00:16:02 +00001789 case tok::kw___private_extern__:
Chris Lattner4b009652007-07-25 00:24:17 +00001790 case tok::kw_static:
1791 case tok::kw_auto:
1792 case tok::kw_register:
1793 case tok::kw___thread:
1794
1795 // type-specifiers
1796 case tok::kw_short:
1797 case tok::kw_long:
1798 case tok::kw_signed:
1799 case tok::kw_unsigned:
1800 case tok::kw__Complex:
1801 case tok::kw__Imaginary:
1802 case tok::kw_void:
1803 case tok::kw_char:
Argiris Kirtzidis1ed03e72008-08-09 16:51:54 +00001804 case tok::kw_wchar_t:
Chris Lattner4b009652007-07-25 00:24:17 +00001805 case tok::kw_int:
1806 case tok::kw_float:
1807 case tok::kw_double:
Chris Lattner2baef2e2007-11-15 05:25:19 +00001808 case tok::kw_bool:
Chris Lattner4b009652007-07-25 00:24:17 +00001809 case tok::kw__Bool:
1810 case tok::kw__Decimal32:
1811 case tok::kw__Decimal64:
1812 case tok::kw__Decimal128:
1813
Chris Lattner2e78db32008-04-13 18:59:07 +00001814 // struct-or-union-specifier (C99) or class-specifier (C++)
1815 case tok::kw_class:
Chris Lattner4b009652007-07-25 00:24:17 +00001816 case tok::kw_struct:
1817 case tok::kw_union:
1818 // enum-specifier
1819 case tok::kw_enum:
1820
1821 // type-qualifier
1822 case tok::kw_const:
1823 case tok::kw_volatile:
1824 case tok::kw_restrict:
Steve Naroff7cbb1462007-07-31 12:34:36 +00001825
Chris Lattner4b009652007-07-25 00:24:17 +00001826 // function-specifier
1827 case tok::kw_inline:
Douglas Gregorf15ac4b2008-10-31 09:07:45 +00001828 case tok::kw_virtual:
1829 case tok::kw_explicit:
Chris Lattnere35d2582007-08-09 16:40:21 +00001830
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001831 // typedef-name
Chris Lattner5d7eace2009-01-06 05:06:21 +00001832 case tok::annot_typename:
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00001833
Chris Lattnerb707a7a2007-08-09 17:01:07 +00001834 // GNU typeof support.
1835 case tok::kw_typeof:
1836
1837 // GNU attributes.
Chris Lattnere35d2582007-08-09 16:40:21 +00001838 case tok::kw___attribute:
Chris Lattner4b009652007-07-25 00:24:17 +00001839 return true;
Chris Lattner1b2251c2008-07-26 03:38:44 +00001840
1841 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
1842 case tok::less:
1843 return getLang().ObjC1;
Steve Naroffedd04d52008-12-25 14:16:32 +00001844
Steve Naroffab1a3632009-01-06 19:34:12 +00001845 case tok::kw___declspec:
Steve Naroffedd04d52008-12-25 14:16:32 +00001846 case tok::kw___cdecl:
1847 case tok::kw___stdcall:
1848 case tok::kw___fastcall:
Eli Friedman891d82f2009-06-08 23:27:34 +00001849 case tok::kw___w64:
1850 case tok::kw___ptr64:
1851 case tok::kw___forceinline:
1852 return true;
Chris Lattner4b009652007-07-25 00:24:17 +00001853 }
1854}
1855
1856
1857/// ParseTypeQualifierListOpt
1858/// type-qualifier-list: [C99 6.7.5]
1859/// type-qualifier
Chris Lattner460696f2008-12-18 07:02:59 +00001860/// [GNU] attributes [ only if AttributesAllowed=true ]
Chris Lattner4b009652007-07-25 00:24:17 +00001861/// type-qualifier-list type-qualifier
Chris Lattner460696f2008-12-18 07:02:59 +00001862/// [GNU] type-qualifier-list attributes [ only if AttributesAllowed=true ]
Chris Lattner4b009652007-07-25 00:24:17 +00001863///
Chris Lattner460696f2008-12-18 07:02:59 +00001864void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed) {
Chris Lattner4b009652007-07-25 00:24:17 +00001865 while (1) {
1866 int isInvalid = false;
1867 const char *PrevSpec = 0;
1868 SourceLocation Loc = Tok.getLocation();
1869
1870 switch (Tok.getKind()) {
Chris Lattner4b009652007-07-25 00:24:17 +00001871 case tok::kw_const:
1872 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
1873 getLang())*2;
1874 break;
1875 case tok::kw_volatile:
1876 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
1877 getLang())*2;
1878 break;
1879 case tok::kw_restrict:
1880 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
1881 getLang())*2;
1882 break;
Eli Friedman891d82f2009-06-08 23:27:34 +00001883 case tok::kw___w64:
Steve Naroffad620402008-12-25 14:41:26 +00001884 case tok::kw___ptr64:
Steve Naroffedd04d52008-12-25 14:16:32 +00001885 case tok::kw___cdecl:
1886 case tok::kw___stdcall:
1887 case tok::kw___fastcall:
Eli Friedman891d82f2009-06-08 23:27:34 +00001888 if (AttributesAllowed) {
1889 DS.AddAttributes(ParseMicrosoftTypeAttributes());
1890 continue;
1891 }
1892 goto DoneWithTypeQuals;
Chris Lattner4b009652007-07-25 00:24:17 +00001893 case tok::kw___attribute:
Chris Lattner460696f2008-12-18 07:02:59 +00001894 if (AttributesAllowed) {
1895 DS.AddAttributes(ParseAttributes());
1896 continue; // do *not* consume the next token!
1897 }
1898 // otherwise, FALL THROUGH!
1899 default:
Steve Naroffedd04d52008-12-25 14:16:32 +00001900 DoneWithTypeQuals:
Chris Lattner460696f2008-12-18 07:02:59 +00001901 // If this is not a type-qualifier token, we're done reading type
1902 // qualifiers. First verify that DeclSpec's are consistent.
Douglas Gregor1ba5cb32009-04-01 22:41:11 +00001903 DS.Finish(Diags, PP);
Chris Lattner460696f2008-12-18 07:02:59 +00001904 return;
Chris Lattner4b009652007-07-25 00:24:17 +00001905 }
Chris Lattner306d4df2008-12-18 06:50:14 +00001906
Chris Lattner4b009652007-07-25 00:24:17 +00001907 // If the specifier combination wasn't legal, issue a diagnostic.
1908 if (isInvalid) {
1909 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattnerf006a222008-11-18 07:48:38 +00001910 // Pick between error or extwarn.
1911 unsigned DiagID = isInvalid == 1 ? diag::err_invalid_decl_spec_combination
1912 : diag::ext_duplicate_declspec;
1913 Diag(Tok, DiagID) << PrevSpec;
Chris Lattner4b009652007-07-25 00:24:17 +00001914 }
1915 ConsumeToken();
1916 }
1917}
1918
1919
1920/// ParseDeclarator - Parse and verify a newly-initialized declarator.
1921///
1922void Parser::ParseDeclarator(Declarator &D) {
1923 /// This implements the 'declarator' production in the C grammar, then checks
1924 /// for well-formedness and issues diagnostics.
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001925 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattner4b009652007-07-25 00:24:17 +00001926}
1927
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001928/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
1929/// is parsed by the function passed to it. Pass null, and the direct-declarator
1930/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001931/// ptr-operator production.
1932///
Sebastian Redl75555032009-01-24 21:16:55 +00001933/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
1934/// [C] pointer[opt] direct-declarator
1935/// [C++] direct-declarator
1936/// [C++] ptr-operator declarator
Chris Lattner4b009652007-07-25 00:24:17 +00001937///
1938/// pointer: [C99 6.7.5]
1939/// '*' type-qualifier-list[opt]
1940/// '*' type-qualifier-list[opt] pointer
1941///
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001942/// ptr-operator:
1943/// '*' cv-qualifier-seq[opt]
1944/// '&'
Sebastian Redl9951dbc2009-03-15 22:02:01 +00001945/// [C++0x] '&&'
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001946/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redl9951dbc2009-03-15 22:02:01 +00001947/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redl75555032009-01-24 21:16:55 +00001948/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001949void Parser::ParseDeclaratorInternal(Declarator &D,
1950 DirectDeclParseFunction DirectDeclParser) {
Chris Lattner4b009652007-07-25 00:24:17 +00001951
Sebastian Redl75555032009-01-24 21:16:55 +00001952 // C++ member pointers start with a '::' or a nested-name.
1953 // Member pointers get special handling, since there's no place for the
1954 // scope spec in the generic path below.
Chris Lattner053dd2d2009-03-24 17:04:48 +00001955 if (getLang().CPlusPlus &&
1956 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
1957 Tok.is(tok::annot_cxxscope))) {
Sebastian Redl75555032009-01-24 21:16:55 +00001958 CXXScopeSpec SS;
1959 if (ParseOptionalCXXScopeSpecifier(SS)) {
1960 if(Tok.isNot(tok::star)) {
1961 // The scope spec really belongs to the direct-declarator.
1962 D.getCXXScopeSpec() = SS;
1963 if (DirectDeclParser)
1964 (this->*DirectDeclParser)(D);
1965 return;
1966 }
1967
1968 SourceLocation Loc = ConsumeToken();
Sebastian Redl0c986032009-02-09 18:23:29 +00001969 D.SetRangeEnd(Loc);
Sebastian Redl75555032009-01-24 21:16:55 +00001970 DeclSpec DS;
1971 ParseTypeQualifierListOpt(DS);
Sebastian Redl0c986032009-02-09 18:23:29 +00001972 D.ExtendWithDeclSpec(DS);
Sebastian Redl75555032009-01-24 21:16:55 +00001973
1974 // Recurse to parse whatever is left.
1975 ParseDeclaratorInternal(D, DirectDeclParser);
1976
1977 // Sema will have to catch (syntactically invalid) pointers into global
1978 // scope. It has to catch pointers into namespace scope anyway.
1979 D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
Sebastian Redl0c986032009-02-09 18:23:29 +00001980 Loc, DS.TakeAttributes()),
1981 /* Don't replace range end. */SourceLocation());
Sebastian Redl75555032009-01-24 21:16:55 +00001982 return;
1983 }
1984 }
1985
1986 tok::TokenKind Kind = Tok.getKind();
Steve Naroff7aa54752008-08-27 16:04:49 +00001987 // Not a pointer, C++ reference, or block.
Chris Lattnerc14c7f02009-03-27 04:18:06 +00001988 if (Kind != tok::star && Kind != tok::caret &&
Chris Lattner053dd2d2009-03-24 17:04:48 +00001989 (Kind != tok::amp || !getLang().CPlusPlus) &&
Sebastian Redl4e67adb2009-03-23 00:00:23 +00001990 // We parse rvalue refs in C++03, because otherwise the errors are scary.
Chris Lattnerc14c7f02009-03-27 04:18:06 +00001991 (Kind != tok::ampamp || !getLang().CPlusPlus)) {
Sebastian Redl19fec9d2008-11-21 19:14:01 +00001992 if (DirectDeclParser)
1993 (this->*DirectDeclParser)(D);
Douglas Gregor3ef6c972008-11-07 20:08:42 +00001994 return;
1995 }
Sebastian Redl75555032009-01-24 21:16:55 +00001996
Sebastian Redl9951dbc2009-03-15 22:02:01 +00001997 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
1998 // '&&' -> rvalue reference
Sebastian Redl4e67adb2009-03-23 00:00:23 +00001999 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redl0c986032009-02-09 18:23:29 +00002000 D.SetRangeEnd(Loc);
Chris Lattner4b009652007-07-25 00:24:17 +00002001
Chris Lattnerc14c7f02009-03-27 04:18:06 +00002002 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner69f01932008-02-21 01:32:26 +00002003 // Is a pointer.
Chris Lattner4b009652007-07-25 00:24:17 +00002004 DeclSpec DS;
Sebastian Redl75555032009-01-24 21:16:55 +00002005
Chris Lattner4b009652007-07-25 00:24:17 +00002006 ParseTypeQualifierListOpt(DS);
Sebastian Redl0c986032009-02-09 18:23:29 +00002007 D.ExtendWithDeclSpec(DS);
Sebastian Redl75555032009-01-24 21:16:55 +00002008
Chris Lattner4b009652007-07-25 00:24:17 +00002009 // Recursively parse the declarator.
Sebastian Redl19fec9d2008-11-21 19:14:01 +00002010 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff7aa54752008-08-27 16:04:49 +00002011 if (Kind == tok::star)
2012 // Remember that we parsed a pointer type, and remember the type-quals.
2013 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
Sebastian Redl0c986032009-02-09 18:23:29 +00002014 DS.TakeAttributes()),
2015 SourceLocation());
Steve Naroff7aa54752008-08-27 16:04:49 +00002016 else
2017 // Remember that we parsed a Block type, and remember the type-quals.
2018 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
Mike Stump7ff82e72009-04-21 00:51:43 +00002019 Loc, DS.TakeAttributes()),
Sebastian Redl0c986032009-02-09 18:23:29 +00002020 SourceLocation());
Chris Lattner4b009652007-07-25 00:24:17 +00002021 } else {
2022 // Is a reference
2023 DeclSpec DS;
2024
Sebastian Redl4e67adb2009-03-23 00:00:23 +00002025 // Complain about rvalue references in C++03, but then go on and build
2026 // the declarator.
2027 if (Kind == tok::ampamp && !getLang().CPlusPlus0x)
2028 Diag(Loc, diag::err_rvalue_reference);
2029
Chris Lattner4b009652007-07-25 00:24:17 +00002030 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
2031 // cv-qualifiers are introduced through the use of a typedef or of a
2032 // template type argument, in which case the cv-qualifiers are ignored.
2033 //
2034 // [GNU] Retricted references are allowed.
2035 // [GNU] Attributes on references are allowed.
2036 ParseTypeQualifierListOpt(DS);
Sebastian Redl0c986032009-02-09 18:23:29 +00002037 D.ExtendWithDeclSpec(DS);
Chris Lattner4b009652007-07-25 00:24:17 +00002038
2039 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
2040 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
2041 Diag(DS.getConstSpecLoc(),
Chris Lattnerf006a222008-11-18 07:48:38 +00002042 diag::err_invalid_reference_qualifier_application) << "const";
Chris Lattner4b009652007-07-25 00:24:17 +00002043 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
2044 Diag(DS.getVolatileSpecLoc(),
Chris Lattnerf006a222008-11-18 07:48:38 +00002045 diag::err_invalid_reference_qualifier_application) << "volatile";
Chris Lattner4b009652007-07-25 00:24:17 +00002046 }
2047
2048 // Recursively parse the declarator.
Sebastian Redl19fec9d2008-11-21 19:14:01 +00002049 ParseDeclaratorInternal(D, DirectDeclParser);
Chris Lattner4b009652007-07-25 00:24:17 +00002050
Douglas Gregorb7b28a22008-11-03 15:51:28 +00002051 if (D.getNumTypeObjects() > 0) {
2052 // C++ [dcl.ref]p4: There shall be no references to references.
2053 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
2054 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattner8f7db152008-11-19 07:37:42 +00002055 if (const IdentifierInfo *II = D.getIdentifier())
2056 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
2057 << II;
2058 else
2059 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
2060 << "type name";
Douglas Gregorb7b28a22008-11-03 15:51:28 +00002061
Sebastian Redl19fec9d2008-11-21 19:14:01 +00002062 // Once we've complained about the reference-to-reference, we
Douglas Gregorb7b28a22008-11-03 15:51:28 +00002063 // can go ahead and build the (technically ill-formed)
2064 // declarator: reference collapsing will take care of it.
2065 }
2066 }
2067
Chris Lattner4b009652007-07-25 00:24:17 +00002068 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner69f01932008-02-21 01:32:26 +00002069 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redl9951dbc2009-03-15 22:02:01 +00002070 DS.TakeAttributes(),
2071 Kind == tok::amp),
Sebastian Redl0c986032009-02-09 18:23:29 +00002072 SourceLocation());
Chris Lattner4b009652007-07-25 00:24:17 +00002073 }
2074}
2075
2076/// ParseDirectDeclarator
2077/// direct-declarator: [C99 6.7.5]
Douglas Gregor8210a8e2008-11-05 20:51:48 +00002078/// [C99] identifier
Chris Lattner4b009652007-07-25 00:24:17 +00002079/// '(' declarator ')'
2080/// [GNU] '(' attributes declarator ')'
2081/// [C90] direct-declarator '[' constant-expression[opt] ']'
2082/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
2083/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
2084/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
2085/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
2086/// direct-declarator '(' parameter-type-list ')'
2087/// direct-declarator '(' identifier-list[opt] ')'
2088/// [GNU] direct-declarator '(' parameter-forward-declarations
2089/// parameter-type-list[opt] ')'
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002090/// [C++] direct-declarator '(' parameter-declaration-clause ')'
2091/// cv-qualifier-seq[opt] exception-specification[opt]
Douglas Gregorf15ac4b2008-10-31 09:07:45 +00002092/// [C++] declarator-id
Douglas Gregor8210a8e2008-11-05 20:51:48 +00002093///
2094/// declarator-id: [C++ 8]
2095/// id-expression
2096/// '::'[opt] nested-name-specifier[opt] type-name
2097///
2098/// id-expression: [C++ 5.1]
2099/// unqualified-id
2100/// qualified-id [TODO]
2101///
2102/// unqualified-id: [C++ 5.1]
2103/// identifier
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00002104/// operator-function-id
Douglas Gregor8210a8e2008-11-05 20:51:48 +00002105/// conversion-function-id [TODO]
2106/// '~' class-name
Douglas Gregor0c281a82009-02-25 19:37:18 +00002107/// template-id
Argiris Kirtzidisc9e909c2008-11-07 22:02:30 +00002108///
Chris Lattner4b009652007-07-25 00:24:17 +00002109void Parser::ParseDirectDeclarator(Declarator &D) {
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002110 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00002111
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002112 if (getLang().CPlusPlus) {
2113 if (D.mayHaveIdentifier()) {
Sebastian Redl75555032009-01-24 21:16:55 +00002114 // ParseDeclaratorInternal might already have parsed the scope.
2115 bool afterCXXScope = D.getCXXScopeSpec().isSet() ||
2116 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec());
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002117 if (afterCXXScope) {
2118 // Change the declaration context for name lookup, until this function
2119 // is exited (and the declarator has been parsed).
2120 DeclScopeObj.EnterDeclaratorScope();
2121 }
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00002122
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002123 if (Tok.is(tok::identifier)) {
2124 assert(Tok.getIdentifierInfo() && "Not an identifier?");
Anders Carlssone19759d2009-04-30 22:41:11 +00002125
2126 // If this identifier is the name of the current class, it's a
2127 // constructor name.
2128 if (!D.getDeclSpec().hasTypeSpecifier() &&
2129 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),CurScope)) {
Douglas Gregorcb0a7f72009-07-06 16:40:48 +00002130 CXXScopeSpec *SS = afterCXXScope? &D.getCXXScopeSpec() : 0;
Anders Carlssone19759d2009-04-30 22:41:11 +00002131 D.setConstructor(Actions.getTypeName(*Tok.getIdentifierInfo(),
Douglas Gregorcb0a7f72009-07-06 16:40:48 +00002132 Tok.getLocation(), CurScope, SS),
Anders Carlssone19759d2009-04-30 22:41:11 +00002133 Tok.getLocation());
2134 // This is a normal identifier.
2135 } else
2136 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002137 ConsumeToken();
2138 goto PastIdentifier;
Douglas Gregor0c281a82009-02-25 19:37:18 +00002139 } else if (Tok.is(tok::annot_template_id)) {
2140 TemplateIdAnnotation *TemplateId
2141 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
2142
2143 // FIXME: Could this template-id name a constructor?
2144
2145 // FIXME: This is an egregious hack, where we silently ignore
2146 // the specialization (which should be a function template
2147 // specialization name) and use the name instead. This hack
2148 // will go away when we have support for function
2149 // specializations.
2150 D.SetIdentifier(TemplateId->Name, Tok.getLocation());
2151 TemplateId->Destroy();
2152 ConsumeToken();
2153 goto PastIdentifier;
Douglas Gregor853dd392008-12-26 15:00:45 +00002154 } else if (Tok.is(tok::kw_operator)) {
2155 SourceLocation OperatorLoc = Tok.getLocation();
Sebastian Redl0c986032009-02-09 18:23:29 +00002156 SourceLocation EndLoc;
Douglas Gregore60e5d32008-11-06 22:13:31 +00002157
Douglas Gregor853dd392008-12-26 15:00:45 +00002158 // First try the name of an overloaded operator
Sebastian Redl0c986032009-02-09 18:23:29 +00002159 if (OverloadedOperatorKind Op = TryParseOperatorFunctionId(&EndLoc)) {
2160 D.setOverloadedOperator(Op, OperatorLoc, EndLoc);
Douglas Gregor853dd392008-12-26 15:00:45 +00002161 } else {
2162 // This must be a conversion function (C++ [class.conv.fct]).
Sebastian Redl0c986032009-02-09 18:23:29 +00002163 if (TypeTy *ConvType = ParseConversionFunctionId(&EndLoc))
2164 D.setConversionFunction(ConvType, OperatorLoc, EndLoc);
2165 else {
Douglas Gregor853dd392008-12-26 15:00:45 +00002166 D.SetIdentifier(0, Tok.getLocation());
Sebastian Redl0c986032009-02-09 18:23:29 +00002167 }
Douglas Gregor853dd392008-12-26 15:00:45 +00002168 }
2169 goto PastIdentifier;
2170 } else if (Tok.is(tok::tilde)) {
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002171 // This should be a C++ destructor.
2172 SourceLocation TildeLoc = ConsumeToken();
2173 if (Tok.is(tok::identifier)) {
Sebastian Redl0c986032009-02-09 18:23:29 +00002174 // FIXME: Inaccurate.
2175 SourceLocation NameLoc = Tok.getLocation();
Douglas Gregor7bbed2a2009-02-25 23:52:28 +00002176 SourceLocation EndLoc;
Douglas Gregorcb0a7f72009-07-06 16:40:48 +00002177 CXXScopeSpec *SS = afterCXXScope? &D.getCXXScopeSpec() : 0;
2178 TypeResult Type = ParseClassName(EndLoc, SS);
Douglas Gregord7cb0372009-04-01 21:51:26 +00002179 if (Type.isInvalid())
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002180 D.SetIdentifier(0, TildeLoc);
Douglas Gregord7cb0372009-04-01 21:51:26 +00002181 else
2182 D.setDestructor(Type.get(), TildeLoc, NameLoc);
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002183 } else {
2184 Diag(Tok, diag::err_expected_class_name);
2185 D.SetIdentifier(0, TildeLoc);
2186 }
2187 goto PastIdentifier;
2188 }
2189
2190 // If we reached this point, token is not identifier and not '~'.
2191
2192 if (afterCXXScope) {
2193 Diag(Tok, diag::err_expected_unqualified_id);
2194 D.SetIdentifier(0, Tok.getLocation());
2195 D.setInvalidType(true);
2196 goto PastIdentifier;
Douglas Gregor3ef6c972008-11-07 20:08:42 +00002197 }
Douglas Gregore60e5d32008-11-06 22:13:31 +00002198 }
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002199 }
2200
2201 // If we reached this point, we are either in C/ObjC or the token didn't
2202 // satisfy any of the C++-specific checks.
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002203 if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
2204 assert(!getLang().CPlusPlus &&
2205 "There's a C++-specific check for tok::identifier above");
2206 assert(Tok.getIdentifierInfo() && "Not an identifier?");
2207 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
2208 ConsumeToken();
2209 } else if (Tok.is(tok::l_paren)) {
Chris Lattner4b009652007-07-25 00:24:17 +00002210 // direct-declarator: '(' declarator ')'
2211 // direct-declarator: '(' attributes declarator ')'
2212 // Example: 'char (*X)' or 'int (*XX)(void)'
2213 ParseParenDeclarator(D);
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002214 } else if (D.mayOmitIdentifier()) {
Chris Lattner4b009652007-07-25 00:24:17 +00002215 // This could be something simple like "int" (in which case the declarator
2216 // portion is empty), if an abstract-declarator is allowed.
2217 D.SetIdentifier(0, Tok.getLocation());
2218 } else {
Douglas Gregorf03265d2009-03-06 23:28:18 +00002219 if (D.getContext() == Declarator::MemberContext)
2220 Diag(Tok, diag::err_expected_member_name_or_semi)
2221 << D.getDeclSpec().getSourceRange();
2222 else if (getLang().CPlusPlus)
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +00002223 Diag(Tok, diag::err_expected_unqualified_id);
2224 else
Chris Lattnerf006a222008-11-18 07:48:38 +00002225 Diag(Tok, diag::err_expected_ident_lparen);
Chris Lattner4b009652007-07-25 00:24:17 +00002226 D.SetIdentifier(0, Tok.getLocation());
Chris Lattnercd61d592008-11-11 06:13:16 +00002227 D.setInvalidType(true);
Chris Lattner4b009652007-07-25 00:24:17 +00002228 }
2229
Argiris Kirtzidisebdc8ea2008-11-26 22:40:03 +00002230 PastIdentifier:
Chris Lattner4b009652007-07-25 00:24:17 +00002231 assert(D.isPastIdentifier() &&
2232 "Haven't past the location of the identifier yet?");
2233
2234 while (1) {
Chris Lattner34a01ad2007-10-09 17:33:22 +00002235 if (Tok.is(tok::l_paren)) {
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00002236 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
2237 // In such a case, check if we actually have a function declarator; if it
2238 // is not, the declarator has been fully parsed.
Chris Lattner1f185292008-10-20 02:05:46 +00002239 if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
2240 // When not in file scope, warn for ambiguous function declarators, just
2241 // in case the author intended it as a variable definition.
2242 bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
2243 if (!isCXXFunctionDeclarator(warnIfAmbiguous))
2244 break;
2245 }
Chris Lattnera0d056d2008-04-06 05:45:57 +00002246 ParseFunctionDeclarator(ConsumeParen(), D);
Chris Lattner34a01ad2007-10-09 17:33:22 +00002247 } else if (Tok.is(tok::l_square)) {
Chris Lattner4b009652007-07-25 00:24:17 +00002248 ParseBracketDeclarator(D);
2249 } else {
2250 break;
2251 }
2252 }
2253}
2254
Chris Lattnera0d056d2008-04-06 05:45:57 +00002255/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
2256/// only called before the identifier, so these are most likely just grouping
2257/// parens for precedence. If we find that these are actually function
2258/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
2259///
2260/// direct-declarator:
2261/// '(' declarator ')'
2262/// [GNU] '(' attributes declarator ')'
Chris Lattner1f185292008-10-20 02:05:46 +00002263/// direct-declarator '(' parameter-type-list ')'
2264/// direct-declarator '(' identifier-list[opt] ')'
2265/// [GNU] direct-declarator '(' parameter-forward-declarations
2266/// parameter-type-list[opt] ')'
Chris Lattnera0d056d2008-04-06 05:45:57 +00002267///
2268void Parser::ParseParenDeclarator(Declarator &D) {
2269 SourceLocation StartLoc = ConsumeParen();
2270 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
2271
Chris Lattner1f185292008-10-20 02:05:46 +00002272 // Eat any attributes before we look at whether this is a grouping or function
2273 // declarator paren. If this is a grouping paren, the attribute applies to
2274 // the type being built up, for example:
2275 // int (__attribute__(()) *x)(long y)
2276 // If this ends up not being a grouping paren, the attribute applies to the
2277 // first argument, for example:
2278 // int (__attribute__(()) int x)
2279 // In either case, we need to eat any attributes to be able to determine what
2280 // sort of paren this is.
2281 //
2282 AttributeList *AttrList = 0;
2283 bool RequiresArg = false;
2284 if (Tok.is(tok::kw___attribute)) {
2285 AttrList = ParseAttributes();
2286
2287 // We require that the argument list (if this is a non-grouping paren) be
2288 // present even if the attribute list was empty.
2289 RequiresArg = true;
2290 }
Steve Naroffedd04d52008-12-25 14:16:32 +00002291 // Eat any Microsoft extensions.
Eli Friedman891d82f2009-06-08 23:27:34 +00002292 if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
2293 Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___w64) ||
2294 Tok.is(tok::kw___ptr64)) {
2295 AttrList = ParseMicrosoftTypeAttributes(AttrList);
2296 }
Chris Lattner1f185292008-10-20 02:05:46 +00002297
Chris Lattnera0d056d2008-04-06 05:45:57 +00002298 // If we haven't past the identifier yet (or where the identifier would be
2299 // stored, if this is an abstract declarator), then this is probably just
2300 // grouping parens. However, if this could be an abstract-declarator, then
2301 // this could also be the start of function arguments (consider 'void()').
2302 bool isGrouping;
2303
2304 if (!D.mayOmitIdentifier()) {
2305 // If this can't be an abstract-declarator, this *must* be a grouping
2306 // paren, because we haven't seen the identifier yet.
2307 isGrouping = true;
2308 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Argiris Kirtzidis1c64fdc2008-10-06 00:07:55 +00002309 (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
Chris Lattnera0d056d2008-04-06 05:45:57 +00002310 isDeclarationSpecifier()) { // 'int(int)' is a function.
2311 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
2312 // considered to be a type, not a K&R identifier-list.
2313 isGrouping = false;
2314 } else {
2315 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
2316 isGrouping = true;
2317 }
2318
2319 // If this is a grouping paren, handle:
2320 // direct-declarator: '(' declarator ')'
2321 // direct-declarator: '(' attributes declarator ')'
2322 if (isGrouping) {
Argiris Kirtzidis0941ff42008-10-07 10:21:57 +00002323 bool hadGroupingParens = D.hasGroupingParens();
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00002324 D.setGroupingParens(true);
Chris Lattner1f185292008-10-20 02:05:46 +00002325 if (AttrList)
Sebastian Redl0c986032009-02-09 18:23:29 +00002326 D.AddAttributes(AttrList, SourceLocation());
Argiris Kirtzidis9e55d462008-10-06 17:10:33 +00002327
Sebastian Redl19fec9d2008-11-21 19:14:01 +00002328 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattnera0d056d2008-04-06 05:45:57 +00002329 // Match the ')'.
Sebastian Redl0c986032009-02-09 18:23:29 +00002330 SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, StartLoc);
Argiris Kirtzidis0941ff42008-10-07 10:21:57 +00002331
2332 D.setGroupingParens(hadGroupingParens);
Sebastian Redl0c986032009-02-09 18:23:29 +00002333 D.SetRangeEnd(Loc);
Chris Lattnera0d056d2008-04-06 05:45:57 +00002334 return;
2335 }
2336
2337 // Okay, if this wasn't a grouping paren, it must be the start of a function
2338 // argument list. Recognize that this declarator will never have an
Chris Lattner1f185292008-10-20 02:05:46 +00002339 // identifier (and remember where it would have been), then call into
2340 // ParseFunctionDeclarator to handle of argument list.
Chris Lattnera0d056d2008-04-06 05:45:57 +00002341 D.SetIdentifier(0, Tok.getLocation());
2342
Chris Lattner1f185292008-10-20 02:05:46 +00002343 ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
Chris Lattnera0d056d2008-04-06 05:45:57 +00002344}
2345
2346/// ParseFunctionDeclarator - We are after the identifier and have parsed the
2347/// declarator D up to a paren, which indicates that we are parsing function
2348/// arguments.
Chris Lattner4b009652007-07-25 00:24:17 +00002349///
Chris Lattner1f185292008-10-20 02:05:46 +00002350/// If AttrList is non-null, then the caller parsed those arguments immediately
2351/// after the open paren - they should be considered to be the first argument of
2352/// a parameter. If RequiresArg is true, then the first argument of the
2353/// function is required to be present and required to not be an identifier
2354/// list.
2355///
Chris Lattner4b009652007-07-25 00:24:17 +00002356/// This method also handles this portion of the grammar:
2357/// parameter-type-list: [C99 6.7.5]
2358/// parameter-list
2359/// parameter-list ',' '...'
2360///
2361/// parameter-list: [C99 6.7.5]
2362/// parameter-declaration
2363/// parameter-list ',' parameter-declaration
2364///
2365/// parameter-declaration: [C99 6.7.5]
2366/// declaration-specifiers declarator
Chris Lattner3e254fb2008-04-08 04:40:51 +00002367/// [C++] declaration-specifiers declarator '=' assignment-expression
Chris Lattner4b009652007-07-25 00:24:17 +00002368/// [GNU] declaration-specifiers declarator attributes
Sebastian Redla8cecf62009-03-24 22:27:57 +00002369/// declaration-specifiers abstract-declarator[opt]
2370/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner97316c02008-04-10 02:22:51 +00002371/// '=' assignment-expression
Chris Lattner4b009652007-07-25 00:24:17 +00002372/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
2373///
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002374/// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
Sebastian Redla8cecf62009-03-24 22:27:57 +00002375/// and "exception-specification[opt]".
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002376///
Chris Lattner1f185292008-10-20 02:05:46 +00002377void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
2378 AttributeList *AttrList,
2379 bool RequiresArg) {
Chris Lattnera0d056d2008-04-06 05:45:57 +00002380 // lparen is already consumed!
2381 assert(D.isPastIdentifier() && "Should not call before identifier!");
Chris Lattner4b009652007-07-25 00:24:17 +00002382
Chris Lattner1f185292008-10-20 02:05:46 +00002383 // This parameter list may be empty.
Chris Lattner34a01ad2007-10-09 17:33:22 +00002384 if (Tok.is(tok::r_paren)) {
Chris Lattner1f185292008-10-20 02:05:46 +00002385 if (RequiresArg) {
Chris Lattnerf006a222008-11-18 07:48:38 +00002386 Diag(Tok, diag::err_argument_required_after_attribute);
Chris Lattner1f185292008-10-20 02:05:46 +00002387 delete AttrList;
2388 }
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002389
Sebastian Redl0c986032009-02-09 18:23:29 +00002390 SourceLocation Loc = ConsumeParen(); // Eat the closing ')'.
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002391
2392 // cv-qualifier-seq[opt].
2393 DeclSpec DS;
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002394 bool hasExceptionSpec = false;
Sebastian Redl9fbe9bf2009-05-31 11:47:27 +00002395 SourceLocation ThrowLoc;
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002396 bool hasAnyExceptionSpec = false;
Sebastian Redlaaacda92009-05-29 18:02:33 +00002397 llvm::SmallVector<TypeTy*, 2> Exceptions;
2398 llvm::SmallVector<SourceRange, 2> ExceptionRanges;
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002399 if (getLang().CPlusPlus) {
Chris Lattner460696f2008-12-18 07:02:59 +00002400 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Sebastian Redl0c986032009-02-09 18:23:29 +00002401 if (!DS.getSourceRange().getEnd().isInvalid())
2402 Loc = DS.getSourceRange().getEnd();
Douglas Gregor90a2c972008-11-25 03:22:00 +00002403
2404 // Parse exception-specification[opt].
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002405 if (Tok.is(tok::kw_throw)) {
2406 hasExceptionSpec = true;
Sebastian Redl9fbe9bf2009-05-31 11:47:27 +00002407 ThrowLoc = Tok.getLocation();
Sebastian Redlaaacda92009-05-29 18:02:33 +00002408 ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges,
2409 hasAnyExceptionSpec);
2410 assert(Exceptions.size() == ExceptionRanges.size() &&
2411 "Produced different number of exception types and ranges.");
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002412 }
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002413 }
2414
Chris Lattner9f7564b2008-04-06 06:57:35 +00002415 // Remember that we parsed a function type, and remember the attributes.
Chris Lattner4b009652007-07-25 00:24:17 +00002416 // int() -> no prototype, no '...'.
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002417 D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
Chris Lattner9f7564b2008-04-06 06:57:35 +00002418 /*variadic*/ false,
Douglas Gregor88a25f82009-02-18 07:07:28 +00002419 SourceLocation(),
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002420 /*arglist*/ 0, 0,
2421 DS.getTypeQualifiers(),
Sebastian Redl9fbe9bf2009-05-31 11:47:27 +00002422 hasExceptionSpec, ThrowLoc,
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002423 hasAnyExceptionSpec,
Sebastian Redlaaacda92009-05-29 18:02:33 +00002424 Exceptions.data(),
2425 ExceptionRanges.data(),
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002426 Exceptions.size(),
Sebastian Redl0c986032009-02-09 18:23:29 +00002427 LParenLoc, D),
2428 Loc);
Chris Lattner9f7564b2008-04-06 06:57:35 +00002429 return;
Sebastian Redlaaacda92009-05-29 18:02:33 +00002430 }
2431
Chris Lattner1f185292008-10-20 02:05:46 +00002432 // Alternatively, this parameter list may be an identifier list form for a
2433 // K&R-style function: void foo(a,b,c)
Steve Naroff3f3f3b42009-01-28 19:16:40 +00002434 if (!getLang().CPlusPlus && Tok.is(tok::identifier)) {
Steve Naroff965f5d72009-01-30 14:23:32 +00002435 if (!TryAnnotateTypeOrScopeToken()) {
Chris Lattner1f185292008-10-20 02:05:46 +00002436 // K&R identifier lists can't have typedefs as identifiers, per
2437 // C99 6.7.5.3p11.
Steve Naroff3f3f3b42009-01-28 19:16:40 +00002438 if (RequiresArg) {
2439 Diag(Tok, diag::err_argument_required_after_attribute);
2440 delete AttrList;
2441 }
Steve Naroff3f3f3b42009-01-28 19:16:40 +00002442 // Identifier list. Note that '(' identifier-list ')' is only allowed for
2443 // normal declarators, not for abstract-declarators.
2444 return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
Chris Lattner1f185292008-10-20 02:05:46 +00002445 }
Chris Lattner9f7564b2008-04-06 06:57:35 +00002446 }
2447
2448 // Finally, a normal, non-empty parameter type list.
2449
2450 // Build up an array of information about the parsed arguments.
2451 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Chris Lattner3e254fb2008-04-08 04:40:51 +00002452
2453 // Enter function-declaration scope, limiting any declarators to the
2454 // function prototype scope, including parameter declarators.
Chris Lattnerc24b8892009-03-05 00:00:31 +00002455 ParseScope PrototypeScope(this,
2456 Scope::FunctionPrototypeScope|Scope::DeclScope);
Chris Lattner9f7564b2008-04-06 06:57:35 +00002457
2458 bool IsVariadic = false;
Douglas Gregor88a25f82009-02-18 07:07:28 +00002459 SourceLocation EllipsisLoc;
Chris Lattner9f7564b2008-04-06 06:57:35 +00002460 while (1) {
2461 if (Tok.is(tok::ellipsis)) {
2462 IsVariadic = true;
Douglas Gregor88a25f82009-02-18 07:07:28 +00002463 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattner9f7564b2008-04-06 06:57:35 +00002464 break;
Chris Lattner4b009652007-07-25 00:24:17 +00002465 }
2466
Chris Lattner9f7564b2008-04-06 06:57:35 +00002467 SourceLocation DSStart = Tok.getLocation();
Chris Lattner4b009652007-07-25 00:24:17 +00002468
Chris Lattner9f7564b2008-04-06 06:57:35 +00002469 // Parse the declaration-specifiers.
2470 DeclSpec DS;
Chris Lattner1f185292008-10-20 02:05:46 +00002471
2472 // If the caller parsed attributes for the first argument, add them now.
2473 if (AttrList) {
2474 DS.AddAttributes(AttrList);
2475 AttrList = 0; // Only apply the attributes to the first parameter.
2476 }
Chris Lattner9e785f52009-02-27 18:38:20 +00002477 ParseDeclarationSpecifiers(DS);
2478
Chris Lattner9f7564b2008-04-06 06:57:35 +00002479 // Parse the declarator. This is "PrototypeContext", because we must
2480 // accept either 'declarator' or 'abstract-declarator' here.
2481 Declarator ParmDecl(DS, Declarator::PrototypeContext);
2482 ParseDeclarator(ParmDecl);
2483
2484 // Parse GNU attributes, if present.
Sebastian Redl0c986032009-02-09 18:23:29 +00002485 if (Tok.is(tok::kw___attribute)) {
2486 SourceLocation Loc;
2487 AttributeList *AttrList = ParseAttributes(&Loc);
2488 ParmDecl.AddAttributes(AttrList, Loc);
2489 }
Chris Lattner9f7564b2008-04-06 06:57:35 +00002490
Chris Lattner9f7564b2008-04-06 06:57:35 +00002491 // Remember this parsed parameter in ParamInfo.
2492 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
2493
Douglas Gregor605de8d2008-12-16 21:30:33 +00002494 // DefArgToks is used when the parsing of default arguments needs
2495 // to be delayed.
2496 CachedTokens *DefArgToks = 0;
2497
Chris Lattner9f7564b2008-04-06 06:57:35 +00002498 // If no parameter was specified, verify that *something* was specified,
2499 // otherwise we have a missing type and identifier.
Chris Lattner9e785f52009-02-27 18:38:20 +00002500 if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
2501 ParmDecl.getNumTypeObjects() == 0) {
Chris Lattner9f7564b2008-04-06 06:57:35 +00002502 // Completely missing, emit error.
2503 Diag(DSStart, diag::err_missing_param);
2504 } else {
2505 // Otherwise, we have something. Add it and let semantic analysis try
2506 // to grok it and add the result to the ParamInfo we are building.
2507
2508 // Inform the actions module about the parameter declarator, so it gets
2509 // added to the current scope.
Chris Lattner5261d0c2009-03-28 19:18:32 +00002510 DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
Chris Lattner3e254fb2008-04-08 04:40:51 +00002511
2512 // Parse the default argument, if any. We parse the default
2513 // arguments in all dialects; the semantic analysis in
2514 // ActOnParamDefaultArgument will reject the default argument in
2515 // C.
2516 if (Tok.is(tok::equal)) {
Douglas Gregor62ae25a2008-12-24 00:01:03 +00002517 SourceLocation EqualLoc = Tok.getLocation();
2518
Chris Lattner3e254fb2008-04-08 04:40:51 +00002519 // Parse the default argument
Douglas Gregor605de8d2008-12-16 21:30:33 +00002520 if (D.getContext() == Declarator::MemberContext) {
2521 // If we're inside a class definition, cache the tokens
2522 // corresponding to the default argument. We'll actually parse
2523 // them when we see the end of the class definition.
2524 // FIXME: Templates will require something similar.
2525 // FIXME: Can we use a smart pointer for Toks?
2526 DefArgToks = new CachedTokens;
2527
2528 if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
2529 tok::semi, false)) {
2530 delete DefArgToks;
2531 DefArgToks = 0;
Douglas Gregor62ae25a2008-12-24 00:01:03 +00002532 Actions.ActOnParamDefaultArgumentError(Param);
2533 } else
Anders Carlssona116e6e2009-06-12 16:51:40 +00002534 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
2535 (*DefArgToks)[1].getLocation());
Chris Lattner3e254fb2008-04-08 04:40:51 +00002536 } else {
Douglas Gregor605de8d2008-12-16 21:30:33 +00002537 // Consume the '='.
Douglas Gregor62ae25a2008-12-24 00:01:03 +00002538 ConsumeToken();
Douglas Gregor605de8d2008-12-16 21:30:33 +00002539
2540 OwningExprResult DefArgResult(ParseAssignmentExpression());
2541 if (DefArgResult.isInvalid()) {
2542 Actions.ActOnParamDefaultArgumentError(Param);
2543 SkipUntil(tok::comma, tok::r_paren, true, true);
2544 } else {
2545 // Inform the actions module about the default argument
2546 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
Sebastian Redl76bb8ec2009-03-15 17:47:39 +00002547 move(DefArgResult));
Douglas Gregor605de8d2008-12-16 21:30:33 +00002548 }
Chris Lattner3e254fb2008-04-08 04:40:51 +00002549 }
2550 }
Chris Lattner9f7564b2008-04-06 06:57:35 +00002551
2552 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Douglas Gregor605de8d2008-12-16 21:30:33 +00002553 ParmDecl.getIdentifierLoc(), Param,
2554 DefArgToks));
Chris Lattner9f7564b2008-04-06 06:57:35 +00002555 }
2556
2557 // If the next token is a comma, consume it and keep reading arguments.
2558 if (Tok.isNot(tok::comma)) break;
2559
2560 // Consume the comma.
2561 ConsumeToken();
Chris Lattner4b009652007-07-25 00:24:17 +00002562 }
2563
Chris Lattner9f7564b2008-04-06 06:57:35 +00002564 // Leave prototype scope.
Douglas Gregor95d40792008-12-10 06:34:36 +00002565 PrototypeScope.Exit();
Chris Lattner9f7564b2008-04-06 06:57:35 +00002566
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002567 // If we have the closing ')', eat it.
Sebastian Redl0c986032009-02-09 18:23:29 +00002568 SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002569
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002570 DeclSpec DS;
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002571 bool hasExceptionSpec = false;
Sebastian Redl9fbe9bf2009-05-31 11:47:27 +00002572 SourceLocation ThrowLoc;
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002573 bool hasAnyExceptionSpec = false;
Sebastian Redlaaacda92009-05-29 18:02:33 +00002574 llvm::SmallVector<TypeTy*, 2> Exceptions;
2575 llvm::SmallVector<SourceRange, 2> ExceptionRanges;
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002576 if (getLang().CPlusPlus) {
Douglas Gregor90a2c972008-11-25 03:22:00 +00002577 // Parse cv-qualifier-seq[opt].
Chris Lattner460696f2008-12-18 07:02:59 +00002578 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Sebastian Redl0c986032009-02-09 18:23:29 +00002579 if (!DS.getSourceRange().getEnd().isInvalid())
2580 Loc = DS.getSourceRange().getEnd();
Douglas Gregor90a2c972008-11-25 03:22:00 +00002581
2582 // Parse exception-specification[opt].
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002583 if (Tok.is(tok::kw_throw)) {
2584 hasExceptionSpec = true;
Sebastian Redl9fbe9bf2009-05-31 11:47:27 +00002585 ThrowLoc = Tok.getLocation();
Sebastian Redlaaacda92009-05-29 18:02:33 +00002586 ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges,
2587 hasAnyExceptionSpec);
2588 assert(Exceptions.size() == ExceptionRanges.size() &&
2589 "Produced different number of exception types and ranges.");
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002590 }
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002591 }
2592
Chris Lattner4b009652007-07-25 00:24:17 +00002593 // Remember that we parsed a function type, and remember the attributes.
Chris Lattner9f7564b2008-04-06 06:57:35 +00002594 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
Douglas Gregor88a25f82009-02-18 07:07:28 +00002595 EllipsisLoc,
Jay Foad9e6bef42009-05-21 09:52:38 +00002596 ParamInfo.data(), ParamInfo.size(),
Argiris Kirtzidis4b269b42008-10-24 21:46:40 +00002597 DS.getTypeQualifiers(),
Sebastian Redl9fbe9bf2009-05-31 11:47:27 +00002598 hasExceptionSpec, ThrowLoc,
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002599 hasAnyExceptionSpec,
Sebastian Redlaaacda92009-05-29 18:02:33 +00002600 Exceptions.data(),
2601 ExceptionRanges.data(),
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002602 Exceptions.size(), LParenLoc, D),
Sebastian Redl0c986032009-02-09 18:23:29 +00002603 Loc);
Chris Lattner4b009652007-07-25 00:24:17 +00002604}
2605
Chris Lattner35d9c912008-04-06 06:34:08 +00002606/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
2607/// we found a K&R-style identifier list instead of a type argument list. The
2608/// current token is known to be the first identifier in the list.
2609///
2610/// identifier-list: [C99 6.7.5]
2611/// identifier
2612/// identifier-list ',' identifier
2613///
2614void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
2615 Declarator &D) {
2616 // Build up an array of information about the parsed arguments.
2617 llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
2618 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
2619
2620 // If there was no identifier specified for the declarator, either we are in
2621 // an abstract-declarator, or we are in a parameter declarator which was found
2622 // to be abstract. In abstract-declarators, identifier lists are not valid:
2623 // diagnose this.
2624 if (!D.getIdentifier())
2625 Diag(Tok, diag::ext_ident_list_in_param);
2626
2627 // Tok is known to be the first identifier in the list. Remember this
2628 // identifier in ParamInfo.
Chris Lattnerc337fa22008-04-06 06:50:56 +00002629 ParamsSoFar.insert(Tok.getIdentifierInfo());
Chris Lattner35d9c912008-04-06 06:34:08 +00002630 ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
Chris Lattner5261d0c2009-03-28 19:18:32 +00002631 Tok.getLocation(),
2632 DeclPtrTy()));
Chris Lattner35d9c912008-04-06 06:34:08 +00002633
Chris Lattner113a56b2008-04-06 06:39:19 +00002634 ConsumeToken(); // eat the first identifier.
Chris Lattner35d9c912008-04-06 06:34:08 +00002635
2636 while (Tok.is(tok::comma)) {
2637 // Eat the comma.
2638 ConsumeToken();
2639
Chris Lattner113a56b2008-04-06 06:39:19 +00002640 // If this isn't an identifier, report the error and skip until ')'.
Chris Lattner35d9c912008-04-06 06:34:08 +00002641 if (Tok.isNot(tok::identifier)) {
2642 Diag(Tok, diag::err_expected_ident);
Chris Lattner113a56b2008-04-06 06:39:19 +00002643 SkipUntil(tok::r_paren);
2644 return;
Chris Lattner35d9c912008-04-06 06:34:08 +00002645 }
Chris Lattneracb67d92008-04-06 06:47:48 +00002646
Chris Lattner35d9c912008-04-06 06:34:08 +00002647 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
Chris Lattneracb67d92008-04-06 06:47:48 +00002648
2649 // Reject 'typedef int y; int test(x, y)', but continue parsing.
Douglas Gregor1075a162009-02-04 17:00:24 +00002650 if (Actions.getTypeName(*ParmII, Tok.getLocation(), CurScope))
Chris Lattner8f7db152008-11-19 07:37:42 +00002651 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
Chris Lattner35d9c912008-04-06 06:34:08 +00002652
2653 // Verify that the argument identifier has not already been mentioned.
2654 if (!ParamsSoFar.insert(ParmII)) {
Chris Lattner8f7db152008-11-19 07:37:42 +00002655 Diag(Tok, diag::err_param_redefinition) << ParmII;
Chris Lattner113a56b2008-04-06 06:39:19 +00002656 } else {
2657 // Remember this identifier in ParamInfo.
Chris Lattner35d9c912008-04-06 06:34:08 +00002658 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Chris Lattner5261d0c2009-03-28 19:18:32 +00002659 Tok.getLocation(),
2660 DeclPtrTy()));
Chris Lattner113a56b2008-04-06 06:39:19 +00002661 }
Chris Lattner35d9c912008-04-06 06:34:08 +00002662
2663 // Eat the identifier.
2664 ConsumeToken();
2665 }
Sebastian Redl0c986032009-02-09 18:23:29 +00002666
2667 // If we have the closing ')', eat it and we're done.
2668 SourceLocation RLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2669
Chris Lattner113a56b2008-04-06 06:39:19 +00002670 // Remember that we parsed a function type, and remember the attributes. This
2671 // function type is always a K&R style function type, which is not varargs and
2672 // has no prototype.
2673 D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
Douglas Gregor88a25f82009-02-18 07:07:28 +00002674 SourceLocation(),
Chris Lattner113a56b2008-04-06 06:39:19 +00002675 &ParamInfo[0], ParamInfo.size(),
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002676 /*TypeQuals*/0,
Sebastian Redl9fbe9bf2009-05-31 11:47:27 +00002677 /*exception*/false,
2678 SourceLocation(), false, 0, 0, 0,
Sebastian Redl35f3a5b2009-04-29 17:30:04 +00002679 LParenLoc, D),
Sebastian Redl0c986032009-02-09 18:23:29 +00002680 RLoc);
Chris Lattner35d9c912008-04-06 06:34:08 +00002681}
Chris Lattnera0d056d2008-04-06 05:45:57 +00002682
Chris Lattner4b009652007-07-25 00:24:17 +00002683/// [C90] direct-declarator '[' constant-expression[opt] ']'
2684/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
2685/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
2686/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
2687/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
2688void Parser::ParseBracketDeclarator(Declarator &D) {
2689 SourceLocation StartLoc = ConsumeBracket();
2690
Chris Lattner1525c3a2008-12-18 07:27:21 +00002691 // C array syntax has many features, but by-far the most common is [] and [4].
2692 // This code does a fast path to handle some of the most obvious cases.
2693 if (Tok.getKind() == tok::r_square) {
Sebastian Redl0c986032009-02-09 18:23:29 +00002694 SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
Chris Lattner1525c3a2008-12-18 07:27:21 +00002695 // Remember that we parsed the empty array type.
2696 OwningExprResult NumElements(Actions);
Douglas Gregor1d381132009-07-06 15:59:29 +00002697 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
2698 StartLoc, EndLoc),
Sebastian Redl0c986032009-02-09 18:23:29 +00002699 EndLoc);
Chris Lattner1525c3a2008-12-18 07:27:21 +00002700 return;
2701 } else if (Tok.getKind() == tok::numeric_constant &&
2702 GetLookAheadToken(1).is(tok::r_square)) {
2703 // [4] is very common. Parse the numeric constant expression.
Sebastian Redlcd883f72009-01-18 18:53:16 +00002704 OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
Chris Lattner1525c3a2008-12-18 07:27:21 +00002705 ConsumeToken();
2706
Sebastian Redl0c986032009-02-09 18:23:29 +00002707 SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
Chris Lattner1525c3a2008-12-18 07:27:21 +00002708
2709 // If there was an error parsing the assignment-expression, recover.
2710 if (ExprRes.isInvalid())
2711 ExprRes.release(); // Deallocate expr, just use [].
2712
2713 // Remember that we parsed a array type, and remember its features.
Douglas Gregor1d381132009-07-06 15:59:29 +00002714 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, ExprRes.release(),
2715 StartLoc, EndLoc),
Sebastian Redl0c986032009-02-09 18:23:29 +00002716 EndLoc);
Chris Lattner1525c3a2008-12-18 07:27:21 +00002717 return;
2718 }
2719
Chris Lattner4b009652007-07-25 00:24:17 +00002720 // If valid, this location is the position where we read the 'static' keyword.
2721 SourceLocation StaticLoc;
Chris Lattner34a01ad2007-10-09 17:33:22 +00002722 if (Tok.is(tok::kw_static))
Chris Lattner4b009652007-07-25 00:24:17 +00002723 StaticLoc = ConsumeToken();
2724
2725 // If there is a type-qualifier-list, read it now.
Chris Lattner306d4df2008-12-18 06:50:14 +00002726 // Type qualifiers in an array subscript are a C99 feature.
Chris Lattner4b009652007-07-25 00:24:17 +00002727 DeclSpec DS;
Chris Lattner460696f2008-12-18 07:02:59 +00002728 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Chris Lattner4b009652007-07-25 00:24:17 +00002729
2730 // If we haven't already read 'static', check to see if there is one after the
2731 // type-qualifier-list.
Chris Lattner34a01ad2007-10-09 17:33:22 +00002732 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Chris Lattner4b009652007-07-25 00:24:17 +00002733 StaticLoc = ConsumeToken();
2734
2735 // Handle "direct-declarator [ type-qual-list[opt] * ]".
2736 bool isStar = false;
Sebastian Redl62261042008-12-09 20:22:58 +00002737 OwningExprResult NumElements(Actions);
Chris Lattner44f6d9d2008-04-06 05:26:30 +00002738
2739 // Handle the case where we have '[*]' as the array size. However, a leading
2740 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
2741 // the the token after the star is a ']'. Since stars in arrays are
2742 // infrequent, use of lookahead is not costly here.
2743 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattner1bb39512008-04-06 05:27:21 +00002744 ConsumeToken(); // Eat the '*'.
Chris Lattner4b009652007-07-25 00:24:17 +00002745
Chris Lattner306d4df2008-12-18 06:50:14 +00002746 if (StaticLoc.isValid()) {
Chris Lattner44f6d9d2008-04-06 05:26:30 +00002747 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattner306d4df2008-12-18 06:50:14 +00002748 StaticLoc = SourceLocation(); // Drop the static.
2749 }
Chris Lattner44f6d9d2008-04-06 05:26:30 +00002750 isStar = true;
Chris Lattner34a01ad2007-10-09 17:33:22 +00002751 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner1525c3a2008-12-18 07:27:21 +00002752 // Note, in C89, this production uses the constant-expr production instead
2753 // of assignment-expr. The only difference is that assignment-expr allows
2754 // things like '=' and '*='. Sema rejects these in C89 mode because they
2755 // are not i-c-e's, so we don't need to distinguish between the two here.
2756
Douglas Gregor98189262009-06-19 23:52:42 +00002757 // Parse the constant-expression or assignment-expression now (depending
2758 // on dialect).
2759 if (getLang().CPlusPlus)
2760 NumElements = ParseConstantExpression();
2761 else
2762 NumElements = ParseAssignmentExpression();
Chris Lattner4b009652007-07-25 00:24:17 +00002763 }
2764
2765 // If there was an error parsing the assignment-expression, recover.
Sebastian Redlbb4dae72008-12-09 13:15:23 +00002766 if (NumElements.isInvalid()) {
Chris Lattnerf3ce8572009-04-24 22:30:50 +00002767 D.setInvalidType(true);
Chris Lattner4b009652007-07-25 00:24:17 +00002768 // If the expression was invalid, skip it.
2769 SkipUntil(tok::r_square);
2770 return;
2771 }
Sebastian Redl0c986032009-02-09 18:23:29 +00002772
2773 SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
2774
Chris Lattner1525c3a2008-12-18 07:27:21 +00002775 // Remember that we parsed a array type, and remember its features.
Chris Lattner4b009652007-07-25 00:24:17 +00002776 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
2777 StaticLoc.isValid(), isStar,
Douglas Gregor1d381132009-07-06 15:59:29 +00002778 NumElements.release(),
2779 StartLoc, EndLoc),
Sebastian Redl0c986032009-02-09 18:23:29 +00002780 EndLoc);
Chris Lattner4b009652007-07-25 00:24:17 +00002781}
2782
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00002783/// [GNU] typeof-specifier:
2784/// typeof ( expressions )
2785/// typeof ( type-name )
2786/// [GNU/C++] typeof unary-expression
Steve Naroff7cbb1462007-07-31 12:34:36 +00002787///
2788void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner34a01ad2007-10-09 17:33:22 +00002789 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Argiris Kirtzidis4c90fb22009-05-22 10:22:50 +00002790 Token OpTok = Tok;
Steve Naroff7cbb1462007-07-31 12:34:36 +00002791 SourceLocation StartLoc = ConsumeToken();
2792
Argiris Kirtzidis4c90fb22009-05-22 10:22:50 +00002793 bool isCastExpr;
2794 TypeTy *CastTy;
2795 SourceRange CastRange;
2796 OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
2797 isCastExpr,
2798 CastTy,
2799 CastRange);
2800
2801 if (CastRange.getEnd().isInvalid())
Argiris Kirtzidis53f05482009-05-22 10:22:18 +00002802 // FIXME: Not accurate, the range gets one token more than it should.
2803 DS.SetRangeEnd(Tok.getLocation());
Argiris Kirtzidis4c90fb22009-05-22 10:22:50 +00002804 else
2805 DS.SetRangeEnd(CastRange.getEnd());
2806
2807 if (isCastExpr) {
2808 if (!CastTy) {
2809 DS.SetTypeSpecError();
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00002810 return;
Douglas Gregor6c0f4062009-02-18 17:45:20 +00002811 }
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00002812
Argiris Kirtzidis4c90fb22009-05-22 10:22:50 +00002813 const char *PrevSpec = 0;
2814 // Check for duplicate type specifiers (e.g. "int typeof(int)").
2815 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
2816 CastTy))
2817 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
2818 return;
Argiris Kirtzidis53f05482009-05-22 10:22:18 +00002819 }
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00002820
Argiris Kirtzidis53f05482009-05-22 10:22:18 +00002821 // If we get here, the operand to the typeof was an expresion.
2822 if (Operand.isInvalid()) {
2823 DS.SetTypeSpecError();
Steve Naroff14bbce82007-08-02 02:53:48 +00002824 return;
Steve Naroff7cbb1462007-07-31 12:34:36 +00002825 }
Argiris Kirtzidisc2a384d2008-09-05 11:26:19 +00002826
Argiris Kirtzidis53f05482009-05-22 10:22:18 +00002827 const char *PrevSpec = 0;
2828 // Check for duplicate type specifiers (e.g. "int typeof(int)").
2829 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
2830 Operand.release()))
2831 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Steve Naroff7cbb1462007-07-31 12:34:36 +00002832}