blob: a50f42bf8ba63511d24d9255c600f1de5a2bafa4 [file] [log] [blame]
Chris Lattner7ad0fbe2006-11-05 07:46:30 +00001//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-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 Lattnerc0acd3d2006-07-31 05:13:43 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
Chris Lattner60f36222009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Peter Collingbourne599cb8e2011-03-18 22:38:29 +000016#include "clang/Basic/OpenCL.h"
Kaelyn Uhrain031643e2012-04-26 23:36:17 +000017#include "clang/Sema/Lookup.h"
John McCall8b0666c2010-08-20 18:27:03 +000018#include "clang/Sema/Scope.h"
19#include "clang/Sema/ParsedTemplate.h"
John McCallfaf5fb42010-08-26 23:41:50 +000020#include "clang/Sema/PrettyDeclStackTrace.h"
Chris Lattner8a9a97a2009-12-10 00:21:05 +000021#include "RAIIObjectsForParser.h"
Chris Lattnerad9ac942007-01-23 01:14:52 +000022#include "llvm/ADT/SmallSet.h"
Benjamin Kramer49038022012-02-04 13:45:25 +000023#include "llvm/ADT/SmallString.h"
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +000024#include "llvm/ADT/StringSwitch.h"
Chris Lattnerc0acd3d2006-07-31 05:13:43 +000025using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// C99 6.7: Declarations.
29//===----------------------------------------------------------------------===//
30
Chris Lattnerf5fbd792006-08-10 23:56:11 +000031/// ParseTypeName
32/// type-name: [C99 6.7.6]
33/// specifier-qualifier-list abstract-declarator[opt]
Sebastian Redlbd150f42008-11-21 19:14:01 +000034///
35/// Called type-id in C++.
Douglas Gregor205d5e32011-01-31 16:09:46 +000036TypeResult Parser::ParseTypeName(SourceRange *Range,
John McCall31168b02011-06-15 23:02:42 +000037 Declarator::TheContext Context,
Richard Smithcd1c0552011-07-01 19:46:12 +000038 AccessSpecifier AS,
39 Decl **OwnedType) {
Richard Smith62dad822012-03-15 01:02:11 +000040 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
Richard Smith2f07ad52012-05-09 20:55:26 +000041 if (DSC == DSC_normal)
42 DSC = DSC_type_specifier;
Richard Smithbfdb1082012-03-12 08:56:40 +000043
Chris Lattnerf5fbd792006-08-10 23:56:11 +000044 // Parse the common declaration-specifiers piece.
John McCall084e83d2011-03-24 11:26:52 +000045 DeclSpec DS(AttrFactory);
Richard Smithbfdb1082012-03-12 08:56:40 +000046 ParseSpecifierQualifierList(DS, AS, DSC);
Richard Smithcd1c0552011-07-01 19:46:12 +000047 if (OwnedType)
48 *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
Sebastian Redld6434562009-05-29 18:02:33 +000049
Chris Lattnerf5fbd792006-08-10 23:56:11 +000050 // Parse the abstract-declarator, if present.
Douglas Gregor205d5e32011-01-31 16:09:46 +000051 Declarator DeclaratorInfo(DS, Context);
Chris Lattnerf5fbd792006-08-10 23:56:11 +000052 ParseDeclarator(DeclaratorInfo);
Sebastian Redld6434562009-05-29 18:02:33 +000053 if (Range)
54 *Range = DeclaratorInfo.getSourceRange();
55
Chris Lattnerf6d1c9c2009-04-25 08:06:05 +000056 if (DeclaratorInfo.isInvalidType())
Douglas Gregor220cac52009-02-18 17:45:20 +000057 return true;
58
Douglas Gregor0be31a22010-07-02 17:43:08 +000059 return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
Chris Lattnerf5fbd792006-08-10 23:56:11 +000060}
61
Caitlin Sadowski9385dd72011-09-08 17:42:22 +000062
63/// isAttributeLateParsed - Return true if the attribute has arguments that
64/// require late parsing.
65static bool isAttributeLateParsed(const IdentifierInfo &II) {
66 return llvm::StringSwitch<bool>(II.getName())
67#include "clang/Parse/AttrLateParsed.inc"
68 .Default(false);
69}
70
71
Alexis Hunt96d5c762009-11-21 08:43:09 +000072/// ParseGNUAttributes - Parse a non-empty attributes list.
Chris Lattnerb8cd5c22006-08-15 04:10:46 +000073///
74/// [GNU] attributes:
75/// attribute
76/// attributes attribute
77///
78/// [GNU] attribute:
79/// '__attribute__' '(' '(' attribute-list ')' ')'
80///
81/// [GNU] attribute-list:
82/// attrib
83/// attribute_list ',' attrib
84///
85/// [GNU] attrib:
86/// empty
Steve Naroff0f2fe172007-06-01 17:11:19 +000087/// attrib-name
88/// attrib-name '(' identifier ')'
89/// attrib-name '(' identifier ',' nonempty-expr-list ')'
90/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
Chris Lattnerb8cd5c22006-08-15 04:10:46 +000091///
Steve Naroff0f2fe172007-06-01 17:11:19 +000092/// [GNU] attrib-name:
93/// identifier
94/// typespec
95/// typequal
96/// storageclass
Mike Stump11289f42009-09-09 15:08:12 +000097///
Steve Naroff0f2fe172007-06-01 17:11:19 +000098/// FIXME: The GCC grammar/code for this construct implies we need two
Mike Stump11289f42009-09-09 15:08:12 +000099/// token lookahead. Comment from gcc: "If they start with an identifier
100/// which is followed by a comma or close parenthesis, then the arguments
Steve Naroff0f2fe172007-06-01 17:11:19 +0000101/// start with that identifier; otherwise they are an expression list."
102///
Richard Smithb12bf692011-10-17 21:20:17 +0000103/// GCC does not require the ',' between attribs in an attribute-list.
104///
Steve Naroff0f2fe172007-06-01 17:11:19 +0000105/// At the moment, I am not doing 2 token lookahead. I am also unaware of
106/// any attributes that don't work (based on my limited testing). Most
107/// attributes are very simple in practice. Until we find a bug, I don't see
108/// a pressing need to implement the 2 token lookahead.
Chris Lattnerb8cd5c22006-08-15 04:10:46 +0000109
John McCall53fa7142010-12-24 02:08:15 +0000110void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000111 SourceLocation *endLoc,
112 LateParsedAttrList *LateAttrs) {
Alexis Hunt96d5c762009-11-21 08:43:09 +0000113 assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
Mike Stump11289f42009-09-09 15:08:12 +0000114
Chris Lattner76c72282007-10-09 17:33:22 +0000115 while (Tok.is(tok::kw___attribute)) {
Steve Naroff0f2fe172007-06-01 17:11:19 +0000116 ConsumeToken();
117 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
118 "attribute")) {
119 SkipUntil(tok::r_paren, true); // skip until ) or ;
John McCall53fa7142010-12-24 02:08:15 +0000120 return;
Steve Naroff0f2fe172007-06-01 17:11:19 +0000121 }
122 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
123 SkipUntil(tok::r_paren, true); // skip until ) or ;
John McCall53fa7142010-12-24 02:08:15 +0000124 return;
Steve Naroff0f2fe172007-06-01 17:11:19 +0000125 }
126 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner76c72282007-10-09 17:33:22 +0000127 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
128 Tok.is(tok::comma)) {
Mike Stump11289f42009-09-09 15:08:12 +0000129 if (Tok.is(tok::comma)) {
Steve Naroff0f2fe172007-06-01 17:11:19 +0000130 // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
131 ConsumeToken();
132 continue;
133 }
134 // we have an identifier or declaration specifier (const, int, etc.)
135 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
136 SourceLocation AttrNameLoc = ConsumeToken();
Mike Stump11289f42009-09-09 15:08:12 +0000137
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000138 if (Tok.is(tok::l_paren)) {
139 // handle "parameterized" attributes
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000140 if (LateAttrs && isAttributeLateParsed(*AttrName)) {
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000141 LateParsedAttribute *LA =
142 new LateParsedAttribute(this, *AttrName, AttrNameLoc);
143 LateAttrs->push_back(LA);
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000144
145 // Attributes in a class are parsed at the end of the class, along
146 // with other late-parsed declarations.
147 if (!ClassStack.empty())
148 getCurrentClass().LateParsedDeclarations.push_back(LA);
Mike Stump11289f42009-09-09 15:08:12 +0000149
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000150 // consume everything up to and including the matching right parens
151 ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
Mike Stump11289f42009-09-09 15:08:12 +0000152
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000153 Token Eof;
154 Eof.startToken();
155 Eof.setLocation(Tok.getLocation());
156 LA->Toks.push_back(Eof);
157 } else {
158 ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc);
Steve Naroff0f2fe172007-06-01 17:11:19 +0000159 }
160 } else {
John McCall084e83d2011-03-24 11:26:52 +0000161 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
Alexis Hunta0e54d42012-06-18 16:13:52 +0000162 0, SourceLocation(), 0, 0, AttributeList::AS_GNU);
Steve Naroff0f2fe172007-06-01 17:11:19 +0000163 }
164 }
Steve Naroff98d153c2007-06-06 23:19:11 +0000165 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
Steve Naroff98d153c2007-06-06 23:19:11 +0000166 SkipUntil(tok::r_paren, false);
Alexis Hunt96d5c762009-11-21 08:43:09 +0000167 SourceLocation Loc = Tok.getLocation();
Sebastian Redlf6591ca2009-02-09 18:23:29 +0000168 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
169 SkipUntil(tok::r_paren, false);
170 }
John McCall53fa7142010-12-24 02:08:15 +0000171 if (endLoc)
172 *endLoc = Loc;
Steve Naroff0f2fe172007-06-01 17:11:19 +0000173 }
Steve Naroff0f2fe172007-06-01 17:11:19 +0000174}
Chris Lattnerf5fbd792006-08-10 23:56:11 +0000175
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000176
177/// Parse the arguments to a parameterized GNU attribute
178void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
179 SourceLocation AttrNameLoc,
180 ParsedAttributes &Attrs,
181 SourceLocation *EndLoc) {
182
183 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
184
185 // Availability attributes have their own grammar.
186 if (AttrName->isStr("availability")) {
187 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
188 return;
189 }
190 // Thread safety attributes fit into the FIXME case above, so we
191 // just parse the arguments as a list of expressions
192 if (IsThreadSafetyAttribute(AttrName->getName())) {
193 ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
194 return;
195 }
196
197 ConsumeParen(); // ignore the left paren loc for now
198
Richard Smithb12bf692011-10-17 21:20:17 +0000199 IdentifierInfo *ParmName = 0;
200 SourceLocation ParmLoc;
201 bool BuiltinType = false;
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000202
Richard Smithb12bf692011-10-17 21:20:17 +0000203 switch (Tok.getKind()) {
204 case tok::kw_char:
205 case tok::kw_wchar_t:
206 case tok::kw_char16_t:
207 case tok::kw_char32_t:
208 case tok::kw_bool:
209 case tok::kw_short:
210 case tok::kw_int:
211 case tok::kw_long:
212 case tok::kw___int64:
Richard Smithf016bbc2012-04-04 06:24:32 +0000213 case tok::kw___int128:
Richard Smithb12bf692011-10-17 21:20:17 +0000214 case tok::kw_signed:
215 case tok::kw_unsigned:
216 case tok::kw_float:
217 case tok::kw_double:
218 case tok::kw_void:
219 case tok::kw_typeof:
220 // __attribute__(( vec_type_hint(char) ))
221 // FIXME: Don't just discard the builtin type token.
222 ConsumeToken();
223 BuiltinType = true;
224 break;
225
226 case tok::identifier:
227 ParmName = Tok.getIdentifierInfo();
228 ParmLoc = ConsumeToken();
229 break;
230
231 default:
232 break;
233 }
234
235 ExprVector ArgExprs(Actions);
236
237 if (!BuiltinType &&
238 (ParmLoc.isValid() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) {
239 // Eat the comma.
240 if (ParmLoc.isValid())
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000241 ConsumeToken();
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000242
Richard Smithb12bf692011-10-17 21:20:17 +0000243 // Parse the non-empty comma-separated list of expressions.
244 while (1) {
245 ExprResult ArgExpr(ParseAssignmentExpression());
246 if (ArgExpr.isInvalid()) {
247 SkipUntil(tok::r_paren);
248 return;
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000249 }
Richard Smithb12bf692011-10-17 21:20:17 +0000250 ArgExprs.push_back(ArgExpr.release());
251 if (Tok.isNot(tok::comma))
252 break;
253 ConsumeToken(); // Eat the comma, move to the next argument
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000254 }
Richard Smithb12bf692011-10-17 21:20:17 +0000255 }
Fariborz Jahanian6b708652011-10-18 17:11:10 +0000256 else if (Tok.is(tok::less) && AttrName->isStr("iboutletcollection")) {
257 if (!ExpectAndConsume(tok::less, diag::err_expected_less_after, "<",
258 tok::greater)) {
Fariborz Jahanian7f733022011-10-18 23:13:50 +0000259 while (Tok.is(tok::identifier)) {
260 ConsumeToken();
261 if (Tok.is(tok::greater))
262 break;
263 if (Tok.is(tok::comma)) {
264 ConsumeToken();
265 continue;
266 }
267 }
268 if (Tok.isNot(tok::greater))
269 Diag(Tok, diag::err_iboutletcollection_with_protocol);
Fariborz Jahanian6b708652011-10-18 17:11:10 +0000270 SkipUntil(tok::r_paren, false, true); // skip until ')'
271 }
272 }
Richard Smithb12bf692011-10-17 21:20:17 +0000273
274 SourceLocation RParen = Tok.getLocation();
275 if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
276 AttributeList *attr =
Argyrios Kyrtzidis635a9b42011-09-13 16:05:53 +0000277 Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0, AttrNameLoc,
Alexis Hunta0e54d42012-06-18 16:13:52 +0000278 ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size(),
279 AttributeList::AS_GNU);
Alexis Hunt3bc72c12012-06-19 23:57:03 +0000280 if (BuiltinType && attr->getKind() == AttributeList::AT_IBOutletCollection)
Richard Smithb12bf692011-10-17 21:20:17 +0000281 Diag(Tok, diag::err_iboutletcollection_builtintype);
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000282 }
283}
284
Chad Rosierc1183952012-06-26 22:30:43 +0000285/// \brief Parses a single argument for a declspec, including the
Aaron Ballman478faed2012-06-19 22:09:27 +0000286/// surrounding parens.
Chad Rosierc1183952012-06-26 22:30:43 +0000287void Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
Aaron Ballman478faed2012-06-19 22:09:27 +0000288 SourceLocation AttrNameLoc,
289 ParsedAttributes &Attrs)
290{
291 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosierc1183952012-06-26 22:30:43 +0000292 if (T.expectAndConsume(diag::err_expected_lparen_after,
Aaron Ballman478faed2012-06-19 22:09:27 +0000293 AttrName->getNameStart(), tok::r_paren))
294 return;
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000295
Aaron Ballman478faed2012-06-19 22:09:27 +0000296 ExprResult ArgExpr(ParseConstantExpression());
297 if (ArgExpr.isInvalid()) {
298 T.skipToEnd();
299 return;
300 }
301 Expr *ExprList = ArgExpr.take();
Chad Rosierc1183952012-06-26 22:30:43 +0000302 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Aaron Ballman478faed2012-06-19 22:09:27 +0000303 &ExprList, 1, AttributeList::AS_Declspec);
304
305 T.consumeClose();
306}
307
Chad Rosierc1183952012-06-26 22:30:43 +0000308/// \brief Determines whether a declspec is a "simple" one requiring no
Aaron Ballman478faed2012-06-19 22:09:27 +0000309/// arguments.
310bool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) {
311 return llvm::StringSwitch<bool>(Ident->getName())
312 .Case("dllimport", true)
313 .Case("dllexport", true)
314 .Case("noreturn", true)
315 .Case("nothrow", true)
316 .Case("noinline", true)
317 .Case("naked", true)
318 .Case("appdomain", true)
319 .Case("process", true)
320 .Case("jitintrinsic", true)
321 .Case("noalias", true)
322 .Case("restrict", true)
323 .Case("novtable", true)
324 .Case("selectany", true)
325 .Case("thread", true)
326 .Default(false);
327}
328
Chad Rosierc1183952012-06-26 22:30:43 +0000329/// \brief Attempts to parse a declspec which is not simple (one that takes
Aaron Ballman478faed2012-06-19 22:09:27 +0000330/// parameters). Will return false if we properly handled the declspec, or
331/// true if it is an unknown declspec.
Chad Rosierc1183952012-06-26 22:30:43 +0000332void Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
Aaron Ballman478faed2012-06-19 22:09:27 +0000333 SourceLocation Loc,
334 ParsedAttributes &Attrs) {
335 // Try to handle the easy case first -- these declspecs all take a single
336 // parameter as their argument.
337 if (llvm::StringSwitch<bool>(Ident->getName())
338 .Case("uuid", true)
339 .Case("align", true)
340 .Case("allocate", true)
341 .Default(false)) {
342 ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
343 } else if (Ident->getName() == "deprecated") {
Chad Rosierc1183952012-06-26 22:30:43 +0000344 // The deprecated declspec has an optional single argument, so we will
345 // check for a l-paren to decide whether we should parse an argument or
Aaron Ballman478faed2012-06-19 22:09:27 +0000346 // not.
347 if (Tok.getKind() == tok::l_paren)
348 ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
349 else
Chad Rosierc1183952012-06-26 22:30:43 +0000350 Attrs.addNew(Ident, Loc, 0, Loc, 0, SourceLocation(), 0, 0,
Aaron Ballman478faed2012-06-19 22:09:27 +0000351 AttributeList::AS_Declspec);
352 } else if (Ident->getName() == "property") {
353 // The property declspec is more complex in that it can take one or two
Chad Rosierc1183952012-06-26 22:30:43 +0000354 // assignment expressions as a parameter, but the lhs of the assignment
Aaron Ballman478faed2012-06-19 22:09:27 +0000355 // must be named get or put.
356 //
Chad Rosierc1183952012-06-26 22:30:43 +0000357 // For right now, we will just skip to the closing right paren of the
Aaron Ballman478faed2012-06-19 22:09:27 +0000358 // property expression.
359 //
360 // FIXME: we should deal with __declspec(property) at some point because it
361 // is used in the platform SDK headers for the Parallel Patterns Library
362 // and ATL.
363 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosierc1183952012-06-26 22:30:43 +0000364 if (T.expectAndConsume(diag::err_expected_lparen_after,
Aaron Ballman478faed2012-06-19 22:09:27 +0000365 Ident->getNameStart(), tok::r_paren))
366 return;
367 T.skipToEnd();
368 } else {
369 // We don't recognize this as a valid declspec, but instead of creating the
370 // attribute and allowing sema to warn about it, we will warn here instead.
371 // This is because some attributes have multiple spellings, but we need to
372 // disallow that for declspecs (such as align vs aligned). If we made the
Chad Rosierc1183952012-06-26 22:30:43 +0000373 // attribute, we'd have to split the valid declspec spelling logic into
Aaron Ballman478faed2012-06-19 22:09:27 +0000374 // both locations.
375 Diag(Loc, diag::warn_ms_declspec_unknown) << Ident;
376
377 // If there's an open paren, we should eat the open and close parens under
378 // the assumption that this unknown declspec has parameters.
379 BalancedDelimiterTracker T(*this, tok::l_paren);
380 if (!T.consumeOpen())
381 T.skipToEnd();
382 }
383}
384
Eli Friedman06de2b52009-06-08 07:21:15 +0000385/// [MS] decl-specifier:
386/// __declspec ( extended-decl-modifier-seq )
387///
388/// [MS] extended-decl-modifier-seq:
389/// extended-decl-modifier[opt]
390/// extended-decl-modifier extended-decl-modifier-seq
Aaron Ballman478faed2012-06-19 22:09:27 +0000391void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
Steve Naroff3a9b7e02008-12-24 20:59:21 +0000392 assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
Eli Friedman06de2b52009-06-08 07:21:15 +0000393
Steve Naroff3a9b7e02008-12-24 20:59:21 +0000394 ConsumeToken();
Aaron Ballman478faed2012-06-19 22:09:27 +0000395 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosierc1183952012-06-26 22:30:43 +0000396 if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
Aaron Ballman478faed2012-06-19 22:09:27 +0000397 tok::r_paren))
John McCall53fa7142010-12-24 02:08:15 +0000398 return;
Jakob Stoklund Olesene1c0ae62012-06-19 21:48:43 +0000399
Chad Rosierc1183952012-06-26 22:30:43 +0000400 // An empty declspec is perfectly legal and should not warn. Additionally,
Aaron Ballman478faed2012-06-19 22:09:27 +0000401 // you can specify multiple attributes per declspec.
402 while (Tok.getKind() != tok::r_paren) {
403 // We expect either a well-known identifier or a generic string. Anything
404 // else is a malformed declspec.
405 bool IsString = Tok.getKind() == tok::string_literal ? true : false;
Chad Rosierc1183952012-06-26 22:30:43 +0000406 if (!IsString && Tok.getKind() != tok::identifier &&
Aaron Ballman478faed2012-06-19 22:09:27 +0000407 Tok.getKind() != tok::kw_restrict) {
408 Diag(Tok, diag::err_ms_declspec_type);
409 T.skipToEnd();
410 return;
Jakob Stoklund Olesene1c0ae62012-06-19 21:48:43 +0000411 }
Aaron Ballman478faed2012-06-19 22:09:27 +0000412
413 IdentifierInfo *AttrName;
414 SourceLocation AttrNameLoc;
415 if (IsString) {
416 SmallString<8> StrBuffer;
417 bool Invalid = false;
418 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
419 if (Invalid) {
420 T.skipToEnd();
421 return;
Jakob Stoklund Olesene1c0ae62012-06-19 21:48:43 +0000422 }
Aaron Ballman478faed2012-06-19 22:09:27 +0000423 AttrName = PP.getIdentifierInfo(Str);
424 AttrNameLoc = ConsumeStringToken();
Jakob Stoklund Olesene1c0ae62012-06-19 21:48:43 +0000425 } else {
Aaron Ballman478faed2012-06-19 22:09:27 +0000426 AttrName = Tok.getIdentifierInfo();
427 AttrNameLoc = ConsumeToken();
Jakob Stoklund Olesene1c0ae62012-06-19 21:48:43 +0000428 }
Chad Rosierc1183952012-06-26 22:30:43 +0000429
Aaron Ballman478faed2012-06-19 22:09:27 +0000430 if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
Chad Rosierc1183952012-06-26 22:30:43 +0000431 // If we have a generic string, we will allow it because there is no
432 // documented list of allowable string declspecs, but we know they exist
Aaron Ballman478faed2012-06-19 22:09:27 +0000433 // (for instance, SAL declspecs in older versions of MSVC).
434 //
Chad Rosierc1183952012-06-26 22:30:43 +0000435 // Alternatively, if the identifier is a simple one, then it requires no
Aaron Ballman478faed2012-06-19 22:09:27 +0000436 // arguments and can be turned into an attribute directly.
Chad Rosierc1183952012-06-26 22:30:43 +0000437 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Aaron Ballman478faed2012-06-19 22:09:27 +0000438 0, 0, AttributeList::AS_Declspec);
439 else
440 ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
Jakob Stoklund Olesene1c0ae62012-06-19 21:48:43 +0000441 }
Aaron Ballman478faed2012-06-19 22:09:27 +0000442 T.consumeClose();
Eli Friedman53339e02009-06-08 23:27:34 +0000443}
444
John McCall53fa7142010-12-24 02:08:15 +0000445void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
Eli Friedman53339e02009-06-08 23:27:34 +0000446 // Treat these like attributes
Eli Friedman53339e02009-06-08 23:27:34 +0000447 while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
Douglas Gregora941dca2010-05-18 16:57:00 +0000448 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) ||
Francois Pichet17ed0202011-08-18 09:59:55 +0000449 Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
Francois Pichetf2fb4112011-08-25 00:36:46 +0000450 Tok.is(tok::kw___ptr32) ||
Francois Pichet17ed0202011-08-18 09:59:55 +0000451 Tok.is(tok::kw___unaligned)) {
Eli Friedman53339e02009-06-08 23:27:34 +0000452 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
453 SourceLocation AttrNameLoc = ConsumeToken();
John McCall084e83d2011-03-24 11:26:52 +0000454 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Aaron Ballman478faed2012-06-19 22:09:27 +0000455 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
Eli Friedman53339e02009-06-08 23:27:34 +0000456 }
Steve Naroff3a9b7e02008-12-24 20:59:21 +0000457}
458
John McCall53fa7142010-12-24 02:08:15 +0000459void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
Dawn Perchik335e16b2010-09-03 01:29:35 +0000460 // Treat these like attributes
461 while (Tok.is(tok::kw___pascal)) {
462 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
463 SourceLocation AttrNameLoc = ConsumeToken();
John McCall084e83d2011-03-24 11:26:52 +0000464 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Aaron Ballman478faed2012-06-19 22:09:27 +0000465 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
Dawn Perchik335e16b2010-09-03 01:29:35 +0000466 }
John McCall53fa7142010-12-24 02:08:15 +0000467}
468
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +0000469void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
470 // Treat these like attributes
471 while (Tok.is(tok::kw___kernel)) {
472 SourceLocation AttrNameLoc = ConsumeToken();
John McCall084e83d2011-03-24 11:26:52 +0000473 attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
474 AttrNameLoc, 0, AttrNameLoc, 0,
Alexis Hunta0e54d42012-06-18 16:13:52 +0000475 SourceLocation(), 0, 0, AttributeList::AS_GNU);
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +0000476 }
477}
478
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000479void Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
480 SourceLocation Loc = Tok.getLocation();
481 switch(Tok.getKind()) {
482 // OpenCL qualifiers:
483 case tok::kw___private:
Chad Rosierc1183952012-06-26 22:30:43 +0000484 case tok::kw_private:
John McCall084e83d2011-03-24 11:26:52 +0000485 DS.getAttributes().addNewInteger(
Chad Rosierc1183952012-06-26 22:30:43 +0000486 Actions.getASTContext(),
John McCall084e83d2011-03-24 11:26:52 +0000487 PP.getIdentifierInfo("address_space"), Loc, 0);
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000488 break;
Chad Rosierc1183952012-06-26 22:30:43 +0000489
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000490 case tok::kw___global:
John McCall084e83d2011-03-24 11:26:52 +0000491 DS.getAttributes().addNewInteger(
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000492 Actions.getASTContext(),
John McCall084e83d2011-03-24 11:26:52 +0000493 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000494 break;
Chad Rosierc1183952012-06-26 22:30:43 +0000495
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000496 case tok::kw___local:
John McCall084e83d2011-03-24 11:26:52 +0000497 DS.getAttributes().addNewInteger(
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000498 Actions.getASTContext(),
John McCall084e83d2011-03-24 11:26:52 +0000499 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000500 break;
Chad Rosierc1183952012-06-26 22:30:43 +0000501
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000502 case tok::kw___constant:
John McCall084e83d2011-03-24 11:26:52 +0000503 DS.getAttributes().addNewInteger(
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000504 Actions.getASTContext(),
John McCall084e83d2011-03-24 11:26:52 +0000505 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000506 break;
Chad Rosierc1183952012-06-26 22:30:43 +0000507
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000508 case tok::kw___read_only:
John McCall084e83d2011-03-24 11:26:52 +0000509 DS.getAttributes().addNewInteger(
Chad Rosierc1183952012-06-26 22:30:43 +0000510 Actions.getASTContext(),
John McCall084e83d2011-03-24 11:26:52 +0000511 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000512 break;
Chad Rosierc1183952012-06-26 22:30:43 +0000513
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000514 case tok::kw___write_only:
John McCall084e83d2011-03-24 11:26:52 +0000515 DS.getAttributes().addNewInteger(
Chad Rosierc1183952012-06-26 22:30:43 +0000516 Actions.getASTContext(),
John McCall084e83d2011-03-24 11:26:52 +0000517 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000518 break;
Chad Rosierc1183952012-06-26 22:30:43 +0000519
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000520 case tok::kw___read_write:
John McCall084e83d2011-03-24 11:26:52 +0000521 DS.getAttributes().addNewInteger(
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000522 Actions.getASTContext(),
John McCall084e83d2011-03-24 11:26:52 +0000523 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
Peter Collingbourne599cb8e2011-03-18 22:38:29 +0000524 break;
525 default: break;
526 }
527}
528
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000529/// \brief Parse a version number.
530///
531/// version:
532/// simple-integer
533/// simple-integer ',' simple-integer
534/// simple-integer ',' simple-integer ',' simple-integer
535VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
536 Range = Tok.getLocation();
537
538 if (!Tok.is(tok::numeric_constant)) {
539 Diag(Tok, diag::err_expected_version);
540 SkipUntil(tok::comma, tok::r_paren, true, true, true);
541 return VersionTuple();
542 }
543
544 // Parse the major (and possibly minor and subminor) versions, which
545 // are stored in the numeric constant. We utilize a quirk of the
546 // lexer, which is that it handles something like 1.2.3 as a single
547 // numeric constant, rather than two separate tokens.
Dylan Noblesmith2c1dd272012-02-05 02:13:05 +0000548 SmallString<512> Buffer;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000549 Buffer.resize(Tok.getLength()+1);
550 const char *ThisTokBegin = &Buffer[0];
551
552 // Get the spelling of the token, which eliminates trigraphs, etc.
553 bool Invalid = false;
554 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
555 if (Invalid)
556 return VersionTuple();
557
558 // Parse the major version.
559 unsigned AfterMajor = 0;
560 unsigned Major = 0;
561 while (AfterMajor < ActualLength && isdigit(ThisTokBegin[AfterMajor])) {
562 Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';
563 ++AfterMajor;
564 }
565
566 if (AfterMajor == 0) {
567 Diag(Tok, diag::err_expected_version);
568 SkipUntil(tok::comma, tok::r_paren, true, true, true);
569 return VersionTuple();
570 }
571
572 if (AfterMajor == ActualLength) {
573 ConsumeToken();
574
575 // We only had a single version component.
576 if (Major == 0) {
577 Diag(Tok, diag::err_zero_version);
578 return VersionTuple();
579 }
580
581 return VersionTuple(Major);
582 }
583
584 if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) {
585 Diag(Tok, diag::err_expected_version);
586 SkipUntil(tok::comma, tok::r_paren, true, true, true);
587 return VersionTuple();
588 }
589
590 // Parse the minor version.
591 unsigned AfterMinor = AfterMajor + 1;
592 unsigned Minor = 0;
593 while (AfterMinor < ActualLength && isdigit(ThisTokBegin[AfterMinor])) {
594 Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';
595 ++AfterMinor;
596 }
597
598 if (AfterMinor == ActualLength) {
599 ConsumeToken();
Chad Rosierc1183952012-06-26 22:30:43 +0000600
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000601 // We had major.minor.
602 if (Major == 0 && Minor == 0) {
603 Diag(Tok, diag::err_zero_version);
604 return VersionTuple();
605 }
606
Chad Rosierc1183952012-06-26 22:30:43 +0000607 return VersionTuple(Major, Minor);
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000608 }
609
610 // If what follows is not a '.', we have a problem.
611 if (ThisTokBegin[AfterMinor] != '.') {
612 Diag(Tok, diag::err_expected_version);
613 SkipUntil(tok::comma, tok::r_paren, true, true, true);
Chad Rosierc1183952012-06-26 22:30:43 +0000614 return VersionTuple();
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000615 }
616
617 // Parse the subminor version.
618 unsigned AfterSubminor = AfterMinor + 1;
619 unsigned Subminor = 0;
620 while (AfterSubminor < ActualLength && isdigit(ThisTokBegin[AfterSubminor])) {
621 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';
622 ++AfterSubminor;
623 }
624
625 if (AfterSubminor != ActualLength) {
626 Diag(Tok, diag::err_expected_version);
627 SkipUntil(tok::comma, tok::r_paren, true, true, true);
628 return VersionTuple();
629 }
630 ConsumeToken();
631 return VersionTuple(Major, Minor, Subminor);
632}
633
634/// \brief Parse the contents of the "availability" attribute.
635///
636/// availability-attribute:
Fariborz Jahanian88d510d2011-12-10 00:28:41 +0000637/// 'availability' '(' platform ',' version-arg-list, opt-message')'
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000638///
639/// platform:
640/// identifier
641///
642/// version-arg-list:
643/// version-arg
644/// version-arg ',' version-arg-list
645///
646/// version-arg:
647/// 'introduced' '=' version
648/// 'deprecated' '=' version
Douglas Gregorfdd417f2012-03-11 04:53:21 +0000649/// 'obsoleted' = version
Douglas Gregor7ab142b2011-03-26 03:35:55 +0000650/// 'unavailable'
Fariborz Jahanian88d510d2011-12-10 00:28:41 +0000651/// opt-message:
652/// 'message' '=' <string>
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000653void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
654 SourceLocation AvailabilityLoc,
655 ParsedAttributes &attrs,
656 SourceLocation *endLoc) {
657 SourceLocation PlatformLoc;
658 IdentifierInfo *Platform = 0;
659
660 enum { Introduced, Deprecated, Obsoleted, Unknown };
661 AvailabilityChange Changes[Unknown];
Fariborz Jahanian88d510d2011-12-10 00:28:41 +0000662 ExprResult MessageExpr;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000663
664 // Opening '('.
Douglas Gregore7a8e3b2011-10-12 16:37:45 +0000665 BalancedDelimiterTracker T(*this, tok::l_paren);
666 if (T.consumeOpen()) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000667 Diag(Tok, diag::err_expected_lparen);
668 return;
669 }
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000670
671 // Parse the platform name,
672 if (Tok.isNot(tok::identifier)) {
673 Diag(Tok, diag::err_availability_expected_platform);
674 SkipUntil(tok::r_paren);
675 return;
676 }
677 Platform = Tok.getIdentifierInfo();
678 PlatformLoc = ConsumeToken();
679
680 // Parse the ',' following the platform name.
681 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
682 return;
683
684 // If we haven't grabbed the pointers for the identifiers
685 // "introduced", "deprecated", and "obsoleted", do so now.
686 if (!Ident_introduced) {
687 Ident_introduced = PP.getIdentifierInfo("introduced");
688 Ident_deprecated = PP.getIdentifierInfo("deprecated");
689 Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
Douglas Gregor7ab142b2011-03-26 03:35:55 +0000690 Ident_unavailable = PP.getIdentifierInfo("unavailable");
Fariborz Jahanian88d510d2011-12-10 00:28:41 +0000691 Ident_message = PP.getIdentifierInfo("message");
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000692 }
693
694 // Parse the set of introductions/deprecations/removals.
Douglas Gregor7ab142b2011-03-26 03:35:55 +0000695 SourceLocation UnavailableLoc;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000696 do {
697 if (Tok.isNot(tok::identifier)) {
698 Diag(Tok, diag::err_availability_expected_change);
699 SkipUntil(tok::r_paren);
700 return;
701 }
702 IdentifierInfo *Keyword = Tok.getIdentifierInfo();
703 SourceLocation KeywordLoc = ConsumeToken();
704
Douglas Gregor7ab142b2011-03-26 03:35:55 +0000705 if (Keyword == Ident_unavailable) {
706 if (UnavailableLoc.isValid()) {
707 Diag(KeywordLoc, diag::err_availability_redundant)
708 << Keyword << SourceRange(UnavailableLoc);
Chad Rosierc1183952012-06-26 22:30:43 +0000709 }
Douglas Gregor7ab142b2011-03-26 03:35:55 +0000710 UnavailableLoc = KeywordLoc;
711
712 if (Tok.isNot(tok::comma))
713 break;
714
715 ConsumeToken();
716 continue;
Chad Rosierc1183952012-06-26 22:30:43 +0000717 }
718
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000719 if (Tok.isNot(tok::equal)) {
720 Diag(Tok, diag::err_expected_equal_after)
721 << Keyword;
722 SkipUntil(tok::r_paren);
723 return;
724 }
725 ConsumeToken();
Fariborz Jahanian88d510d2011-12-10 00:28:41 +0000726 if (Keyword == Ident_message) {
727 if (!isTokenStringLiteral()) {
728 Diag(Tok, diag::err_expected_string_literal);
729 SkipUntil(tok::r_paren);
730 return;
731 }
732 MessageExpr = ParseStringLiteralExpression();
733 break;
734 }
Chad Rosierc1183952012-06-26 22:30:43 +0000735
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000736 SourceRange VersionRange;
737 VersionTuple Version = ParseVersionTuple(VersionRange);
Chad Rosierc1183952012-06-26 22:30:43 +0000738
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000739 if (Version.empty()) {
740 SkipUntil(tok::r_paren);
741 return;
742 }
743
744 unsigned Index;
745 if (Keyword == Ident_introduced)
746 Index = Introduced;
747 else if (Keyword == Ident_deprecated)
748 Index = Deprecated;
749 else if (Keyword == Ident_obsoleted)
750 Index = Obsoleted;
Chad Rosierc1183952012-06-26 22:30:43 +0000751 else
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000752 Index = Unknown;
753
754 if (Index < Unknown) {
755 if (!Changes[Index].KeywordLoc.isInvalid()) {
756 Diag(KeywordLoc, diag::err_availability_redundant)
Chad Rosierc1183952012-06-26 22:30:43 +0000757 << Keyword
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000758 << SourceRange(Changes[Index].KeywordLoc,
759 Changes[Index].VersionRange.getEnd());
760 }
761
762 Changes[Index].KeywordLoc = KeywordLoc;
763 Changes[Index].Version = Version;
764 Changes[Index].VersionRange = VersionRange;
765 } else {
766 Diag(KeywordLoc, diag::err_availability_unknown_change)
767 << Keyword << VersionRange;
768 }
769
770 if (Tok.isNot(tok::comma))
771 break;
772
773 ConsumeToken();
774 } while (true);
775
776 // Closing ')'.
Douglas Gregore7a8e3b2011-10-12 16:37:45 +0000777 if (T.consumeClose())
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000778 return;
779
780 if (endLoc)
Douglas Gregore7a8e3b2011-10-12 16:37:45 +0000781 *endLoc = T.getCloseLocation();
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000782
Douglas Gregor7ab142b2011-03-26 03:35:55 +0000783 // The 'unavailable' availability cannot be combined with any other
784 // availability changes. Make sure that hasn't happened.
785 if (UnavailableLoc.isValid()) {
786 bool Complained = false;
787 for (unsigned Index = Introduced; Index != Unknown; ++Index) {
788 if (Changes[Index].KeywordLoc.isValid()) {
789 if (!Complained) {
790 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
791 << SourceRange(Changes[Index].KeywordLoc,
792 Changes[Index].VersionRange.getEnd());
793 Complained = true;
794 }
795
796 // Clear out the availability.
797 Changes[Index] = AvailabilityChange();
798 }
799 }
800 }
801
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000802 // Record this attribute
Chad Rosierc1183952012-06-26 22:30:43 +0000803 attrs.addNew(&Availability,
804 SourceRange(AvailabilityLoc, T.getCloseLocation()),
Fariborz Jahanian586be882012-01-23 23:38:32 +0000805 0, AvailabilityLoc,
John McCall084e83d2011-03-24 11:26:52 +0000806 Platform, PlatformLoc,
807 Changes[Introduced],
808 Changes[Deprecated],
Chad Rosierc1183952012-06-26 22:30:43 +0000809 Changes[Obsoleted],
Fariborz Jahanian88d510d2011-12-10 00:28:41 +0000810 UnavailableLoc, MessageExpr.take(),
Alexis Hunta0e54d42012-06-18 16:13:52 +0000811 AttributeList::AS_GNU);
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000812}
813
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000814
815// Late Parsed Attributes:
816// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
817
818void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
819
820void Parser::LateParsedClass::ParseLexedAttributes() {
821 Self->ParseLexedAttributes(*Class);
822}
823
824void Parser::LateParsedAttribute::ParseLexedAttributes() {
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000825 Self->ParseLexedAttribute(*this, true, false);
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000826}
827
828/// Wrapper class which calls ParseLexedAttribute, after setting up the
829/// scope appropriately.
830void Parser::ParseLexedAttributes(ParsingClass &Class) {
831 // Deal with templates
832 // FIXME: Test cases to make sure this does the right thing for templates.
833 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
834 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
835 HasTemplateScope);
836 if (HasTemplateScope)
837 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
838
Douglas Gregor3024f072012-04-16 07:05:22 +0000839 // Set or update the scope flags.
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000840 bool AlreadyHasClassScope = Class.TopLevelClass;
Douglas Gregor3024f072012-04-16 07:05:22 +0000841 unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000842 ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
843 ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
844
DeLesley Hutchins6f860042012-04-06 15:10:17 +0000845 // Enter the scope of nested classes
846 if (!AlreadyHasClassScope)
847 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
848 Class.TagOrTemplate);
Benjamin Kramer1d373c62012-05-17 12:01:52 +0000849 if (!Class.LateParsedDeclarations.empty()) {
Douglas Gregor3024f072012-04-16 07:05:22 +0000850 // Allow 'this' within late-parsed attributes.
Chad Rosierc1183952012-06-26 22:30:43 +0000851 Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
Douglas Gregor3024f072012-04-16 07:05:22 +0000852 /*TypeQuals=*/0);
Chad Rosierc1183952012-06-26 22:30:43 +0000853
Douglas Gregor3024f072012-04-16 07:05:22 +0000854 for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
855 Class.LateParsedDeclarations[i]->ParseLexedAttributes();
856 }
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000857 }
Chad Rosierc1183952012-06-26 22:30:43 +0000858
DeLesley Hutchins6f860042012-04-06 15:10:17 +0000859 if (!AlreadyHasClassScope)
860 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
861 Class.TagOrTemplate);
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000862}
863
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000864
865/// \brief Parse all attributes in LAs, and attach them to Decl D.
866void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
867 bool EnterScope, bool OnDefinition) {
868 for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
DeLesley Hutchins19c722d2012-08-15 22:41:04 +0000869 if (D)
870 LAs[i]->addDecl(D);
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000871 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
Benjamin Kramerbafc49a2012-04-14 12:44:47 +0000872 delete LAs[i];
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000873 }
874 LAs.clear();
875}
876
877
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000878/// \brief Finish parsing an attribute for which parsing was delayed.
879/// This will be called at the end of parsing a class declaration
880/// for each LateParsedAttribute. We consume the saved tokens and
Chad Rosierc1183952012-06-26 22:30:43 +0000881/// create an attribute with the arguments filled in. We add this
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000882/// to the Attribute list for the decl.
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000883void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
884 bool EnterScope, bool OnDefinition) {
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000885 // Save the current token position.
886 SourceLocation OrigLoc = Tok.getLocation();
887
888 // Append the current token at the end of the new token stream so that it
889 // doesn't get lost.
890 LA.Toks.push_back(Tok);
891 PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
892 // Consume the previously pushed token.
893 ConsumeAnyToken();
894
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +0000895 if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
896 Diag(Tok, diag::warn_attribute_on_function_definition)
897 << LA.AttrName.getName();
898 }
899
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000900 ParsedAttributes Attrs(AttrFactory);
901 SourceLocation endLoc;
902
DeLesley Hutchinsbd2ee132012-03-02 22:12:59 +0000903 if (LA.Decls.size() == 1) {
904 Decl *D = LA.Decls[0];
Caitlin Sadowski990d5712011-09-08 17:42:31 +0000905
DeLesley Hutchinsbd2ee132012-03-02 22:12:59 +0000906 // If the Decl is templatized, add template parameters to scope.
907 bool HasTemplateScope = EnterScope && D->isTemplateDecl();
908 ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
909 if (HasTemplateScope)
910 Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000911
DeLesley Hutchinsbd2ee132012-03-02 22:12:59 +0000912 // If the Decl is on a function, add function parameters to the scope.
913 bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate();
914 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope);
915 if (HasFunctionScope)
916 Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
917
918 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
919
920 if (HasFunctionScope) {
921 Actions.ActOnExitFunctionContext();
922 FnScope.Exit(); // Pop scope, and remove Decls from IdResolver
923 }
924 if (HasTemplateScope) {
925 TempScope.Exit();
926 }
DeLesley Hutchins71d61032012-03-02 22:29:50 +0000927 } else if (LA.Decls.size() > 0) {
DeLesley Hutchinsbd2ee132012-03-02 22:12:59 +0000928 // If there are multiple decls, then the decl cannot be within the
929 // function scope.
930 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
DeLesley Hutchins71d61032012-03-02 22:29:50 +0000931 } else {
932 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
Caitlin Sadowski990d5712011-09-08 17:42:31 +0000933 }
934
DeLesley Hutchinsbd2ee132012-03-02 22:12:59 +0000935 for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
936 Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
937 }
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000938
939 if (Tok.getLocation() != OrigLoc) {
940 // Due to a parsing error, we either went over the cached tokens or
941 // there are still cached tokens left, so we skip the leftover tokens.
942 // Since this is an uncommon situation that should be avoided, use the
943 // expensive isBeforeInTranslationUnit call.
944 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
945 OrigLoc))
946 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
Douglas Gregor0cf55e92012-03-08 01:00:17 +0000947 ConsumeAnyToken();
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000948 }
949}
950
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000951/// \brief Wrapper around a case statement checking if AttrName is
952/// one of the thread safety attributes
953bool Parser::IsThreadSafetyAttribute(llvm::StringRef AttrName){
954 return llvm::StringSwitch<bool>(AttrName)
955 .Case("guarded_by", true)
956 .Case("guarded_var", true)
957 .Case("pt_guarded_by", true)
958 .Case("pt_guarded_var", true)
959 .Case("lockable", true)
960 .Case("scoped_lockable", true)
961 .Case("no_thread_safety_analysis", true)
962 .Case("acquired_after", true)
963 .Case("acquired_before", true)
964 .Case("exclusive_lock_function", true)
965 .Case("shared_lock_function", true)
966 .Case("exclusive_trylock_function", true)
967 .Case("shared_trylock_function", true)
968 .Case("unlock_function", true)
969 .Case("lock_returned", true)
970 .Case("locks_excluded", true)
971 .Case("exclusive_locks_required", true)
972 .Case("shared_locks_required", true)
973 .Default(false);
974}
975
976/// \brief Parse the contents of thread safety attributes. These
977/// should always be parsed as an expression list.
978///
979/// We need to special case the parsing due to the fact that if the first token
980/// of the first argument is an identifier, the main parse loop will store
981/// that token as a "parameter" and the rest of
982/// the arguments will be added to a list of "arguments". However,
983/// subsequent tokens in the first argument are lost. We instead parse each
984/// argument as an expression and add all arguments to the list of "arguments".
985/// In future, we will take advantage of this special case to also
986/// deal with some argument scoping issues here (for example, referring to a
987/// function parameter in the attribute on that function).
988void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
989 SourceLocation AttrNameLoc,
990 ParsedAttributes &Attrs,
991 SourceLocation *EndLoc) {
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000992 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +0000993
Douglas Gregore7a8e3b2011-10-12 16:37:45 +0000994 BalancedDelimiterTracker T(*this, tok::l_paren);
995 T.consumeOpen();
Chad Rosierc1183952012-06-26 22:30:43 +0000996
Caitlin Sadowski9385dd72011-09-08 17:42:22 +0000997 ExprVector ArgExprs(Actions);
998 bool ArgExprsOk = true;
Chad Rosierc1183952012-06-26 22:30:43 +0000999
Caitlin Sadowski9385dd72011-09-08 17:42:22 +00001000 // now parse the list of expressions
DeLesley Hutchins36f5d852011-12-14 19:36:06 +00001001 while (Tok.isNot(tok::r_paren)) {
Caitlin Sadowski9385dd72011-09-08 17:42:22 +00001002 ExprResult ArgExpr(ParseAssignmentExpression());
1003 if (ArgExpr.isInvalid()) {
1004 ArgExprsOk = false;
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00001005 T.consumeClose();
Caitlin Sadowski9385dd72011-09-08 17:42:22 +00001006 break;
1007 } else {
1008 ArgExprs.push_back(ArgExpr.release());
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +00001009 }
Caitlin Sadowski9385dd72011-09-08 17:42:22 +00001010 if (Tok.isNot(tok::comma))
1011 break;
1012 ConsumeToken(); // Eat the comma, move to the next argument
1013 }
1014 // Match the ')'.
DeLesley Hutchins30398dd2012-01-20 22:50:54 +00001015 if (ArgExprsOk && !T.consumeClose()) {
Caitlin Sadowski9385dd72011-09-08 17:42:22 +00001016 Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Alexis Hunta0e54d42012-06-18 16:13:52 +00001017 ArgExprs.take(), ArgExprs.size(), AttributeList::AS_GNU);
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +00001018 }
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00001019 if (EndLoc)
1020 *EndLoc = T.getCloseLocation();
Caitlin Sadowski4b1e8392011-08-09 17:59:31 +00001021}
1022
Richard Smith7bdcc4a2012-04-10 01:32:12 +00001023/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
1024/// of a C++11 attribute-specifier in a location where an attribute is not
1025/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
1026/// situation.
1027///
1028/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
1029/// this doesn't appear to actually be an attribute-specifier, and the caller
1030/// should try to parse it.
1031bool Parser::DiagnoseProhibitedCXX11Attribute() {
1032 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1033
1034 switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1035 case CAK_NotAttributeSpecifier:
1036 // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1037 return false;
1038
1039 case CAK_InvalidAttributeSpecifier:
1040 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1041 return false;
1042
1043 case CAK_AttributeSpecifier:
1044 // Parse and discard the attributes.
1045 SourceLocation BeginLoc = ConsumeBracket();
1046 ConsumeBracket();
1047 SkipUntil(tok::r_square, /*StopAtSemi*/ false);
1048 assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1049 SourceLocation EndLoc = ConsumeBracket();
1050 Diag(BeginLoc, diag::err_attributes_not_allowed)
1051 << SourceRange(BeginLoc, EndLoc);
1052 return true;
1053 }
Chandler Carruthd8f7d382012-04-10 16:03:08 +00001054 llvm_unreachable("All cases handled above.");
Richard Smith7bdcc4a2012-04-10 01:32:12 +00001055}
1056
John McCall53fa7142010-12-24 02:08:15 +00001057void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1058 Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1059 << attrs.Range;
Dawn Perchik335e16b2010-09-03 01:29:35 +00001060}
1061
Chris Lattner53361ac2006-08-10 05:19:57 +00001062/// ParseDeclaration - Parse a full 'declaration', which consists of
1063/// declaration-specifiers, some number of declarators, and a semicolon.
Chris Lattner49836b42009-04-02 04:16:50 +00001064/// 'Context' should be a Declarator::TheContext value. This returns the
1065/// location of the semicolon in DeclEnd.
Chris Lattnera5235172007-08-25 06:57:03 +00001066///
1067/// declaration: [C99 6.7]
1068/// block-declaration ->
1069/// simple-declaration
1070/// others [FIXME]
Douglas Gregoreb31f392008-12-01 23:54:00 +00001071/// [C++] template-declaration
Chris Lattnera5235172007-08-25 06:57:03 +00001072/// [C++] namespace-definition
Douglas Gregord7c4d982008-12-30 03:27:21 +00001073/// [C++] using-directive
Douglas Gregor77b50e12009-06-22 23:06:13 +00001074/// [C++] using-declaration
Richard Smithc202b282012-04-14 00:33:13 +00001075/// [C++11/C11] static_assert-declaration
Chris Lattnera5235172007-08-25 06:57:03 +00001076/// others... [FIXME]
1077///
Fariborz Jahanian1db5c942010-09-28 20:42:35 +00001078Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1079 unsigned Context,
Alexis Hunt96d5c762009-11-21 08:43:09 +00001080 SourceLocation &DeclEnd,
John McCall53fa7142010-12-24 02:08:15 +00001081 ParsedAttributesWithRange &attrs) {
Argyrios Kyrtzidis355094e2010-06-17 10:52:18 +00001082 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Fariborz Jahanian59b75282011-08-30 17:10:52 +00001083 // Must temporarily exit the objective-c container scope for
1084 // parsing c none objective-c decls.
1085 ObjCDeclContextSwitch ObjCDC(*this);
Chad Rosierc1183952012-06-26 22:30:43 +00001086
John McCall48871652010-08-21 09:40:31 +00001087 Decl *SingleDecl = 0;
Richard Smithcd1c0552011-07-01 19:46:12 +00001088 Decl *OwnedType = 0;
Chris Lattnera5235172007-08-25 06:57:03 +00001089 switch (Tok.getKind()) {
Douglas Gregoreb31f392008-12-01 23:54:00 +00001090 case tok::kw_template:
Douglas Gregor23996282009-05-12 21:31:51 +00001091 case tok::kw_export:
John McCall53fa7142010-12-24 02:08:15 +00001092 ProhibitAttributes(attrs);
Douglas Gregor1b57ff32009-05-12 23:25:50 +00001093 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
Chris Lattner5bbb3c82009-03-29 16:50:03 +00001094 break;
Sebastian Redl67667942010-08-27 23:12:46 +00001095 case tok::kw_inline:
Sebastian Redl5a5f2c72010-08-31 00:36:45 +00001096 // Could be the start of an inline namespace. Allowed as an ext in C++03.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001097 if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
John McCall53fa7142010-12-24 02:08:15 +00001098 ProhibitAttributes(attrs);
Sebastian Redl67667942010-08-27 23:12:46 +00001099 SourceLocation InlineLoc = ConsumeToken();
1100 SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1101 break;
1102 }
Chad Rosierc1183952012-06-26 22:30:43 +00001103 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
Fariborz Jahanian1db5c942010-09-28 20:42:35 +00001104 true);
Chris Lattnera5235172007-08-25 06:57:03 +00001105 case tok::kw_namespace:
John McCall53fa7142010-12-24 02:08:15 +00001106 ProhibitAttributes(attrs);
Chris Lattner49836b42009-04-02 04:16:50 +00001107 SingleDecl = ParseNamespace(Context, DeclEnd);
Chris Lattner5bbb3c82009-03-29 16:50:03 +00001108 break;
Douglas Gregord7c4d982008-12-30 03:27:21 +00001109 case tok::kw_using:
John McCall9b72f892010-11-10 02:40:36 +00001110 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
Richard Smithcd1c0552011-07-01 19:46:12 +00001111 DeclEnd, attrs, &OwnedType);
Chris Lattner5bbb3c82009-03-29 16:50:03 +00001112 break;
Anders Carlssonf24fcff62009-03-11 16:27:10 +00001113 case tok::kw_static_assert:
Peter Collingbourne3d9cbdc2011-04-15 00:35:57 +00001114 case tok::kw__Static_assert:
John McCall53fa7142010-12-24 02:08:15 +00001115 ProhibitAttributes(attrs);
Chris Lattner49836b42009-04-02 04:16:50 +00001116 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
Chris Lattner5bbb3c82009-03-29 16:50:03 +00001117 break;
Chris Lattnera5235172007-08-25 06:57:03 +00001118 default:
John McCall53fa7142010-12-24 02:08:15 +00001119 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
Chris Lattnera5235172007-08-25 06:57:03 +00001120 }
Chad Rosierc1183952012-06-26 22:30:43 +00001121
Chris Lattner5bbb3c82009-03-29 16:50:03 +00001122 // This routine returns a DeclGroup, if the thing we parsed only contains a
Richard Smithcd1c0552011-07-01 19:46:12 +00001123 // single decl, convert it now. Alias declarations can also declare a type;
1124 // include that too if it is present.
1125 return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
Chris Lattnera5235172007-08-25 06:57:03 +00001126}
1127
1128/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
1129/// declaration-specifiers init-declarator-list[opt] ';'
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00001130/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1131/// init-declarator-list ';'
Chris Lattnera5235172007-08-25 06:57:03 +00001132///[C90/C++]init-declarator-list ';' [TODO]
1133/// [OMP] threadprivate-directive [TODO]
Chris Lattner32dc41c2009-03-29 17:27:48 +00001134///
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00001135/// for-range-declaration: [C++11 6.5p1: stmt.ranged]
Richard Smith02e85f32011-04-14 22:09:26 +00001136/// attribute-specifier-seq[opt] type-specifier-seq declarator
1137///
Chris Lattner32dc41c2009-03-29 17:27:48 +00001138/// If RequireSemi is false, this does not check for a ';' at the end of the
Chris Lattner005fc1b2010-04-05 18:18:31 +00001139/// declaration. If it is true, it checks for and eats it.
Richard Smith02e85f32011-04-14 22:09:26 +00001140///
1141/// If FRI is non-null, we might be parsing a for-range-declaration instead
1142/// of a simple-declaration. If we find that we are, we also parse the
1143/// for-range-initializer, and place it here.
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00001144Parser::DeclGroupPtrTy
1145Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1146 SourceLocation &DeclEnd,
1147 ParsedAttributesWithRange &attrs,
1148 bool RequireSemi, ForRangeInit *FRI) {
Chris Lattner53361ac2006-08-10 05:19:57 +00001149 // Parse the common declaration-specifiers piece.
John McCall28a6aea2009-11-04 02:18:39 +00001150 ParsingDeclSpec DS(*this);
John McCall53fa7142010-12-24 02:08:15 +00001151 DS.takeAttributesFrom(attrs);
Douglas Gregor0e7dde52011-04-24 05:37:28 +00001152
Douglas Gregor9de54ea2010-01-13 17:31:36 +00001153 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
Richard Smith30482bc2011-02-20 03:19:35 +00001154 getDeclSpecContextFromDeclaratorContext(Context));
Abramo Bagnara1cd83682012-01-07 10:52:36 +00001155
Chris Lattner0e894622006-08-13 19:58:17 +00001156 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1157 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner76c72282007-10-09 17:33:22 +00001158 if (Tok.is(tok::semi)) {
Argyrios Kyrtzidisfbb2bb52012-05-16 23:49:15 +00001159 DeclEnd = Tok.getLocation();
Chris Lattner005fc1b2010-04-05 18:18:31 +00001160 if (RequireSemi) ConsumeToken();
John McCall48871652010-08-21 09:40:31 +00001161 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
Douglas Gregor0e7dde52011-04-24 05:37:28 +00001162 DS);
John McCall28a6aea2009-11-04 02:18:39 +00001163 DS.complete(TheDecl);
Chris Lattner5bbb3c82009-03-29 16:50:03 +00001164 return Actions.ConvertDeclToDeclGroup(TheDecl);
Chris Lattner0e894622006-08-13 19:58:17 +00001165 }
Chad Rosierc1183952012-06-26 22:30:43 +00001166
1167 return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
John McCalld5a36322009-11-03 19:26:08 +00001168}
Mike Stump11289f42009-09-09 15:08:12 +00001169
Richard Smith09f76ee2011-10-19 21:33:05 +00001170/// Returns true if this might be the start of a declarator, or a common typo
1171/// for a declarator.
1172bool Parser::MightBeDeclarator(unsigned Context) {
1173 switch (Tok.getKind()) {
1174 case tok::annot_cxxscope:
1175 case tok::annot_template_id:
1176 case tok::caret:
1177 case tok::code_completion:
1178 case tok::coloncolon:
1179 case tok::ellipsis:
1180 case tok::kw___attribute:
1181 case tok::kw_operator:
1182 case tok::l_paren:
1183 case tok::star:
1184 return true;
1185
1186 case tok::amp:
1187 case tok::ampamp:
David Blaikiebbafb8a2012-03-11 07:00:24 +00001188 return getLangOpts().CPlusPlus;
Richard Smith09f76ee2011-10-19 21:33:05 +00001189
Richard Smithc8a79032012-01-09 22:31:44 +00001190 case tok::l_square: // Might be an attribute on an unnamed bit-field.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001191 return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x &&
Richard Smithc8a79032012-01-09 22:31:44 +00001192 NextToken().is(tok::l_square);
1193
1194 case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001195 return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
Richard Smithc8a79032012-01-09 22:31:44 +00001196
Richard Smith09f76ee2011-10-19 21:33:05 +00001197 case tok::identifier:
1198 switch (NextToken().getKind()) {
1199 case tok::code_completion:
1200 case tok::coloncolon:
1201 case tok::comma:
1202 case tok::equal:
1203 case tok::equalequal: // Might be a typo for '='.
1204 case tok::kw_alignas:
1205 case tok::kw_asm:
1206 case tok::kw___attribute:
1207 case tok::l_brace:
1208 case tok::l_paren:
1209 case tok::l_square:
1210 case tok::less:
1211 case tok::r_brace:
1212 case tok::r_paren:
1213 case tok::r_square:
1214 case tok::semi:
1215 return true;
1216
1217 case tok::colon:
1218 // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
Richard Smithc8a79032012-01-09 22:31:44 +00001219 // and in block scope it's probably a label. Inside a class definition,
1220 // this is a bit-field.
1221 return Context == Declarator::MemberContext ||
David Blaikiebbafb8a2012-03-11 07:00:24 +00001222 (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
Richard Smithc8a79032012-01-09 22:31:44 +00001223
1224 case tok::identifier: // Possible virt-specifier.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001225 return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
Richard Smith09f76ee2011-10-19 21:33:05 +00001226
1227 default:
1228 return false;
1229 }
1230
1231 default:
1232 return false;
1233 }
1234}
1235
Richard Smithb8caac82012-04-11 20:59:20 +00001236/// Skip until we reach something which seems like a sensible place to pick
1237/// up parsing after a malformed declaration. This will sometimes stop sooner
1238/// than SkipUntil(tok::r_brace) would, but will never stop later.
1239void Parser::SkipMalformedDecl() {
1240 while (true) {
1241 switch (Tok.getKind()) {
1242 case tok::l_brace:
1243 // Skip until matching }, then stop. We've probably skipped over
1244 // a malformed class or function definition or similar.
1245 ConsumeBrace();
1246 SkipUntil(tok::r_brace, /*StopAtSemi*/false);
1247 if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
1248 // This declaration isn't over yet. Keep skipping.
1249 continue;
1250 }
1251 if (Tok.is(tok::semi))
1252 ConsumeToken();
1253 return;
1254
1255 case tok::l_square:
1256 ConsumeBracket();
1257 SkipUntil(tok::r_square, /*StopAtSemi*/false);
1258 continue;
1259
1260 case tok::l_paren:
1261 ConsumeParen();
1262 SkipUntil(tok::r_paren, /*StopAtSemi*/false);
1263 continue;
1264
1265 case tok::r_brace:
1266 return;
1267
1268 case tok::semi:
1269 ConsumeToken();
1270 return;
1271
1272 case tok::kw_inline:
1273 // 'inline namespace' at the start of a line is almost certainly
Jordan Rose12e730c2012-07-09 16:54:53 +00001274 // a good place to pick back up parsing, except in an Objective-C
1275 // @interface context.
1276 if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&
1277 (!ParsingInObjCContainer || CurParsedObjCImpl))
Richard Smithb8caac82012-04-11 20:59:20 +00001278 return;
1279 break;
1280
1281 case tok::kw_namespace:
1282 // 'namespace' at the start of a line is almost certainly a good
Jordan Rose12e730c2012-07-09 16:54:53 +00001283 // place to pick back up parsing, except in an Objective-C
1284 // @interface context.
1285 if (Tok.isAtStartOfLine() &&
1286 (!ParsingInObjCContainer || CurParsedObjCImpl))
1287 return;
1288 break;
1289
1290 case tok::at:
1291 // @end is very much like } in Objective-C contexts.
1292 if (NextToken().isObjCAtKeyword(tok::objc_end) &&
1293 ParsingInObjCContainer)
1294 return;
1295 break;
1296
1297 case tok::minus:
1298 case tok::plus:
1299 // - and + probably start new method declarations in Objective-C contexts.
1300 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
Richard Smithb8caac82012-04-11 20:59:20 +00001301 return;
1302 break;
1303
1304 case tok::eof:
1305 return;
1306
1307 default:
1308 break;
1309 }
1310
1311 ConsumeAnyToken();
1312 }
1313}
1314
John McCalld5a36322009-11-03 19:26:08 +00001315/// ParseDeclGroup - Having concluded that this is either a function
1316/// definition or a group of object declarations, actually parse the
1317/// result.
John McCall28a6aea2009-11-04 02:18:39 +00001318Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1319 unsigned Context,
John McCalld5a36322009-11-03 19:26:08 +00001320 bool AllowFunctionDefinitions,
Richard Smith02e85f32011-04-14 22:09:26 +00001321 SourceLocation *DeclEnd,
1322 ForRangeInit *FRI) {
John McCalld5a36322009-11-03 19:26:08 +00001323 // Parse the first declarator.
John McCall28a6aea2009-11-04 02:18:39 +00001324 ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
John McCalld5a36322009-11-03 19:26:08 +00001325 ParseDeclarator(D);
Chris Lattner32dc41c2009-03-29 17:27:48 +00001326
John McCalld5a36322009-11-03 19:26:08 +00001327 // Bail out if the first declarator didn't seem well-formed.
1328 if (!D.hasName() && !D.mayOmitIdentifier()) {
Richard Smithb8caac82012-04-11 20:59:20 +00001329 SkipMalformedDecl();
John McCalld5a36322009-11-03 19:26:08 +00001330 return DeclGroupPtrTy();
Chris Lattnerefb0f112009-03-29 17:18:04 +00001331 }
Mike Stump11289f42009-09-09 15:08:12 +00001332
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +00001333 // Save late-parsed attributes for now; they need to be parsed in the
1334 // appropriate function scope after the function Decl has been constructed.
1335 LateParsedAttrList LateParsedAttrs;
1336 if (D.isFunctionDeclarator())
1337 MaybeParseGNUAttributes(D, &LateParsedAttrs);
1338
Chris Lattnerdbb1e932010-07-11 22:24:20 +00001339 // Check to see if we have a function *definition* which must have a body.
1340 if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
1341 // Look at the next token to make sure that this isn't a function
1342 // declaration. We have to check this because __attribute__ might be the
1343 // start of a function definition in GCC-extended K&R C.
Fariborz Jahanian712bb812012-08-10 15:54:40 +00001344 !isDeclarationAfterDeclarator()) {
Chad Rosierc1183952012-06-26 22:30:43 +00001345
Chris Lattner13901342010-07-11 22:42:07 +00001346 if (isStartOfFunctionDefinition(D)) {
John McCalld5a36322009-11-03 19:26:08 +00001347 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
1348 Diag(Tok, diag::err_function_declared_typedef);
1349
1350 // Recover by treating the 'typedef' as spurious.
1351 DS.ClearStorageClassSpecs();
1352 }
1353
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +00001354 Decl *TheDecl =
1355 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
John McCalld5a36322009-11-03 19:26:08 +00001356 return Actions.ConvertDeclToDeclGroup(TheDecl);
Chris Lattner13901342010-07-11 22:42:07 +00001357 }
Chad Rosierc1183952012-06-26 22:30:43 +00001358
Chris Lattner13901342010-07-11 22:42:07 +00001359 if (isDeclarationSpecifier()) {
1360 // If there is an invalid declaration specifier right after the function
1361 // prototype, then we must be in a missing semicolon case where this isn't
1362 // actually a body. Just fall through into the code that handles it as a
1363 // prototype, and let the top-level code handle the erroneous declspec
1364 // where it would otherwise expect a comma or semicolon.
John McCalld5a36322009-11-03 19:26:08 +00001365 } else {
1366 Diag(Tok, diag::err_expected_fn_body);
1367 SkipUntil(tok::semi);
1368 return DeclGroupPtrTy();
1369 }
1370 }
1371
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +00001372 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smith02e85f32011-04-14 22:09:26 +00001373 return DeclGroupPtrTy();
1374
1375 // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
1376 // must parse and analyze the for-range-initializer before the declaration is
1377 // analyzed.
1378 if (FRI && Tok.is(tok::colon)) {
1379 FRI->ColonLoc = ConsumeToken();
Sebastian Redl3da34892011-06-05 12:23:16 +00001380 if (Tok.is(tok::l_brace))
1381 FRI->RangeExpr = ParseBraceInitializer();
1382 else
1383 FRI->RangeExpr = ParseExpression();
Richard Smith02e85f32011-04-14 22:09:26 +00001384 Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1385 Actions.ActOnCXXForRangeDecl(ThisDecl);
1386 Actions.FinalizeDeclaration(ThisDecl);
John McCallcf6e0c82012-01-27 01:29:43 +00001387 D.complete(ThisDecl);
Richard Smith02e85f32011-04-14 22:09:26 +00001388 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1);
1389 }
1390
Chris Lattner0e62c1c2011-07-23 10:55:15 +00001391 SmallVector<Decl *, 8> DeclsInGroup;
Richard Smith02e85f32011-04-14 22:09:26 +00001392 Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +00001393 if (LateParsedAttrs.size() > 0)
1394 ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
John McCall28a6aea2009-11-04 02:18:39 +00001395 D.complete(FirstDecl);
John McCall48871652010-08-21 09:40:31 +00001396 if (FirstDecl)
John McCalld5a36322009-11-03 19:26:08 +00001397 DeclsInGroup.push_back(FirstDecl);
1398
Richard Smith09f76ee2011-10-19 21:33:05 +00001399 bool ExpectSemi = Context != Declarator::ForContext;
Fariborz Jahanian577574a2012-07-02 23:37:09 +00001400
John McCalld5a36322009-11-03 19:26:08 +00001401 // If we don't have a comma, it is either the end of the list (a ';') or an
1402 // error, bail out.
1403 while (Tok.is(tok::comma)) {
Richard Smith09f76ee2011-10-19 21:33:05 +00001404 SourceLocation CommaLoc = ConsumeToken();
1405
1406 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1407 // This comma was followed by a line-break and something which can't be
1408 // the start of a declarator. The comma was probably a typo for a
1409 // semicolon.
1410 Diag(CommaLoc, diag::err_expected_semi_declaration)
1411 << FixItHint::CreateReplacement(CommaLoc, ";");
1412 ExpectSemi = false;
1413 break;
1414 }
John McCalld5a36322009-11-03 19:26:08 +00001415
1416 // Parse the next declarator.
1417 D.clear();
Richard Smith8d06f422012-01-12 23:53:29 +00001418 D.setCommaLoc(CommaLoc);
John McCalld5a36322009-11-03 19:26:08 +00001419
1420 // Accept attributes in an init-declarator. In the first declarator in a
1421 // declaration, these would be part of the declspec. In subsequent
1422 // declarators, they become part of the declarator itself, so that they
1423 // don't apply to declarators after *this* one. Examples:
1424 // short __attribute__((common)) var; -> declspec
1425 // short var __attribute__((common)); -> declarator
1426 // short x, __attribute__((common)) var; -> declarator
John McCall53fa7142010-12-24 02:08:15 +00001427 MaybeParseGNUAttributes(D);
John McCalld5a36322009-11-03 19:26:08 +00001428
1429 ParseDeclarator(D);
Fariborz Jahanian372030b2012-01-13 00:14:12 +00001430 if (!D.isInvalidType()) {
1431 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1432 D.complete(ThisDecl);
1433 if (ThisDecl)
Chad Rosierc1183952012-06-26 22:30:43 +00001434 DeclsInGroup.push_back(ThisDecl);
Fariborz Jahanian372030b2012-01-13 00:14:12 +00001435 }
John McCalld5a36322009-11-03 19:26:08 +00001436 }
1437
1438 if (DeclEnd)
1439 *DeclEnd = Tok.getLocation();
1440
Richard Smith09f76ee2011-10-19 21:33:05 +00001441 if (ExpectSemi &&
Chris Lattner02f1b612012-04-28 16:12:17 +00001442 ExpectAndConsumeSemi(Context == Declarator::FileContext
1443 ? diag::err_invalid_token_after_toplevel_declarator
1444 : diag::err_expected_semi_declaration)) {
Chris Lattner13901342010-07-11 22:42:07 +00001445 // Okay, there was no semicolon and one was expected. If we see a
1446 // declaration specifier, just assume it was missing and continue parsing.
1447 // Otherwise things are very confused and we skip to recover.
1448 if (!isDeclarationSpecifier()) {
1449 SkipUntil(tok::r_brace, true, true);
1450 if (Tok.is(tok::semi))
1451 ConsumeToken();
1452 }
John McCalld5a36322009-11-03 19:26:08 +00001453 }
1454
Douglas Gregor0be31a22010-07-02 17:43:08 +00001455 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
John McCalld5a36322009-11-03 19:26:08 +00001456 DeclsInGroup.data(),
1457 DeclsInGroup.size());
Chris Lattner53361ac2006-08-10 05:19:57 +00001458}
1459
Richard Smith02e85f32011-04-14 22:09:26 +00001460/// Parse an optional simple-asm-expr and attributes, and attach them to a
1461/// declarator. Returns true on an error.
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +00001462bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
Richard Smith02e85f32011-04-14 22:09:26 +00001463 // If a simple-asm-expr is present, parse it.
1464 if (Tok.is(tok::kw_asm)) {
1465 SourceLocation Loc;
1466 ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1467 if (AsmLabel.isInvalid()) {
1468 SkipUntil(tok::semi, true, true);
1469 return true;
1470 }
1471
1472 D.setAsmLabel(AsmLabel.release());
1473 D.SetRangeEnd(Loc);
1474 }
1475
1476 MaybeParseGNUAttributes(D);
1477 return false;
1478}
1479
Douglas Gregor23996282009-05-12 21:31:51 +00001480/// \brief Parse 'declaration' after parsing 'declaration-specifiers
1481/// declarator'. This method parses the remainder of the declaration
1482/// (including any attributes or initializer, among other things) and
1483/// finalizes the declaration.
Chris Lattnerf0f3baa2006-08-14 00:15:20 +00001484///
Chris Lattnerf0f3baa2006-08-14 00:15:20 +00001485/// init-declarator: [C99 6.7]
1486/// declarator
1487/// declarator '=' initializer
Chris Lattner6d7e6342006-08-15 03:41:14 +00001488/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
1489/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argyrios Kyrtzidis9a1191c2008-10-06 17:10:33 +00001490/// [C++] declarator initializer[opt]
1491///
1492/// [C++] initializer:
1493/// [C++] '=' initializer-clause
1494/// [C++] '(' expression-list ')'
Sebastian Redlf769df52009-03-24 22:27:57 +00001495/// [C++0x] '=' 'default' [TODO]
1496/// [C++0x] '=' 'delete'
Sebastian Redl3da34892011-06-05 12:23:16 +00001497/// [C++0x] braced-init-list
Sebastian Redlf769df52009-03-24 22:27:57 +00001498///
1499/// According to the standard grammar, =default and =delete are function
1500/// definitions, but that definitely doesn't fit with the parser here.
Chris Lattnerf0f3baa2006-08-14 00:15:20 +00001501///
John McCall48871652010-08-21 09:40:31 +00001502Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
Douglas Gregorb52fabb2009-06-23 23:11:28 +00001503 const ParsedTemplateInfo &TemplateInfo) {
DeLesley Hutchins3fc6e4a2012-02-16 16:50:43 +00001504 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smith02e85f32011-04-14 22:09:26 +00001505 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001506
Richard Smith02e85f32011-04-14 22:09:26 +00001507 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1508}
Mike Stump11289f42009-09-09 15:08:12 +00001509
Richard Smith02e85f32011-04-14 22:09:26 +00001510Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1511 const ParsedTemplateInfo &TemplateInfo) {
Douglas Gregor23996282009-05-12 21:31:51 +00001512 // Inform the current actions module that we just parsed this declarator.
John McCall48871652010-08-21 09:40:31 +00001513 Decl *ThisDecl = 0;
Douglas Gregor450f00842009-09-25 18:43:00 +00001514 switch (TemplateInfo.Kind) {
1515 case ParsedTemplateInfo::NonTemplate:
Douglas Gregor0be31a22010-07-02 17:43:08 +00001516 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
Douglas Gregor450f00842009-09-25 18:43:00 +00001517 break;
Chad Rosierc1183952012-06-26 22:30:43 +00001518
Douglas Gregor450f00842009-09-25 18:43:00 +00001519 case ParsedTemplateInfo::Template:
1520 case ParsedTemplateInfo::ExplicitSpecialization:
Douglas Gregor0be31a22010-07-02 17:43:08 +00001521 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
John McCallfaf5fb42010-08-26 23:41:50 +00001522 MultiTemplateParamsArg(Actions,
Douglas Gregorb52fabb2009-06-23 23:11:28 +00001523 TemplateInfo.TemplateParams->data(),
1524 TemplateInfo.TemplateParams->size()),
Douglas Gregor450f00842009-09-25 18:43:00 +00001525 D);
1526 break;
Chad Rosierc1183952012-06-26 22:30:43 +00001527
Douglas Gregor450f00842009-09-25 18:43:00 +00001528 case ParsedTemplateInfo::ExplicitInstantiation: {
Chad Rosierc1183952012-06-26 22:30:43 +00001529 DeclResult ThisRes
Douglas Gregor0be31a22010-07-02 17:43:08 +00001530 = Actions.ActOnExplicitInstantiation(getCurScope(),
Douglas Gregor450f00842009-09-25 18:43:00 +00001531 TemplateInfo.ExternLoc,
1532 TemplateInfo.TemplateLoc,
1533 D);
1534 if (ThisRes.isInvalid()) {
1535 SkipUntil(tok::semi, true, true);
John McCall48871652010-08-21 09:40:31 +00001536 return 0;
Douglas Gregor450f00842009-09-25 18:43:00 +00001537 }
Chad Rosierc1183952012-06-26 22:30:43 +00001538
Douglas Gregor450f00842009-09-25 18:43:00 +00001539 ThisDecl = ThisRes.get();
1540 break;
1541 }
1542 }
Mike Stump11289f42009-09-09 15:08:12 +00001543
Richard Smith30482bc2011-02-20 03:19:35 +00001544 bool TypeContainsAuto =
1545 D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
1546
Douglas Gregor23996282009-05-12 21:31:51 +00001547 // Parse declarator '=' initializer.
Richard Trieuc64d3232012-01-18 22:54:52 +00001548 // If a '==' or '+=' is found, suggest a fixit to '='.
Richard Trieu4972a6d2012-01-19 22:01:51 +00001549 if (isTokenEqualOrEqualTypo()) {
Douglas Gregor23996282009-05-12 21:31:51 +00001550 ConsumeToken();
Anders Carlsson991285e2010-09-24 21:25:25 +00001551 if (Tok.is(tok::kw_delete)) {
Alexis Hunt5a7fa252011-05-12 06:15:49 +00001552 if (D.isFunctionDeclarator())
1553 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1554 << 1 /* delete */;
1555 else
1556 Diag(ConsumeToken(), diag::err_deleted_non_function);
Alexis Hunt5dafebc2011-05-06 01:42:00 +00001557 } else if (Tok.is(tok::kw_default)) {
Alexis Hunt5a7fa252011-05-12 06:15:49 +00001558 if (D.isFunctionDeclarator())
Sebastian Redl46afb552012-02-11 23:51:21 +00001559 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1560 << 0 /* default */;
Alexis Hunt5a7fa252011-05-12 06:15:49 +00001561 else
1562 Diag(ConsumeToken(), diag::err_default_special_members);
Douglas Gregor23996282009-05-12 21:31:51 +00001563 } else {
David Blaikiebbafb8a2012-03-11 07:00:24 +00001564 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
John McCall1f4ee7b2009-12-19 09:28:58 +00001565 EnterScope(0);
Douglas Gregor0be31a22010-07-02 17:43:08 +00001566 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
John McCall1f4ee7b2009-12-19 09:28:58 +00001567 }
Argyrios Kyrtzidis3df19782009-06-17 22:50:06 +00001568
Douglas Gregor7aa6b222010-05-30 01:49:25 +00001569 if (Tok.is(tok::code_completion)) {
Douglas Gregor0be31a22010-07-02 17:43:08 +00001570 Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
Peter Collingbourne6b4fdc22012-07-27 12:56:09 +00001571 Actions.FinalizeDeclaration(ThisDecl);
Argyrios Kyrtzidis5cec2ae2011-09-04 03:32:15 +00001572 cutOffParsing();
1573 return 0;
Douglas Gregor7aa6b222010-05-30 01:49:25 +00001574 }
Chad Rosierc1183952012-06-26 22:30:43 +00001575
John McCalldadc5752010-08-24 06:29:42 +00001576 ExprResult Init(ParseInitializer());
Argyrios Kyrtzidis3df19782009-06-17 22:50:06 +00001577
David Blaikiebbafb8a2012-03-11 07:00:24 +00001578 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor0be31a22010-07-02 17:43:08 +00001579 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
John McCall1f4ee7b2009-12-19 09:28:58 +00001580 ExitScope();
1581 }
Argyrios Kyrtzidis3df19782009-06-17 22:50:06 +00001582
Douglas Gregor23996282009-05-12 21:31:51 +00001583 if (Init.isInvalid()) {
Douglas Gregor604c3022010-03-01 18:27:54 +00001584 SkipUntil(tok::comma, true, true);
1585 Actions.ActOnInitializerError(ThisDecl);
1586 } else
Richard Smith30482bc2011-02-20 03:19:35 +00001587 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1588 /*DirectInit=*/false, TypeContainsAuto);
Douglas Gregor23996282009-05-12 21:31:51 +00001589 }
1590 } else if (Tok.is(tok::l_paren)) {
1591 // Parse C++ direct initializer: '(' expression-list ')'
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00001592 BalancedDelimiterTracker T(*this, tok::l_paren);
1593 T.consumeOpen();
1594
Douglas Gregor23996282009-05-12 21:31:51 +00001595 ExprVector Exprs(Actions);
1596 CommaLocsTy CommaLocs;
1597
David Blaikiebbafb8a2012-03-11 07:00:24 +00001598 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor613bf102009-12-22 17:47:17 +00001599 EnterScope(0);
Douglas Gregor0be31a22010-07-02 17:43:08 +00001600 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregor613bf102009-12-22 17:47:17 +00001601 }
1602
Douglas Gregor23996282009-05-12 21:31:51 +00001603 if (ParseExpressionList(Exprs, CommaLocs)) {
1604 SkipUntil(tok::r_paren);
Douglas Gregor613bf102009-12-22 17:47:17 +00001605
David Blaikiebbafb8a2012-03-11 07:00:24 +00001606 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor0be31a22010-07-02 17:43:08 +00001607 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregor613bf102009-12-22 17:47:17 +00001608 ExitScope();
1609 }
Douglas Gregor23996282009-05-12 21:31:51 +00001610 } else {
1611 // Match the ')'.
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00001612 T.consumeClose();
Douglas Gregor23996282009-05-12 21:31:51 +00001613
1614 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1615 "Unexpected number of commas!");
Douglas Gregor613bf102009-12-22 17:47:17 +00001616
David Blaikiebbafb8a2012-03-11 07:00:24 +00001617 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor0be31a22010-07-02 17:43:08 +00001618 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregor613bf102009-12-22 17:47:17 +00001619 ExitScope();
1620 }
1621
Sebastian Redla9351792012-02-11 23:51:47 +00001622 ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
1623 T.getCloseLocation(),
1624 move_arg(Exprs));
1625 Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
1626 /*DirectInit=*/true, TypeContainsAuto);
Douglas Gregor23996282009-05-12 21:31:51 +00001627 }
Fariborz Jahanian8a369a82012-07-03 22:54:28 +00001628 } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace) &&
Fariborz Jahanian8be1ecd2012-07-03 23:22:13 +00001629 (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
Sebastian Redl3da34892011-06-05 12:23:16 +00001630 // Parse C++0x braced-init-list.
Richard Smith5d164bc2011-10-15 05:09:34 +00001631 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1632
Sebastian Redl3da34892011-06-05 12:23:16 +00001633 if (D.getCXXScopeSpec().isSet()) {
1634 EnterScope(0);
1635 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1636 }
1637
1638 ExprResult Init(ParseBraceInitializer());
1639
1640 if (D.getCXXScopeSpec().isSet()) {
1641 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1642 ExitScope();
1643 }
1644
1645 if (Init.isInvalid()) {
1646 Actions.ActOnInitializerError(ThisDecl);
1647 } else
1648 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1649 /*DirectInit=*/true, TypeContainsAuto);
1650
Douglas Gregor23996282009-05-12 21:31:51 +00001651 } else {
Richard Smith30482bc2011-02-20 03:19:35 +00001652 Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
Douglas Gregor23996282009-05-12 21:31:51 +00001653 }
1654
Richard Smithb2bc2e62011-02-21 20:05:19 +00001655 Actions.FinalizeDeclaration(ThisDecl);
1656
Douglas Gregor23996282009-05-12 21:31:51 +00001657 return ThisDecl;
1658}
1659
Chris Lattner1890ac82006-08-13 01:16:23 +00001660/// ParseSpecifierQualifierList
1661/// specifier-qualifier-list:
1662/// type-specifier specifier-qualifier-list[opt]
1663/// type-qualifier specifier-qualifier-list[opt]
Chris Lattnere37e2332006-08-15 04:50:22 +00001664/// [GNU] attributes specifier-qualifier-list[opt]
Chris Lattner1890ac82006-08-13 01:16:23 +00001665///
Richard Smithc5b05522012-03-12 07:56:15 +00001666void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1667 DeclSpecContext DSC) {
Chris Lattner1890ac82006-08-13 01:16:23 +00001668 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
1669 /// parse declaration-specifiers and complain about extra stuff.
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001670 /// TODO: diagnose attribute-specifiers and alignment-specifiers.
Richard Smithc5b05522012-03-12 07:56:15 +00001671 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
Mike Stump11289f42009-09-09 15:08:12 +00001672
Chris Lattner1890ac82006-08-13 01:16:23 +00001673 // Validate declspec for type-name.
1674 unsigned Specs = DS.getParsedSpecifiers();
Richard Smith2f07ad52012-05-09 20:55:26 +00001675 if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1676 !DS.hasTypeSpecifier()) {
Richard Smithc5b05522012-03-12 07:56:15 +00001677 Diag(Tok, diag::err_expected_type);
1678 DS.SetTypeSpecError();
1679 } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
1680 !DS.hasAttributes()) {
Chris Lattner1890ac82006-08-13 01:16:23 +00001681 Diag(Tok, diag::err_typename_requires_specqual);
Richard Smithc5b05522012-03-12 07:56:15 +00001682 if (!DS.hasTypeSpecifier())
1683 DS.SetTypeSpecError();
1684 }
Mike Stump11289f42009-09-09 15:08:12 +00001685
Chris Lattner1b22eed2006-11-28 05:12:07 +00001686 // Issue diagnostic and remove storage class if present.
Chris Lattner1890ac82006-08-13 01:16:23 +00001687 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
Chris Lattner1b22eed2006-11-28 05:12:07 +00001688 if (DS.getStorageClassSpecLoc().isValid())
1689 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1690 else
1691 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
Chris Lattnera925dc62006-11-28 04:33:46 +00001692 DS.ClearStorageClassSpecs();
Chris Lattner1890ac82006-08-13 01:16:23 +00001693 }
Mike Stump11289f42009-09-09 15:08:12 +00001694
Chris Lattner1b22eed2006-11-28 05:12:07 +00001695 // Issue diagnostic and remove function specfier if present.
Chris Lattner1890ac82006-08-13 01:16:23 +00001696 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregor61956c42008-10-31 09:07:45 +00001697 if (DS.isInlineSpecified())
1698 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
1699 if (DS.isVirtualSpecified())
1700 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
1701 if (DS.isExplicitSpecified())
1702 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
Chris Lattnera925dc62006-11-28 04:33:46 +00001703 DS.ClearFunctionSpecs();
Chris Lattner1890ac82006-08-13 01:16:23 +00001704 }
Richard Smithc5b05522012-03-12 07:56:15 +00001705
1706 // Issue diagnostic and remove constexpr specfier if present.
1707 if (DS.isConstexprSpecified()) {
1708 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
1709 DS.ClearConstexprSpec();
1710 }
Chris Lattner1890ac82006-08-13 01:16:23 +00001711}
Chris Lattner53361ac2006-08-10 05:19:57 +00001712
Chris Lattner6cc055a2009-04-12 20:42:31 +00001713/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
1714/// specified token is valid after the identifier in a declarator which
1715/// immediately follows the declspec. For example, these things are valid:
1716///
1717/// int x [ 4]; // direct-declarator
1718/// int x ( int y); // direct-declarator
1719/// int(int x ) // direct-declarator
1720/// int x ; // simple-declaration
1721/// int x = 17; // init-declarator-list
1722/// int x , y; // init-declarator-list
1723/// int x __asm__ ("foo"); // init-declarator-list
Chris Lattnera723ba92009-04-14 21:16:09 +00001724/// int x : 4; // struct-declarator
Chris Lattner2b988c12009-04-12 22:29:43 +00001725/// int x { 5}; // C++'0x unified initializers
Chris Lattner6cc055a2009-04-12 20:42:31 +00001726///
1727/// This is not, because 'x' does not immediately follow the declspec (though
1728/// ')' happens to be valid anyway).
1729/// int (x)
1730///
1731static bool isValidAfterIdentifierInDeclarator(const Token &T) {
1732 return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
1733 T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
Chris Lattnera723ba92009-04-14 21:16:09 +00001734 T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
Chris Lattner6cc055a2009-04-12 20:42:31 +00001735}
1736
Chris Lattner20a0c612009-04-14 21:34:55 +00001737
1738/// ParseImplicitInt - This method is called when we have an non-typename
1739/// identifier in a declspec (which normally terminates the decl spec) when
1740/// the declspec has no type specifier. In this case, the declspec is either
1741/// malformed or is "implicit int" (in K&R and C89).
1742///
1743/// This method handles diagnosing this prettily and returns false if the
1744/// declspec is done being processed. If it recovers and thinks there may be
1745/// other pieces of declspec after it, it returns true.
1746///
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001747bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
Douglas Gregor1b57ff32009-05-12 23:25:50 +00001748 const ParsedTemplateInfo &TemplateInfo,
Richard Smithc5b05522012-03-12 07:56:15 +00001749 AccessSpecifier AS, DeclSpecContext DSC) {
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001750 assert(Tok.is(tok::identifier) && "should have identifier");
Mike Stump11289f42009-09-09 15:08:12 +00001751
Chris Lattner20a0c612009-04-14 21:34:55 +00001752 SourceLocation Loc = Tok.getLocation();
1753 // If we see an identifier that is not a type name, we normally would
1754 // parse it as the identifer being declared. However, when a typename
1755 // is typo'd or the definition is not included, this will incorrectly
1756 // parse the typename as the identifier name and fall over misparsing
1757 // later parts of the diagnostic.
1758 //
1759 // As such, we try to do some look-ahead in cases where this would
1760 // otherwise be an "implicit-int" case to see if this is invalid. For
1761 // example: "static foo_t x = 4;" In this case, if we parsed foo_t as
1762 // an identifier with implicit int, we'd get a parse error because the
1763 // next token is obviously invalid for a type. Parse these as a case
1764 // with an invalid type specifier.
1765 assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
Mike Stump11289f42009-09-09 15:08:12 +00001766
Chris Lattner20a0c612009-04-14 21:34:55 +00001767 // Since we know that this either implicit int (which is rare) or an
Richard Smitha952ebb2012-05-15 21:01:51 +00001768 // error, do lookahead to try to do better recovery. This never applies
1769 // within a type specifier. Outside of C++, we allow this even if the
1770 // language doesn't "officially" support implicit int -- we support
1771 // implicit int as an extension in C99 and C11. Allegedly, MS also
1772 // supports implicit int in C++ mode.
Richard Smith2f07ad52012-05-09 20:55:26 +00001773 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
Richard Smitha952ebb2012-05-15 21:01:51 +00001774 (!getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt) &&
Richard Smithc5b05522012-03-12 07:56:15 +00001775 isValidAfterIdentifierInDeclarator(NextToken())) {
Chris Lattner20a0c612009-04-14 21:34:55 +00001776 // If this token is valid for implicit int, e.g. "static x = 4", then
1777 // we just avoid eating the identifier, so it will be parsed as the
1778 // identifier in the declarator.
1779 return false;
1780 }
Mike Stump11289f42009-09-09 15:08:12 +00001781
Richard Smitha952ebb2012-05-15 21:01:51 +00001782 if (getLangOpts().CPlusPlus &&
1783 DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
1784 // Don't require a type specifier if we have the 'auto' storage class
1785 // specifier in C++98 -- we'll promote it to a type specifier.
1786 return false;
1787 }
1788
Chris Lattner20a0c612009-04-14 21:34:55 +00001789 // Otherwise, if we don't consume this token, we are going to emit an
1790 // error anyway. Try to recover from various common problems. Check
1791 // to see if this was a reference to a tag name without a tag specified.
1792 // This is a common problem in C (saying 'foo' instead of 'struct foo').
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001793 //
1794 // C++ doesn't need this, and isTagName doesn't take SS.
1795 if (SS == 0) {
Argyrios Kyrtzidis1f329402011-04-21 17:29:47 +00001796 const char *TagName = 0, *FixitTagName = 0;
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001797 tok::TokenKind TagKind = tok::unknown;
Mike Stump11289f42009-09-09 15:08:12 +00001798
Douglas Gregor0be31a22010-07-02 17:43:08 +00001799 switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
Chris Lattner20a0c612009-04-14 21:34:55 +00001800 default: break;
Argyrios Kyrtzidis1f329402011-04-21 17:29:47 +00001801 case DeclSpec::TST_enum:
1802 TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break;
1803 case DeclSpec::TST_union:
1804 TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
1805 case DeclSpec::TST_struct:
1806 TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
1807 case DeclSpec::TST_class:
1808 TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
Chris Lattner20a0c612009-04-14 21:34:55 +00001809 }
Mike Stump11289f42009-09-09 15:08:12 +00001810
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001811 if (TagName) {
Kaelyn Uhrain031643e2012-04-26 23:36:17 +00001812 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
1813 LookupResult R(Actions, TokenName, SourceLocation(),
1814 Sema::LookupOrdinaryName);
1815
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001816 Diag(Loc, diag::err_use_of_tag_name_without_tag)
Kaelyn Uhrain031643e2012-04-26 23:36:17 +00001817 << TokenName << TagName << getLangOpts().CPlusPlus
1818 << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
1819
1820 if (Actions.LookupParsedName(R, getCurScope(), SS)) {
1821 for (LookupResult::iterator I = R.begin(), IEnd = R.end();
1822 I != IEnd; ++I)
Kaelyn Uhrain3fe3f852012-04-27 18:26:49 +00001823 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
Kaelyn Uhrain031643e2012-04-26 23:36:17 +00001824 << TokenName << TagName;
1825 }
Mike Stump11289f42009-09-09 15:08:12 +00001826
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001827 // Parse this as a tag as if the missing tag were present.
1828 if (TagKind == tok::kw_enum)
Richard Smithc5b05522012-03-12 07:56:15 +00001829 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001830 else
Richard Smithc5b05522012-03-12 07:56:15 +00001831 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
1832 /*EnteringContext*/ false, DSC_normal);
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00001833 return true;
1834 }
Chris Lattner20a0c612009-04-14 21:34:55 +00001835 }
Mike Stump11289f42009-09-09 15:08:12 +00001836
Richard Smithfe904f02012-05-15 21:29:55 +00001837 // Determine whether this identifier could plausibly be the name of something
Richard Smithedd124e2012-05-15 21:42:17 +00001838 // being declared (with a missing type).
Richard Smithfe904f02012-05-15 21:29:55 +00001839 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
1840 (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
Richard Smitha952ebb2012-05-15 21:01:51 +00001841 // Look ahead to the next token to try to figure out what this declaration
1842 // was supposed to be.
1843 switch (NextToken().getKind()) {
1844 case tok::comma:
1845 case tok::equal:
1846 case tok::kw_asm:
1847 case tok::l_brace:
1848 case tok::l_square:
1849 case tok::semi:
1850 // This looks like a variable declaration. The type is probably missing.
1851 // We're done parsing decl-specifiers.
1852 return false;
1853
1854 case tok::l_paren: {
1855 // static x(4); // 'x' is not a type
1856 // x(int n); // 'x' is not a type
1857 // x (*p)[]; // 'x' is a type
1858 //
1859 // Since we're in an error case (or the rare 'implicit int in C++' MS
1860 // extension), we can afford to perform a tentative parse to determine
1861 // which case we're in.
1862 TentativeParsingAction PA(*this);
1863 ConsumeToken();
1864 TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
1865 PA.Revert();
1866 if (TPR == TPResult::False())
1867 return false;
1868 // The identifier is followed by a parenthesized declarator.
1869 // It's supposed to be a type.
1870 break;
1871 }
1872
1873 default:
1874 // This is probably supposed to be a type. This includes cases like:
1875 // int f(itn);
1876 // struct S { unsinged : 4; };
1877 break;
1878 }
1879 }
1880
Chad Rosierc1183952012-06-26 22:30:43 +00001881 // This is almost certainly an invalid type name. Let the action emit a
Douglas Gregor15e56022009-10-13 23:27:22 +00001882 // diagnostic and attempt to recover.
John McCallba7bf592010-08-24 05:47:05 +00001883 ParsedType T;
Kaelyn Uhrainb5b17fe2012-06-15 23:45:58 +00001884 IdentifierInfo *II = Tok.getIdentifierInfo();
1885 if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
Douglas Gregor15e56022009-10-13 23:27:22 +00001886 // The action emitted a diagnostic, so we don't have to.
1887 if (T) {
1888 // The action has suggested that the type T could be used. Set that as
1889 // the type in the declaration specifiers, consume the would-be type
1890 // name token, and we're done.
1891 const char *PrevSpec;
1892 unsigned DiagID;
John McCallba7bf592010-08-24 05:47:05 +00001893 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
Douglas Gregor15e56022009-10-13 23:27:22 +00001894 DS.SetRangeEnd(Tok.getLocation());
1895 ConsumeToken();
Kaelyn Uhrainb5b17fe2012-06-15 23:45:58 +00001896 // There may be other declaration specifiers after this.
1897 return true;
1898 } else if (II != Tok.getIdentifierInfo()) {
1899 // If no type was suggested, the correction is to a keyword
1900 Tok.setKind(II->getTokenID());
Douglas Gregor15e56022009-10-13 23:27:22 +00001901 // There may be other declaration specifiers after this.
1902 return true;
1903 }
Chad Rosierc1183952012-06-26 22:30:43 +00001904
Douglas Gregor15e56022009-10-13 23:27:22 +00001905 // Fall through; the action had no suggestion for us.
1906 } else {
1907 // The action did not emit a diagnostic, so emit one now.
1908 SourceRange R;
1909 if (SS) R = SS->getRange();
1910 Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
1911 }
Mike Stump11289f42009-09-09 15:08:12 +00001912
Douglas Gregor15e56022009-10-13 23:27:22 +00001913 // Mark this as an error.
Richard Smithc5b05522012-03-12 07:56:15 +00001914 DS.SetTypeSpecError();
Chris Lattner20a0c612009-04-14 21:34:55 +00001915 DS.SetRangeEnd(Tok.getLocation());
1916 ConsumeToken();
Mike Stump11289f42009-09-09 15:08:12 +00001917
Chris Lattner20a0c612009-04-14 21:34:55 +00001918 // TODO: Could inject an invalid typedef decl in an enclosing scope to
1919 // avoid rippling error messages on subsequent uses of the same type,
1920 // could be useful if #include was forgotten.
1921 return false;
1922}
1923
Douglas Gregor9de54ea2010-01-13 17:31:36 +00001924/// \brief Determine the declaration specifier context from the declarator
1925/// context.
1926///
1927/// \param Context the declarator context, which is one of the
1928/// Declarator::TheContext enumerator values.
Chad Rosierc1183952012-06-26 22:30:43 +00001929Parser::DeclSpecContext
Douglas Gregor9de54ea2010-01-13 17:31:36 +00001930Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
1931 if (Context == Declarator::MemberContext)
1932 return DSC_class;
1933 if (Context == Declarator::FileContext)
1934 return DSC_top_level;
Richard Smith62dad822012-03-15 01:02:11 +00001935 if (Context == Declarator::TrailingReturnContext)
1936 return DSC_trailing;
Douglas Gregor9de54ea2010-01-13 17:31:36 +00001937 return DSC_normal;
1938}
1939
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001940/// ParseAlignArgument - Parse the argument to an alignment-specifier.
1941///
1942/// FIXME: Simply returns an alignof() expression if the argument is a
1943/// type. Ideally, the type should be propagated directly into Sema.
1944///
Benjamin Kramere56f3932011-12-23 17:00:35 +00001945/// [C11] type-id
1946/// [C11] constant-expression
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00001947/// [C++0x] type-id ...[opt]
1948/// [C++0x] assignment-expression ...[opt]
1949ExprResult Parser::ParseAlignArgument(SourceLocation Start,
1950 SourceLocation &EllipsisLoc) {
1951 ExprResult ER;
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001952 if (isTypeIdInParens()) {
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001953 SourceLocation TypeLoc = Tok.getLocation();
1954 ParsedType Ty = ParseTypeName().get();
1955 SourceRange TypeRange(Start, Tok.getLocation());
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00001956 ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
1957 Ty.getAsOpaquePtr(), TypeRange);
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001958 } else
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00001959 ER = ParseConstantExpression();
1960
David Blaikiebbafb8a2012-03-11 07:00:24 +00001961 if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis))
Peter Collingbourneccbcce02011-10-24 17:56:00 +00001962 EllipsisLoc = ConsumeToken();
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00001963
1964 return ER;
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001965}
1966
1967/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
1968/// attribute to Attrs.
1969///
1970/// alignment-specifier:
Benjamin Kramere56f3932011-12-23 17:00:35 +00001971/// [C11] '_Alignas' '(' type-id ')'
1972/// [C11] '_Alignas' '(' constant-expression ')'
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00001973/// [C++0x] 'alignas' '(' type-id ...[opt] ')'
1974/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')'
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001975void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
1976 SourceLocation *endLoc) {
1977 assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
1978 "Not an alignment-specifier!");
1979
1980 SourceLocation KWLoc = Tok.getLocation();
1981 ConsumeToken();
1982
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00001983 BalancedDelimiterTracker T(*this, tok::l_paren);
1984 if (T.expectAndConsume(diag::err_expected_lparen))
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001985 return;
1986
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00001987 SourceLocation EllipsisLoc;
1988 ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001989 if (ArgExpr.isInvalid()) {
1990 SkipUntil(tok::r_paren);
1991 return;
1992 }
1993
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00001994 T.consumeClose();
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001995 if (endLoc)
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00001996 *endLoc = T.getCloseLocation();
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00001997
Peter Collingbourne7d33cd32011-10-23 20:07:52 +00001998 // FIXME: Handle pack-expansions here.
1999 if (EllipsisLoc.isValid()) {
2000 Diag(EllipsisLoc, diag::err_alignas_pack_exp_unsupported);
2001 return;
2002 }
2003
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00002004 ExprVector ArgExprs(Actions);
2005 ArgExprs.push_back(ArgExpr.release());
Alexis Hunt3bc72c12012-06-19 23:57:03 +00002006 // FIXME: This should not be GNU, but we since the attribute used is
2007 // based on the spelling, and there is no true spelling for
2008 // C++11 attributes, this isn't accepted.
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00002009 Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
Alexis Hunta0e54d42012-06-18 16:13:52 +00002010 0, T.getOpenLocation(), ArgExprs.take(), 1,
Alexis Hunt3bc72c12012-06-19 23:57:03 +00002011 AttributeList::AS_GNU);
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00002012}
2013
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00002014/// ParseDeclarationSpecifiers
2015/// declaration-specifiers: [C99 6.7]
Chris Lattner3b561a32006-08-13 00:12:11 +00002016/// storage-class-specifier declaration-specifiers[opt]
2017/// type-specifier declaration-specifiers[opt]
Chris Lattner3b561a32006-08-13 00:12:11 +00002018/// [C99] function-specifier declaration-specifiers[opt]
Benjamin Kramere56f3932011-12-23 17:00:35 +00002019/// [C11] alignment-specifier declaration-specifiers[opt]
Chris Lattnere37e2332006-08-15 04:50:22 +00002020/// [GNU] attributes declaration-specifiers[opt]
Douglas Gregor26701a42011-09-09 02:06:17 +00002021/// [Clang] '__module_private__' declaration-specifiers[opt]
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00002022///
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002023/// storage-class-specifier: [C99 6.7.1]
Chris Lattnerda48a8e2006-08-04 05:25:55 +00002024/// 'typedef'
2025/// 'extern'
2026/// 'static'
2027/// 'auto'
2028/// 'register'
Sebastian Redlccdfaba2008-11-14 23:42:31 +00002029/// [C++] 'mutable'
Chris Lattnerda48a8e2006-08-04 05:25:55 +00002030/// [GNU] '__thread'
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002031/// function-specifier: [C99 6.7.4]
Chris Lattner3b561a32006-08-13 00:12:11 +00002032/// [C99] 'inline'
Douglas Gregor61956c42008-10-31 09:07:45 +00002033/// [C++] 'virtual'
2034/// [C++] 'explicit'
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +00002035/// [OpenCL] '__kernel'
Anders Carlssoncd8db412009-05-06 04:46:28 +00002036/// 'friend': [C++ dcl.friend]
Sebastian Redl39c2a8b2009-11-05 15:47:02 +00002037/// 'constexpr': [C++0x dcl.constexpr]
Anders Carlssoncd8db412009-05-06 04:46:28 +00002038
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002039///
Douglas Gregorb9bd8a92008-12-24 02:52:09 +00002040void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Douglas Gregor1b57ff32009-05-12 23:25:50 +00002041 const ParsedTemplateInfo &TemplateInfo,
John McCall07e91c02009-08-06 02:15:43 +00002042 AccessSpecifier AS,
DeLesley Hutchinsbd2ee132012-03-02 22:12:59 +00002043 DeclSpecContext DSContext,
2044 LateParsedAttrList *LateAttrs) {
Douglas Gregor0e7dde52011-04-24 05:37:28 +00002045 if (DS.getSourceRange().isInvalid()) {
2046 DS.SetRangeStart(Tok.getLocation());
2047 DS.SetRangeEnd(Tok.getLocation());
2048 }
Chad Rosierc1183952012-06-26 22:30:43 +00002049
Douglas Gregordf593fb2011-11-07 17:33:42 +00002050 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00002051 bool AttrsLastTime = false;
2052 ParsedAttributesWithRange attrs(AttrFactory);
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00002053 while (1) {
John McCall49bfce42009-08-03 20:12:06 +00002054 bool isInvalid = false;
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002055 const char *PrevSpec = 0;
John McCall49bfce42009-08-03 20:12:06 +00002056 unsigned DiagID = 0;
2057
Chris Lattner4d8f8732006-11-28 05:05:08 +00002058 SourceLocation Loc = Tok.getLocation();
Douglas Gregor450c75a2008-11-07 15:42:26 +00002059
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00002060 switch (Tok.getKind()) {
Mike Stump11289f42009-09-09 15:08:12 +00002061 default:
Chris Lattner0974b232008-07-26 00:20:22 +00002062 DoneWithDeclSpec:
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00002063 if (!AttrsLastTime)
2064 ProhibitAttributes(attrs);
2065 else
2066 DS.takeAttributesFrom(attrs);
Peter Collingbourne70188b32011-09-29 18:03:57 +00002067
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002068 // If this is not a declaration specifier token, we're done reading decl
2069 // specifiers. First verify that DeclSpec's are consistent.
Douglas Gregore3e01a22009-04-01 22:41:11 +00002070 DS.Finish(Diags, PP);
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002071 return;
Mike Stump11289f42009-09-09 15:08:12 +00002072
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00002073 case tok::l_square:
2074 case tok::kw_alignas:
2075 if (!isCXX11AttributeSpecifier())
2076 goto DoneWithDeclSpec;
2077
2078 ProhibitAttributes(attrs);
2079 // FIXME: It would be good to recover by accepting the attributes,
2080 // but attempting to do that now would cause serious
2081 // madness in terms of diagnostics.
2082 attrs.clear();
2083 attrs.Range = SourceRange();
2084
2085 ParseCXX11Attributes(attrs);
2086 AttrsLastTime = true;
Chad Rosierc1183952012-06-26 22:30:43 +00002087 continue;
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00002088
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002089 case tok::code_completion: {
John McCallfaf5fb42010-08-26 23:41:50 +00002090 Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002091 if (DS.hasTypeSpecifier()) {
2092 bool AllowNonIdentifiers
2093 = (getCurScope()->getFlags() & (Scope::ControlScope |
2094 Scope::BlockScope |
2095 Scope::TemplateParamScope |
2096 Scope::FunctionPrototypeScope |
2097 Scope::AtCatchScope)) == 0;
2098 bool AllowNestedNameSpecifiers
Chad Rosierc1183952012-06-26 22:30:43 +00002099 = DSContext == DSC_top_level ||
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002100 (DSContext == DSC_class && DS.isFriendSpecified());
2101
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002102 Actions.CodeCompleteDeclSpec(getCurScope(), DS,
Chad Rosierc1183952012-06-26 22:30:43 +00002103 AllowNonIdentifiers,
Douglas Gregorbfcea8b2010-09-16 15:14:18 +00002104 AllowNestedNameSpecifiers);
Argyrios Kyrtzidis5cec2ae2011-09-04 03:32:15 +00002105 return cutOffParsing();
Chad Rosierc1183952012-06-26 22:30:43 +00002106 }
2107
Douglas Gregor80039242011-02-15 20:33:25 +00002108 if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2109 CCC = Sema::PCC_LocalDeclarationSpecifiers;
2110 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
Chad Rosierc1183952012-06-26 22:30:43 +00002111 CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
John McCallfaf5fb42010-08-26 23:41:50 +00002112 : Sema::PCC_Template;
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002113 else if (DSContext == DSC_class)
John McCallfaf5fb42010-08-26 23:41:50 +00002114 CCC = Sema::PCC_Class;
Argyrios Kyrtzidisb6c6a582012-02-07 16:50:53 +00002115 else if (CurParsedObjCImpl)
John McCallfaf5fb42010-08-26 23:41:50 +00002116 CCC = Sema::PCC_ObjCImplementation;
Chad Rosierc1183952012-06-26 22:30:43 +00002117
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002118 Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
Argyrios Kyrtzidis5cec2ae2011-09-04 03:32:15 +00002119 return cutOffParsing();
Douglas Gregorc49f5b22010-08-23 18:23:48 +00002120 }
2121
Chris Lattnerbd31aa32009-01-05 00:07:25 +00002122 case tok::coloncolon: // ::foo::bar
John McCall1f476a12010-02-26 08:45:28 +00002123 // C++ scope specifier. Annotate and loop, or bail out on error.
2124 if (TryAnnotateCXXScopeToken(true)) {
2125 if (!DS.hasTypeSpecifier())
2126 DS.SetTypeSpecError();
2127 goto DoneWithDeclSpec;
2128 }
John McCall8bc2a702010-03-01 18:20:46 +00002129 if (Tok.is(tok::coloncolon)) // ::new or ::delete
2130 goto DoneWithDeclSpec;
John McCall1f476a12010-02-26 08:45:28 +00002131 continue;
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002132
2133 case tok::annot_cxxscope: {
Richard Smith3092a3b2012-05-09 18:56:43 +00002134 if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002135 goto DoneWithDeclSpec;
2136
John McCall9dab4e62009-12-12 11:40:51 +00002137 CXXScopeSpec SS;
Douglas Gregor869ad452011-02-24 17:54:50 +00002138 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2139 Tok.getAnnotationRange(),
2140 SS);
John McCall9dab4e62009-12-12 11:40:51 +00002141
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002142 // We are looking for a qualified typename.
Douglas Gregor167fa622009-03-25 15:40:00 +00002143 Token Next = NextToken();
Mike Stump11289f42009-09-09 15:08:12 +00002144 if (Next.is(tok::annot_template_id) &&
Douglas Gregor167fa622009-03-25 15:40:00 +00002145 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
Douglas Gregorb67535d2009-03-31 00:43:58 +00002146 ->Kind == TNK_Type_template) {
Douglas Gregor167fa622009-03-25 15:40:00 +00002147 // We have a qualified template-id, e.g., N::A<int>
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002148
2149 // C++ [class.qual]p2:
2150 // In a lookup in which the constructor is an acceptable lookup
2151 // result and the nested-name-specifier nominates a class C:
2152 //
2153 // - if the name specified after the
2154 // nested-name-specifier, when looked up in C, is the
2155 // injected-class-name of C (Clause 9), or
2156 //
2157 // - if the name specified after the nested-name-specifier
2158 // is the same as the identifier or the
2159 // simple-template-id's template-name in the last
2160 // component of the nested-name-specifier,
2161 //
2162 // the name is instead considered to name the constructor of
2163 // class C.
Chad Rosierc1183952012-06-26 22:30:43 +00002164 //
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002165 // Thus, if the template-name is actually the constructor
2166 // name, then the code is ill-formed; this interpretation is
Chad Rosierc1183952012-06-26 22:30:43 +00002167 // reinforced by the NAD status of core issue 635.
Argyrios Kyrtzidisc0c5dd22011-06-22 06:09:49 +00002168 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
John McCall84821e72010-04-13 06:39:49 +00002169 if ((DSContext == DSC_top_level ||
2170 (DSContext == DSC_class && DS.isFriendSpecified())) &&
2171 TemplateId->Name &&
Douglas Gregor0be31a22010-07-02 17:43:08 +00002172 Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002173 if (isConstructorDeclarator()) {
2174 // The user meant this to be an out-of-line constructor
2175 // definition, but template arguments are not allowed
2176 // there. Just allow this as a constructor; we'll
2177 // complain about it later.
2178 goto DoneWithDeclSpec;
2179 }
2180
2181 // The user meant this to name a type, but it actually names
2182 // a constructor with some extraneous template
2183 // arguments. Complain, then parse it as a type as the user
2184 // intended.
2185 Diag(TemplateId->TemplateNameLoc,
2186 diag::err_out_of_line_template_id_names_constructor)
2187 << TemplateId->Name;
2188 }
2189
John McCall9dab4e62009-12-12 11:40:51 +00002190 DS.getTypeSpecScope() = SS;
2191 ConsumeToken(); // The C++ scope.
Mike Stump11289f42009-09-09 15:08:12 +00002192 assert(Tok.is(tok::annot_template_id) &&
Douglas Gregor167fa622009-03-25 15:40:00 +00002193 "ParseOptionalCXXScopeSpecifier not working");
Douglas Gregore7c20652011-03-02 00:47:37 +00002194 AnnotateTemplateIdTokenAsType();
Douglas Gregor167fa622009-03-25 15:40:00 +00002195 continue;
2196 }
2197
Douglas Gregorc5790df2009-09-28 07:26:33 +00002198 if (Next.is(tok::annot_typename)) {
John McCall9dab4e62009-12-12 11:40:51 +00002199 DS.getTypeSpecScope() = SS;
2200 ConsumeToken(); // The C++ scope.
John McCallba7bf592010-08-24 05:47:05 +00002201 if (Tok.getAnnotationValue()) {
2202 ParsedType T = getTypeAnnotation(Tok);
Nico Weber77430342010-11-22 10:30:56 +00002203 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
Chad Rosierc1183952012-06-26 22:30:43 +00002204 Tok.getAnnotationEndLoc(),
John McCallba7bf592010-08-24 05:47:05 +00002205 PrevSpec, DiagID, T);
2206 }
Douglas Gregorc5790df2009-09-28 07:26:33 +00002207 else
2208 DS.SetTypeSpecError();
2209 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2210 ConsumeToken(); // The typename
2211 }
2212
Douglas Gregor167fa622009-03-25 15:40:00 +00002213 if (Next.isNot(tok::identifier))
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002214 goto DoneWithDeclSpec;
2215
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002216 // If we're in a context where the identifier could be a class name,
2217 // check whether this is a constructor declaration.
John McCall84821e72010-04-13 06:39:49 +00002218 if ((DSContext == DSC_top_level ||
2219 (DSContext == DSC_class && DS.isFriendSpecified())) &&
Chad Rosierc1183952012-06-26 22:30:43 +00002220 Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002221 &SS)) {
2222 if (isConstructorDeclarator())
2223 goto DoneWithDeclSpec;
2224
2225 // As noted in C++ [class.qual]p2 (cited above), when the name
2226 // of the class is qualified in a context where it could name
2227 // a constructor, its a constructor name. However, we've
2228 // looked at the declarator, and the user probably meant this
2229 // to be a type. Complain that it isn't supposed to be treated
2230 // as a type, then proceed to parse it as a type.
2231 Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
2232 << Next.getIdentifierInfo();
2233 }
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002234
John McCallba7bf592010-08-24 05:47:05 +00002235 ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2236 Next.getLocation(),
Douglas Gregor844cb502011-03-01 18:12:44 +00002237 getCurScope(), &SS,
2238 false, false, ParsedType(),
Abramo Bagnara4244b432012-01-27 08:46:19 +00002239 /*IsCtorOrDtorName=*/false,
Douglas Gregor844cb502011-03-01 18:12:44 +00002240 /*NonTrivialSourceInfo=*/true);
Douglas Gregor8bf42052009-02-09 18:46:07 +00002241
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00002242 // If the referenced identifier is not a type, then this declspec is
2243 // erroneous: We already checked about that it has no type specifier, and
2244 // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
Mike Stump11289f42009-09-09 15:08:12 +00002245 // typename.
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00002246 if (TypeRep == 0) {
2247 ConsumeToken(); // Eat the scope spec so the identifier is current.
Richard Smithc5b05522012-03-12 07:56:15 +00002248 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue;
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002249 goto DoneWithDeclSpec;
Chris Lattnerb4a8fe82009-04-14 22:17:06 +00002250 }
Mike Stump11289f42009-09-09 15:08:12 +00002251
John McCall9dab4e62009-12-12 11:40:51 +00002252 DS.getTypeSpecScope() = SS;
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002253 ConsumeToken(); // The C++ scope.
2254
Douglas Gregor9817f4a2009-02-09 15:09:02 +00002255 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCall49bfce42009-08-03 20:12:06 +00002256 DiagID, TypeRep);
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002257 if (isInvalid)
2258 break;
Mike Stump11289f42009-09-09 15:08:12 +00002259
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002260 DS.SetRangeEnd(Tok.getLocation());
2261 ConsumeToken(); // The typename.
2262
2263 continue;
2264 }
Mike Stump11289f42009-09-09 15:08:12 +00002265
Chris Lattnere387d9e2009-01-21 19:48:37 +00002266 case tok::annot_typename: {
John McCallba7bf592010-08-24 05:47:05 +00002267 if (Tok.getAnnotationValue()) {
2268 ParsedType T = getTypeAnnotation(Tok);
Nico Weber7f8bb362010-11-22 12:50:03 +00002269 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallba7bf592010-08-24 05:47:05 +00002270 DiagID, T);
2271 } else
Douglas Gregorfe3d7d02009-04-01 21:51:26 +00002272 DS.SetTypeSpecError();
Chad Rosierc1183952012-06-26 22:30:43 +00002273
Chris Lattner005fc1b2010-04-05 18:18:31 +00002274 if (isInvalid)
2275 break;
2276
Chris Lattnere387d9e2009-01-21 19:48:37 +00002277 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2278 ConsumeToken(); // The typename
Mike Stump11289f42009-09-09 15:08:12 +00002279
Chris Lattnere387d9e2009-01-21 19:48:37 +00002280 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2281 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosierc1183952012-06-26 22:30:43 +00002282 // Objective-C interface.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002283 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor06e41ae2010-10-21 23:17:00 +00002284 ParseObjCProtocolQualifiers(DS);
Chad Rosierc1183952012-06-26 22:30:43 +00002285
Chris Lattnere387d9e2009-01-21 19:48:37 +00002286 continue;
2287 }
Mike Stump11289f42009-09-09 15:08:12 +00002288
Douglas Gregor06873092011-04-28 15:48:45 +00002289 case tok::kw___is_signed:
2290 // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
2291 // typically treats it as a trait. If we see __is_signed as it appears
2292 // in libstdc++, e.g.,
2293 //
2294 // static const bool __is_signed;
2295 //
2296 // then treat __is_signed as an identifier rather than as a keyword.
2297 if (DS.getTypeSpecType() == TST_bool &&
2298 DS.getTypeQualifiers() == DeclSpec::TQ_const &&
2299 DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2300 Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
2301 Tok.setKind(tok::identifier);
2302 }
2303
2304 // We're done with the declaration-specifiers.
2305 goto DoneWithDeclSpec;
Chad Rosierc1183952012-06-26 22:30:43 +00002306
Chris Lattner16fac4f2008-07-26 01:18:38 +00002307 // typedef-name
David Blaikie15a430a2011-12-04 05:04:18 +00002308 case tok::kw_decltype:
Chris Lattner16fac4f2008-07-26 01:18:38 +00002309 case tok::identifier: {
Chris Lattnerbd31aa32009-01-05 00:07:25 +00002310 // In C++, check to see if this is a scope specifier like foo::bar::, if
2311 // so handle it as such. This is important for ctor parsing.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002312 if (getLangOpts().CPlusPlus) {
John McCall1f476a12010-02-26 08:45:28 +00002313 if (TryAnnotateCXXScopeToken(true)) {
2314 if (!DS.hasTypeSpecifier())
2315 DS.SetTypeSpecError();
2316 goto DoneWithDeclSpec;
2317 }
2318 if (!Tok.is(tok::identifier))
2319 continue;
2320 }
Mike Stump11289f42009-09-09 15:08:12 +00002321
Chris Lattner16fac4f2008-07-26 01:18:38 +00002322 // This identifier can only be a typedef name if we haven't already seen
2323 // a type-specifier. Without this check we misparse:
2324 // typedef int X; struct Y { short X; }; as 'short int'.
2325 if (DS.hasTypeSpecifier())
2326 goto DoneWithDeclSpec;
Mike Stump11289f42009-09-09 15:08:12 +00002327
John Thompson22334602010-02-05 00:12:22 +00002328 // Check for need to substitute AltiVec keyword tokens.
2329 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2330 break;
2331
Richard Smith3092a3b2012-05-09 18:56:43 +00002332 // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2333 // allow the use of a typedef name as a type specifier.
2334 if (DS.isTypeAltiVecVector())
2335 goto DoneWithDeclSpec;
2336
John McCallba7bf592010-08-24 05:47:05 +00002337 ParsedType TypeRep =
2338 Actions.getTypeName(*Tok.getIdentifierInfo(),
2339 Tok.getLocation(), getCurScope());
Douglas Gregor8bf42052009-02-09 18:46:07 +00002340
Chris Lattner6cc055a2009-04-12 20:42:31 +00002341 // If this is not a typedef name, don't parse it as part of the declspec,
2342 // it must be an implicit int or an error.
John McCallba7bf592010-08-24 05:47:05 +00002343 if (!TypeRep) {
Richard Smithc5b05522012-03-12 07:56:15 +00002344 if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue;
Chris Lattner16fac4f2008-07-26 01:18:38 +00002345 goto DoneWithDeclSpec;
Chris Lattner6cc055a2009-04-12 20:42:31 +00002346 }
Douglas Gregor8bf42052009-02-09 18:46:07 +00002347
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002348 // If we're in a context where the identifier could be a class name,
2349 // check whether this is a constructor declaration.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002350 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor0be31a22010-07-02 17:43:08 +00002351 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002352 isConstructorDeclarator())
Douglas Gregor61956c42008-10-31 09:07:45 +00002353 goto DoneWithDeclSpec;
2354
Douglas Gregor9817f4a2009-02-09 15:09:02 +00002355 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCall49bfce42009-08-03 20:12:06 +00002356 DiagID, TypeRep);
Chris Lattner16fac4f2008-07-26 01:18:38 +00002357 if (isInvalid)
2358 break;
Mike Stump11289f42009-09-09 15:08:12 +00002359
Chris Lattner16fac4f2008-07-26 01:18:38 +00002360 DS.SetRangeEnd(Tok.getLocation());
2361 ConsumeToken(); // The identifier
2362
2363 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2364 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosierc1183952012-06-26 22:30:43 +00002365 // Objective-C interface.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002366 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor06e41ae2010-10-21 23:17:00 +00002367 ParseObjCProtocolQualifiers(DS);
Chad Rosierc1183952012-06-26 22:30:43 +00002368
Steve Naroffcd5e7822008-09-22 10:28:57 +00002369 // Need to support trailing type qualifiers (e.g. "id<p> const").
2370 // If a type specifier follows, it will be diagnosed elsewhere.
2371 continue;
Chris Lattner16fac4f2008-07-26 01:18:38 +00002372 }
Douglas Gregor7f741122009-02-25 19:37:18 +00002373
2374 // type-name
2375 case tok::annot_template_id: {
Argyrios Kyrtzidisc0c5dd22011-06-22 06:09:49 +00002376 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
Douglas Gregorb67535d2009-03-31 00:43:58 +00002377 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor7f741122009-02-25 19:37:18 +00002378 // This template-id does not refer to a type name, so we're
2379 // done with the type-specifiers.
2380 goto DoneWithDeclSpec;
2381 }
2382
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002383 // If we're in a context where the template-id could be a
2384 // constructor name or specialization, check whether this is a
2385 // constructor declaration.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002386 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor0be31a22010-07-02 17:43:08 +00002387 Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
Douglas Gregor9de54ea2010-01-13 17:31:36 +00002388 isConstructorDeclarator())
2389 goto DoneWithDeclSpec;
2390
Douglas Gregor7f741122009-02-25 19:37:18 +00002391 // Turn the template-id annotation token into a type annotation
2392 // token, then try again to parse it as a type-specifier.
Douglas Gregorfe3d7d02009-04-01 21:51:26 +00002393 AnnotateTemplateIdTokenAsType();
Douglas Gregor7f741122009-02-25 19:37:18 +00002394 continue;
2395 }
2396
Chris Lattnere37e2332006-08-15 04:50:22 +00002397 // GNU attributes support.
2398 case tok::kw___attribute:
DeLesley Hutchinsbd2ee132012-03-02 22:12:59 +00002399 ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
Chris Lattnerb95cca02006-10-17 03:01:08 +00002400 continue;
Steve Naroff3a9b7e02008-12-24 20:59:21 +00002401
2402 // Microsoft declspec support.
2403 case tok::kw___declspec:
John McCall53fa7142010-12-24 02:08:15 +00002404 ParseMicrosoftDeclSpec(DS.getAttributes());
Steve Naroff3a9b7e02008-12-24 20:59:21 +00002405 continue;
Mike Stump11289f42009-09-09 15:08:12 +00002406
Steve Naroff44ac7772008-12-25 14:16:32 +00002407 // Microsoft single token adornments.
Michael J. Spencerf97bd8c2012-06-18 07:00:48 +00002408 case tok::kw___forceinline: {
2409 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
2410 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
2411 SourceLocation AttrNameLoc = ConsumeToken();
Alexis Hunta0e54d42012-06-18 16:13:52 +00002412 // FIXME: This does not work correctly if it is set to be a declspec
2413 // attribute, and a GNU attribute is simply incorrect.
Michael J. Spencerf97bd8c2012-06-18 07:00:48 +00002414 DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Alexis Hunta0e54d42012-06-18 16:13:52 +00002415 SourceLocation(), 0, 0, AttributeList::AS_GNU);
Michael J. Spencerf97bd8c2012-06-18 07:00:48 +00002416 continue;
2417 }
Eli Friedman53339e02009-06-08 23:27:34 +00002418
2419 case tok::kw___ptr64:
Francois Pichetf2fb4112011-08-25 00:36:46 +00002420 case tok::kw___ptr32:
Steve Narofff9c29d42008-12-25 14:41:26 +00002421 case tok::kw___w64:
Steve Naroff44ac7772008-12-25 14:16:32 +00002422 case tok::kw___cdecl:
2423 case tok::kw___stdcall:
2424 case tok::kw___fastcall:
Douglas Gregora941dca2010-05-18 16:57:00 +00002425 case tok::kw___thiscall:
Francois Pichet17ed0202011-08-18 09:59:55 +00002426 case tok::kw___unaligned:
John McCall53fa7142010-12-24 02:08:15 +00002427 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman53339e02009-06-08 23:27:34 +00002428 continue;
2429
Dawn Perchik335e16b2010-09-03 01:29:35 +00002430 // Borland single token adornments.
2431 case tok::kw___pascal:
John McCall53fa7142010-12-24 02:08:15 +00002432 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik335e16b2010-09-03 01:29:35 +00002433 continue;
2434
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +00002435 // OpenCL single token adornments.
2436 case tok::kw___kernel:
2437 ParseOpenCLAttributes(DS.getAttributes());
2438 continue;
2439
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002440 // storage-class-specifier
2441 case tok::kw_typedef:
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002442 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2443 PrevSpec, DiagID);
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002444 break;
2445 case tok::kw_extern:
Chris Lattner353f5742006-11-28 04:50:12 +00002446 if (DS.isThreadSpecified())
Chris Lattner6d29c102008-11-18 07:48:38 +00002447 Diag(Tok, diag::ext_thread_before) << "extern";
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002448 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2449 PrevSpec, DiagID);
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002450 break;
Steve Naroff2050b0d2007-12-18 00:16:02 +00002451 case tok::kw___private_extern__:
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002452 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2453 Loc, PrevSpec, DiagID);
Steve Naroff2050b0d2007-12-18 00:16:02 +00002454 break;
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002455 case tok::kw_static:
Chris Lattner353f5742006-11-28 04:50:12 +00002456 if (DS.isThreadSpecified())
Chris Lattner6d29c102008-11-18 07:48:38 +00002457 Diag(Tok, diag::ext_thread_before) << "static";
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002458 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2459 PrevSpec, DiagID);
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002460 break;
2461 case tok::kw_auto:
David Blaikiebbafb8a2012-03-11 07:00:24 +00002462 if (getLangOpts().CPlusPlus0x) {
Fariborz Jahanianbb6db562011-02-22 23:17:49 +00002463 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002464 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2465 PrevSpec, DiagID);
Fariborz Jahanianbb6db562011-02-22 23:17:49 +00002466 if (!isInvalid)
Richard Smith58c74332011-09-04 19:54:14 +00002467 Diag(Tok, diag::ext_auto_storage_class)
Fariborz Jahanianbb6db562011-02-22 23:17:49 +00002468 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
Richard Smith58c74332011-09-04 19:54:14 +00002469 } else
Fariborz Jahanianbb6db562011-02-22 23:17:49 +00002470 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2471 DiagID);
Richard Smith58c74332011-09-04 19:54:14 +00002472 } else
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002473 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2474 PrevSpec, DiagID);
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002475 break;
2476 case tok::kw_register:
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002477 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2478 PrevSpec, DiagID);
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002479 break;
Sebastian Redlccdfaba2008-11-14 23:42:31 +00002480 case tok::kw_mutable:
Peter Collingbourne485b80f2011-10-06 03:01:00 +00002481 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2482 PrevSpec, DiagID);
Sebastian Redlccdfaba2008-11-14 23:42:31 +00002483 break;
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002484 case tok::kw___thread:
John McCall49bfce42009-08-03 20:12:06 +00002485 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
Chris Lattnerf63f89a2006-08-05 03:28:50 +00002486 break;
Mike Stump11289f42009-09-09 15:08:12 +00002487
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002488 // function-specifier
2489 case tok::kw_inline:
John McCall49bfce42009-08-03 20:12:06 +00002490 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002491 break;
Douglas Gregor61956c42008-10-31 09:07:45 +00002492 case tok::kw_virtual:
John McCall49bfce42009-08-03 20:12:06 +00002493 isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
Douglas Gregor61956c42008-10-31 09:07:45 +00002494 break;
Douglas Gregor61956c42008-10-31 09:07:45 +00002495 case tok::kw_explicit:
John McCall49bfce42009-08-03 20:12:06 +00002496 isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
Douglas Gregor61956c42008-10-31 09:07:45 +00002497 break;
Chris Lattnere387d9e2009-01-21 19:48:37 +00002498
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00002499 // alignment-specifier
2500 case tok::kw__Alignas:
David Blaikiebbafb8a2012-03-11 07:00:24 +00002501 if (!getLangOpts().C11)
Jordan Rose58d54722012-06-30 21:33:57 +00002502 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
Peter Collingbourne2f3cf4b2011-09-29 18:04:28 +00002503 ParseAlignmentSpecifier(DS.getAttributes());
2504 continue;
2505
Anders Carlssoncd8db412009-05-06 04:46:28 +00002506 // friend
2507 case tok::kw_friend:
John McCall07e91c02009-08-06 02:15:43 +00002508 if (DSContext == DSC_class)
2509 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2510 else {
2511 PrevSpec = ""; // not actually used by the diagnostic
2512 DiagID = diag::err_friend_invalid_in_context;
2513 isInvalid = true;
2514 }
Anders Carlssoncd8db412009-05-06 04:46:28 +00002515 break;
Mike Stump11289f42009-09-09 15:08:12 +00002516
Douglas Gregor26701a42011-09-09 02:06:17 +00002517 // Modules
2518 case tok::kw___module_private__:
2519 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2520 break;
Chad Rosierc1183952012-06-26 22:30:43 +00002521
Sebastian Redl39c2a8b2009-11-05 15:47:02 +00002522 // constexpr
2523 case tok::kw_constexpr:
2524 isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2525 break;
2526
Chris Lattnere387d9e2009-01-21 19:48:37 +00002527 // type-specifier
2528 case tok::kw_short:
John McCall49bfce42009-08-03 20:12:06 +00002529 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2530 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002531 break;
2532 case tok::kw_long:
2533 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
John McCall49bfce42009-08-03 20:12:06 +00002534 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2535 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002536 else
John McCall49bfce42009-08-03 20:12:06 +00002537 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2538 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002539 break;
Francois Pichet84133e42011-04-28 01:59:37 +00002540 case tok::kw___int64:
2541 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2542 DiagID);
2543 break;
Chris Lattnere387d9e2009-01-21 19:48:37 +00002544 case tok::kw_signed:
John McCall49bfce42009-08-03 20:12:06 +00002545 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2546 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002547 break;
2548 case tok::kw_unsigned:
John McCall49bfce42009-08-03 20:12:06 +00002549 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
2550 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002551 break;
2552 case tok::kw__Complex:
John McCall49bfce42009-08-03 20:12:06 +00002553 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
2554 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002555 break;
2556 case tok::kw__Imaginary:
John McCall49bfce42009-08-03 20:12:06 +00002557 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
2558 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002559 break;
2560 case tok::kw_void:
John McCall49bfce42009-08-03 20:12:06 +00002561 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
2562 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002563 break;
2564 case tok::kw_char:
John McCall49bfce42009-08-03 20:12:06 +00002565 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
2566 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002567 break;
2568 case tok::kw_int:
John McCall49bfce42009-08-03 20:12:06 +00002569 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
2570 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002571 break;
Richard Smithf016bbc2012-04-04 06:24:32 +00002572 case tok::kw___int128:
2573 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
2574 DiagID);
2575 break;
2576 case tok::kw_half:
2577 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
2578 DiagID);
2579 break;
Chris Lattnere387d9e2009-01-21 19:48:37 +00002580 case tok::kw_float:
John McCall49bfce42009-08-03 20:12:06 +00002581 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
2582 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002583 break;
2584 case tok::kw_double:
John McCall49bfce42009-08-03 20:12:06 +00002585 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
2586 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002587 break;
2588 case tok::kw_wchar_t:
John McCall49bfce42009-08-03 20:12:06 +00002589 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
2590 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002591 break;
Alisdair Mereditha9ad47d2009-07-14 06:30:34 +00002592 case tok::kw_char16_t:
John McCall49bfce42009-08-03 20:12:06 +00002593 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
2594 DiagID);
Alisdair Mereditha9ad47d2009-07-14 06:30:34 +00002595 break;
2596 case tok::kw_char32_t:
John McCall49bfce42009-08-03 20:12:06 +00002597 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
2598 DiagID);
Alisdair Mereditha9ad47d2009-07-14 06:30:34 +00002599 break;
Chris Lattnere387d9e2009-01-21 19:48:37 +00002600 case tok::kw_bool:
2601 case tok::kw__Bool:
Argyrios Kyrtzidis20ee5ae2010-11-16 18:18:13 +00002602 if (Tok.is(tok::kw_bool) &&
2603 DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
2604 DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
2605 PrevSpec = ""; // Not used by the diagnostic.
2606 DiagID = diag::err_bool_redeclaration;
Fariborz Jahanian2b059992011-04-19 21:42:37 +00002607 // For better error recovery.
2608 Tok.setKind(tok::identifier);
Argyrios Kyrtzidis20ee5ae2010-11-16 18:18:13 +00002609 isInvalid = true;
2610 } else {
2611 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
2612 DiagID);
2613 }
Chris Lattnere387d9e2009-01-21 19:48:37 +00002614 break;
2615 case tok::kw__Decimal32:
John McCall49bfce42009-08-03 20:12:06 +00002616 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
2617 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002618 break;
2619 case tok::kw__Decimal64:
John McCall49bfce42009-08-03 20:12:06 +00002620 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
2621 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002622 break;
2623 case tok::kw__Decimal128:
John McCall49bfce42009-08-03 20:12:06 +00002624 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
2625 DiagID);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002626 break;
John Thompson22334602010-02-05 00:12:22 +00002627 case tok::kw___vector:
2628 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
2629 break;
2630 case tok::kw___pixel:
2631 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
2632 break;
John McCall39439732011-04-09 22:50:59 +00002633 case tok::kw___unknown_anytype:
2634 isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
2635 PrevSpec, DiagID);
2636 break;
Chris Lattnere387d9e2009-01-21 19:48:37 +00002637
2638 // class-specifier:
2639 case tok::kw_class:
2640 case tok::kw_struct:
Chris Lattnerffaa0e62009-04-12 21:49:30 +00002641 case tok::kw_union: {
2642 tok::TokenKind Kind = Tok.getKind();
2643 ConsumeToken();
Richard Smithc5b05522012-03-12 07:56:15 +00002644 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
2645 EnteringContext, DSContext);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002646 continue;
Chris Lattnerffaa0e62009-04-12 21:49:30 +00002647 }
Chris Lattnere387d9e2009-01-21 19:48:37 +00002648
2649 // enum-specifier:
2650 case tok::kw_enum:
Chris Lattnerffaa0e62009-04-12 21:49:30 +00002651 ConsumeToken();
Richard Smithc5b05522012-03-12 07:56:15 +00002652 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002653 continue;
2654
2655 // cv-qualifier:
2656 case tok::kw_const:
John McCall49bfce42009-08-03 20:12:06 +00002657 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
Richard Smith7ac3c6a2012-07-24 20:24:58 +00002658 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002659 break;
2660 case tok::kw_volatile:
John McCall49bfce42009-08-03 20:12:06 +00002661 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smith7ac3c6a2012-07-24 20:24:58 +00002662 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002663 break;
2664 case tok::kw_restrict:
John McCall49bfce42009-08-03 20:12:06 +00002665 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smith7ac3c6a2012-07-24 20:24:58 +00002666 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattnere387d9e2009-01-21 19:48:37 +00002667 break;
2668
Douglas Gregor333489b2009-03-27 23:10:48 +00002669 // C++ typename-specifier:
2670 case tok::kw_typename:
John McCall1f476a12010-02-26 08:45:28 +00002671 if (TryAnnotateTypeOrScopeToken()) {
2672 DS.SetTypeSpecError();
2673 goto DoneWithDeclSpec;
2674 }
2675 if (!Tok.is(tok::kw_typename))
Douglas Gregor333489b2009-03-27 23:10:48 +00002676 continue;
2677 break;
2678
Chris Lattnere387d9e2009-01-21 19:48:37 +00002679 // GNU typeof support.
2680 case tok::kw_typeof:
2681 ParseTypeofSpecifier(DS);
2682 continue;
2683
David Blaikie15a430a2011-12-04 05:04:18 +00002684 case tok::annot_decltype:
Anders Carlsson74948d02009-06-24 17:47:40 +00002685 ParseDecltypeSpecifier(DS);
2686 continue;
2687
Alexis Hunt4a257072011-05-19 05:37:45 +00002688 case tok::kw___underlying_type:
2689 ParseUnderlyingTypeSpecifier(DS);
Eli Friedman0dfb8892011-10-06 23:00:33 +00002690 continue;
2691
2692 case tok::kw__Atomic:
2693 ParseAtomicSpecifier(DS);
2694 continue;
Alexis Hunt4a257072011-05-19 05:37:45 +00002695
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00002696 // OpenCL qualifiers:
Chad Rosierc1183952012-06-26 22:30:43 +00002697 case tok::kw_private:
David Blaikiebbafb8a2012-03-11 07:00:24 +00002698 if (!getLangOpts().OpenCL)
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00002699 goto DoneWithDeclSpec;
2700 case tok::kw___private:
2701 case tok::kw___global:
2702 case tok::kw___local:
2703 case tok::kw___constant:
2704 case tok::kw___read_only:
2705 case tok::kw___write_only:
2706 case tok::kw___read_write:
2707 ParseOpenCLQualifiers(DS);
2708 break;
Chad Rosierc1183952012-06-26 22:30:43 +00002709
Steve Naroffcfdf6162008-06-05 00:02:44 +00002710 case tok::less:
Chris Lattner16fac4f2008-07-26 01:18:38 +00002711 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattner0974b232008-07-26 00:20:22 +00002712 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
2713 // but we support it.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002714 if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
Chris Lattner0974b232008-07-26 00:20:22 +00002715 goto DoneWithDeclSpec;
Mike Stump11289f42009-09-09 15:08:12 +00002716
Douglas Gregor3a001f42010-11-19 17:10:50 +00002717 if (!ParseObjCProtocolQualifiers(DS))
2718 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
2719 << FixItHint::CreateInsertion(Loc, "id")
2720 << SourceRange(Loc, DS.getSourceRange().getEnd());
Chad Rosierc1183952012-06-26 22:30:43 +00002721
Douglas Gregor06e41ae2010-10-21 23:17:00 +00002722 // Need to support trailing type qualifiers (e.g. "id<p> const").
2723 // If a type specifier follows, it will be diagnosed elsewhere.
2724 continue;
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00002725 }
John McCall49bfce42009-08-03 20:12:06 +00002726 // If the specifier wasn't legal, issue a diagnostic.
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002727 if (isInvalid) {
2728 assert(PrevSpec && "Method did not return previous specifier!");
John McCall49bfce42009-08-03 20:12:06 +00002729 assert(DiagID);
Chad Rosierc1183952012-06-26 22:30:43 +00002730
Douglas Gregora05f5ab2010-08-23 14:34:43 +00002731 if (DiagID == diag::ext_duplicate_declspec)
2732 Diag(Tok, DiagID)
2733 << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
2734 else
2735 Diag(Tok, DiagID) << PrevSpec;
Chris Lattnerb9093cd2006-08-04 04:39:53 +00002736 }
Fariborz Jahanianbb6db562011-02-22 23:17:49 +00002737
Chris Lattner2e232092008-03-13 06:29:04 +00002738 DS.SetRangeEnd(Tok.getLocation());
Fariborz Jahanian2b059992011-04-19 21:42:37 +00002739 if (DiagID != diag::err_bool_redeclaration)
2740 ConsumeToken();
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00002741
2742 AttrsLastTime = false;
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00002743 }
2744}
Douglas Gregoreb31f392008-12-01 23:54:00 +00002745
Chris Lattner70ae4912007-10-29 04:42:53 +00002746/// ParseStructDeclaration - Parse a struct declaration without the terminating
2747/// semicolon.
2748///
Chris Lattner90a26b02007-01-23 04:38:16 +00002749/// struct-declaration:
Chris Lattner70ae4912007-10-29 04:42:53 +00002750/// specifier-qualifier-list struct-declarator-list
Chris Lattner736ed5d2007-06-09 05:59:07 +00002751/// [GNU] __extension__ struct-declaration
Chris Lattner70ae4912007-10-29 04:42:53 +00002752/// [GNU] specifier-qualifier-list
Chris Lattner90a26b02007-01-23 04:38:16 +00002753/// struct-declarator-list:
2754/// struct-declarator
2755/// struct-declarator-list ',' struct-declarator
2756/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
2757/// struct-declarator:
2758/// declarator
2759/// [GNU] declarator attributes[opt]
2760/// declarator[opt] ':' constant-expression
2761/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
2762///
Chris Lattnera12405b2008-04-10 06:46:29 +00002763void Parser::
Eli Friedman89b1f2c2012-08-08 23:04:35 +00002764ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
Chad Rosierc1183952012-06-26 22:30:43 +00002765
Chris Lattnerf02ef3e2008-10-20 06:45:43 +00002766 if (Tok.is(tok::kw___extension__)) {
2767 // __extension__ silences extension warnings in the subexpression.
2768 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroff97170802007-08-20 22:28:22 +00002769 ConsumeToken();
Chris Lattnerf02ef3e2008-10-20 06:45:43 +00002770 return ParseStructDeclaration(DS, Fields);
2771 }
Mike Stump11289f42009-09-09 15:08:12 +00002772
Steve Naroff97170802007-08-20 22:28:22 +00002773 // Parse the common specifier-qualifiers-list piece.
Steve Naroff97170802007-08-20 22:28:22 +00002774 ParseSpecifierQualifierList(DS);
Mike Stump11289f42009-09-09 15:08:12 +00002775
Douglas Gregorc6f58fe2009-01-12 22:49:06 +00002776 // If there are no declarators, this is a free-standing declaration
2777 // specifier. Let the actions module cope with it.
Chris Lattner76c72282007-10-09 17:33:22 +00002778 if (Tok.is(tok::semi)) {
Eli Friedman89b1f2c2012-08-08 23:04:35 +00002779 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
2780 DS);
2781 DS.complete(TheDecl);
Steve Naroff97170802007-08-20 22:28:22 +00002782 return;
2783 }
2784
2785 // Read struct-declarators until we find the semicolon.
John McCallcfefb6d2009-11-03 02:38:08 +00002786 bool FirstDeclarator = true;
Richard Smith8d06f422012-01-12 23:53:29 +00002787 SourceLocation CommaLoc;
Steve Naroff97170802007-08-20 22:28:22 +00002788 while (1) {
Eli Friedman89b1f2c2012-08-08 23:04:35 +00002789 ParsingFieldDeclarator DeclaratorInfo(*this, DS);
Richard Smith8d06f422012-01-12 23:53:29 +00002790 DeclaratorInfo.D.setCommaLoc(CommaLoc);
John McCallcfefb6d2009-11-03 02:38:08 +00002791
2792 // Attributes are only allowed here on successive declarators.
John McCall53fa7142010-12-24 02:08:15 +00002793 if (!FirstDeclarator)
2794 MaybeParseGNUAttributes(DeclaratorInfo.D);
Mike Stump11289f42009-09-09 15:08:12 +00002795
Steve Naroff97170802007-08-20 22:28:22 +00002796 /// struct-declarator: declarator
2797 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattner17c3b1f2009-12-10 01:59:24 +00002798 if (Tok.isNot(tok::colon)) {
2799 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
2800 ColonProtectionRAIIObject X(*this);
Chris Lattnera12405b2008-04-10 06:46:29 +00002801 ParseDeclarator(DeclaratorInfo.D);
Chris Lattner17c3b1f2009-12-10 01:59:24 +00002802 }
Mike Stump11289f42009-09-09 15:08:12 +00002803
Chris Lattner76c72282007-10-09 17:33:22 +00002804 if (Tok.is(tok::colon)) {
Steve Naroff97170802007-08-20 22:28:22 +00002805 ConsumeToken();
John McCalldadc5752010-08-24 06:29:42 +00002806 ExprResult Res(ParseConstantExpression());
Sebastian Redl17f2c7d2008-12-09 13:15:23 +00002807 if (Res.isInvalid())
Steve Naroff97170802007-08-20 22:28:22 +00002808 SkipUntil(tok::semi, true, true);
Chris Lattner32295d32008-04-10 06:15:14 +00002809 else
Sebastian Redld9f7b1c2008-12-10 00:02:53 +00002810 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroff97170802007-08-20 22:28:22 +00002811 }
Sebastian Redlf6591ca2009-02-09 18:23:29 +00002812
Steve Naroff97170802007-08-20 22:28:22 +00002813 // If attributes exist after the declarator, parse them.
John McCall53fa7142010-12-24 02:08:15 +00002814 MaybeParseGNUAttributes(DeclaratorInfo.D);
Sebastian Redlf6591ca2009-02-09 18:23:29 +00002815
John McCallcfefb6d2009-11-03 02:38:08 +00002816 // We're done with this declarator; invoke the callback.
Eli Friedmanba01f2b2012-08-08 23:35:12 +00002817 Fields.invoke(DeclaratorInfo);
John McCallcfefb6d2009-11-03 02:38:08 +00002818
Steve Naroff97170802007-08-20 22:28:22 +00002819 // If we don't have a comma, it is either the end of the list (a ';')
2820 // or an error, bail out.
Chris Lattner76c72282007-10-09 17:33:22 +00002821 if (Tok.isNot(tok::comma))
Chris Lattner70ae4912007-10-29 04:42:53 +00002822 return;
Sebastian Redlf6591ca2009-02-09 18:23:29 +00002823
Steve Naroff97170802007-08-20 22:28:22 +00002824 // Consume the comma.
Richard Smith8d06f422012-01-12 23:53:29 +00002825 CommaLoc = ConsumeToken();
Sebastian Redlf6591ca2009-02-09 18:23:29 +00002826
John McCallcfefb6d2009-11-03 02:38:08 +00002827 FirstDeclarator = false;
Steve Naroff97170802007-08-20 22:28:22 +00002828 }
Steve Naroff97170802007-08-20 22:28:22 +00002829}
2830
2831/// ParseStructUnionBody
2832/// struct-contents:
2833/// struct-declaration-list
2834/// [EXT] empty
2835/// [GNU] "struct-declaration-list" without terminatoring ';'
2836/// struct-declaration-list:
2837/// struct-declaration
2838/// struct-declaration-list struct-declaration
Chris Lattner535b8302008-06-21 19:39:06 +00002839/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroff97170802007-08-20 22:28:22 +00002840///
Chris Lattner1300fb92007-01-23 23:42:53 +00002841void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
John McCall48871652010-08-21 09:40:31 +00002842 unsigned TagType, Decl *TagDecl) {
John McCallfaf5fb42010-08-26 23:41:50 +00002843 PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2844 "parsing struct/union body");
Mike Stump11289f42009-09-09 15:08:12 +00002845
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00002846 BalancedDelimiterTracker T(*this, tok::l_brace);
2847 if (T.consumeOpen())
2848 return;
Mike Stump11289f42009-09-09 15:08:12 +00002849
Douglas Gregor658b9552009-01-09 22:42:13 +00002850 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregor0be31a22010-07-02 17:43:08 +00002851 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
Douglas Gregor82ac25e2009-01-08 20:45:30 +00002852
Chris Lattner7b9ace62007-01-23 20:11:08 +00002853 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
2854 // C++.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002855 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {
Richard Smithe4345902011-12-29 21:57:33 +00002856 Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union);
2857 Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union);
2858 }
Chris Lattner7b9ace62007-01-23 20:11:08 +00002859
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002860 SmallVector<Decl *, 32> FieldDecls;
Chris Lattnera12405b2008-04-10 06:46:29 +00002861
Chris Lattner7b9ace62007-01-23 20:11:08 +00002862 // While we still have something to read, read the declarations in the struct.
Chris Lattner76c72282007-10-09 17:33:22 +00002863 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Chris Lattner90a26b02007-01-23 04:38:16 +00002864 // Each iteration of this loop reads one struct-declaration.
Mike Stump11289f42009-09-09 15:08:12 +00002865
Chris Lattner736ed5d2007-06-09 05:59:07 +00002866 // Check for extraneous top-level semicolon.
Chris Lattner76c72282007-10-09 17:33:22 +00002867 if (Tok.is(tok::semi)) {
Richard Smith87f5dc52012-07-23 05:45:25 +00002868 ConsumeExtraSemi(InsideStruct, TagType);
Chris Lattner36e46a22007-06-09 05:49:55 +00002869 continue;
2870 }
Chris Lattnera12405b2008-04-10 06:46:29 +00002871
John McCallcfefb6d2009-11-03 02:38:08 +00002872 if (!Tok.is(tok::at)) {
2873 struct CFieldCallback : FieldCallback {
2874 Parser &P;
John McCall48871652010-08-21 09:40:31 +00002875 Decl *TagDecl;
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002876 SmallVectorImpl<Decl *> &FieldDecls;
John McCallcfefb6d2009-11-03 02:38:08 +00002877
John McCall48871652010-08-21 09:40:31 +00002878 CFieldCallback(Parser &P, Decl *TagDecl,
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002879 SmallVectorImpl<Decl *> &FieldDecls) :
John McCallcfefb6d2009-11-03 02:38:08 +00002880 P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
2881
Eli Friedman934dbbf2012-08-08 23:53:27 +00002882 void invoke(ParsingFieldDeclarator &FD) {
John McCallcfefb6d2009-11-03 02:38:08 +00002883 // Install the declarator into the current TagDecl.
John McCall48871652010-08-21 09:40:31 +00002884 Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
John McCall5e6253b2009-11-03 21:13:47 +00002885 FD.D.getDeclSpec().getSourceRange().getBegin(),
2886 FD.D, FD.BitfieldSize);
John McCallcfefb6d2009-11-03 02:38:08 +00002887 FieldDecls.push_back(Field);
Eli Friedman89b1f2c2012-08-08 23:04:35 +00002888 FD.complete(Field);
Douglas Gregor66a985d2009-08-26 14:27:30 +00002889 }
John McCallcfefb6d2009-11-03 02:38:08 +00002890 } Callback(*this, TagDecl, FieldDecls);
2891
Eli Friedman89b1f2c2012-08-08 23:04:35 +00002892 // Parse all the comma separated declarators.
2893 ParsingDeclSpec DS(*this);
John McCallcfefb6d2009-11-03 02:38:08 +00002894 ParseStructDeclaration(DS, Callback);
Chris Lattner535b8302008-06-21 19:39:06 +00002895 } else { // Handle @defs
2896 ConsumeToken();
2897 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
2898 Diag(Tok, diag::err_unexpected_at);
Chris Lattner245c5332010-02-02 00:37:27 +00002899 SkipUntil(tok::semi, true);
Chris Lattner535b8302008-06-21 19:39:06 +00002900 continue;
2901 }
2902 ConsumeToken();
2903 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
2904 if (!Tok.is(tok::identifier)) {
2905 Diag(Tok, diag::err_expected_ident);
Chris Lattner245c5332010-02-02 00:37:27 +00002906 SkipUntil(tok::semi, true);
Chris Lattner535b8302008-06-21 19:39:06 +00002907 continue;
2908 }
Chris Lattner0e62c1c2011-07-23 10:55:15 +00002909 SmallVector<Decl *, 16> Fields;
Douglas Gregor0be31a22010-07-02 17:43:08 +00002910 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
Douglas Gregor91f84212008-12-11 16:49:14 +00002911 Tok.getIdentifierInfo(), Fields);
Chris Lattner535b8302008-06-21 19:39:06 +00002912 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
2913 ConsumeToken();
2914 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
Mike Stump11289f42009-09-09 15:08:12 +00002915 }
Chris Lattner736ed5d2007-06-09 05:59:07 +00002916
Chris Lattner76c72282007-10-09 17:33:22 +00002917 if (Tok.is(tok::semi)) {
Chris Lattner90a26b02007-01-23 04:38:16 +00002918 ConsumeToken();
Chris Lattner76c72282007-10-09 17:33:22 +00002919 } else if (Tok.is(tok::r_brace)) {
Chris Lattner245c5332010-02-02 00:37:27 +00002920 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
Chris Lattner0c7e82d2007-06-09 05:54:40 +00002921 break;
Chris Lattner90a26b02007-01-23 04:38:16 +00002922 } else {
Chris Lattner245c5332010-02-02 00:37:27 +00002923 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
2924 // Skip to end of block or statement to avoid ext-warning on extra ';'.
Chris Lattner90a26b02007-01-23 04:38:16 +00002925 SkipUntil(tok::r_brace, true, true);
Chris Lattner245c5332010-02-02 00:37:27 +00002926 // If we stopped at a ';', eat it.
2927 if (Tok.is(tok::semi)) ConsumeToken();
Chris Lattner90a26b02007-01-23 04:38:16 +00002928 }
2929 }
Mike Stump11289f42009-09-09 15:08:12 +00002930
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00002931 T.consumeClose();
Mike Stump11289f42009-09-09 15:08:12 +00002932
John McCall084e83d2011-03-24 11:26:52 +00002933 ParsedAttributes attrs(AttrFactory);
Chris Lattner90a26b02007-01-23 04:38:16 +00002934 // If attributes exist after struct contents, parse them.
John McCall53fa7142010-12-24 02:08:15 +00002935 MaybeParseGNUAttributes(attrs);
Daniel Dunbar15619c72008-10-03 02:03:53 +00002936
Douglas Gregor0be31a22010-07-02 17:43:08 +00002937 Actions.ActOnFields(getCurScope(),
David Blaikie751c5582011-09-22 02:58:26 +00002938 RecordLoc, TagDecl, FieldDecls,
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00002939 T.getOpenLocation(), T.getCloseLocation(),
John McCall53fa7142010-12-24 02:08:15 +00002940 attrs.getList());
Douglas Gregor82ac25e2009-01-08 20:45:30 +00002941 StructScope.Exit();
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00002942 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
2943 T.getCloseLocation());
Chris Lattner90a26b02007-01-23 04:38:16 +00002944}
2945
Chris Lattner3b561a32006-08-13 00:12:11 +00002946/// ParseEnumSpecifier
Chris Lattner1890ac82006-08-13 01:16:23 +00002947/// enum-specifier: [C99 6.7.2.2]
Chris Lattner3b561a32006-08-13 00:12:11 +00002948/// 'enum' identifier[opt] '{' enumerator-list '}'
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002949///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Chris Lattnere37e2332006-08-15 04:50:22 +00002950/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
2951/// '}' attributes[opt]
Aaron Ballman9ecff022012-03-01 04:09:28 +00002952/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
2953/// '}'
Chris Lattner3b561a32006-08-13 00:12:11 +00002954/// 'enum' identifier
Chris Lattnere37e2332006-08-15 04:50:22 +00002955/// [GNU] 'enum' attributes[opt] identifier
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002956///
Richard Smith7d137e32012-03-23 03:33:32 +00002957/// [C++11] enum-head '{' enumerator-list[opt] '}'
2958/// [C++11] enum-head '{' enumerator-list ',' '}'
Douglas Gregor0bf31402010-10-08 23:50:27 +00002959///
Richard Smith7d137e32012-03-23 03:33:32 +00002960/// enum-head: [C++11]
2961/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
2962/// enum-key attribute-specifier-seq[opt] nested-name-specifier
2963/// identifier enum-base[opt]
Douglas Gregor0bf31402010-10-08 23:50:27 +00002964///
Richard Smith7d137e32012-03-23 03:33:32 +00002965/// enum-key: [C++11]
Douglas Gregor0bf31402010-10-08 23:50:27 +00002966/// 'enum'
2967/// 'enum' 'class'
2968/// 'enum' 'struct'
2969///
Richard Smith7d137e32012-03-23 03:33:32 +00002970/// enum-base: [C++11]
Douglas Gregor0bf31402010-10-08 23:50:27 +00002971/// ':' type-specifier-seq
2972///
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00002973/// [C++] elaborated-type-specifier:
2974/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
2975///
Chris Lattnerffaa0e62009-04-12 21:49:30 +00002976void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Douglas Gregordc70c3a2010-03-02 17:53:14 +00002977 const ParsedTemplateInfo &TemplateInfo,
Richard Smithc5b05522012-03-12 07:56:15 +00002978 AccessSpecifier AS, DeclSpecContext DSC) {
Chris Lattnerffbc2712007-01-25 06:05:38 +00002979 // Parse the tag portion of this.
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002980 if (Tok.is(tok::code_completion)) {
2981 // Code completion for an enum name.
Douglas Gregor0be31a22010-07-02 17:43:08 +00002982 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
Argyrios Kyrtzidis5cec2ae2011-09-04 03:32:15 +00002983 return cutOffParsing();
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002984 }
John McCallcb432fa2011-07-06 05:58:41 +00002985
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00002986 // If attributes exist after tag, parse them.
2987 ParsedAttributesWithRange attrs(AttrFactory);
2988 MaybeParseGNUAttributes(attrs);
2989 MaybeParseCXX0XAttributes(attrs);
2990
2991 // If declspecs exist after tag, parse them.
2992 while (Tok.is(tok::kw___declspec))
2993 ParseMicrosoftDeclSpec(attrs);
2994
Richard Smith0f8ee222012-01-10 01:33:14 +00002995 SourceLocation ScopedEnumKWLoc;
John McCallcb432fa2011-07-06 05:58:41 +00002996 bool IsScopedUsingClassTag = false;
2997
John McCallbeae29a2012-06-23 22:30:04 +00002998 // In C++11, recognize 'enum class' and 'enum struct'.
David Blaikiebbafb8a2012-03-11 07:00:24 +00002999 if (getLangOpts().CPlusPlus0x &&
John McCallcb432fa2011-07-06 05:58:41 +00003000 (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
Richard Smith5d164bc2011-10-15 05:09:34 +00003001 Diag(Tok, diag::warn_cxx98_compat_scoped_enum);
John McCallcb432fa2011-07-06 05:58:41 +00003002 IsScopedUsingClassTag = Tok.is(tok::kw_class);
Richard Smith0f8ee222012-01-10 01:33:14 +00003003 ScopedEnumKWLoc = ConsumeToken();
Chad Rosierc1183952012-06-26 22:30:43 +00003004
John McCallbeae29a2012-06-23 22:30:04 +00003005 // Attributes are not allowed between these keywords. Diagnose,
3006 // but then just treat them like they appeared in the right place.
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00003007 ProhibitAttributes(attrs);
John McCallbeae29a2012-06-23 22:30:04 +00003008
3009 // They are allowed afterwards, though.
3010 MaybeParseGNUAttributes(attrs);
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00003011 MaybeParseCXX0XAttributes(attrs);
John McCallbeae29a2012-06-23 22:30:04 +00003012 while (Tok.is(tok::kw___declspec))
3013 ParseMicrosoftDeclSpec(attrs);
John McCallcb432fa2011-07-06 05:58:41 +00003014 }
Richard Smith7d137e32012-03-23 03:33:32 +00003015
John McCall6347b682012-05-07 06:16:58 +00003016 // C++11 [temp.explicit]p12:
3017 // The usual access controls do not apply to names used to specify
3018 // explicit instantiations.
3019 // We extend this to also cover explicit specializations. Note that
3020 // we don't suppress if this turns out to be an elaborated type
3021 // specifier.
3022 bool shouldDelayDiagsInTag =
3023 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3024 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3025 SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
Richard Smith7d137e32012-03-23 03:33:32 +00003026
Richard Smithbfdb1082012-03-12 08:56:40 +00003027 // Enum definitions should not be parsed in a trailing-return-type.
3028 bool AllowDeclaration = DSC != DSC_trailing;
3029
3030 bool AllowFixedUnderlyingType = AllowDeclaration &&
3031 (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt ||
3032 getLangOpts().ObjC2);
John McCallcb432fa2011-07-06 05:58:41 +00003033
Abramo Bagnarad7548482010-05-19 21:37:53 +00003034 CXXScopeSpec &SS = DS.getTypeSpecScope();
David Blaikiebbafb8a2012-03-11 07:00:24 +00003035 if (getLangOpts().CPlusPlus) {
John McCallcb432fa2011-07-06 05:58:41 +00003036 // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3037 // if a fixed underlying type is allowed.
3038 ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
Chad Rosierc1183952012-06-26 22:30:43 +00003039
3040 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregordf593fb2011-11-07 17:33:42 +00003041 /*EnteringContext=*/false))
John McCall1f476a12010-02-26 08:45:28 +00003042 return;
3043
3044 if (SS.isSet() && Tok.isNot(tok::identifier)) {
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00003045 Diag(Tok, diag::err_expected_ident);
3046 if (Tok.isNot(tok::l_brace)) {
3047 // Has no name and is not a definition.
3048 // Skip the rest of this declarator, up until the comma or semicolon.
3049 SkipUntil(tok::comma, true);
3050 return;
3051 }
3052 }
3053 }
Mike Stump11289f42009-09-09 15:08:12 +00003054
Argyrios Kyrtzidisf01fa822008-09-11 00:21:41 +00003055 // Must have either 'enum name' or 'enum {...}'.
Douglas Gregor6cd5ae42011-02-22 02:55:24 +00003056 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
Richard Smithbfdb1082012-03-12 08:56:40 +00003057 !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Argyrios Kyrtzidisf01fa822008-09-11 00:21:41 +00003058 Diag(Tok, diag::err_expected_ident_lbrace);
Mike Stump11289f42009-09-09 15:08:12 +00003059
Argyrios Kyrtzidisf01fa822008-09-11 00:21:41 +00003060 // Skip the rest of this declarator, up until the comma or semicolon.
3061 SkipUntil(tok::comma, true);
Chris Lattner3b561a32006-08-13 00:12:11 +00003062 return;
Argyrios Kyrtzidisf01fa822008-09-11 00:21:41 +00003063 }
Mike Stump11289f42009-09-09 15:08:12 +00003064
Argyrios Kyrtzidisf01fa822008-09-11 00:21:41 +00003065 // If an identifier is present, consume and remember it.
3066 IdentifierInfo *Name = 0;
3067 SourceLocation NameLoc;
3068 if (Tok.is(tok::identifier)) {
3069 Name = Tok.getIdentifierInfo();
3070 NameLoc = ConsumeToken();
3071 }
Mike Stump11289f42009-09-09 15:08:12 +00003072
Richard Smith0f8ee222012-01-10 01:33:14 +00003073 if (!Name && ScopedEnumKWLoc.isValid()) {
Douglas Gregor0bf31402010-10-08 23:50:27 +00003074 // C++0x 7.2p2: The optional identifier shall not be omitted in the
3075 // declaration of a scoped enumeration.
3076 Diag(Tok, diag::err_scoped_enum_missing_identifier);
Richard Smith0f8ee222012-01-10 01:33:14 +00003077 ScopedEnumKWLoc = SourceLocation();
Abramo Bagnara0e05e242010-12-03 18:54:17 +00003078 IsScopedUsingClassTag = false;
Douglas Gregor0bf31402010-10-08 23:50:27 +00003079 }
3080
John McCall6347b682012-05-07 06:16:58 +00003081 // Okay, end the suppression area. We'll decide whether to emit the
3082 // diagnostics in a second.
3083 if (shouldDelayDiagsInTag)
3084 diagsFromTag.done();
Richard Smith7d137e32012-03-23 03:33:32 +00003085
Douglas Gregor0bf31402010-10-08 23:50:27 +00003086 TypeResult BaseType;
3087
Douglas Gregord1f69f62010-12-01 17:42:47 +00003088 // Parse the fixed underlying type.
Richard Smith200f47c2012-07-02 19:14:01 +00003089 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
Douglas Gregor6cd5ae42011-02-22 02:55:24 +00003090 if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
Douglas Gregord1f69f62010-12-01 17:42:47 +00003091 bool PossibleBitfield = false;
Richard Smith200f47c2012-07-02 19:14:01 +00003092 if (CanBeBitfield) {
Douglas Gregord1f69f62010-12-01 17:42:47 +00003093 // If we're in class scope, this can either be an enum declaration with
3094 // an underlying type, or a declaration of a bitfield member. We try to
3095 // use a simple disambiguation scheme first to catch the common cases
Chad Rosierc1183952012-06-26 22:30:43 +00003096 // (integer literal, sizeof); if it's still ambiguous, we then consider
3097 // anything that's a simple-type-specifier followed by '(' as an
3098 // expression. This suffices because function types are not valid
Douglas Gregord1f69f62010-12-01 17:42:47 +00003099 // underlying types anyway.
3100 TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
Chad Rosierc1183952012-06-26 22:30:43 +00003101 // If the next token starts an expression, we know we're parsing a
Douglas Gregord1f69f62010-12-01 17:42:47 +00003102 // bit-field. This is the common case.
3103 if (TPR == TPResult::True())
3104 PossibleBitfield = true;
3105 // If the next token starts a type-specifier-seq, it may be either a
3106 // a fixed underlying type or the start of a function-style cast in C++;
Chad Rosierc1183952012-06-26 22:30:43 +00003107 // lookahead one more token to see if it's obvious that we have a
Douglas Gregord1f69f62010-12-01 17:42:47 +00003108 // fixed underlying type.
Chad Rosierc1183952012-06-26 22:30:43 +00003109 else if (TPR == TPResult::False() &&
Douglas Gregord1f69f62010-12-01 17:42:47 +00003110 GetLookAheadToken(2).getKind() == tok::semi) {
3111 // Consume the ':'.
3112 ConsumeToken();
3113 } else {
3114 // We have the start of a type-specifier-seq, so we have to perform
3115 // tentative parsing to determine whether we have an expression or a
3116 // type.
3117 TentativeParsingAction TPA(*this);
3118
3119 // Consume the ':'.
3120 ConsumeToken();
Richard Smith1e3b0f02012-02-23 01:36:12 +00003121
3122 // If we see a type specifier followed by an open-brace, we have an
3123 // ambiguity between an underlying type and a C++11 braced
3124 // function-style cast. Resolve this by always treating it as an
3125 // underlying type.
3126 // FIXME: The standard is not entirely clear on how to disambiguate in
3127 // this case.
David Blaikiebbafb8a2012-03-11 07:00:24 +00003128 if ((getLangOpts().CPlusPlus &&
Richard Smith1e3b0f02012-02-23 01:36:12 +00003129 isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
David Blaikiebbafb8a2012-03-11 07:00:24 +00003130 (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
Douglas Gregord1f69f62010-12-01 17:42:47 +00003131 // We'll parse this as a bitfield later.
3132 PossibleBitfield = true;
3133 TPA.Revert();
3134 } else {
3135 // We have a type-specifier-seq.
3136 TPA.Commit();
3137 }
3138 }
3139 } else {
3140 // Consume the ':'.
3141 ConsumeToken();
3142 }
3143
3144 if (!PossibleBitfield) {
3145 SourceRange Range;
3146 BaseType = ParseTypeName(&Range);
Chad Rosierc1183952012-06-26 22:30:43 +00003147
David Blaikiebbafb8a2012-03-11 07:00:24 +00003148 if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2)
Douglas Gregora1aec292011-02-22 20:32:04 +00003149 Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
3150 << Range;
David Blaikiebbafb8a2012-03-11 07:00:24 +00003151 if (getLangOpts().CPlusPlus0x)
Richard Smith5d164bc2011-10-15 05:09:34 +00003152 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
Douglas Gregord1f69f62010-12-01 17:42:47 +00003153 }
Douglas Gregor0bf31402010-10-08 23:50:27 +00003154 }
3155
Richard Smith0f8ee222012-01-10 01:33:14 +00003156 // There are four options here. If we have 'friend enum foo;' then this is a
3157 // friend declaration, and cannot have an accompanying definition. If we have
3158 // 'enum foo;', then this is a forward declaration. If we have
3159 // 'enum foo {...' then this is a definition. Otherwise we have something
3160 // like 'enum foo xyz', a reference.
Argyrios Kyrtzidisf01fa822008-09-11 00:21:41 +00003161 //
3162 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3163 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
3164 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
3165 //
John McCallfaf5fb42010-08-26 23:41:50 +00003166 Sema::TagUseKind TUK;
John McCall6347b682012-05-07 06:16:58 +00003167 if (!AllowDeclaration) {
Richard Smithbfdb1082012-03-12 08:56:40 +00003168 TUK = Sema::TUK_Reference;
John McCall6347b682012-05-07 06:16:58 +00003169 } else if (Tok.is(tok::l_brace)) {
3170 if (DS.isFriendSpecified()) {
3171 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3172 << SourceRange(DS.getFriendSpecLoc());
3173 ConsumeBrace();
3174 SkipUntil(tok::r_brace);
3175 TUK = Sema::TUK_Friend;
3176 } else {
3177 TUK = Sema::TUK_Definition;
3178 }
Richard Smith369b9f92012-06-25 21:37:02 +00003179 } else if (DSC != DSC_type_specifier &&
3180 (Tok.is(tok::semi) ||
Richard Smith200f47c2012-07-02 19:14:01 +00003181 (Tok.isAtStartOfLine() &&
3182 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
Richard Smith369b9f92012-06-25 21:37:02 +00003183 TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3184 if (Tok.isNot(tok::semi)) {
3185 // A semicolon was missing after this declaration. Diagnose and recover.
3186 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3187 "enum");
3188 PP.EnterToken(Tok);
3189 Tok.setKind(tok::semi);
3190 }
John McCall6347b682012-05-07 06:16:58 +00003191 } else {
John McCallfaf5fb42010-08-26 23:41:50 +00003192 TUK = Sema::TUK_Reference;
John McCall6347b682012-05-07 06:16:58 +00003193 }
3194
3195 // If this is an elaborated type specifier, and we delayed
3196 // diagnostics before, just merge them into the current pool.
3197 if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3198 diagsFromTag.redelay();
3199 }
Richard Smith7d137e32012-03-23 03:33:32 +00003200
3201 MultiTemplateParamsArg TParams;
Douglas Gregorcbbf3e32010-05-03 17:48:54 +00003202 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
John McCallfaf5fb42010-08-26 23:41:50 +00003203 TUK != Sema::TUK_Reference) {
Richard Smith7d137e32012-03-23 03:33:32 +00003204 if (!getLangOpts().CPlusPlus0x || !SS.isSet()) {
3205 // Skip the rest of this declarator, up until the comma or semicolon.
3206 Diag(Tok, diag::err_enum_template);
3207 SkipUntil(tok::comma, true);
3208 return;
3209 }
3210
3211 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3212 // Enumerations can't be explicitly instantiated.
3213 DS.SetTypeSpecError();
3214 Diag(StartLoc, diag::err_explicit_instantiation_enum);
3215 return;
3216 }
3217
3218 assert(TemplateInfo.TemplateParams && "no template parameters");
3219 TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3220 TemplateInfo.TemplateParams->size());
Douglas Gregorcbbf3e32010-05-03 17:48:54 +00003221 }
Chad Rosierc1183952012-06-26 22:30:43 +00003222
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00003223 if (TUK == Sema::TUK_Reference)
3224 ProhibitAttributes(attrs);
Richard Smith7d137e32012-03-23 03:33:32 +00003225
Douglas Gregor6cd5ae42011-02-22 02:55:24 +00003226 if (!Name && TUK != Sema::TUK_Definition) {
3227 Diag(Tok, diag::err_enumerator_unnamed_no_def);
Richard Smith7d137e32012-03-23 03:33:32 +00003228
Douglas Gregor6cd5ae42011-02-22 02:55:24 +00003229 // Skip the rest of this declarator, up until the comma or semicolon.
3230 SkipUntil(tok::comma, true);
3231 return;
3232 }
Richard Smith7d137e32012-03-23 03:33:32 +00003233
Douglas Gregord6ab8742009-05-28 23:31:59 +00003234 bool Owned = false;
John McCall7f41d982009-09-11 04:59:25 +00003235 bool IsDependent = false;
Douglas Gregorba41d012010-04-24 16:38:41 +00003236 const char *PrevSpec = 0;
3237 unsigned DiagID;
John McCall48871652010-08-21 09:40:31 +00003238 Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
John McCall53fa7142010-12-24 02:08:15 +00003239 StartLoc, SS, Name, NameLoc, attrs.getList(),
Richard Smith7d137e32012-03-23 03:33:32 +00003240 AS, DS.getModulePrivateSpecLoc(), TParams,
Richard Smith0f8ee222012-01-10 01:33:14 +00003241 Owned, IsDependent, ScopedEnumKWLoc,
Abramo Bagnara0e05e242010-12-03 18:54:17 +00003242 IsScopedUsingClassTag, BaseType);
Douglas Gregor0bf31402010-10-08 23:50:27 +00003243
Douglas Gregorba41d012010-04-24 16:38:41 +00003244 if (IsDependent) {
Chad Rosierc1183952012-06-26 22:30:43 +00003245 // This enum has a dependent nested-name-specifier. Handle it as a
Douglas Gregorba41d012010-04-24 16:38:41 +00003246 // dependent tag.
3247 if (!Name) {
3248 DS.SetTypeSpecError();
3249 Diag(Tok, diag::err_expected_type_name_after_typename);
3250 return;
3251 }
Chad Rosierc1183952012-06-26 22:30:43 +00003252
Douglas Gregor0be31a22010-07-02 17:43:08 +00003253 TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
Chad Rosierc1183952012-06-26 22:30:43 +00003254 TUK, SS, Name, StartLoc,
Douglas Gregorba41d012010-04-24 16:38:41 +00003255 NameLoc);
3256 if (Type.isInvalid()) {
3257 DS.SetTypeSpecError();
3258 return;
3259 }
Chad Rosierc1183952012-06-26 22:30:43 +00003260
Abramo Bagnara9875a3c2011-03-16 20:16:18 +00003261 if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3262 NameLoc.isValid() ? NameLoc : StartLoc,
3263 PrevSpec, DiagID, Type.get()))
Douglas Gregorba41d012010-04-24 16:38:41 +00003264 Diag(StartLoc, DiagID) << PrevSpec;
Chad Rosierc1183952012-06-26 22:30:43 +00003265
Douglas Gregorba41d012010-04-24 16:38:41 +00003266 return;
3267 }
Mike Stump11289f42009-09-09 15:08:12 +00003268
John McCall48871652010-08-21 09:40:31 +00003269 if (!TagDecl) {
Chad Rosierc1183952012-06-26 22:30:43 +00003270 // The action failed to produce an enumeration tag. If this is a
Douglas Gregorba41d012010-04-24 16:38:41 +00003271 // definition, consume the entire definition.
Richard Smithbfdb1082012-03-12 08:56:40 +00003272 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
Douglas Gregorba41d012010-04-24 16:38:41 +00003273 ConsumeBrace();
3274 SkipUntil(tok::r_brace);
3275 }
Chad Rosierc1183952012-06-26 22:30:43 +00003276
Douglas Gregorba41d012010-04-24 16:38:41 +00003277 DS.SetTypeSpecError();
3278 return;
3279 }
Richard Smith0f8ee222012-01-10 01:33:14 +00003280
Richard Smith369b9f92012-06-25 21:37:02 +00003281 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
John McCall6347b682012-05-07 06:16:58 +00003282 ParseEnumBody(StartLoc, TagDecl);
Mike Stump11289f42009-09-09 15:08:12 +00003283
Abramo Bagnara9875a3c2011-03-16 20:16:18 +00003284 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3285 NameLoc.isValid() ? NameLoc : StartLoc,
3286 PrevSpec, DiagID, TagDecl, Owned))
John McCall49bfce42009-08-03 20:12:06 +00003287 Diag(StartLoc, DiagID) << PrevSpec;
Chris Lattner3b561a32006-08-13 00:12:11 +00003288}
3289
Chris Lattnerc1915e22007-01-25 07:29:02 +00003290/// ParseEnumBody - Parse a {} enclosed enumerator-list.
3291/// enumerator-list:
3292/// enumerator
3293/// enumerator-list ',' enumerator
3294/// enumerator:
3295/// enumeration-constant
3296/// enumeration-constant '=' constant-expression
3297/// enumeration-constant:
3298/// identifier
3299///
John McCall48871652010-08-21 09:40:31 +00003300void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Douglas Gregor07665a62009-01-05 19:45:36 +00003301 // Enter the scope of the enum body and start the definition.
3302 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregor0be31a22010-07-02 17:43:08 +00003303 Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
Douglas Gregor07665a62009-01-05 19:45:36 +00003304
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00003305 BalancedDelimiterTracker T(*this, tok::l_brace);
3306 T.consumeOpen();
Mike Stump11289f42009-09-09 15:08:12 +00003307
Chris Lattner37256fb2007-08-27 17:24:30 +00003308 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
David Blaikiebbafb8a2012-03-11 07:00:24 +00003309 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
Fariborz Jahanian6e814922010-05-28 22:23:22 +00003310 Diag(Tok, diag::error_empty_enum);
Mike Stump11289f42009-09-09 15:08:12 +00003311
Chris Lattner0e62c1c2011-07-23 10:55:15 +00003312 SmallVector<Decl *, 32> EnumConstantDecls;
Chris Lattnerc1915e22007-01-25 07:29:02 +00003313
John McCall48871652010-08-21 09:40:31 +00003314 Decl *LastEnumConstDecl = 0;
Mike Stump11289f42009-09-09 15:08:12 +00003315
Chris Lattnerc1915e22007-01-25 07:29:02 +00003316 // Parse the enumerator-list.
Chris Lattner76c72282007-10-09 17:33:22 +00003317 while (Tok.is(tok::identifier)) {
Chris Lattnerc1915e22007-01-25 07:29:02 +00003318 IdentifierInfo *Ident = Tok.getIdentifierInfo();
3319 SourceLocation IdentLoc = ConsumeToken();
Mike Stump11289f42009-09-09 15:08:12 +00003320
John McCall811a0f52010-10-22 23:36:17 +00003321 // If attributes exist after the enumerator, parse them.
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00003322 ParsedAttributesWithRange attrs(AttrFactory);
John McCall53fa7142010-12-24 02:08:15 +00003323 MaybeParseGNUAttributes(attrs);
Alexis Hunt6aa9bee2012-06-23 05:07:58 +00003324 MaybeParseCXX0XAttributes(attrs);
3325 ProhibitAttributes(attrs);
John McCall811a0f52010-10-22 23:36:17 +00003326
Chris Lattnerc1915e22007-01-25 07:29:02 +00003327 SourceLocation EqualLoc;
John McCalldadc5752010-08-24 06:29:42 +00003328 ExprResult AssignedVal;
John McCall2ec85372012-05-07 06:16:41 +00003329 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
Chad Rosierc1183952012-06-26 22:30:43 +00003330
Chris Lattner76c72282007-10-09 17:33:22 +00003331 if (Tok.is(tok::equal)) {
Chris Lattnerc1915e22007-01-25 07:29:02 +00003332 EqualLoc = ConsumeToken();
Sebastian Redl17f2c7d2008-12-09 13:15:23 +00003333 AssignedVal = ParseConstantExpression();
3334 if (AssignedVal.isInvalid())
Chris Lattnerda6c2ce2007-04-27 19:13:15 +00003335 SkipUntil(tok::comma, tok::r_brace, true, true);
Chris Lattnerc1915e22007-01-25 07:29:02 +00003336 }
Mike Stump11289f42009-09-09 15:08:12 +00003337
Chris Lattnerc1915e22007-01-25 07:29:02 +00003338 // Install the enumerator constant into EnumDecl.
John McCall48871652010-08-21 09:40:31 +00003339 Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3340 LastEnumConstDecl,
3341 IdentLoc, Ident,
John McCall53fa7142010-12-24 02:08:15 +00003342 attrs.getList(), EqualLoc,
John McCall48871652010-08-21 09:40:31 +00003343 AssignedVal.release());
Fariborz Jahanian329b3512011-12-09 01:15:54 +00003344 PD.complete(EnumConstDecl);
Chad Rosierc1183952012-06-26 22:30:43 +00003345
Chris Lattner4ef40012007-06-11 01:28:17 +00003346 EnumConstantDecls.push_back(EnumConstDecl);
3347 LastEnumConstDecl = EnumConstDecl;
Mike Stump11289f42009-09-09 15:08:12 +00003348
Douglas Gregorce66d022010-09-07 14:51:08 +00003349 if (Tok.is(tok::identifier)) {
3350 // We're missing a comma between enumerators.
3351 SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
Chad Rosierc1183952012-06-26 22:30:43 +00003352 Diag(Loc, diag::err_enumerator_list_missing_comma)
Douglas Gregorce66d022010-09-07 14:51:08 +00003353 << FixItHint::CreateInsertion(Loc, ", ");
3354 continue;
3355 }
Chad Rosierc1183952012-06-26 22:30:43 +00003356
Chris Lattner76c72282007-10-09 17:33:22 +00003357 if (Tok.isNot(tok::comma))
Chris Lattnerc1915e22007-01-25 07:29:02 +00003358 break;
3359 SourceLocation CommaLoc = ConsumeToken();
Mike Stump11289f42009-09-09 15:08:12 +00003360
Richard Smith5d164bc2011-10-15 05:09:34 +00003361 if (Tok.isNot(tok::identifier)) {
David Blaikiebbafb8a2012-03-11 07:00:24 +00003362 if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x)
Richard Smith87f5dc52012-07-23 05:45:25 +00003363 Diag(CommaLoc, getLangOpts().CPlusPlus ?
3364 diag::ext_enumerator_list_comma_cxx :
3365 diag::ext_enumerator_list_comma_c)
Richard Smith5d164bc2011-10-15 05:09:34 +00003366 << FixItHint::CreateRemoval(CommaLoc);
David Blaikiebbafb8a2012-03-11 07:00:24 +00003367 else if (getLangOpts().CPlusPlus0x)
Richard Smith5d164bc2011-10-15 05:09:34 +00003368 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3369 << FixItHint::CreateRemoval(CommaLoc);
3370 }
Chris Lattnerc1915e22007-01-25 07:29:02 +00003371 }
Mike Stump11289f42009-09-09 15:08:12 +00003372
Chris Lattnerc1915e22007-01-25 07:29:02 +00003373 // Eat the }.
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00003374 T.consumeClose();
Chris Lattnerc1915e22007-01-25 07:29:02 +00003375
Chris Lattnerc1915e22007-01-25 07:29:02 +00003376 // If attributes exist after the identifier list, parse them.
John McCall084e83d2011-03-24 11:26:52 +00003377 ParsedAttributes attrs(AttrFactory);
John McCall53fa7142010-12-24 02:08:15 +00003378 MaybeParseGNUAttributes(attrs);
Douglas Gregor82ac25e2009-01-08 20:45:30 +00003379
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00003380 Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
3381 EnumDecl, EnumConstantDecls.data(),
3382 EnumConstantDecls.size(), getCurScope(),
3383 attrs.getList());
Mike Stump11289f42009-09-09 15:08:12 +00003384
Douglas Gregor82ac25e2009-01-08 20:45:30 +00003385 EnumScope.Exit();
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00003386 Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3387 T.getCloseLocation());
Richard Smith369b9f92012-06-25 21:37:02 +00003388
3389 // The next token must be valid after an enum definition. If not, a ';'
3390 // was probably forgotten.
Richard Smith200f47c2012-07-02 19:14:01 +00003391 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3392 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
Richard Smith369b9f92012-06-25 21:37:02 +00003393 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3394 // Push this token back into the preprocessor and change our current token
3395 // to ';' so that the rest of the code recovers as though there were an
3396 // ';' after the definition.
3397 PP.EnterToken(Tok);
3398 Tok.setKind(tok::semi);
3399 }
Chris Lattnerc1915e22007-01-25 07:29:02 +00003400}
Chris Lattner3b561a32006-08-13 00:12:11 +00003401
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003402/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff69e8f9e2008-02-11 23:15:56 +00003403/// start of a type-qualifier-list.
3404bool Parser::isTypeQualifier() const {
3405 switch (Tok.getKind()) {
3406 default: return false;
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003407
3408 // type-qualifier only in OpenCL
3409 case tok::kw_private:
David Blaikiebbafb8a2012-03-11 07:00:24 +00003410 return getLangOpts().OpenCL;
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003411
Steve Naroff69e8f9e2008-02-11 23:15:56 +00003412 // type-qualifier
3413 case tok::kw_const:
3414 case tok::kw_volatile:
3415 case tok::kw_restrict:
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003416 case tok::kw___private:
3417 case tok::kw___local:
3418 case tok::kw___global:
3419 case tok::kw___constant:
3420 case tok::kw___read_only:
3421 case tok::kw___read_write:
3422 case tok::kw___write_only:
Steve Naroff69e8f9e2008-02-11 23:15:56 +00003423 return true;
3424 }
3425}
3426
Chris Lattnerfd48afe2010-02-28 18:18:36 +00003427/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3428/// is definitely a type-specifier. Return false if it isn't part of a type
3429/// specifier or if we're not sure.
3430bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3431 switch (Tok.getKind()) {
3432 default: return false;
3433 // type-specifiers
3434 case tok::kw_short:
3435 case tok::kw_long:
Francois Pichet84133e42011-04-28 01:59:37 +00003436 case tok::kw___int64:
Richard Smithf016bbc2012-04-04 06:24:32 +00003437 case tok::kw___int128:
Chris Lattnerfd48afe2010-02-28 18:18:36 +00003438 case tok::kw_signed:
3439 case tok::kw_unsigned:
3440 case tok::kw__Complex:
3441 case tok::kw__Imaginary:
3442 case tok::kw_void:
3443 case tok::kw_char:
3444 case tok::kw_wchar_t:
3445 case tok::kw_char16_t:
3446 case tok::kw_char32_t:
3447 case tok::kw_int:
Anton Korobeynikovf0c267e2011-10-14 23:23:15 +00003448 case tok::kw_half:
Chris Lattnerfd48afe2010-02-28 18:18:36 +00003449 case tok::kw_float:
3450 case tok::kw_double:
3451 case tok::kw_bool:
3452 case tok::kw__Bool:
3453 case tok::kw__Decimal32:
3454 case tok::kw__Decimal64:
3455 case tok::kw__Decimal128:
3456 case tok::kw___vector:
Chad Rosierc1183952012-06-26 22:30:43 +00003457
Chris Lattnerfd48afe2010-02-28 18:18:36 +00003458 // struct-or-union-specifier (C99) or class-specifier (C++)
3459 case tok::kw_class:
3460 case tok::kw_struct:
3461 case tok::kw_union:
3462 // enum-specifier
3463 case tok::kw_enum:
Chad Rosierc1183952012-06-26 22:30:43 +00003464
Chris Lattnerfd48afe2010-02-28 18:18:36 +00003465 // typedef-name
3466 case tok::annot_typename:
3467 return true;
3468 }
3469}
3470
Steve Naroff69e8f9e2008-02-11 23:15:56 +00003471/// isTypeSpecifierQualifier - Return true if the current token could be the
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003472/// start of a specifier-qualifier-list.
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00003473bool Parser::isTypeSpecifierQualifier() {
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003474 switch (Tok.getKind()) {
3475 default: return false;
Mike Stump11289f42009-09-09 15:08:12 +00003476
Chris Lattner020bab92009-01-04 23:41:41 +00003477 case tok::identifier: // foo::bar
John Thompson22334602010-02-05 00:12:22 +00003478 if (TryAltiVecVectorToken())
3479 return true;
3480 // Fall through.
Douglas Gregor333489b2009-03-27 23:10:48 +00003481 case tok::kw_typename: // typename T::type
Chris Lattner020bab92009-01-04 23:41:41 +00003482 // Annotate typenames and C++ scope specifiers. If we get one, just
3483 // recurse to handle whatever we get.
3484 if (TryAnnotateTypeOrScopeToken())
John McCall1f476a12010-02-26 08:45:28 +00003485 return true;
3486 if (Tok.is(tok::identifier))
3487 return false;
3488 return isTypeSpecifierQualifier();
Douglas Gregor333489b2009-03-27 23:10:48 +00003489
Chris Lattner020bab92009-01-04 23:41:41 +00003490 case tok::coloncolon: // ::foo::bar
3491 if (NextToken().is(tok::kw_new) || // ::new
3492 NextToken().is(tok::kw_delete)) // ::delete
3493 return false;
3494
Chris Lattner020bab92009-01-04 23:41:41 +00003495 if (TryAnnotateTypeOrScopeToken())
John McCall1f476a12010-02-26 08:45:28 +00003496 return true;
3497 return isTypeSpecifierQualifier();
Mike Stump11289f42009-09-09 15:08:12 +00003498
Chris Lattnere37e2332006-08-15 04:50:22 +00003499 // GNU attributes support.
3500 case tok::kw___attribute:
Steve Naroffad373bd2007-07-31 12:34:36 +00003501 // GNU typeof support.
3502 case tok::kw_typeof:
Mike Stump11289f42009-09-09 15:08:12 +00003503
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003504 // type-specifiers
3505 case tok::kw_short:
3506 case tok::kw_long:
Francois Pichet84133e42011-04-28 01:59:37 +00003507 case tok::kw___int64:
Richard Smithf016bbc2012-04-04 06:24:32 +00003508 case tok::kw___int128:
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003509 case tok::kw_signed:
3510 case tok::kw_unsigned:
3511 case tok::kw__Complex:
3512 case tok::kw__Imaginary:
3513 case tok::kw_void:
3514 case tok::kw_char:
Argyrios Kyrtzidis40e9e482008-08-09 16:51:54 +00003515 case tok::kw_wchar_t:
Alisdair Mereditha9ad47d2009-07-14 06:30:34 +00003516 case tok::kw_char16_t:
3517 case tok::kw_char32_t:
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003518 case tok::kw_int:
Anton Korobeynikovf0c267e2011-10-14 23:23:15 +00003519 case tok::kw_half:
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003520 case tok::kw_float:
3521 case tok::kw_double:
Chris Lattnerbb31a422007-11-15 05:25:19 +00003522 case tok::kw_bool:
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003523 case tok::kw__Bool:
3524 case tok::kw__Decimal32:
3525 case tok::kw__Decimal64:
3526 case tok::kw__Decimal128:
John Thompson22334602010-02-05 00:12:22 +00003527 case tok::kw___vector:
Mike Stump11289f42009-09-09 15:08:12 +00003528
Chris Lattner861a2262008-04-13 18:59:07 +00003529 // struct-or-union-specifier (C99) or class-specifier (C++)
3530 case tok::kw_class:
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003531 case tok::kw_struct:
3532 case tok::kw_union:
3533 // enum-specifier
3534 case tok::kw_enum:
Mike Stump11289f42009-09-09 15:08:12 +00003535
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003536 // type-qualifier
3537 case tok::kw_const:
3538 case tok::kw_volatile:
3539 case tok::kw_restrict:
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00003540
3541 // typedef-name
Chris Lattnera8a3f732009-01-06 05:06:21 +00003542 case tok::annot_typename:
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003543 return true;
Mike Stump11289f42009-09-09 15:08:12 +00003544
Chris Lattner409bf7d2008-10-20 00:25:30 +00003545 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3546 case tok::less:
David Blaikiebbafb8a2012-03-11 07:00:24 +00003547 return getLangOpts().ObjC1;
Mike Stump11289f42009-09-09 15:08:12 +00003548
Steve Naroff44ac7772008-12-25 14:16:32 +00003549 case tok::kw___cdecl:
3550 case tok::kw___stdcall:
3551 case tok::kw___fastcall:
Douglas Gregora941dca2010-05-18 16:57:00 +00003552 case tok::kw___thiscall:
Eli Friedman53339e02009-06-08 23:27:34 +00003553 case tok::kw___w64:
3554 case tok::kw___ptr64:
Francois Pichetf2fb4112011-08-25 00:36:46 +00003555 case tok::kw___ptr32:
Dawn Perchik335e16b2010-09-03 01:29:35 +00003556 case tok::kw___pascal:
Francois Pichet17ed0202011-08-18 09:59:55 +00003557 case tok::kw___unaligned:
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003558
3559 case tok::kw___private:
3560 case tok::kw___local:
3561 case tok::kw___global:
3562 case tok::kw___constant:
3563 case tok::kw___read_only:
3564 case tok::kw___read_write:
3565 case tok::kw___write_only:
3566
Eli Friedman53339e02009-06-08 23:27:34 +00003567 return true;
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003568
3569 case tok::kw_private:
David Blaikiebbafb8a2012-03-11 07:00:24 +00003570 return getLangOpts().OpenCL;
Eli Friedman0dfb8892011-10-06 23:00:33 +00003571
Benjamin Kramere56f3932011-12-23 17:00:35 +00003572 // C11 _Atomic()
Eli Friedman0dfb8892011-10-06 23:00:33 +00003573 case tok::kw__Atomic:
3574 return true;
Chris Lattnerf5fbd792006-08-10 23:56:11 +00003575 }
3576}
3577
Chris Lattneracd58a32006-08-06 17:24:14 +00003578/// isDeclarationSpecifier() - Return true if the current token is part of a
3579/// declaration specifier.
Douglas Gregorabf4a3e2010-09-16 01:51:54 +00003580///
3581/// \param DisambiguatingWithExpression True to indicate that the purpose of
3582/// this check is to disambiguate between an expression and a declaration.
3583bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
Chris Lattneracd58a32006-08-06 17:24:14 +00003584 switch (Tok.getKind()) {
3585 default: return false;
Mike Stump11289f42009-09-09 15:08:12 +00003586
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003587 case tok::kw_private:
David Blaikiebbafb8a2012-03-11 07:00:24 +00003588 return getLangOpts().OpenCL;
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003589
Chris Lattner020bab92009-01-04 23:41:41 +00003590 case tok::identifier: // foo::bar
Steve Naroff9527bbf2009-03-09 21:12:44 +00003591 // Unfortunate hack to support "Class.factoryMethod" notation.
David Blaikiebbafb8a2012-03-11 07:00:24 +00003592 if (getLangOpts().ObjC1 && NextToken().is(tok::period))
Steve Naroff9527bbf2009-03-09 21:12:44 +00003593 return false;
John Thompson22334602010-02-05 00:12:22 +00003594 if (TryAltiVecVectorToken())
3595 return true;
3596 // Fall through.
David Blaikie15a430a2011-12-04 05:04:18 +00003597 case tok::kw_decltype: // decltype(T())::type
Douglas Gregor333489b2009-03-27 23:10:48 +00003598 case tok::kw_typename: // typename T::type
Chris Lattner020bab92009-01-04 23:41:41 +00003599 // Annotate typenames and C++ scope specifiers. If we get one, just
3600 // recurse to handle whatever we get.
3601 if (TryAnnotateTypeOrScopeToken())
John McCall1f476a12010-02-26 08:45:28 +00003602 return true;
3603 if (Tok.is(tok::identifier))
3604 return false;
Chad Rosierc1183952012-06-26 22:30:43 +00003605
Douglas Gregorabf4a3e2010-09-16 01:51:54 +00003606 // If we're in Objective-C and we have an Objective-C class type followed
Chad Rosierc1183952012-06-26 22:30:43 +00003607 // by an identifier and then either ':' or ']', in a place where an
Douglas Gregorabf4a3e2010-09-16 01:51:54 +00003608 // expression is permitted, then this is probably a class message send
3609 // missing the initial '['. In this case, we won't consider this to be
3610 // the start of a declaration.
Chad Rosierc1183952012-06-26 22:30:43 +00003611 if (DisambiguatingWithExpression &&
Douglas Gregorabf4a3e2010-09-16 01:51:54 +00003612 isStartOfObjCClassMessageMissingOpenBracket())
3613 return false;
Chad Rosierc1183952012-06-26 22:30:43 +00003614
John McCall1f476a12010-02-26 08:45:28 +00003615 return isDeclarationSpecifier();
3616
Chris Lattner020bab92009-01-04 23:41:41 +00003617 case tok::coloncolon: // ::foo::bar
3618 if (NextToken().is(tok::kw_new) || // ::new
3619 NextToken().is(tok::kw_delete)) // ::delete
3620 return false;
Mike Stump11289f42009-09-09 15:08:12 +00003621
Chris Lattner020bab92009-01-04 23:41:41 +00003622 // Annotate typenames and C++ scope specifiers. If we get one, just
3623 // recurse to handle whatever we get.
3624 if (TryAnnotateTypeOrScopeToken())
John McCall1f476a12010-02-26 08:45:28 +00003625 return true;
3626 return isDeclarationSpecifier();
Mike Stump11289f42009-09-09 15:08:12 +00003627
Chris Lattneracd58a32006-08-06 17:24:14 +00003628 // storage-class-specifier
3629 case tok::kw_typedef:
3630 case tok::kw_extern:
Steve Naroff2050b0d2007-12-18 00:16:02 +00003631 case tok::kw___private_extern__:
Chris Lattneracd58a32006-08-06 17:24:14 +00003632 case tok::kw_static:
3633 case tok::kw_auto:
3634 case tok::kw_register:
3635 case tok::kw___thread:
Mike Stump11289f42009-09-09 15:08:12 +00003636
Douglas Gregor26701a42011-09-09 02:06:17 +00003637 // Modules
3638 case tok::kw___module_private__:
Chad Rosierc1183952012-06-26 22:30:43 +00003639
Chris Lattneracd58a32006-08-06 17:24:14 +00003640 // type-specifiers
3641 case tok::kw_short:
3642 case tok::kw_long:
Francois Pichet84133e42011-04-28 01:59:37 +00003643 case tok::kw___int64:
Richard Smithf016bbc2012-04-04 06:24:32 +00003644 case tok::kw___int128:
Chris Lattneracd58a32006-08-06 17:24:14 +00003645 case tok::kw_signed:
3646 case tok::kw_unsigned:
3647 case tok::kw__Complex:
3648 case tok::kw__Imaginary:
3649 case tok::kw_void:
3650 case tok::kw_char:
Argyrios Kyrtzidis40e9e482008-08-09 16:51:54 +00003651 case tok::kw_wchar_t:
Alisdair Mereditha9ad47d2009-07-14 06:30:34 +00003652 case tok::kw_char16_t:
3653 case tok::kw_char32_t:
3654
Chris Lattneracd58a32006-08-06 17:24:14 +00003655 case tok::kw_int:
Anton Korobeynikovf0c267e2011-10-14 23:23:15 +00003656 case tok::kw_half:
Chris Lattneracd58a32006-08-06 17:24:14 +00003657 case tok::kw_float:
3658 case tok::kw_double:
Chris Lattnerbb31a422007-11-15 05:25:19 +00003659 case tok::kw_bool:
Chris Lattneracd58a32006-08-06 17:24:14 +00003660 case tok::kw__Bool:
3661 case tok::kw__Decimal32:
3662 case tok::kw__Decimal64:
3663 case tok::kw__Decimal128:
John Thompson22334602010-02-05 00:12:22 +00003664 case tok::kw___vector:
Mike Stump11289f42009-09-09 15:08:12 +00003665
Chris Lattner861a2262008-04-13 18:59:07 +00003666 // struct-or-union-specifier (C99) or class-specifier (C++)
3667 case tok::kw_class:
Chris Lattneracd58a32006-08-06 17:24:14 +00003668 case tok::kw_struct:
3669 case tok::kw_union:
3670 // enum-specifier
3671 case tok::kw_enum:
Mike Stump11289f42009-09-09 15:08:12 +00003672
Chris Lattneracd58a32006-08-06 17:24:14 +00003673 // type-qualifier
3674 case tok::kw_const:
3675 case tok::kw_volatile:
3676 case tok::kw_restrict:
Steve Naroffad373bd2007-07-31 12:34:36 +00003677
Chris Lattneracd58a32006-08-06 17:24:14 +00003678 // function-specifier
3679 case tok::kw_inline:
Douglas Gregor61956c42008-10-31 09:07:45 +00003680 case tok::kw_virtual:
3681 case tok::kw_explicit:
Chris Lattner7b20dc72007-08-09 16:40:21 +00003682
Peter Collingbourne3d9cbdc2011-04-15 00:35:57 +00003683 // static_assert-declaration
3684 case tok::kw__Static_assert:
3685
Chris Lattner599e47e2007-08-09 17:01:07 +00003686 // GNU typeof support.
3687 case tok::kw_typeof:
Mike Stump11289f42009-09-09 15:08:12 +00003688
Chris Lattner599e47e2007-08-09 17:01:07 +00003689 // GNU attributes.
Chris Lattner7b20dc72007-08-09 16:40:21 +00003690 case tok::kw___attribute:
Chris Lattneracd58a32006-08-06 17:24:14 +00003691 return true;
Mike Stump11289f42009-09-09 15:08:12 +00003692
Francois Pichete878cb62011-06-19 08:02:06 +00003693 // C++0x decltype.
David Blaikie15a430a2011-12-04 05:04:18 +00003694 case tok::annot_decltype:
Francois Pichete878cb62011-06-19 08:02:06 +00003695 return true;
3696
Benjamin Kramere56f3932011-12-23 17:00:35 +00003697 // C11 _Atomic()
Eli Friedman0dfb8892011-10-06 23:00:33 +00003698 case tok::kw__Atomic:
3699 return true;
3700
Chris Lattner8b2ec162008-07-26 03:38:44 +00003701 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3702 case tok::less:
David Blaikiebbafb8a2012-03-11 07:00:24 +00003703 return getLangOpts().ObjC1;
Mike Stump11289f42009-09-09 15:08:12 +00003704
Douglas Gregor19b7acf2011-04-27 05:41:15 +00003705 // typedef-name
3706 case tok::annot_typename:
3707 return !DisambiguatingWithExpression ||
3708 !isStartOfObjCClassMessageMissingOpenBracket();
Chad Rosierc1183952012-06-26 22:30:43 +00003709
Steve Narofff192fab2009-01-06 19:34:12 +00003710 case tok::kw___declspec:
Steve Naroff44ac7772008-12-25 14:16:32 +00003711 case tok::kw___cdecl:
3712 case tok::kw___stdcall:
3713 case tok::kw___fastcall:
Douglas Gregora941dca2010-05-18 16:57:00 +00003714 case tok::kw___thiscall:
Eli Friedman53339e02009-06-08 23:27:34 +00003715 case tok::kw___w64:
3716 case tok::kw___ptr64:
Francois Pichetf2fb4112011-08-25 00:36:46 +00003717 case tok::kw___ptr32:
Eli Friedman53339e02009-06-08 23:27:34 +00003718 case tok::kw___forceinline:
Dawn Perchik335e16b2010-09-03 01:29:35 +00003719 case tok::kw___pascal:
Francois Pichet17ed0202011-08-18 09:59:55 +00003720 case tok::kw___unaligned:
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003721
3722 case tok::kw___private:
3723 case tok::kw___local:
3724 case tok::kw___global:
3725 case tok::kw___constant:
3726 case tok::kw___read_only:
3727 case tok::kw___read_write:
3728 case tok::kw___write_only:
3729
Eli Friedman53339e02009-06-08 23:27:34 +00003730 return true;
Chris Lattneracd58a32006-08-06 17:24:14 +00003731 }
3732}
3733
Douglas Gregor9de54ea2010-01-13 17:31:36 +00003734bool Parser::isConstructorDeclarator() {
3735 TentativeParsingAction TPA(*this);
3736
3737 // Parse the C++ scope specifier.
3738 CXXScopeSpec SS;
Chad Rosierc1183952012-06-26 22:30:43 +00003739 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregordf593fb2011-11-07 17:33:42 +00003740 /*EnteringContext=*/true)) {
John McCall1f476a12010-02-26 08:45:28 +00003741 TPA.Revert();
3742 return false;
3743 }
Douglas Gregor9de54ea2010-01-13 17:31:36 +00003744
3745 // Parse the constructor name.
3746 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
3747 // We already know that we have a constructor name; just consume
3748 // the token.
3749 ConsumeToken();
3750 } else {
3751 TPA.Revert();
3752 return false;
3753 }
3754
Richard Smith43f340f2012-03-27 23:05:05 +00003755 // Current class name must be followed by a left parenthesis.
Douglas Gregor9de54ea2010-01-13 17:31:36 +00003756 if (Tok.isNot(tok::l_paren)) {
3757 TPA.Revert();
3758 return false;
3759 }
3760 ConsumeParen();
3761
Richard Smith43f340f2012-03-27 23:05:05 +00003762 // A right parenthesis, or ellipsis followed by a right parenthesis signals
3763 // that we have a constructor.
3764 if (Tok.is(tok::r_paren) ||
3765 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
Douglas Gregor9de54ea2010-01-13 17:31:36 +00003766 TPA.Revert();
3767 return true;
3768 }
3769
3770 // If we need to, enter the specified scope.
3771 DeclaratorScopeObj DeclScopeObj(*this, SS);
Douglas Gregor0be31a22010-07-02 17:43:08 +00003772 if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
Douglas Gregor9de54ea2010-01-13 17:31:36 +00003773 DeclScopeObj.EnterDeclaratorScope();
3774
Francois Pichet79f3a872011-01-31 04:54:32 +00003775 // Optionally skip Microsoft attributes.
John McCall084e83d2011-03-24 11:26:52 +00003776 ParsedAttributes Attrs(AttrFactory);
Francois Pichet79f3a872011-01-31 04:54:32 +00003777 MaybeParseMicrosoftAttributes(Attrs);
3778
Douglas Gregor9de54ea2010-01-13 17:31:36 +00003779 // Check whether the next token(s) are part of a declaration
3780 // specifier, in which case we have the start of a parameter and,
3781 // therefore, we know that this is a constructor.
Richard Smithefd009d2012-03-27 00:56:56 +00003782 bool IsConstructor = false;
3783 if (isDeclarationSpecifier())
3784 IsConstructor = true;
3785 else if (Tok.is(tok::identifier) ||
3786 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
3787 // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
3788 // This might be a parenthesized member name, but is more likely to
3789 // be a constructor declaration with an invalid argument type. Keep
3790 // looking.
3791 if (Tok.is(tok::annot_cxxscope))
3792 ConsumeToken();
3793 ConsumeToken();
3794
3795 // If this is not a constructor, we must be parsing a declarator,
Richard Smith1453e312012-03-27 01:42:32 +00003796 // which must have one of the following syntactic forms (see the
3797 // grammar extract at the start of ParseDirectDeclarator):
Richard Smithefd009d2012-03-27 00:56:56 +00003798 switch (Tok.getKind()) {
3799 case tok::l_paren:
3800 // C(X ( int));
3801 case tok::l_square:
3802 // C(X [ 5]);
3803 // C(X [ [attribute]]);
3804 case tok::coloncolon:
3805 // C(X :: Y);
3806 // C(X :: *p);
3807 case tok::r_paren:
3808 // C(X )
3809 // Assume this isn't a constructor, rather than assuming it's a
3810 // constructor with an unnamed parameter of an ill-formed type.
3811 break;
3812
3813 default:
3814 IsConstructor = true;
3815 break;
3816 }
3817 }
3818
Douglas Gregor9de54ea2010-01-13 17:31:36 +00003819 TPA.Revert();
3820 return IsConstructor;
3821}
Chris Lattnerb9093cd2006-08-04 04:39:53 +00003822
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003823/// ParseTypeQualifierListOpt
Dawn Perchik335e16b2010-09-03 01:29:35 +00003824/// type-qualifier-list: [C99 6.7.5]
3825/// type-qualifier
Chad Rosierc1183952012-06-26 22:30:43 +00003826/// [vendor] attributes
Dawn Perchik335e16b2010-09-03 01:29:35 +00003827/// [ only if VendorAttributesAllowed=true ]
3828/// type-qualifier-list type-qualifier
Chad Rosierc1183952012-06-26 22:30:43 +00003829/// [vendor] type-qualifier-list attributes
Dawn Perchik335e16b2010-09-03 01:29:35 +00003830/// [ only if VendorAttributesAllowed=true ]
3831/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
3832/// [ only if CXX0XAttributesAllowed=true ]
3833/// Note: vendor can be GNU, MS, etc.
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003834///
Dawn Perchik335e16b2010-09-03 01:29:35 +00003835void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
3836 bool VendorAttributesAllowed,
Richard Smith3dff2512012-04-10 03:25:07 +00003837 bool CXX11AttributesAllowed) {
3838 if (getLangOpts().CPlusPlus0x && CXX11AttributesAllowed &&
Richard Smith7bdcc4a2012-04-10 01:32:12 +00003839 isCXX11AttributeSpecifier()) {
John McCall084e83d2011-03-24 11:26:52 +00003840 ParsedAttributesWithRange attrs(AttrFactory);
Richard Smith3dff2512012-04-10 03:25:07 +00003841 ParseCXX11Attributes(attrs);
Richard Smith7bdcc4a2012-04-10 01:32:12 +00003842 DS.takeAttributesFrom(attrs);
Alexis Hunt96d5c762009-11-21 08:43:09 +00003843 }
Abramo Bagnaraf2a79d92011-03-12 11:17:06 +00003844
3845 SourceLocation EndLoc;
3846
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003847 while (1) {
John McCall49bfce42009-08-03 20:12:06 +00003848 bool isInvalid = false;
Chris Lattnerd9c3c592006-08-05 06:26:47 +00003849 const char *PrevSpec = 0;
John McCall49bfce42009-08-03 20:12:06 +00003850 unsigned DiagID = 0;
Chris Lattner60809f52006-11-28 05:18:46 +00003851 SourceLocation Loc = Tok.getLocation();
Chris Lattnerd9c3c592006-08-05 06:26:47 +00003852
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003853 switch (Tok.getKind()) {
Douglas Gregor28c78432010-08-27 17:35:51 +00003854 case tok::code_completion:
3855 Actions.CodeCompleteTypeQualifiers(DS);
Argyrios Kyrtzidis5cec2ae2011-09-04 03:32:15 +00003856 return cutOffParsing();
Chad Rosierc1183952012-06-26 22:30:43 +00003857
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003858 case tok::kw_const:
John McCall49bfce42009-08-03 20:12:06 +00003859 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
Richard Smith7ac3c6a2012-07-24 20:24:58 +00003860 getLangOpts(), /*IsTypeSpec*/false);
Chris Lattnerd9c3c592006-08-05 06:26:47 +00003861 break;
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003862 case tok::kw_volatile:
John McCall49bfce42009-08-03 20:12:06 +00003863 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smith7ac3c6a2012-07-24 20:24:58 +00003864 getLangOpts(), /*IsTypeSpec*/false);
Chris Lattnerd9c3c592006-08-05 06:26:47 +00003865 break;
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003866 case tok::kw_restrict:
John McCall49bfce42009-08-03 20:12:06 +00003867 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smith7ac3c6a2012-07-24 20:24:58 +00003868 getLangOpts(), /*IsTypeSpec*/false);
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003869 break;
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003870
3871 // OpenCL qualifiers:
Chad Rosierc1183952012-06-26 22:30:43 +00003872 case tok::kw_private:
David Blaikiebbafb8a2012-03-11 07:00:24 +00003873 if (!getLangOpts().OpenCL)
Peter Collingbourne599cb8e2011-03-18 22:38:29 +00003874 goto DoneWithTypeQuals;
3875 case tok::kw___private:
3876 case tok::kw___global:
3877 case tok::kw___local:
3878 case tok::kw___constant:
3879 case tok::kw___read_only:
3880 case tok::kw___write_only:
3881 case tok::kw___read_write:
3882 ParseOpenCLQualifiers(DS);
3883 break;
3884
Eli Friedman53339e02009-06-08 23:27:34 +00003885 case tok::kw___w64:
Steve Narofff9c29d42008-12-25 14:41:26 +00003886 case tok::kw___ptr64:
Francois Pichetf2fb4112011-08-25 00:36:46 +00003887 case tok::kw___ptr32:
Steve Naroff44ac7772008-12-25 14:16:32 +00003888 case tok::kw___cdecl:
3889 case tok::kw___stdcall:
3890 case tok::kw___fastcall:
Douglas Gregora941dca2010-05-18 16:57:00 +00003891 case tok::kw___thiscall:
Francois Pichet17ed0202011-08-18 09:59:55 +00003892 case tok::kw___unaligned:
Dawn Perchik335e16b2010-09-03 01:29:35 +00003893 if (VendorAttributesAllowed) {
John McCall53fa7142010-12-24 02:08:15 +00003894 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman53339e02009-06-08 23:27:34 +00003895 continue;
3896 }
3897 goto DoneWithTypeQuals;
Dawn Perchik335e16b2010-09-03 01:29:35 +00003898 case tok::kw___pascal:
3899 if (VendorAttributesAllowed) {
John McCall53fa7142010-12-24 02:08:15 +00003900 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik335e16b2010-09-03 01:29:35 +00003901 continue;
3902 }
3903 goto DoneWithTypeQuals;
Chris Lattnere37e2332006-08-15 04:50:22 +00003904 case tok::kw___attribute:
Dawn Perchik335e16b2010-09-03 01:29:35 +00003905 if (VendorAttributesAllowed) {
John McCall53fa7142010-12-24 02:08:15 +00003906 ParseGNUAttributes(DS.getAttributes());
Chris Lattnercf0bab22008-12-18 07:02:59 +00003907 continue; // do *not* consume the next token!
3908 }
3909 // otherwise, FALL THROUGH!
3910 default:
Steve Naroff44ac7772008-12-25 14:16:32 +00003911 DoneWithTypeQuals:
Chris Lattnercf0bab22008-12-18 07:02:59 +00003912 // If this is not a type-qualifier token, we're done reading type
3913 // qualifiers. First verify that DeclSpec's are consistent.
Douglas Gregore3e01a22009-04-01 22:41:11 +00003914 DS.Finish(Diags, PP);
Abramo Bagnaraf2a79d92011-03-12 11:17:06 +00003915 if (EndLoc.isValid())
3916 DS.SetRangeEnd(EndLoc);
Chris Lattnercf0bab22008-12-18 07:02:59 +00003917 return;
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003918 }
Chris Lattnerb6ec4e72008-12-18 06:50:14 +00003919
Chris Lattnerd9c3c592006-08-05 06:26:47 +00003920 // If the specifier combination wasn't legal, issue a diagnostic.
3921 if (isInvalid) {
3922 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner6d29c102008-11-18 07:48:38 +00003923 Diag(Tok, DiagID) << PrevSpec;
Chris Lattnerd9c3c592006-08-05 06:26:47 +00003924 }
Abramo Bagnaraf2a79d92011-03-12 11:17:06 +00003925 EndLoc = ConsumeToken();
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00003926 }
3927}
3928
Chris Lattnerd5d0a6c2006-08-07 00:58:14 +00003929
3930/// ParseDeclarator - Parse and verify a newly-initialized declarator.
3931///
3932void Parser::ParseDeclarator(Declarator &D) {
3933 /// This implements the 'declarator' production in the C grammar, then checks
3934 /// for well-formedness and issues diagnostics.
Sebastian Redlbd150f42008-11-21 19:14:01 +00003935 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattnerd5d0a6c2006-08-07 00:58:14 +00003936}
3937
Richard Smith0efa75c2012-03-29 01:16:42 +00003938static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
3939 if (Kind == tok::star || Kind == tok::caret)
3940 return true;
3941
3942 // We parse rvalue refs in C++03, because otherwise the errors are scary.
3943 if (!Lang.CPlusPlus)
3944 return false;
3945
3946 return Kind == tok::amp || Kind == tok::ampamp;
3947}
3948
Sebastian Redlbd150f42008-11-21 19:14:01 +00003949/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
3950/// is parsed by the function passed to it. Pass null, and the direct-declarator
3951/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregordbc5daf2008-11-07 20:08:42 +00003952/// ptr-operator production.
3953///
Richard Smith09f76ee2011-10-19 21:33:05 +00003954/// If the grammar of this construct is extended, matching changes must also be
Richard Smith1453e312012-03-27 01:42:32 +00003955/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
3956/// isConstructorDeclarator.
Richard Smith09f76ee2011-10-19 21:33:05 +00003957///
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00003958/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
3959/// [C] pointer[opt] direct-declarator
3960/// [C++] direct-declarator
3961/// [C++] ptr-operator declarator
Chris Lattner6c7416c2006-08-07 00:19:33 +00003962///
3963/// pointer: [C99 6.7.5]
3964/// '*' type-qualifier-list[opt]
3965/// '*' type-qualifier-list[opt] pointer
3966///
Douglas Gregordbc5daf2008-11-07 20:08:42 +00003967/// ptr-operator:
3968/// '*' cv-qualifier-seq[opt]
3969/// '&'
Sebastian Redled0f3b02009-03-15 22:02:01 +00003970/// [C++0x] '&&'
Douglas Gregordbc5daf2008-11-07 20:08:42 +00003971/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redled0f3b02009-03-15 22:02:01 +00003972/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00003973/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redlbd150f42008-11-21 19:14:01 +00003974void Parser::ParseDeclaratorInternal(Declarator &D,
3975 DirectDeclParseFunction DirectDeclParser) {
Douglas Gregor66a985d2009-08-26 14:27:30 +00003976 if (Diags.hasAllExtensionsSilenced())
3977 D.setExtension();
Chad Rosierc1183952012-06-26 22:30:43 +00003978
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00003979 // C++ member pointers start with a '::' or a nested-name.
3980 // Member pointers get special handling, since there's no place for the
3981 // scope spec in the generic path below.
David Blaikiebbafb8a2012-03-11 07:00:24 +00003982 if (getLangOpts().CPlusPlus &&
Chris Lattner803802d2009-03-24 17:04:48 +00003983 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
3984 Tok.is(tok::annot_cxxscope))) {
Douglas Gregordf593fb2011-11-07 17:33:42 +00003985 bool EnteringContext = D.getContext() == Declarator::FileContext ||
3986 D.getContext() == Declarator::MemberContext;
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00003987 CXXScopeSpec SS;
Douglas Gregordf593fb2011-11-07 17:33:42 +00003988 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
John McCall1f476a12010-02-26 08:45:28 +00003989
Jeffrey Yasskin4e150f82010-04-07 23:29:58 +00003990 if (SS.isNotEmpty()) {
Mike Stump11289f42009-09-09 15:08:12 +00003991 if (Tok.isNot(tok::star)) {
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00003992 // The scope spec really belongs to the direct-declarator.
3993 D.getCXXScopeSpec() = SS;
3994 if (DirectDeclParser)
3995 (this->*DirectDeclParser)(D);
3996 return;
3997 }
3998
3999 SourceLocation Loc = ConsumeToken();
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004000 D.SetRangeEnd(Loc);
John McCall084e83d2011-03-24 11:26:52 +00004001 DeclSpec DS(AttrFactory);
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00004002 ParseTypeQualifierListOpt(DS);
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004003 D.ExtendWithDeclSpec(DS);
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00004004
4005 // Recurse to parse whatever is left.
4006 ParseDeclaratorInternal(D, DirectDeclParser);
4007
4008 // Sema will have to catch (syntactically invalid) pointers into global
4009 // scope. It has to catch pointers into namespace scope anyway.
4010 D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
John McCall084e83d2011-03-24 11:26:52 +00004011 Loc),
4012 DS.getAttributes(),
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004013 /* Don't replace range end. */SourceLocation());
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00004014 return;
4015 }
4016 }
4017
4018 tok::TokenKind Kind = Tok.getKind();
Steve Naroffec33ed92008-08-27 16:04:49 +00004019 // Not a pointer, C++ reference, or block.
Richard Smith0efa75c2012-03-29 01:16:42 +00004020 if (!isPtrOperatorToken(Kind, getLangOpts())) {
Sebastian Redlbd150f42008-11-21 19:14:01 +00004021 if (DirectDeclParser)
4022 (this->*DirectDeclParser)(D);
Douglas Gregordbc5daf2008-11-07 20:08:42 +00004023 return;
4024 }
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00004025
Sebastian Redled0f3b02009-03-15 22:02:01 +00004026 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4027 // '&&' -> rvalue reference
Sebastian Redl3b27be62009-03-23 00:00:23 +00004028 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004029 D.SetRangeEnd(Loc);
Bill Wendling3708c182007-05-27 10:15:43 +00004030
Chris Lattner9eac9312009-03-27 04:18:06 +00004031 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner788404f2008-02-21 01:32:26 +00004032 // Is a pointer.
John McCall084e83d2011-03-24 11:26:52 +00004033 DeclSpec DS(AttrFactory);
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00004034
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004035 // FIXME: GNU attributes are not allowed here in a new-type-id.
Bill Wendling3708c182007-05-27 10:15:43 +00004036 ParseTypeQualifierListOpt(DS);
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004037 D.ExtendWithDeclSpec(DS);
Sebastian Redl9ed6efd2009-01-24 21:16:55 +00004038
Bill Wendling3708c182007-05-27 10:15:43 +00004039 // Recursively parse the declarator.
Sebastian Redlbd150f42008-11-21 19:14:01 +00004040 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroffec33ed92008-08-27 16:04:49 +00004041 if (Kind == tok::star)
4042 // Remember that we parsed a pointer type, and remember the type-quals.
4043 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
Chandler Carruthe71b378d2011-02-23 18:51:59 +00004044 DS.getConstSpecLoc(),
4045 DS.getVolatileSpecLoc(),
John McCall084e83d2011-03-24 11:26:52 +00004046 DS.getRestrictSpecLoc()),
4047 DS.getAttributes(),
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004048 SourceLocation());
Steve Naroffec33ed92008-08-27 16:04:49 +00004049 else
4050 // Remember that we parsed a Block type, and remember the type-quals.
Mike Stump11289f42009-09-09 15:08:12 +00004051 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
John McCall084e83d2011-03-24 11:26:52 +00004052 Loc),
4053 DS.getAttributes(),
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004054 SourceLocation());
Bill Wendling3708c182007-05-27 10:15:43 +00004055 } else {
4056 // Is a reference
John McCall084e83d2011-03-24 11:26:52 +00004057 DeclSpec DS(AttrFactory);
Bill Wendling93efb222007-06-02 23:28:54 +00004058
Sebastian Redl3b27be62009-03-23 00:00:23 +00004059 // Complain about rvalue references in C++03, but then go on and build
4060 // the declarator.
Richard Smith5d164bc2011-10-15 05:09:34 +00004061 if (Kind == tok::ampamp)
David Blaikiebbafb8a2012-03-11 07:00:24 +00004062 Diag(Loc, getLangOpts().CPlusPlus0x ?
Richard Smith5d164bc2011-10-15 05:09:34 +00004063 diag::warn_cxx98_compat_rvalue_reference :
4064 diag::ext_rvalue_reference);
Sebastian Redl3b27be62009-03-23 00:00:23 +00004065
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004066 // GNU-style and C++11 attributes are allowed here, as is restrict.
4067 ParseTypeQualifierListOpt(DS);
4068 D.ExtendWithDeclSpec(DS);
4069
Bill Wendling93efb222007-06-02 23:28:54 +00004070 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4071 // cv-qualifiers are introduced through the use of a typedef or of a
4072 // template type argument, in which case the cv-qualifiers are ignored.
Bill Wendling93efb222007-06-02 23:28:54 +00004073 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4074 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4075 Diag(DS.getConstSpecLoc(),
Chris Lattner6d29c102008-11-18 07:48:38 +00004076 diag::err_invalid_reference_qualifier_application) << "const";
Bill Wendling93efb222007-06-02 23:28:54 +00004077 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4078 Diag(DS.getVolatileSpecLoc(),
Chris Lattner6d29c102008-11-18 07:48:38 +00004079 diag::err_invalid_reference_qualifier_application) << "volatile";
Bill Wendling93efb222007-06-02 23:28:54 +00004080 }
Bill Wendling3708c182007-05-27 10:15:43 +00004081
4082 // Recursively parse the declarator.
Sebastian Redlbd150f42008-11-21 19:14:01 +00004083 ParseDeclaratorInternal(D, DirectDeclParser);
Bill Wendling3708c182007-05-27 10:15:43 +00004084
Douglas Gregor66583c52008-11-03 15:51:28 +00004085 if (D.getNumTypeObjects() > 0) {
4086 // C++ [dcl.ref]p4: There shall be no references to references.
4087 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4088 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattnerebad6a22008-11-19 07:37:42 +00004089 if (const IdentifierInfo *II = D.getIdentifier())
4090 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4091 << II;
4092 else
4093 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4094 << "type name";
Douglas Gregor66583c52008-11-03 15:51:28 +00004095
Sebastian Redlbd150f42008-11-21 19:14:01 +00004096 // Once we've complained about the reference-to-reference, we
Douglas Gregor66583c52008-11-03 15:51:28 +00004097 // can go ahead and build the (technically ill-formed)
4098 // declarator: reference collapsing will take care of it.
4099 }
4100 }
4101
Bill Wendling3708c182007-05-27 10:15:43 +00004102 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner788404f2008-02-21 01:32:26 +00004103 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redled0f3b02009-03-15 22:02:01 +00004104 Kind == tok::amp),
John McCall084e83d2011-03-24 11:26:52 +00004105 DS.getAttributes(),
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004106 SourceLocation());
Bill Wendling3708c182007-05-27 10:15:43 +00004107 }
Chris Lattner6c7416c2006-08-07 00:19:33 +00004108}
4109
Richard Smith0efa75c2012-03-29 01:16:42 +00004110static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4111 SourceLocation EllipsisLoc) {
4112 if (EllipsisLoc.isValid()) {
4113 FixItHint Insertion;
4114 if (!D.getEllipsisLoc().isValid()) {
4115 Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4116 D.setEllipsisLoc(EllipsisLoc);
4117 }
4118 P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4119 << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4120 }
4121}
4122
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00004123/// ParseDirectDeclarator
4124/// direct-declarator: [C99 6.7.5]
Douglas Gregor831c93f2008-11-05 20:51:48 +00004125/// [C99] identifier
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00004126/// '(' declarator ')'
4127/// [GNU] '(' attributes declarator ')'
Chris Lattnere8074e62006-08-06 18:30:15 +00004128/// [C90] direct-declarator '[' constant-expression[opt] ']'
4129/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4130/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4131/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4132/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004133/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4134/// attribute-specifier-seq[opt]
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00004135/// direct-declarator '(' parameter-type-list ')'
4136/// direct-declarator '(' identifier-list[opt] ')'
4137/// [GNU] direct-declarator '(' parameter-forward-declarations
4138/// parameter-type-list[opt] ')'
Argyrios Kyrtzidis22c40fa2008-10-24 21:46:40 +00004139/// [C++] direct-declarator '(' parameter-declaration-clause ')'
4140/// cv-qualifier-seq[opt] exception-specification[opt]
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004141/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4142/// attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4143/// ref-qualifier[opt] exception-specification[opt]
Douglas Gregor61956c42008-10-31 09:07:45 +00004144/// [C++] declarator-id
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004145/// [C++11] declarator-id attribute-specifier-seq[opt]
Douglas Gregor831c93f2008-11-05 20:51:48 +00004146///
4147/// declarator-id: [C++ 8]
Douglas Gregor27b4c162010-12-23 22:44:42 +00004148/// '...'[opt] id-expression
Douglas Gregor831c93f2008-11-05 20:51:48 +00004149/// '::'[opt] nested-name-specifier[opt] type-name
4150///
4151/// id-expression: [C++ 5.1]
4152/// unqualified-id
Douglas Gregord90fd522009-09-25 21:45:23 +00004153/// qualified-id
Douglas Gregor831c93f2008-11-05 20:51:48 +00004154///
4155/// unqualified-id: [C++ 5.1]
Mike Stump11289f42009-09-09 15:08:12 +00004156/// identifier
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00004157/// operator-function-id
Douglas Gregord90fd522009-09-25 21:45:23 +00004158/// conversion-function-id
Mike Stump11289f42009-09-09 15:08:12 +00004159/// '~' class-name
Douglas Gregor7f741122009-02-25 19:37:18 +00004160/// template-id
Argyrios Kyrtzidise4426352008-11-07 22:02:30 +00004161///
Richard Smith1453e312012-03-27 01:42:32 +00004162/// Note, any additional constructs added here may need corresponding changes
4163/// in isConstructorDeclarator.
Chris Lattneracd58a32006-08-06 17:24:14 +00004164void Parser::ParseDirectDeclarator(Declarator &D) {
Argyrios Kyrtzidis9323b042008-11-26 22:40:03 +00004165 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00004166
David Blaikiebbafb8a2012-03-11 07:00:24 +00004167 if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
Douglas Gregor7861a802009-11-03 01:35:08 +00004168 // ParseDeclaratorInternal might already have parsed the scope.
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00004169 if (D.getCXXScopeSpec().isEmpty()) {
Douglas Gregordf593fb2011-11-07 17:33:42 +00004170 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4171 D.getContext() == Declarator::MemberContext;
Chad Rosierc1183952012-06-26 22:30:43 +00004172 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
Douglas Gregordf593fb2011-11-07 17:33:42 +00004173 EnteringContext);
John McCall1f476a12010-02-26 08:45:28 +00004174 }
4175
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00004176 if (D.getCXXScopeSpec().isValid()) {
Douglas Gregor0be31a22010-07-02 17:43:08 +00004177 if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
John McCall2b058ef2009-12-11 20:04:54 +00004178 // Change the declaration context for name lookup, until this function
4179 // is exited (and the declarator has been parsed).
4180 DeclScopeObj.EnterDeclaratorScope();
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00004181 }
4182
Douglas Gregor27b4c162010-12-23 22:44:42 +00004183 // C++0x [dcl.fct]p14:
4184 // There is a syntactic ambiguity when an ellipsis occurs at the end
Chad Rosierc1183952012-06-26 22:30:43 +00004185 // of a parameter-declaration-clause without a preceding comma. In
4186 // this case, the ellipsis is parsed as part of the
4187 // abstract-declarator if the type of the parameter names a template
Douglas Gregor27b4c162010-12-23 22:44:42 +00004188 // parameter pack that has not been expanded; otherwise, it is parsed
4189 // as part of the parameter-declaration-clause.
Richard Smith0efa75c2012-03-29 01:16:42 +00004190 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
Douglas Gregor27b4c162010-12-23 22:44:42 +00004191 !((D.getContext() == Declarator::PrototypeContext ||
4192 D.getContext() == Declarator::BlockLiteralContext) &&
Douglas Gregor27b4c162010-12-23 22:44:42 +00004193 NextToken().is(tok::r_paren) &&
Richard Smith0efa75c2012-03-29 01:16:42 +00004194 !Actions.containsUnexpandedParameterPacks(D))) {
4195 SourceLocation EllipsisLoc = ConsumeToken();
4196 if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4197 // The ellipsis was put in the wrong place. Recover, and explain to
4198 // the user what they should have done.
4199 ParseDeclarator(D);
4200 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4201 return;
4202 } else
4203 D.setEllipsisLoc(EllipsisLoc);
4204
4205 // The ellipsis can't be followed by a parenthesized declarator. We
4206 // check for that in ParseParenDeclarator, after we have disambiguated
4207 // the l_paren token.
4208 }
4209
Douglas Gregor7861a802009-11-03 01:35:08 +00004210 if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4211 Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4212 // We found something that indicates the start of an unqualified-id.
4213 // Parse that unqualified-id.
John McCall84821e72010-04-13 06:39:49 +00004214 bool AllowConstructorName;
4215 if (D.getDeclSpec().hasTypeSpecifier())
4216 AllowConstructorName = false;
4217 else if (D.getCXXScopeSpec().isSet())
4218 AllowConstructorName =
4219 (D.getContext() == Declarator::FileContext ||
4220 (D.getContext() == Declarator::MemberContext &&
4221 D.getDeclSpec().isFriendSpecified()));
4222 else
4223 AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4224
Abramo Bagnara7945c982012-01-27 09:46:47 +00004225 SourceLocation TemplateKWLoc;
Chad Rosierc1183952012-06-26 22:30:43 +00004226 if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4227 /*EnteringContext=*/true,
4228 /*AllowDestructorName=*/true,
Douglas Gregor9de54ea2010-01-13 17:31:36 +00004229 AllowConstructorName,
John McCallba7bf592010-08-24 05:47:05 +00004230 ParsedType(),
Abramo Bagnara7945c982012-01-27 09:46:47 +00004231 TemplateKWLoc,
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00004232 D.getName()) ||
4233 // Once we're past the identifier, if the scope was bad, mark the
4234 // whole declarator bad.
4235 D.getCXXScopeSpec().isInvalid()) {
Argyrios Kyrtzidis9323b042008-11-26 22:40:03 +00004236 D.SetIdentifier(0, Tok.getLocation());
4237 D.setInvalidType(true);
Douglas Gregor7861a802009-11-03 01:35:08 +00004238 } else {
4239 // Parsed the unqualified-id; update range information and move along.
4240 if (D.getSourceRange().getBegin().isInvalid())
4241 D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4242 D.SetRangeEnd(D.getName().getSourceRange().getEnd());
Douglas Gregordbc5daf2008-11-07 20:08:42 +00004243 }
Douglas Gregor7861a802009-11-03 01:35:08 +00004244 goto PastIdentifier;
Douglas Gregor11d0c4c2008-11-06 22:13:31 +00004245 }
Douglas Gregor7861a802009-11-03 01:35:08 +00004246 } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
David Blaikiebbafb8a2012-03-11 07:00:24 +00004247 assert(!getLangOpts().CPlusPlus &&
Argyrios Kyrtzidis9323b042008-11-26 22:40:03 +00004248 "There's a C++-specific check for tok::identifier above");
4249 assert(Tok.getIdentifierInfo() && "Not an identifier?");
4250 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4251 ConsumeToken();
Douglas Gregor7861a802009-11-03 01:35:08 +00004252 goto PastIdentifier;
4253 }
Richard Smith0efa75c2012-03-29 01:16:42 +00004254
Douglas Gregor7861a802009-11-03 01:35:08 +00004255 if (Tok.is(tok::l_paren)) {
Chris Lattneracd58a32006-08-06 17:24:14 +00004256 // direct-declarator: '(' declarator ')'
Chris Lattnere37e2332006-08-15 04:50:22 +00004257 // direct-declarator: '(' attributes declarator ')'
Chris Lattneracd58a32006-08-06 17:24:14 +00004258 // Example: 'char (*X)' or 'int (*XX)(void)'
4259 ParseParenDeclarator(D);
Douglas Gregor9de54ea2010-01-13 17:31:36 +00004260
4261 // If the declarator was parenthesized, we entered the declarator
4262 // scope when parsing the parenthesized declarator, then exited
4263 // the scope already. Re-enter the scope, if we need to.
4264 if (D.getCXXScopeSpec().isSet()) {
Fariborz Jahanian358acd52010-08-17 23:50:37 +00004265 // If there was an error parsing parenthesized declarator, declarator
Richard Smith0efa75c2012-03-29 01:16:42 +00004266 // scope may have been entered before. Don't do it again.
Fariborz Jahanian358acd52010-08-17 23:50:37 +00004267 if (!D.isInvalidType() &&
4268 Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
Douglas Gregor9de54ea2010-01-13 17:31:36 +00004269 // Change the declaration context for name lookup, until this function
4270 // is exited (and the declarator has been parsed).
Fariborz Jahanian358acd52010-08-17 23:50:37 +00004271 DeclScopeObj.EnterDeclaratorScope();
Douglas Gregor9de54ea2010-01-13 17:31:36 +00004272 }
Argyrios Kyrtzidis9323b042008-11-26 22:40:03 +00004273 } else if (D.mayOmitIdentifier()) {
Chris Lattneracd58a32006-08-06 17:24:14 +00004274 // This could be something simple like "int" (in which case the declarator
4275 // portion is empty), if an abstract-declarator is allowed.
4276 D.SetIdentifier(0, Tok.getLocation());
4277 } else {
David Blaikie5d577a22012-06-29 22:03:56 +00004278 if (Tok.getKind() == tok::annot_pragma_parser_crash)
4279 *(volatile int*) 0x11 = 0;
Douglas Gregord9f92e22009-03-06 23:28:18 +00004280 if (D.getContext() == Declarator::MemberContext)
4281 Diag(Tok, diag::err_expected_member_name_or_semi)
4282 << D.getDeclSpec().getSourceRange();
David Blaikiebbafb8a2012-03-11 07:00:24 +00004283 else if (getLangOpts().CPlusPlus)
4284 Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
Argyrios Kyrtzidis32a03792008-11-08 16:45:02 +00004285 else
Chris Lattner6d29c102008-11-18 07:48:38 +00004286 Diag(Tok, diag::err_expected_ident_lparen);
Chris Lattnereec40f92006-08-06 21:55:29 +00004287 D.SetIdentifier(0, Tok.getLocation());
Chris Lattner8c5dd732008-11-11 06:13:16 +00004288 D.setInvalidType(true);
Chris Lattneracd58a32006-08-06 17:24:14 +00004289 }
Mike Stump11289f42009-09-09 15:08:12 +00004290
Argyrios Kyrtzidis9323b042008-11-26 22:40:03 +00004291 PastIdentifier:
Chris Lattneracd58a32006-08-06 17:24:14 +00004292 assert(D.isPastIdentifier() &&
4293 "Haven't past the location of the identifier yet?");
Mike Stump11289f42009-09-09 15:08:12 +00004294
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004295 // Don't parse attributes unless we have parsed an unparenthesized name.
4296 if (D.hasName() && !D.getNumTypeObjects())
John McCall53fa7142010-12-24 02:08:15 +00004297 MaybeParseCXX0XAttributes(D);
Alexis Hunt96d5c762009-11-21 08:43:09 +00004298
Chris Lattneracd58a32006-08-06 17:24:14 +00004299 while (1) {
Chris Lattner76c72282007-10-09 17:33:22 +00004300 if (Tok.is(tok::l_paren)) {
David Blaikie15a430a2011-12-04 05:04:18 +00004301 // Enter function-declaration scope, limiting any declarators to the
4302 // function prototype scope, including parameter declarators.
4303 ParseScope PrototypeScope(this,
4304 Scope::FunctionPrototypeScope|Scope::DeclScope);
Argyrios Kyrtzidis9a1191c2008-10-06 17:10:33 +00004305 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4306 // In such a case, check if we actually have a function declarator; if it
4307 // is not, the declarator has been fully parsed.
Richard Smith943c4402012-07-30 21:30:52 +00004308 bool IsAmbiguous = false;
4309 if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit() &&
4310 !isCXXFunctionDeclarator(&IsAmbiguous))
4311 break;
John McCall084e83d2011-03-24 11:26:52 +00004312 ParsedAttributes attrs(AttrFactory);
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004313 BalancedDelimiterTracker T(*this, tok::l_paren);
4314 T.consumeOpen();
Richard Smith943c4402012-07-30 21:30:52 +00004315 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
David Blaikie15a430a2011-12-04 05:04:18 +00004316 PrototypeScope.Exit();
Chris Lattner76c72282007-10-09 17:33:22 +00004317 } else if (Tok.is(tok::l_square)) {
Chris Lattnere8074e62006-08-06 18:30:15 +00004318 ParseBracketDeclarator(D);
Chris Lattneracd58a32006-08-06 17:24:14 +00004319 } else {
4320 break;
4321 }
4322 }
Chad Rosierc1183952012-06-26 22:30:43 +00004323}
Chris Lattneracd58a32006-08-06 17:24:14 +00004324
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004325/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
4326/// only called before the identifier, so these are most likely just grouping
Mike Stump11289f42009-09-09 15:08:12 +00004327/// parens for precedence. If we find that these are actually function
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004328/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4329///
4330/// direct-declarator:
4331/// '(' declarator ')'
4332/// [GNU] '(' attributes declarator ')'
Chris Lattner8ff2c6c2008-10-20 02:05:46 +00004333/// direct-declarator '(' parameter-type-list ')'
4334/// direct-declarator '(' identifier-list[opt] ')'
4335/// [GNU] direct-declarator '(' parameter-forward-declarations
4336/// parameter-type-list[opt] ')'
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004337///
4338void Parser::ParseParenDeclarator(Declarator &D) {
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004339 BalancedDelimiterTracker T(*this, tok::l_paren);
4340 T.consumeOpen();
4341
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004342 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
Mike Stump11289f42009-09-09 15:08:12 +00004343
Chris Lattner8ff2c6c2008-10-20 02:05:46 +00004344 // Eat any attributes before we look at whether this is a grouping or function
4345 // declarator paren. If this is a grouping paren, the attribute applies to
4346 // the type being built up, for example:
4347 // int (__attribute__(()) *x)(long y)
4348 // If this ends up not being a grouping paren, the attribute applies to the
4349 // first argument, for example:
4350 // int (__attribute__(()) int x)
4351 // In either case, we need to eat any attributes to be able to determine what
4352 // sort of paren this is.
4353 //
John McCall084e83d2011-03-24 11:26:52 +00004354 ParsedAttributes attrs(AttrFactory);
Chris Lattner8ff2c6c2008-10-20 02:05:46 +00004355 bool RequiresArg = false;
4356 if (Tok.is(tok::kw___attribute)) {
John McCall53fa7142010-12-24 02:08:15 +00004357 ParseGNUAttributes(attrs);
Mike Stump11289f42009-09-09 15:08:12 +00004358
Chris Lattner8ff2c6c2008-10-20 02:05:46 +00004359 // We require that the argument list (if this is a non-grouping paren) be
4360 // present even if the attribute list was empty.
4361 RequiresArg = true;
4362 }
Steve Naroff44ac7772008-12-25 14:16:32 +00004363 // Eat any Microsoft extensions.
Eli Friedman53339e02009-06-08 23:27:34 +00004364 if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
Douglas Gregora941dca2010-05-18 16:57:00 +00004365 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
Francois Pichet17ed0202011-08-18 09:59:55 +00004366 Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64) ||
Francois Pichetf2fb4112011-08-25 00:36:46 +00004367 Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) {
John McCall53fa7142010-12-24 02:08:15 +00004368 ParseMicrosoftTypeAttributes(attrs);
Eli Friedman53339e02009-06-08 23:27:34 +00004369 }
Dawn Perchik335e16b2010-09-03 01:29:35 +00004370 // Eat any Borland extensions.
Ted Kremenek5eec2b02010-11-10 05:59:39 +00004371 if (Tok.is(tok::kw___pascal))
John McCall53fa7142010-12-24 02:08:15 +00004372 ParseBorlandTypeAttributes(attrs);
Mike Stump11289f42009-09-09 15:08:12 +00004373
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004374 // If we haven't past the identifier yet (or where the identifier would be
4375 // stored, if this is an abstract declarator), then this is probably just
4376 // grouping parens. However, if this could be an abstract-declarator, then
4377 // this could also be the start of function arguments (consider 'void()').
4378 bool isGrouping;
Mike Stump11289f42009-09-09 15:08:12 +00004379
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004380 if (!D.mayOmitIdentifier()) {
4381 // If this can't be an abstract-declarator, this *must* be a grouping
4382 // paren, because we haven't seen the identifier yet.
4383 isGrouping = true;
4384 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Richard Smith43f340f2012-03-27 23:05:05 +00004385 (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
4386 NextToken().is(tok::r_paren)) || // C++ int(...)
Richard Smith2620cd92012-04-11 04:01:28 +00004387 isDeclarationSpecifier() || // 'int(int)' is a function.
4388 isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function.
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004389 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
4390 // considered to be a type, not a K&R identifier-list.
4391 isGrouping = false;
4392 } else {
4393 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
4394 isGrouping = true;
4395 }
Mike Stump11289f42009-09-09 15:08:12 +00004396
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004397 // If this is a grouping paren, handle:
4398 // direct-declarator: '(' declarator ')'
4399 // direct-declarator: '(' attributes declarator ')'
4400 if (isGrouping) {
Richard Smith0efa75c2012-03-29 01:16:42 +00004401 SourceLocation EllipsisLoc = D.getEllipsisLoc();
4402 D.setEllipsisLoc(SourceLocation());
4403
Argyrios Kyrtzidis8ae36842008-10-07 10:21:57 +00004404 bool hadGroupingParens = D.hasGroupingParens();
Argyrios Kyrtzidis9a1191c2008-10-06 17:10:33 +00004405 D.setGroupingParens(true);
Sebastian Redlbd150f42008-11-21 19:14:01 +00004406 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004407 // Match the ')'.
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004408 T.consumeClose();
Chad Rosierc1183952012-06-26 22:30:43 +00004409 D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004410 T.getCloseLocation()),
4411 attrs, T.getCloseLocation());
Argyrios Kyrtzidis8ae36842008-10-07 10:21:57 +00004412
4413 D.setGroupingParens(hadGroupingParens);
Richard Smith0efa75c2012-03-29 01:16:42 +00004414
4415 // An ellipsis cannot be placed outside parentheses.
4416 if (EllipsisLoc.isValid())
4417 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4418
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004419 return;
4420 }
Mike Stump11289f42009-09-09 15:08:12 +00004421
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004422 // Okay, if this wasn't a grouping paren, it must be the start of a function
4423 // argument list. Recognize that this declarator will never have an
Chris Lattner8ff2c6c2008-10-20 02:05:46 +00004424 // identifier (and remember where it would have been), then call into
4425 // ParseFunctionDeclarator to handle of argument list.
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004426 D.SetIdentifier(0, Tok.getLocation());
4427
David Blaikie15a430a2011-12-04 05:04:18 +00004428 // Enter function-declaration scope, limiting any declarators to the
4429 // function prototype scope, including parameter declarators.
4430 ParseScope PrototypeScope(this,
4431 Scope::FunctionPrototypeScope|Scope::DeclScope);
Richard Smith943c4402012-07-30 21:30:52 +00004432 ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
David Blaikie15a430a2011-12-04 05:04:18 +00004433 PrototypeScope.Exit();
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004434}
4435
4436/// ParseFunctionDeclarator - We are after the identifier and have parsed the
4437/// declarator D up to a paren, which indicates that we are parsing function
4438/// arguments.
Chris Lattneracd58a32006-08-06 17:24:14 +00004439///
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004440/// If FirstArgAttrs is non-null, then the caller parsed those arguments
4441/// immediately after the open paren - they should be considered to be the
4442/// first argument of a parameter.
Chris Lattner8ff2c6c2008-10-20 02:05:46 +00004443///
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004444/// If RequiresArg is true, then the first argument of the function is required
4445/// to be present and required to not be an identifier list.
Douglas Gregor9e66af42011-07-05 16:44:18 +00004446///
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004447/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
4448/// (C++11) ref-qualifier[opt], exception-specification[opt],
4449/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
4450///
4451/// [C++11] exception-specification:
Douglas Gregor9e66af42011-07-05 16:44:18 +00004452/// dynamic-exception-specification
4453/// noexcept-specification
4454///
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004455void Parser::ParseFunctionDeclarator(Declarator &D,
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004456 ParsedAttributes &FirstArgAttrs,
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004457 BalancedDelimiterTracker &Tracker,
Richard Smith943c4402012-07-30 21:30:52 +00004458 bool IsAmbiguous,
Douglas Gregor9e66af42011-07-05 16:44:18 +00004459 bool RequiresArg) {
Chad Rosierc1183952012-06-26 22:30:43 +00004460 assert(getCurScope()->isFunctionPrototypeScope() &&
David Blaikie15a430a2011-12-04 05:04:18 +00004461 "Should call from a Function scope");
Douglas Gregor9e66af42011-07-05 16:44:18 +00004462 // lparen is already consumed!
4463 assert(D.isPastIdentifier() && "Should not call before identifier!");
4464
4465 // This should be true when the function has typed arguments.
4466 // Otherwise, it is treated as a K&R-style function.
4467 bool HasProto = false;
4468 // Build up an array of information about the parsed arguments.
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004469 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Douglas Gregor9e66af42011-07-05 16:44:18 +00004470 // Remember where we see an ellipsis, if any.
4471 SourceLocation EllipsisLoc;
4472
4473 DeclSpec DS(AttrFactory);
4474 bool RefQualifierIsLValueRef = true;
4475 SourceLocation RefQualifierLoc;
Douglas Gregore248eea2011-10-19 06:04:55 +00004476 SourceLocation ConstQualifierLoc;
4477 SourceLocation VolatileQualifierLoc;
Douglas Gregor9e66af42011-07-05 16:44:18 +00004478 ExceptionSpecificationType ESpecType = EST_None;
4479 SourceRange ESpecRange;
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004480 SmallVector<ParsedType, 2> DynamicExceptions;
4481 SmallVector<SourceRange, 2> DynamicExceptionRanges;
Douglas Gregor9e66af42011-07-05 16:44:18 +00004482 ExprResult NoexceptExpr;
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004483 ParsedAttributes FnAttrs(AttrFactory);
Richard Smith700537c2012-06-12 01:51:59 +00004484 TypeResult TrailingReturnType;
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004485
James Molloy6f8780b2012-02-29 10:24:19 +00004486 Actions.ActOnStartFunctionDeclarator();
4487
Douglas Gregor9e66af42011-07-05 16:44:18 +00004488 SourceLocation EndLoc;
Douglas Gregor9e66af42011-07-05 16:44:18 +00004489 if (isFunctionDeclaratorIdentifierList()) {
4490 if (RequiresArg)
4491 Diag(Tok, diag::err_argument_required_after_attribute);
4492
4493 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
4494
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004495 Tracker.consumeClose();
4496 EndLoc = Tracker.getCloseLocation();
Douglas Gregor9e66af42011-07-05 16:44:18 +00004497 } else {
Douglas Gregor9e66af42011-07-05 16:44:18 +00004498 if (Tok.isNot(tok::r_paren))
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004499 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
Douglas Gregor9e66af42011-07-05 16:44:18 +00004500 else if (RequiresArg)
4501 Diag(Tok, diag::err_argument_required_after_attribute);
4502
David Blaikiebbafb8a2012-03-11 07:00:24 +00004503 HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
Douglas Gregor9e66af42011-07-05 16:44:18 +00004504
4505 // If we have the closing ')', eat it.
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004506 Tracker.consumeClose();
4507 EndLoc = Tracker.getCloseLocation();
Douglas Gregor9e66af42011-07-05 16:44:18 +00004508
David Blaikiebbafb8a2012-03-11 07:00:24 +00004509 if (getLangOpts().CPlusPlus) {
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004510 // FIXME: Accept these components in any order, and produce fixits to
4511 // correct the order if the user gets it wrong. Ideally we should deal
4512 // with the virt-specifier-seq and pure-specifier in the same way.
Douglas Gregor9e66af42011-07-05 16:44:18 +00004513
4514 // Parse cv-qualifier-seq[opt].
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004515 ParseTypeQualifierListOpt(DS, false /*no attributes*/, false);
4516 if (!DS.getSourceRange().getEnd().isInvalid()) {
4517 EndLoc = DS.getSourceRange().getEnd();
4518 ConstQualifierLoc = DS.getConstSpecLoc();
4519 VolatileQualifierLoc = DS.getVolatileSpecLoc();
4520 }
Douglas Gregor9e66af42011-07-05 16:44:18 +00004521
4522 // Parse ref-qualifier[opt].
4523 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
David Blaikiebbafb8a2012-03-11 07:00:24 +00004524 Diag(Tok, getLangOpts().CPlusPlus0x ?
Richard Smith5d164bc2011-10-15 05:09:34 +00004525 diag::warn_cxx98_compat_ref_qualifier :
4526 diag::ext_ref_qualifier);
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004527
Douglas Gregor9e66af42011-07-05 16:44:18 +00004528 RefQualifierIsLValueRef = Tok.is(tok::amp);
4529 RefQualifierLoc = ConsumeToken();
4530 EndLoc = RefQualifierLoc;
4531 }
4532
Douglas Gregor3024f072012-04-16 07:05:22 +00004533 // C++11 [expr.prim.general]p3:
Chad Rosierc1183952012-06-26 22:30:43 +00004534 // If a declaration declares a member function or member function
4535 // template of a class X, the expression this is a prvalue of type
Douglas Gregor3024f072012-04-16 07:05:22 +00004536 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
Chad Rosierc1183952012-06-26 22:30:43 +00004537 // and the end of the function-definition, member-declarator, or
Douglas Gregor3024f072012-04-16 07:05:22 +00004538 // declarator.
Chad Rosierc1183952012-06-26 22:30:43 +00004539 bool IsCXX11MemberFunction =
Douglas Gregor3024f072012-04-16 07:05:22 +00004540 getLangOpts().CPlusPlus0x &&
4541 (D.getContext() == Declarator::MemberContext ||
4542 (D.getContext() == Declarator::FileContext &&
Chad Rosierc1183952012-06-26 22:30:43 +00004543 D.getCXXScopeSpec().isValid() &&
Douglas Gregor3024f072012-04-16 07:05:22 +00004544 Actions.CurContext->isRecord()));
4545 Sema::CXXThisScopeRAII ThisScope(Actions,
4546 dyn_cast<CXXRecordDecl>(Actions.CurContext),
4547 DS.getTypeQualifiers(),
4548 IsCXX11MemberFunction);
Richard Smith2331bbf2012-05-02 22:22:32 +00004549
Douglas Gregor9e66af42011-07-05 16:44:18 +00004550 // Parse exception-specification[opt].
Richard Smith2331bbf2012-05-02 22:22:32 +00004551 ESpecType = tryParseExceptionSpecification(ESpecRange,
Douglas Gregor433e0532012-04-16 18:27:27 +00004552 DynamicExceptions,
4553 DynamicExceptionRanges,
Richard Smith2331bbf2012-05-02 22:22:32 +00004554 NoexceptExpr);
Douglas Gregor9e66af42011-07-05 16:44:18 +00004555 if (ESpecType != EST_None)
4556 EndLoc = ESpecRange.getEnd();
4557
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004558 // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
4559 // after the exception-specification.
4560 MaybeParseCXX0XAttributes(FnAttrs);
4561
Douglas Gregor9e66af42011-07-05 16:44:18 +00004562 // Parse trailing-return-type[opt].
David Blaikiebbafb8a2012-03-11 07:00:24 +00004563 if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) {
Richard Smith5d164bc2011-10-15 05:09:34 +00004564 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
Douglas Gregordb0b9f12011-08-04 15:30:47 +00004565 SourceRange Range;
Richard Smith700537c2012-06-12 01:51:59 +00004566 TrailingReturnType = ParseTrailingReturnType(Range);
Douglas Gregordb0b9f12011-08-04 15:30:47 +00004567 if (Range.getEnd().isValid())
4568 EndLoc = Range.getEnd();
Douglas Gregor9e66af42011-07-05 16:44:18 +00004569 }
4570 }
Douglas Gregor9e66af42011-07-05 16:44:18 +00004571 }
4572
4573 // Remember that we parsed a function type, and remember the attributes.
4574 D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
4575 /*isVariadic=*/EllipsisLoc.isValid(),
Richard Smith943c4402012-07-30 21:30:52 +00004576 IsAmbiguous, EllipsisLoc,
Douglas Gregor9e66af42011-07-05 16:44:18 +00004577 ParamInfo.data(), ParamInfo.size(),
4578 DS.getTypeQualifiers(),
4579 RefQualifierIsLValueRef,
Douglas Gregore248eea2011-10-19 06:04:55 +00004580 RefQualifierLoc, ConstQualifierLoc,
4581 VolatileQualifierLoc,
Douglas Gregorad69e652011-07-13 21:47:47 +00004582 /*MutableLoc=*/SourceLocation(),
Douglas Gregor9e66af42011-07-05 16:44:18 +00004583 ESpecType, ESpecRange.getBegin(),
4584 DynamicExceptions.data(),
4585 DynamicExceptionRanges.data(),
4586 DynamicExceptions.size(),
4587 NoexceptExpr.isUsable() ?
4588 NoexceptExpr.get() : 0,
Chad Rosierc1183952012-06-26 22:30:43 +00004589 Tracker.getOpenLocation(),
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004590 EndLoc, D,
Douglas Gregor9e66af42011-07-05 16:44:18 +00004591 TrailingReturnType),
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004592 FnAttrs, EndLoc);
James Molloy6f8780b2012-02-29 10:24:19 +00004593
4594 Actions.ActOnEndFunctionDeclarator();
Douglas Gregor9e66af42011-07-05 16:44:18 +00004595}
4596
4597/// isFunctionDeclaratorIdentifierList - This parameter list may have an
4598/// identifier list form for a K&R-style function: void foo(a,b,c)
4599///
4600/// Note that identifier-lists are only allowed for normal declarators, not for
4601/// abstract-declarators.
4602bool Parser::isFunctionDeclaratorIdentifierList() {
David Blaikiebbafb8a2012-03-11 07:00:24 +00004603 return !getLangOpts().CPlusPlus
Douglas Gregor9e66af42011-07-05 16:44:18 +00004604 && Tok.is(tok::identifier)
4605 && !TryAltiVecVectorToken()
4606 // K&R identifier lists can't have typedefs as identifiers, per C99
4607 // 6.7.5.3p11.
4608 && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
4609 // Identifier lists follow a really simple grammar: the identifiers can
4610 // be followed *only* by a ", identifier" or ")". However, K&R
4611 // identifier lists are really rare in the brave new modern world, and
4612 // it is very common for someone to typo a type in a non-K&R style
4613 // list. If we are presented with something like: "void foo(intptr x,
4614 // float y)", we don't want to start parsing the function declarator as
4615 // though it is a K&R style declarator just because intptr is an
4616 // invalid type.
4617 //
4618 // To handle this, we check to see if the token after the first
4619 // identifier is a "," or ")". Only then do we parse it as an
4620 // identifier list.
4621 && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
4622}
4623
4624/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
4625/// we found a K&R-style identifier list instead of a typed parameter list.
4626///
4627/// After returning, ParamInfo will hold the parsed parameters.
4628///
4629/// identifier-list: [C99 6.7.5]
4630/// identifier
4631/// identifier-list ',' identifier
4632///
4633void Parser::ParseFunctionDeclaratorIdentifierList(
4634 Declarator &D,
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004635 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) {
Douglas Gregor9e66af42011-07-05 16:44:18 +00004636 // If there was no identifier specified for the declarator, either we are in
4637 // an abstract-declarator, or we are in a parameter declarator which was found
4638 // to be abstract. In abstract-declarators, identifier lists are not valid:
4639 // diagnose this.
4640 if (!D.getIdentifier())
4641 Diag(Tok, diag::ext_ident_list_in_param);
4642
4643 // Maintain an efficient lookup of params we have seen so far.
4644 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
4645
4646 while (1) {
4647 // If this isn't an identifier, report the error and skip until ')'.
4648 if (Tok.isNot(tok::identifier)) {
4649 Diag(Tok, diag::err_expected_ident);
4650 SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true);
4651 // Forget we parsed anything.
4652 ParamInfo.clear();
4653 return;
4654 }
4655
4656 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
4657
4658 // Reject 'typedef int y; int test(x, y)', but continue parsing.
4659 if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
4660 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
4661
4662 // Verify that the argument identifier has not already been mentioned.
4663 if (!ParamsSoFar.insert(ParmII)) {
4664 Diag(Tok, diag::err_param_redefinition) << ParmII;
4665 } else {
4666 // Remember this identifier in ParamInfo.
4667 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4668 Tok.getLocation(),
4669 0));
4670 }
4671
4672 // Eat the identifier.
4673 ConsumeToken();
4674
4675 // The list continues if we see a comma.
4676 if (Tok.isNot(tok::comma))
4677 break;
4678 ConsumeToken();
4679 }
4680}
4681
4682/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
4683/// after the opening parenthesis. This function will not parse a K&R-style
4684/// identifier list.
4685///
Richard Smith2620cd92012-04-11 04:01:28 +00004686/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the
4687/// caller parsed those arguments immediately after the open paren - they should
4688/// be considered to be part of the first parameter.
Douglas Gregor9e66af42011-07-05 16:44:18 +00004689///
4690/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
4691/// be the location of the ellipsis, if any was parsed.
4692///
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00004693/// parameter-type-list: [C99 6.7.5]
4694/// parameter-list
4695/// parameter-list ',' '...'
Douglas Gregor9bfc2e52009-09-22 21:41:40 +00004696/// [C++] parameter-list '...'
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00004697///
4698/// parameter-list: [C99 6.7.5]
4699/// parameter-declaration
4700/// parameter-list ',' parameter-declaration
4701///
4702/// parameter-declaration: [C99 6.7.5]
4703/// declaration-specifiers declarator
Chris Lattneraa9c7ae2008-04-08 04:40:51 +00004704/// [C++] declaration-specifiers declarator '=' assignment-expression
Sebastian Redldb63af22012-03-14 15:54:00 +00004705/// [C++11] initializer-clause
Chris Lattnere37e2332006-08-15 04:50:22 +00004706/// [GNU] declaration-specifiers declarator attributes
Sebastian Redlf769df52009-03-24 22:27:57 +00004707/// declaration-specifiers abstract-declarator[opt]
4708/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner58258242008-04-10 02:22:51 +00004709/// '=' assignment-expression
Chris Lattnere37e2332006-08-15 04:50:22 +00004710/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
Richard Smith2620cd92012-04-11 04:01:28 +00004711/// [C++11] attribute-specifier-seq parameter-declaration
Chris Lattnerc0acd3d2006-07-31 05:13:43 +00004712///
Douglas Gregor9e66af42011-07-05 16:44:18 +00004713void Parser::ParseParameterDeclarationClause(
4714 Declarator &D,
Richard Smith2620cd92012-04-11 04:01:28 +00004715 ParsedAttributes &FirstArgAttrs,
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004716 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo,
Douglas Gregor9e66af42011-07-05 16:44:18 +00004717 SourceLocation &EllipsisLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00004718
Chris Lattner371ed4e2008-04-06 06:57:35 +00004719 while (1) {
4720 if (Tok.is(tok::ellipsis)) {
Richard Smith2620cd92012-04-11 04:01:28 +00004721 // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
4722 // before deciding this was a parameter-declaration-clause.
Douglas Gregor94349fd2009-02-18 07:07:28 +00004723 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattner371ed4e2008-04-06 06:57:35 +00004724 break;
Chris Lattneracd58a32006-08-06 17:24:14 +00004725 }
Mike Stump11289f42009-09-09 15:08:12 +00004726
Chris Lattner371ed4e2008-04-06 06:57:35 +00004727 // Parse the declaration-specifiers.
John McCall28a6aea2009-11-04 02:18:39 +00004728 // Just use the ParsingDeclaration "scope" of the declarator.
John McCall084e83d2011-03-24 11:26:52 +00004729 DeclSpec DS(AttrFactory);
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004730
Richard Smith2620cd92012-04-11 04:01:28 +00004731 // Parse any C++11 attributes.
4732 MaybeParseCXX0XAttributes(DS.getAttributes());
4733
John McCall53fa7142010-12-24 02:08:15 +00004734 // Skip any Microsoft attributes before a param.
David Blaikiebbafb8a2012-03-11 07:00:24 +00004735 if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
John McCall53fa7142010-12-24 02:08:15 +00004736 ParseMicrosoftAttributes(DS.getAttributes());
4737
4738 SourceLocation DSStart = Tok.getLocation();
Chris Lattner8ff2c6c2008-10-20 02:05:46 +00004739
4740 // If the caller parsed attributes for the first argument, add them now.
John McCall53fa7142010-12-24 02:08:15 +00004741 // Take them so that we only apply the attributes to the first parameter.
Douglas Gregor9e66af42011-07-05 16:44:18 +00004742 // FIXME: If we can leave the attributes in the token stream somehow, we can
Richard Smith2620cd92012-04-11 04:01:28 +00004743 // get rid of a parameter (FirstArgAttrs) and this statement. It might be
4744 // too much hassle.
4745 DS.takeAttributesFrom(FirstArgAttrs);
John McCall53fa7142010-12-24 02:08:15 +00004746
Chris Lattnerde39c3e2009-02-27 18:38:20 +00004747 ParseDeclarationSpecifiers(DS);
Mike Stump11289f42009-09-09 15:08:12 +00004748
Chris Lattner371ed4e2008-04-06 06:57:35 +00004749 // Parse the declarator. This is "PrototypeContext", because we must
4750 // accept either 'declarator' or 'abstract-declarator' here.
4751 Declarator ParmDecl(DS, Declarator::PrototypeContext);
4752 ParseDeclarator(ParmDecl);
4753
4754 // Parse GNU attributes, if present.
John McCall53fa7142010-12-24 02:08:15 +00004755 MaybeParseGNUAttributes(ParmDecl);
Mike Stump11289f42009-09-09 15:08:12 +00004756
Chris Lattner371ed4e2008-04-06 06:57:35 +00004757 // Remember this parsed parameter in ParamInfo.
4758 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
Mike Stump11289f42009-09-09 15:08:12 +00004759
Douglas Gregor4d87df52008-12-16 21:30:33 +00004760 // DefArgToks is used when the parsing of default arguments needs
4761 // to be delayed.
4762 CachedTokens *DefArgToks = 0;
4763
Chris Lattner371ed4e2008-04-06 06:57:35 +00004764 // If no parameter was specified, verify that *something* was specified,
4765 // otherwise we have a missing type and identifier.
Chris Lattnerde39c3e2009-02-27 18:38:20 +00004766 if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
4767 ParmDecl.getNumTypeObjects() == 0) {
Chris Lattner371ed4e2008-04-06 06:57:35 +00004768 // Completely missing, emit error.
4769 Diag(DSStart, diag::err_missing_param);
4770 } else {
4771 // Otherwise, we have something. Add it and let semantic analysis try
4772 // to grok it and add the result to the ParamInfo we are building.
Mike Stump11289f42009-09-09 15:08:12 +00004773
Chris Lattner371ed4e2008-04-06 06:57:35 +00004774 // Inform the actions module about the parameter declarator, so it gets
4775 // added to the current scope.
John McCall48871652010-08-21 09:40:31 +00004776 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
Chris Lattneraa9c7ae2008-04-08 04:40:51 +00004777
4778 // Parse the default argument, if any. We parse the default
4779 // arguments in all dialects; the semantic analysis in
4780 // ActOnParamDefaultArgument will reject the default argument in
4781 // C.
4782 if (Tok.is(tok::equal)) {
Douglas Gregor58354032008-12-24 00:01:03 +00004783 SourceLocation EqualLoc = Tok.getLocation();
4784
Chris Lattneraa9c7ae2008-04-08 04:40:51 +00004785 // Parse the default argument
Douglas Gregor4d87df52008-12-16 21:30:33 +00004786 if (D.getContext() == Declarator::MemberContext) {
4787 // If we're inside a class definition, cache the tokens
4788 // corresponding to the default argument. We'll actually parse
4789 // them when we see the end of the class definition.
Douglas Gregor4d87df52008-12-16 21:30:33 +00004790 // FIXME: Can we use a smart pointer for Toks?
4791 DefArgToks = new CachedTokens;
4792
Mike Stump11289f42009-09-09 15:08:12 +00004793 if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
Argyrios Kyrtzidis8d7bdba2010-04-23 21:20:12 +00004794 /*StopAtSemi=*/true,
4795 /*ConsumeFinalToken=*/false)) {
Douglas Gregor4d87df52008-12-16 21:30:33 +00004796 delete DefArgToks;
4797 DefArgToks = 0;
Douglas Gregor58354032008-12-24 00:01:03 +00004798 Actions.ActOnParamDefaultArgumentError(Param);
Argyrios Kyrtzidis249179c2010-08-06 09:47:24 +00004799 } else {
4800 // Mark the end of the default argument so that we know when to
4801 // stop when we parse it later on.
4802 Token DefArgEnd;
4803 DefArgEnd.startToken();
4804 DefArgEnd.setKind(tok::cxx_defaultarg_end);
4805 DefArgEnd.setLocation(Tok.getLocation());
4806 DefArgToks->push_back(DefArgEnd);
Mike Stump11289f42009-09-09 15:08:12 +00004807 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
Anders Carlsson84613c42009-06-12 16:51:40 +00004808 (*DefArgToks)[1].getLocation());
Argyrios Kyrtzidis249179c2010-08-06 09:47:24 +00004809 }
Chris Lattneraa9c7ae2008-04-08 04:40:51 +00004810 } else {
Douglas Gregor4d87df52008-12-16 21:30:33 +00004811 // Consume the '='.
Douglas Gregor58354032008-12-24 00:01:03 +00004812 ConsumeToken();
Mike Stump11289f42009-09-09 15:08:12 +00004813
Chad Rosierc1183952012-06-26 22:30:43 +00004814 // The argument isn't actually potentially evaluated unless it is
Douglas Gregor8a01b2a2010-09-11 20:24:53 +00004815 // used.
4816 EnterExpressionEvaluationContext Eval(Actions,
Douglas Gregor7fcbd902012-02-21 00:37:24 +00004817 Sema::PotentiallyEvaluatedIfUsed,
4818 Param);
Douglas Gregor8a01b2a2010-09-11 20:24:53 +00004819
Sebastian Redldb63af22012-03-14 15:54:00 +00004820 ExprResult DefArgResult;
Sebastian Redl1678d5f2012-03-18 22:25:45 +00004821 if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
4822 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Sebastian Redldb63af22012-03-14 15:54:00 +00004823 DefArgResult = ParseBraceInitializer();
Sebastian Redl1678d5f2012-03-18 22:25:45 +00004824 } else
Sebastian Redldb63af22012-03-14 15:54:00 +00004825 DefArgResult = ParseAssignmentExpression();
Douglas Gregor4d87df52008-12-16 21:30:33 +00004826 if (DefArgResult.isInvalid()) {
4827 Actions.ActOnParamDefaultArgumentError(Param);
4828 SkipUntil(tok::comma, tok::r_paren, true, true);
4829 } else {
4830 // Inform the actions module about the default argument
4831 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
John McCallb268a282010-08-23 23:25:46 +00004832 DefArgResult.take());
Douglas Gregor4d87df52008-12-16 21:30:33 +00004833 }
Chris Lattneraa9c7ae2008-04-08 04:40:51 +00004834 }
4835 }
Mike Stump11289f42009-09-09 15:08:12 +00004836
4837 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4838 ParmDecl.getIdentifierLoc(), Param,
Douglas Gregor4d87df52008-12-16 21:30:33 +00004839 DefArgToks));
Chris Lattner371ed4e2008-04-06 06:57:35 +00004840 }
4841
4842 // If the next token is a comma, consume it and keep reading arguments.
Douglas Gregor9bfc2e52009-09-22 21:41:40 +00004843 if (Tok.isNot(tok::comma)) {
4844 if (Tok.is(tok::ellipsis)) {
Douglas Gregor9bfc2e52009-09-22 21:41:40 +00004845 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chad Rosierc1183952012-06-26 22:30:43 +00004846
David Blaikiebbafb8a2012-03-11 07:00:24 +00004847 if (!getLangOpts().CPlusPlus) {
Douglas Gregor9bfc2e52009-09-22 21:41:40 +00004848 // We have ellipsis without a preceding ',', which is ill-formed
4849 // in C. Complain and provide the fix.
4850 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
Douglas Gregora771f462010-03-31 17:46:05 +00004851 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
Douglas Gregor9bfc2e52009-09-22 21:41:40 +00004852 }
4853 }
Chad Rosierc1183952012-06-26 22:30:43 +00004854
Douglas Gregor9bfc2e52009-09-22 21:41:40 +00004855 break;
4856 }
Mike Stump11289f42009-09-09 15:08:12 +00004857
Chris Lattner371ed4e2008-04-06 06:57:35 +00004858 // Consume the comma.
4859 ConsumeToken();
Chris Lattneracd58a32006-08-06 17:24:14 +00004860 }
Mike Stump11289f42009-09-09 15:08:12 +00004861
Chris Lattner6c940e62008-04-06 06:34:08 +00004862}
Chris Lattnerc0a1c7d2008-04-06 05:45:57 +00004863
Chris Lattnere8074e62006-08-06 18:30:15 +00004864/// [C90] direct-declarator '[' constant-expression[opt] ']'
4865/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4866/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4867/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4868/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004869/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4870/// attribute-specifier-seq[opt]
Chris Lattnere8074e62006-08-06 18:30:15 +00004871void Parser::ParseBracketDeclarator(Declarator &D) {
Richard Smith7bdcc4a2012-04-10 01:32:12 +00004872 if (CheckProhibitedCXX11Attribute())
4873 return;
4874
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004875 BalancedDelimiterTracker T(*this, tok::l_square);
4876 T.consumeOpen();
Mike Stump11289f42009-09-09 15:08:12 +00004877
Chris Lattner84a11622008-12-18 07:27:21 +00004878 // C array syntax has many features, but by-far the most common is [] and [4].
4879 // This code does a fast path to handle some of the most obvious cases.
4880 if (Tok.getKind() == tok::r_square) {
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004881 T.consumeClose();
John McCall084e83d2011-03-24 11:26:52 +00004882 ParsedAttributes attrs(AttrFactory);
John McCall53fa7142010-12-24 02:08:15 +00004883 MaybeParseCXX0XAttributes(attrs);
Chad Rosierc1183952012-06-26 22:30:43 +00004884
Chris Lattner84a11622008-12-18 07:27:21 +00004885 // Remember that we parsed the empty array type.
John McCalldadc5752010-08-24 06:29:42 +00004886 ExprResult NumElements;
John McCall084e83d2011-03-24 11:26:52 +00004887 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004888 T.getOpenLocation(),
4889 T.getCloseLocation()),
4890 attrs, T.getCloseLocation());
Chris Lattner84a11622008-12-18 07:27:21 +00004891 return;
4892 } else if (Tok.getKind() == tok::numeric_constant &&
4893 GetLookAheadToken(1).is(tok::r_square)) {
4894 // [4] is very common. Parse the numeric constant expression.
Richard Smithbcc22fc2012-03-09 08:00:36 +00004895 ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
Chris Lattner84a11622008-12-18 07:27:21 +00004896 ConsumeToken();
4897
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004898 T.consumeClose();
John McCall084e83d2011-03-24 11:26:52 +00004899 ParsedAttributes attrs(AttrFactory);
John McCall53fa7142010-12-24 02:08:15 +00004900 MaybeParseCXX0XAttributes(attrs);
Mike Stump11289f42009-09-09 15:08:12 +00004901
Chris Lattner84a11622008-12-18 07:27:21 +00004902 // Remember that we parsed a array type, and remember its features.
John McCall084e83d2011-03-24 11:26:52 +00004903 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
John McCall53fa7142010-12-24 02:08:15 +00004904 ExprRes.release(),
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004905 T.getOpenLocation(),
4906 T.getCloseLocation()),
4907 attrs, T.getCloseLocation());
Chris Lattner84a11622008-12-18 07:27:21 +00004908 return;
4909 }
Mike Stump11289f42009-09-09 15:08:12 +00004910
Chris Lattnere8074e62006-08-06 18:30:15 +00004911 // If valid, this location is the position where we read the 'static' keyword.
4912 SourceLocation StaticLoc;
Chris Lattner76c72282007-10-09 17:33:22 +00004913 if (Tok.is(tok::kw_static))
Chris Lattneraf635312006-10-16 06:06:51 +00004914 StaticLoc = ConsumeToken();
Mike Stump11289f42009-09-09 15:08:12 +00004915
Chris Lattnere8074e62006-08-06 18:30:15 +00004916 // If there is a type-qualifier-list, read it now.
Chris Lattnerb6ec4e72008-12-18 06:50:14 +00004917 // Type qualifiers in an array subscript are a C99 feature.
John McCall084e83d2011-03-24 11:26:52 +00004918 DeclSpec DS(AttrFactory);
Chris Lattnercf0bab22008-12-18 07:02:59 +00004919 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Mike Stump11289f42009-09-09 15:08:12 +00004920
Chris Lattnere8074e62006-08-06 18:30:15 +00004921 // If we haven't already read 'static', check to see if there is one after the
4922 // type-qualifier-list.
Chris Lattner76c72282007-10-09 17:33:22 +00004923 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Chris Lattneraf635312006-10-16 06:06:51 +00004924 StaticLoc = ConsumeToken();
Mike Stump11289f42009-09-09 15:08:12 +00004925
Chris Lattnere8074e62006-08-06 18:30:15 +00004926 // Handle "direct-declarator [ type-qual-list[opt] * ]".
Chris Lattnere8074e62006-08-06 18:30:15 +00004927 bool isStar = false;
John McCalldadc5752010-08-24 06:29:42 +00004928 ExprResult NumElements;
Mike Stump11289f42009-09-09 15:08:12 +00004929
Chris Lattner521ff2b2008-04-06 05:26:30 +00004930 // Handle the case where we have '[*]' as the array size. However, a leading
4931 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
Sylvestre Ledru830885c2012-07-23 08:59:39 +00004932 // the token after the star is a ']'. Since stars in arrays are
Chris Lattner521ff2b2008-04-06 05:26:30 +00004933 // infrequent, use of lookahead is not costly here.
4934 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattnerc439f0d2008-04-06 05:27:21 +00004935 ConsumeToken(); // Eat the '*'.
Chris Lattner1906f802006-08-06 19:14:46 +00004936
Chris Lattnerb6ec4e72008-12-18 06:50:14 +00004937 if (StaticLoc.isValid()) {
Chris Lattner521ff2b2008-04-06 05:26:30 +00004938 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattnerb6ec4e72008-12-18 06:50:14 +00004939 StaticLoc = SourceLocation(); // Drop the static.
4940 }
Chris Lattner521ff2b2008-04-06 05:26:30 +00004941 isStar = true;
Chris Lattner76c72282007-10-09 17:33:22 +00004942 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner84a11622008-12-18 07:27:21 +00004943 // Note, in C89, this production uses the constant-expr production instead
4944 // of assignment-expr. The only difference is that assignment-expr allows
4945 // things like '=' and '*='. Sema rejects these in C89 mode because they
4946 // are not i-c-e's, so we don't need to distinguish between the two here.
Mike Stump11289f42009-09-09 15:08:12 +00004947
Douglas Gregorc9c02ed2009-06-19 23:52:42 +00004948 // Parse the constant-expression or assignment-expression now (depending
4949 // on dialect).
David Blaikiebbafb8a2012-03-11 07:00:24 +00004950 if (getLangOpts().CPlusPlus) {
Douglas Gregorc9c02ed2009-06-19 23:52:42 +00004951 NumElements = ParseConstantExpression();
Eli Friedmane0afc982012-01-21 01:01:51 +00004952 } else {
4953 EnterExpressionEvaluationContext Unevaluated(Actions,
4954 Sema::ConstantEvaluated);
Douglas Gregorc9c02ed2009-06-19 23:52:42 +00004955 NumElements = ParseAssignmentExpression();
Eli Friedmane0afc982012-01-21 01:01:51 +00004956 }
Chris Lattner62591722006-08-12 18:40:58 +00004957 }
Mike Stump11289f42009-09-09 15:08:12 +00004958
Chris Lattner62591722006-08-12 18:40:58 +00004959 // If there was an error parsing the assignment-expression, recover.
Sebastian Redl17f2c7d2008-12-09 13:15:23 +00004960 if (NumElements.isInvalid()) {
Chris Lattnercd2a8c52009-04-24 22:30:50 +00004961 D.setInvalidType(true);
Chris Lattner62591722006-08-12 18:40:58 +00004962 // If the expression was invalid, skip it.
4963 SkipUntil(tok::r_square);
4964 return;
Chris Lattnere8074e62006-08-06 18:30:15 +00004965 }
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004966
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004967 T.consumeClose();
Sebastian Redlf6591ca2009-02-09 18:23:29 +00004968
John McCall084e83d2011-03-24 11:26:52 +00004969 ParsedAttributes attrs(AttrFactory);
John McCall53fa7142010-12-24 02:08:15 +00004970 MaybeParseCXX0XAttributes(attrs);
Alexis Hunt96d5c762009-11-21 08:43:09 +00004971
Chris Lattner84a11622008-12-18 07:27:21 +00004972 // Remember that we parsed a array type, and remember its features.
John McCall084e83d2011-03-24 11:26:52 +00004973 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
Chris Lattnercbc426d2006-12-02 06:43:02 +00004974 StaticLoc.isValid(), isStar,
Douglas Gregor04318252009-07-06 15:59:29 +00004975 NumElements.release(),
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00004976 T.getOpenLocation(),
4977 T.getCloseLocation()),
4978 attrs, T.getCloseLocation());
Chris Lattnere8074e62006-08-06 18:30:15 +00004979}
4980
Argyrios Kyrtzidis2545aeb2008-09-05 11:26:19 +00004981/// [GNU] typeof-specifier:
4982/// typeof ( expressions )
4983/// typeof ( type-name )
4984/// [GNU/C++] typeof unary-expression
Steve Naroffad373bd2007-07-31 12:34:36 +00004985///
4986void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner76c72282007-10-09 17:33:22 +00004987 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00004988 Token OpTok = Tok;
Steve Naroffad373bd2007-07-31 12:34:36 +00004989 SourceLocation StartLoc = ConsumeToken();
4990
John McCalle8595032010-01-13 20:03:27 +00004991 const bool hasParens = Tok.is(tok::l_paren);
4992
Eli Friedmane0afc982012-01-21 01:01:51 +00004993 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
4994
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00004995 bool isCastExpr;
John McCallba7bf592010-08-24 05:47:05 +00004996 ParsedType CastTy;
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00004997 SourceRange CastRange;
Peter Collingbournee190dee2011-03-11 19:24:49 +00004998 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
4999 CastTy, CastRange);
John McCalle8595032010-01-13 20:03:27 +00005000 if (hasParens)
5001 DS.setTypeofParensRange(CastRange);
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00005002
5003 if (CastRange.getEnd().isInvalid())
Argyrios Kyrtzidisf5cc7ac2009-05-22 10:22:18 +00005004 // FIXME: Not accurate, the range gets one token more than it should.
5005 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00005006 else
5007 DS.SetRangeEnd(CastRange.getEnd());
Mike Stump11289f42009-09-09 15:08:12 +00005008
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00005009 if (isCastExpr) {
5010 if (!CastTy) {
5011 DS.SetTypeSpecError();
Argyrios Kyrtzidis2545aeb2008-09-05 11:26:19 +00005012 return;
Douglas Gregor220cac52009-02-18 17:45:20 +00005013 }
Argyrios Kyrtzidis2545aeb2008-09-05 11:26:19 +00005014
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00005015 const char *PrevSpec = 0;
John McCall49bfce42009-08-03 20:12:06 +00005016 unsigned DiagID;
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00005017 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5018 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
John McCall49bfce42009-08-03 20:12:06 +00005019 DiagID, CastTy))
5020 Diag(StartLoc, DiagID) << PrevSpec;
Argyrios Kyrtzidis7bd98442009-05-22 10:22:50 +00005021 return;
Argyrios Kyrtzidisf5cc7ac2009-05-22 10:22:18 +00005022 }
Argyrios Kyrtzidis2545aeb2008-09-05 11:26:19 +00005023
Argyrios Kyrtzidisf5cc7ac2009-05-22 10:22:18 +00005024 // If we get here, the operand to the typeof was an expresion.
5025 if (Operand.isInvalid()) {
5026 DS.SetTypeSpecError();
Steve Naroff4bd2f712007-08-02 02:53:48 +00005027 return;
Steve Naroffad373bd2007-07-31 12:34:36 +00005028 }
Argyrios Kyrtzidis2545aeb2008-09-05 11:26:19 +00005029
Eli Friedmane0afc982012-01-21 01:01:51 +00005030 // We might need to transform the operand if it is potentially evaluated.
5031 Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5032 if (Operand.isInvalid()) {
5033 DS.SetTypeSpecError();
5034 return;
5035 }
5036
Argyrios Kyrtzidisf5cc7ac2009-05-22 10:22:18 +00005037 const char *PrevSpec = 0;
John McCall49bfce42009-08-03 20:12:06 +00005038 unsigned DiagID;
Argyrios Kyrtzidisf5cc7ac2009-05-22 10:22:18 +00005039 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5040 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
John McCallba7bf592010-08-24 05:47:05 +00005041 DiagID, Operand.get()))
John McCall49bfce42009-08-03 20:12:06 +00005042 Diag(StartLoc, DiagID) << PrevSpec;
Steve Naroffad373bd2007-07-31 12:34:36 +00005043}
Chris Lattner73a9c7d2010-02-28 18:33:55 +00005044
Benjamin Kramere56f3932011-12-23 17:00:35 +00005045/// [C11] atomic-specifier:
Eli Friedman0dfb8892011-10-06 23:00:33 +00005046/// _Atomic ( type-name )
5047///
5048void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
5049 assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier");
5050
5051 SourceLocation StartLoc = ConsumeToken();
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00005052 BalancedDelimiterTracker T(*this, tok::l_paren);
5053 if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) {
Eli Friedman0dfb8892011-10-06 23:00:33 +00005054 SkipUntil(tok::r_paren);
5055 return;
5056 }
5057
5058 TypeResult Result = ParseTypeName();
5059 if (Result.isInvalid()) {
5060 SkipUntil(tok::r_paren);
5061 return;
5062 }
5063
5064 // Match the ')'
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00005065 T.consumeClose();
Eli Friedman0dfb8892011-10-06 23:00:33 +00005066
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00005067 if (T.getCloseLocation().isInvalid())
Eli Friedman0dfb8892011-10-06 23:00:33 +00005068 return;
5069
Douglas Gregore7a8e3b2011-10-12 16:37:45 +00005070 DS.setTypeofParensRange(T.getRange());
5071 DS.SetRangeEnd(T.getCloseLocation());
Eli Friedman0dfb8892011-10-06 23:00:33 +00005072
5073 const char *PrevSpec = 0;
5074 unsigned DiagID;
5075 if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5076 DiagID, Result.release()))
5077 Diag(StartLoc, DiagID) << PrevSpec;
5078}
5079
Chris Lattner73a9c7d2010-02-28 18:33:55 +00005080
5081/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5082/// from TryAltiVecVectorToken.
5083bool Parser::TryAltiVecVectorTokenOutOfLine() {
5084 Token Next = NextToken();
5085 switch (Next.getKind()) {
5086 default: return false;
5087 case tok::kw_short:
5088 case tok::kw_long:
5089 case tok::kw_signed:
5090 case tok::kw_unsigned:
5091 case tok::kw_void:
5092 case tok::kw_char:
5093 case tok::kw_int:
5094 case tok::kw_float:
5095 case tok::kw_double:
5096 case tok::kw_bool:
5097 case tok::kw___pixel:
5098 Tok.setKind(tok::kw___vector);
5099 return true;
5100 case tok::identifier:
5101 if (Next.getIdentifierInfo() == Ident_pixel) {
5102 Tok.setKind(tok::kw___vector);
5103 return true;
5104 }
5105 return false;
5106 }
5107}
5108
5109bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5110 const char *&PrevSpec, unsigned &DiagID,
5111 bool &isInvalid) {
5112 if (Tok.getIdentifierInfo() == Ident_vector) {
5113 Token Next = NextToken();
5114 switch (Next.getKind()) {
5115 case tok::kw_short:
5116 case tok::kw_long:
5117 case tok::kw_signed:
5118 case tok::kw_unsigned:
5119 case tok::kw_void:
5120 case tok::kw_char:
5121 case tok::kw_int:
5122 case tok::kw_float:
5123 case tok::kw_double:
5124 case tok::kw_bool:
5125 case tok::kw___pixel:
5126 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5127 return true;
5128 case tok::identifier:
5129 if (Next.getIdentifierInfo() == Ident_pixel) {
5130 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5131 return true;
5132 }
5133 break;
5134 default:
5135 break;
5136 }
Douglas Gregor9938e3b2010-06-16 15:28:57 +00005137 } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
Chris Lattner73a9c7d2010-02-28 18:33:55 +00005138 DS.isTypeAltiVecVector()) {
5139 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5140 return true;
5141 }
5142 return false;
5143}