blob: a50f42bf8ba63511d24d9255c600f1de5a2bafa4 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
Chris Lattner500d3292009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Peter Collingbourne207f4d82011-03-18 22:38:29 +000016#include "clang/Basic/OpenCL.h"
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +000017#include "clang/Sema/Lookup.h"
John McCall19510852010-08-20 18:27:03 +000018#include "clang/Sema/Scope.h"
19#include "clang/Sema/ParsedTemplate.h"
John McCallf312b1e2010-08-26 23:41:50 +000020#include "clang/Sema/PrettyDeclStackTrace.h"
Chris Lattnerd167ca02009-12-10 00:21:05 +000021#include "RAIIObjectsForParser.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000022#include "llvm/ADT/SmallSet.h"
Benjamin Kramer8fe83e12012-02-04 13:45:25 +000023#include "llvm/ADT/SmallString.h"
Caitlin Sadowskib51e0312011-08-09 17:59:31 +000024#include "llvm/ADT/StringSwitch.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000025using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// C99 6.7: Declarations.
29//===----------------------------------------------------------------------===//
30
31/// ParseTypeName
32/// type-name: [C99 6.7.6]
33/// specifier-qualifier-list abstract-declarator[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +000034///
35/// Called type-id in C++.
Douglas Gregor683a81f2011-01-31 16:09:46 +000036TypeResult Parser::ParseTypeName(SourceRange *Range,
John McCallf85e1932011-06-15 23:02:42 +000037 Declarator::TheContext Context,
Richard Smithc89edf52011-07-01 19:46:12 +000038 AccessSpecifier AS,
39 Decl **OwnedType) {
Richard Smith6d96d3a2012-03-15 01:02:11 +000040 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
Richard Smitha971d242012-05-09 20:55:26 +000041 if (DSC == DSC_normal)
42 DSC = DSC_type_specifier;
Richard Smith7796eb52012-03-12 08:56:40 +000043
Reid Spencer5f016e22007-07-11 17:01:13 +000044 // Parse the common declaration-specifiers piece.
John McCall0b7e6782011-03-24 11:26:52 +000045 DeclSpec DS(AttrFactory);
Richard Smith7796eb52012-03-12 08:56:40 +000046 ParseSpecifierQualifierList(DS, AS, DSC);
Richard Smithc89edf52011-07-01 19:46:12 +000047 if (OwnedType)
48 *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
Sebastian Redlef65f062009-05-29 18:02:33 +000049
Reid Spencer5f016e22007-07-11 17:01:13 +000050 // Parse the abstract-declarator, if present.
Douglas Gregor683a81f2011-01-31 16:09:46 +000051 Declarator DeclaratorInfo(DS, Context);
Reid Spencer5f016e22007-07-11 17:01:13 +000052 ParseDeclarator(DeclaratorInfo);
Sebastian Redlef65f062009-05-29 18:02:33 +000053 if (Range)
54 *Range = DeclaratorInfo.getSourceRange();
55
Chris Lattnereaaebc72009-04-25 08:06:05 +000056 if (DeclaratorInfo.isInvalidType())
Douglas Gregor809070a2009-02-18 17:45:20 +000057 return true;
58
Douglas Gregor23c94db2010-07-02 17:43:08 +000059 return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
Reid Spencer5f016e22007-07-11 17:01:13 +000060}
61
Caitlin Sadowskieff98fc2011-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
Sean Huntbbd37c62009-11-21 08:43:09 +000072/// ParseGNUAttributes - Parse a non-empty attributes list.
Reid Spencer5f016e22007-07-11 17:01:13 +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
87/// attrib-name
88/// attrib-name '(' identifier ')'
89/// attrib-name '(' identifier ',' nonempty-expr-list ')'
90/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
91///
92/// [GNU] attrib-name:
93/// identifier
94/// typespec
95/// typequal
96/// storageclass
Mike Stump1eb44332009-09-09 15:08:12 +000097///
Reid Spencer5f016e22007-07-11 17:01:13 +000098/// FIXME: The GCC grammar/code for this construct implies we need two
Mike Stump1eb44332009-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
Reid Spencer5f016e22007-07-11 17:01:13 +0000101/// start with that identifier; otherwise they are an expression list."
102///
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000103/// GCC does not require the ',' between attribs in an attribute-list.
104///
Reid Spencer5f016e22007-07-11 17:01:13 +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.
109
John McCall7f040a92010-12-24 02:08:15 +0000110void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000111 SourceLocation *endLoc,
112 LateParsedAttrList *LateAttrs) {
Sean Huntbbd37c62009-11-21 08:43:09 +0000113 assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
Mike Stump1eb44332009-09-09 15:08:12 +0000114
Chris Lattner04d66662007-10-09 17:33:22 +0000115 while (Tok.is(tok::kw___attribute)) {
Reid Spencer5f016e22007-07-11 17:01:13 +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 McCall7f040a92010-12-24 02:08:15 +0000120 return;
Reid Spencer5f016e22007-07-11 17:01:13 +0000121 }
122 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
123 SkipUntil(tok::r_paren, true); // skip until ) or ;
John McCall7f040a92010-12-24 02:08:15 +0000124 return;
Reid Spencer5f016e22007-07-11 17:01:13 +0000125 }
126 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner04d66662007-10-09 17:33:22 +0000127 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
128 Tok.is(tok::comma)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000129 if (Tok.is(tok::comma)) {
Reid Spencer5f016e22007-07-11 17:01:13 +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 Stump1eb44332009-09-09 15:08:12 +0000137
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000138 if (Tok.is(tok::l_paren)) {
139 // handle "parameterized" attributes
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000140 if (LateAttrs && isAttributeLateParsed(*AttrName)) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000141 LateParsedAttribute *LA =
142 new LateParsedAttribute(this, *AttrName, AttrNameLoc);
143 LateAttrs->push_back(LA);
DeLesley Hutchinsc24a2332012-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 Stump1eb44332009-09-09 15:08:12 +0000149
Caitlin Sadowskieff98fc2011-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 Stump1eb44332009-09-09 15:08:12 +0000152
Caitlin Sadowskieff98fc2011-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);
Reid Spencer5f016e22007-07-11 17:01:13 +0000159 }
160 } else {
John McCall0b7e6782011-03-24 11:26:52 +0000161 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
Sean Hunt93f95f22012-06-18 16:13:52 +0000162 0, SourceLocation(), 0, 0, AttributeList::AS_GNU);
Reid Spencer5f016e22007-07-11 17:01:13 +0000163 }
164 }
165 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
Reid Spencer5f016e22007-07-11 17:01:13 +0000166 SkipUntil(tok::r_paren, false);
Sean Huntbbd37c62009-11-21 08:43:09 +0000167 SourceLocation Loc = Tok.getLocation();
Sebastian Redlab197ba2009-02-09 18:23:29 +0000168 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
169 SkipUntil(tok::r_paren, false);
170 }
John McCall7f040a92010-12-24 02:08:15 +0000171 if (endLoc)
172 *endLoc = Loc;
Reid Spencer5f016e22007-07-11 17:01:13 +0000173 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000174}
175
Caitlin Sadowskieff98fc2011-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 Smithfe0a0fb2011-10-17 21:20:17 +0000199 IdentifierInfo *ParmName = 0;
200 SourceLocation ParmLoc;
201 bool BuiltinType = false;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000202
Richard Smithfe0a0fb2011-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 Smith5a5a9712012-04-04 06:24:32 +0000213 case tok::kw___int128:
Richard Smithfe0a0fb2011-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 Sadowskieff98fc2011-09-08 17:42:22 +0000241 ConsumeToken();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000242
Richard Smithfe0a0fb2011-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 Sadowskieff98fc2011-09-08 17:42:22 +0000249 }
Richard Smithfe0a0fb2011-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 Sadowskieff98fc2011-09-08 17:42:22 +0000254 }
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000255 }
Fariborz Jahanian7a81e412011-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 Jahanianb2243432011-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 Jahanian7a81e412011-10-18 17:11:10 +0000270 SkipUntil(tok::r_paren, false, true); // skip until ')'
271 }
272 }
Richard Smithfe0a0fb2011-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 Kyrtzidisffcc3102011-09-13 16:05:53 +0000277 Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0, AttrNameLoc,
Sean Hunt93f95f22012-06-18 16:13:52 +0000278 ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size(),
279 AttributeList::AS_GNU);
Sean Hunt8e083e72012-06-19 23:57:03 +0000280 if (BuiltinType && attr->getKind() == AttributeList::AT_IBOutletCollection)
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000281 Diag(Tok, diag::err_iboutletcollection_builtintype);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000282 }
283}
284
Chad Rosier8decdee2012-06-26 22:30:43 +0000285/// \brief Parses a single argument for a declspec, including the
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000286/// surrounding parens.
Chad Rosier8decdee2012-06-26 22:30:43 +0000287void Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000288 SourceLocation AttrNameLoc,
289 ParsedAttributes &Attrs)
290{
291 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosier8decdee2012-06-26 22:30:43 +0000292 if (T.expectAndConsume(diag::err_expected_lparen_after,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000293 AttrName->getNameStart(), tok::r_paren))
294 return;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000295
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-06-26 22:30:43 +0000302 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000303 &ExprList, 1, AttributeList::AS_Declspec);
304
305 T.consumeClose();
306}
307
Chad Rosier8decdee2012-06-26 22:30:43 +0000308/// \brief Determines whether a declspec is a "simple" one requiring no
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-06-26 22:30:43 +0000329/// \brief Attempts to parse a declspec which is not simple (one that takes
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-06-26 22:30:43 +0000332void Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-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 Ballmanfc685ac2012-06-19 22:09:27 +0000346 // not.
347 if (Tok.getKind() == tok::l_paren)
348 ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
349 else
Chad Rosier8decdee2012-06-26 22:30:43 +0000350 Attrs.addNew(Ident, Loc, 0, Loc, 0, SourceLocation(), 0, 0,
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-06-26 22:30:43 +0000354 // assignment expressions as a parameter, but the lhs of the assignment
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000355 // must be named get or put.
356 //
Chad Rosier8decdee2012-06-26 22:30:43 +0000357 // For right now, we will just skip to the closing right paren of the
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-06-26 22:30:43 +0000364 if (T.expectAndConsume(diag::err_expected_lparen_after,
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-06-26 22:30:43 +0000373 // attribute, we'd have to split the valid declspec spelling logic into
Aaron Ballmanfc685ac2012-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 Friedmana23b4852009-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 Ballmanfc685ac2012-06-19 22:09:27 +0000391void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
Steve Narofff59e17e2008-12-24 20:59:21 +0000392 assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
Eli Friedmana23b4852009-06-08 07:21:15 +0000393
Steve Narofff59e17e2008-12-24 20:59:21 +0000394 ConsumeToken();
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000395 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosier8decdee2012-06-26 22:30:43 +0000396 if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000397 tok::r_paren))
John McCall7f040a92010-12-24 02:08:15 +0000398 return;
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000399
Chad Rosier8decdee2012-06-26 22:30:43 +0000400 // An empty declspec is perfectly legal and should not warn. Additionally,
Aaron Ballmanfc685ac2012-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 Rosier8decdee2012-06-26 22:30:43 +0000406 if (!IsString && Tok.getKind() != tok::identifier &&
Aaron Ballmanfc685ac2012-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 Olesen35329362012-06-19 21:48:43 +0000411 }
Aaron Ballmanfc685ac2012-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 Olesen35329362012-06-19 21:48:43 +0000422 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000423 AttrName = PP.getIdentifierInfo(Str);
424 AttrNameLoc = ConsumeStringToken();
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000425 } else {
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000426 AttrName = Tok.getIdentifierInfo();
427 AttrNameLoc = ConsumeToken();
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000428 }
Chad Rosier8decdee2012-06-26 22:30:43 +0000429
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000430 if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
Chad Rosier8decdee2012-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 Ballmanfc685ac2012-06-19 22:09:27 +0000433 // (for instance, SAL declspecs in older versions of MSVC).
434 //
Chad Rosier8decdee2012-06-26 22:30:43 +0000435 // Alternatively, if the identifier is a simple one, then it requires no
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000436 // arguments and can be turned into an attribute directly.
Chad Rosier8decdee2012-06-26 22:30:43 +0000437 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000438 0, 0, AttributeList::AS_Declspec);
439 else
440 ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000441 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000442 T.consumeClose();
Eli Friedman290eeb02009-06-08 23:27:34 +0000443}
444
John McCall7f040a92010-12-24 02:08:15 +0000445void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
Eli Friedman290eeb02009-06-08 23:27:34 +0000446 // Treat these like attributes
Eli Friedman290eeb02009-06-08 23:27:34 +0000447 while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
Douglas Gregorf813a2c2010-05-18 16:57:00 +0000448 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +0000449 Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
Francois Pichet58fd97a2011-08-25 00:36:46 +0000450 Tok.is(tok::kw___ptr32) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +0000451 Tok.is(tok::kw___unaligned)) {
Eli Friedman290eeb02009-06-08 23:27:34 +0000452 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
453 SourceLocation AttrNameLoc = ConsumeToken();
John McCall0b7e6782011-03-24 11:26:52 +0000454 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000455 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
Eli Friedman290eeb02009-06-08 23:27:34 +0000456 }
Steve Narofff59e17e2008-12-24 20:59:21 +0000457}
458
John McCall7f040a92010-12-24 02:08:15 +0000459void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
Dawn Perchik52fc3142010-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 McCall0b7e6782011-03-24 11:26:52 +0000464 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000465 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
Dawn Perchik52fc3142010-09-03 01:29:35 +0000466 }
John McCall7f040a92010-12-24 02:08:15 +0000467}
468
Peter Collingbournef315fa82011-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 McCall0b7e6782011-03-24 11:26:52 +0000473 attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
474 AttrNameLoc, 0, AttrNameLoc, 0,
Sean Hunt93f95f22012-06-18 16:13:52 +0000475 SourceLocation(), 0, 0, AttributeList::AS_GNU);
Peter Collingbournef315fa82011-02-14 01:42:53 +0000476 }
477}
478
Peter Collingbourne207f4d82011-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 Rosier8decdee2012-06-26 22:30:43 +0000484 case tok::kw_private:
John McCall0b7e6782011-03-24 11:26:52 +0000485 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000486 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000487 PP.getIdentifierInfo("address_space"), Loc, 0);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000488 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000489
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000490 case tok::kw___global:
John McCall0b7e6782011-03-24 11:26:52 +0000491 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000492 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000493 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000494 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000495
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000496 case tok::kw___local:
John McCall0b7e6782011-03-24 11:26:52 +0000497 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000498 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000499 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000500 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000501
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000502 case tok::kw___constant:
John McCall0b7e6782011-03-24 11:26:52 +0000503 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000504 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000505 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000506 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000507
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000508 case tok::kw___read_only:
John McCall0b7e6782011-03-24 11:26:52 +0000509 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000510 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000511 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000512 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000513
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000514 case tok::kw___write_only:
John McCall0b7e6782011-03-24 11:26:52 +0000515 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000516 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000517 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000518 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000519
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000520 case tok::kw___read_write:
John McCall0b7e6782011-03-24 11:26:52 +0000521 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000522 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000523 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000524 break;
525 default: break;
526 }
527}
528
Douglas Gregor0a0d2b12011-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 Noblesmithf7ccbad2012-02-05 02:13:05 +0000548 SmallString<512> Buffer;
Douglas Gregor0a0d2b12011-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 Rosier8decdee2012-06-26 22:30:43 +0000600
Douglas Gregor0a0d2b12011-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 Rosier8decdee2012-06-26 22:30:43 +0000607 return VersionTuple(Major, Minor);
Douglas Gregor0a0d2b12011-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 Rosier8decdee2012-06-26 22:30:43 +0000614 return VersionTuple();
Douglas Gregor0a0d2b12011-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 Jahanian006e42f2011-12-10 00:28:41 +0000637/// 'availability' '(' platform ',' version-arg-list, opt-message')'
Douglas Gregor0a0d2b12011-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 Gregor93a70672012-03-11 04:53:21 +0000649/// 'obsoleted' = version
Douglas Gregorb53e4172011-03-26 03:35:55 +0000650/// 'unavailable'
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000651/// opt-message:
652/// 'message' '=' <string>
Douglas Gregor0a0d2b12011-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 Jahanian006e42f2011-12-10 00:28:41 +0000662 ExprResult MessageExpr;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000663
664 // Opening '('.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000665 BalancedDelimiterTracker T(*this, tok::l_paren);
666 if (T.consumeOpen()) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000667 Diag(Tok, diag::err_expected_lparen);
668 return;
669 }
Douglas Gregor0a0d2b12011-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 Gregorb53e4172011-03-26 03:35:55 +0000690 Ident_unavailable = PP.getIdentifierInfo("unavailable");
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000691 Ident_message = PP.getIdentifierInfo("message");
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000692 }
693
694 // Parse the set of introductions/deprecations/removals.
Douglas Gregorb53e4172011-03-26 03:35:55 +0000695 SourceLocation UnavailableLoc;
Douglas Gregor0a0d2b12011-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 Gregorb53e4172011-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 Rosier8decdee2012-06-26 22:30:43 +0000709 }
Douglas Gregorb53e4172011-03-26 03:35:55 +0000710 UnavailableLoc = KeywordLoc;
711
712 if (Tok.isNot(tok::comma))
713 break;
714
715 ConsumeToken();
716 continue;
Chad Rosier8decdee2012-06-26 22:30:43 +0000717 }
718
Douglas Gregor0a0d2b12011-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 Jahanian006e42f2011-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 Rosier8decdee2012-06-26 22:30:43 +0000735
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000736 SourceRange VersionRange;
737 VersionTuple Version = ParseVersionTuple(VersionRange);
Chad Rosier8decdee2012-06-26 22:30:43 +0000738
Douglas Gregor0a0d2b12011-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 Rosier8decdee2012-06-26 22:30:43 +0000751 else
Douglas Gregor0a0d2b12011-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 Rosier8decdee2012-06-26 22:30:43 +0000757 << Keyword
Douglas Gregor0a0d2b12011-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 Gregor4a8dfb52011-10-12 16:37:45 +0000777 if (T.consumeClose())
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000778 return;
779
780 if (endLoc)
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000781 *endLoc = T.getCloseLocation();
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000782
Douglas Gregorb53e4172011-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 Gregor0a0d2b12011-03-23 00:50:03 +0000802 // Record this attribute
Chad Rosier8decdee2012-06-26 22:30:43 +0000803 attrs.addNew(&Availability,
804 SourceRange(AvailabilityLoc, T.getCloseLocation()),
Fariborz Jahanianf96708d2012-01-23 23:38:32 +0000805 0, AvailabilityLoc,
John McCall0b7e6782011-03-24 11:26:52 +0000806 Platform, PlatformLoc,
807 Changes[Introduced],
808 Changes[Deprecated],
Chad Rosier8decdee2012-06-26 22:30:43 +0000809 Changes[Obsoleted],
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000810 UnavailableLoc, MessageExpr.take(),
Sean Hunt93f95f22012-06-18 16:13:52 +0000811 AttributeList::AS_GNU);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000812}
813
Caitlin Sadowskieff98fc2011-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 Hutchinsc24a2332012-02-16 16:50:43 +0000825 Self->ParseLexedAttribute(*this, true, false);
Caitlin Sadowskieff98fc2011-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 Gregorcefc3af2012-04-16 07:05:22 +0000839 // Set or update the scope flags.
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000840 bool AlreadyHasClassScope = Class.TopLevelClass;
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000841 unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000842 ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
843 ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
844
DeLesley Hutchinscf2fa2f2012-04-06 15:10:17 +0000845 // Enter the scope of nested classes
846 if (!AlreadyHasClassScope)
847 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
848 Class.TagOrTemplate);
Benjamin Kramer268efba2012-05-17 12:01:52 +0000849 if (!Class.LateParsedDeclarations.empty()) {
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000850 // Allow 'this' within late-parsed attributes.
Chad Rosier8decdee2012-06-26 22:30:43 +0000851 Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000852 /*TypeQuals=*/0);
Chad Rosier8decdee2012-06-26 22:30:43 +0000853
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000854 for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
855 Class.LateParsedDeclarations[i]->ParseLexedAttributes();
856 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000857 }
Chad Rosier8decdee2012-06-26 22:30:43 +0000858
DeLesley Hutchinscf2fa2f2012-04-06 15:10:17 +0000859 if (!AlreadyHasClassScope)
860 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
861 Class.TagOrTemplate);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000862}
863
DeLesley Hutchinsc24a2332012-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 Hutchins95526a42012-08-15 22:41:04 +0000869 if (D)
870 LAs[i]->addDecl(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000871 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
Benjamin Kramerd306cf72012-04-14 12:44:47 +0000872 delete LAs[i];
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000873 }
874 LAs.clear();
875}
876
877
Caitlin Sadowskieff98fc2011-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 Rosier8decdee2012-06-26 22:30:43 +0000881/// create an attribute with the arguments filled in. We add this
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000882/// to the Attribute list for the decl.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000883void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
884 bool EnterScope, bool OnDefinition) {
Caitlin Sadowskieff98fc2011-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 Hutchinsc24a2332012-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 Sadowskieff98fc2011-09-08 17:42:22 +0000900 ParsedAttributes Attrs(AttrFactory);
901 SourceLocation endLoc;
902
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000903 if (LA.Decls.size() == 1) {
904 Decl *D = LA.Decls[0];
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000905
DeLesley Hutchins2287c5e2012-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 Sadowskieff98fc2011-09-08 17:42:22 +0000911
DeLesley Hutchins2287c5e2012-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 Hutchins7ec419a2012-03-02 22:29:50 +0000927 } else if (LA.Decls.size() > 0) {
DeLesley Hutchins2287c5e2012-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 Hutchins7ec419a2012-03-02 22:29:50 +0000931 } else {
932 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000933 }
934
DeLesley Hutchins2287c5e2012-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 Sadowskieff98fc2011-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 Gregord78ef5b2012-03-08 01:00:17 +0000947 ConsumeAnyToken();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000948 }
949}
950
Caitlin Sadowskib51e0312011-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 Sadowskieff98fc2011-09-08 17:42:22 +0000992 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000993
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000994 BalancedDelimiterTracker T(*this, tok::l_paren);
995 T.consumeOpen();
Chad Rosier8decdee2012-06-26 22:30:43 +0000996
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000997 ExprVector ArgExprs(Actions);
998 bool ArgExprsOk = true;
Chad Rosier8decdee2012-06-26 22:30:43 +0000999
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001000 // now parse the list of expressions
DeLesley Hutchins4805f152011-12-14 19:36:06 +00001001 while (Tok.isNot(tok::r_paren)) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001002 ExprResult ArgExpr(ParseAssignmentExpression());
1003 if (ArgExpr.isInvalid()) {
1004 ArgExprsOk = false;
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001005 T.consumeClose();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001006 break;
1007 } else {
1008 ArgExprs.push_back(ArgExpr.release());
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001009 }
Caitlin Sadowskieff98fc2011-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 Hutchins23323e02012-01-20 22:50:54 +00001015 if (ArgExprsOk && !T.consumeClose()) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001016 Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Sean Hunt93f95f22012-06-18 16:13:52 +00001017 ArgExprs.take(), ArgExprs.size(), AttributeList::AS_GNU);
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001018 }
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001019 if (EndLoc)
1020 *EndLoc = T.getCloseLocation();
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001021}
1022
Richard Smith6ee326a2012-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 Carruth2c6dbd72012-04-10 16:03:08 +00001054 llvm_unreachable("All cases handled above.");
Richard Smith6ee326a2012-04-10 01:32:12 +00001055}
1056
John McCall7f040a92010-12-24 02:08:15 +00001057void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1058 Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1059 << attrs.Range;
Dawn Perchik52fc3142010-09-03 01:29:35 +00001060}
1061
Reid Spencer5f016e22007-07-11 17:01:13 +00001062/// ParseDeclaration - Parse a full 'declaration', which consists of
1063/// declaration-specifiers, some number of declarators, and a semicolon.
Chris Lattner97144fc2009-04-02 04:16:50 +00001064/// 'Context' should be a Declarator::TheContext value. This returns the
1065/// location of the semicolon in DeclEnd.
Chris Lattner8f08cb72007-08-25 06:57:03 +00001066///
1067/// declaration: [C99 6.7]
1068/// block-declaration ->
1069/// simple-declaration
1070/// others [FIXME]
Douglas Gregoradcac882008-12-01 23:54:00 +00001071/// [C++] template-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001072/// [C++] namespace-definition
Douglas Gregorf780abc2008-12-30 03:27:21 +00001073/// [C++] using-directive
Douglas Gregord7f37bf2009-06-22 23:06:13 +00001074/// [C++] using-declaration
Richard Smith534986f2012-04-14 00:33:13 +00001075/// [C++11/C11] static_assert-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001076/// others... [FIXME]
1077///
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001078Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1079 unsigned Context,
Sean Huntbbd37c62009-11-21 08:43:09 +00001080 SourceLocation &DeclEnd,
John McCall7f040a92010-12-24 02:08:15 +00001081 ParsedAttributesWithRange &attrs) {
Argyrios Kyrtzidis36d36802010-06-17 10:52:18 +00001082 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Fariborz Jahaniane8cff362011-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 Rosier8decdee2012-06-26 22:30:43 +00001086
John McCalld226f652010-08-21 09:40:31 +00001087 Decl *SingleDecl = 0;
Richard Smithc89edf52011-07-01 19:46:12 +00001088 Decl *OwnedType = 0;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001089 switch (Tok.getKind()) {
Douglas Gregoradcac882008-12-01 23:54:00 +00001090 case tok::kw_template:
Douglas Gregor1426e532009-05-12 21:31:51 +00001091 case tok::kw_export:
John McCall7f040a92010-12-24 02:08:15 +00001092 ProhibitAttributes(attrs);
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00001093 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001094 break;
Sebastian Redld078e642010-08-27 23:12:46 +00001095 case tok::kw_inline:
Sebastian Redl88e64ca2010-08-31 00:36:45 +00001096 // Could be the start of an inline namespace. Allowed as an ext in C++03.
David Blaikie4e4d0842012-03-11 07:00:24 +00001097 if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
John McCall7f040a92010-12-24 02:08:15 +00001098 ProhibitAttributes(attrs);
Sebastian Redld078e642010-08-27 23:12:46 +00001099 SourceLocation InlineLoc = ConsumeToken();
1100 SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1101 break;
1102 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001103 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001104 true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001105 case tok::kw_namespace:
John McCall7f040a92010-12-24 02:08:15 +00001106 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001107 SingleDecl = ParseNamespace(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001108 break;
Douglas Gregorf780abc2008-12-30 03:27:21 +00001109 case tok::kw_using:
John McCall78b81052010-11-10 02:40:36 +00001110 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
Richard Smithc89edf52011-07-01 19:46:12 +00001111 DeclEnd, attrs, &OwnedType);
Chris Lattner682bf922009-03-29 16:50:03 +00001112 break;
Anders Carlsson511d7ab2009-03-11 16:27:10 +00001113 case tok::kw_static_assert:
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00001114 case tok::kw__Static_assert:
John McCall7f040a92010-12-24 02:08:15 +00001115 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001116 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001117 break;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001118 default:
John McCall7f040a92010-12-24 02:08:15 +00001119 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001120 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001121
Chris Lattner682bf922009-03-29 16:50:03 +00001122 // This routine returns a DeclGroup, if the thing we parsed only contains a
Richard Smithc89edf52011-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 Lattner8f08cb72007-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] ';'
Sean Hunt2edf0a22012-06-23 05:07:58 +00001130/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1131/// init-declarator-list ';'
Chris Lattner8f08cb72007-08-25 06:57:03 +00001132///[C90/C++]init-declarator-list ';' [TODO]
1133/// [OMP] threadprivate-directive [TODO]
Chris Lattnercd147752009-03-29 17:27:48 +00001134///
Sean Hunt2edf0a22012-06-23 05:07:58 +00001135/// for-range-declaration: [C++11 6.5p1: stmt.ranged]
Richard Smithad762fc2011-04-14 22:09:26 +00001136/// attribute-specifier-seq[opt] type-specifier-seq declarator
1137///
Chris Lattnercd147752009-03-29 17:27:48 +00001138/// If RequireSemi is false, this does not check for a ';' at the end of the
Chris Lattner5c5db552010-04-05 18:18:31 +00001139/// declaration. If it is true, it checks for and eats it.
Richard Smithad762fc2011-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.
Sean Hunt2edf0a22012-06-23 05:07:58 +00001144Parser::DeclGroupPtrTy
1145Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1146 SourceLocation &DeclEnd,
1147 ParsedAttributesWithRange &attrs,
1148 bool RequireSemi, ForRangeInit *FRI) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001149 // Parse the common declaration-specifiers piece.
John McCall54abf7d2009-11-04 02:18:39 +00001150 ParsingDeclSpec DS(*this);
John McCall7f040a92010-12-24 02:08:15 +00001151 DS.takeAttributesFrom(attrs);
Douglas Gregor312eadb2011-04-24 05:37:28 +00001152
Douglas Gregor0efc2c12010-01-13 17:31:36 +00001153 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
Richard Smith34b41d92011-02-20 03:19:35 +00001154 getDeclSpecContextFromDeclaratorContext(Context));
Abramo Bagnara06284c12012-01-07 10:52:36 +00001155
Reid Spencer5f016e22007-07-11 17:01:13 +00001156 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1157 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner04d66662007-10-09 17:33:22 +00001158 if (Tok.is(tok::semi)) {
Argyrios Kyrtzidis5641b0d2012-05-16 23:49:15 +00001159 DeclEnd = Tok.getLocation();
Chris Lattner5c5db552010-04-05 18:18:31 +00001160 if (RequireSemi) ConsumeToken();
John McCalld226f652010-08-21 09:40:31 +00001161 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
Douglas Gregor312eadb2011-04-24 05:37:28 +00001162 DS);
John McCall54abf7d2009-11-04 02:18:39 +00001163 DS.complete(TheDecl);
Chris Lattner682bf922009-03-29 16:50:03 +00001164 return Actions.ConvertDeclToDeclGroup(TheDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +00001165 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001166
1167 return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
John McCalld8ac0572009-11-03 19:26:08 +00001168}
Mike Stump1eb44332009-09-09 15:08:12 +00001169
Richard Smith0706df42011-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 Blaikie4e4d0842012-03-11 07:00:24 +00001188 return getLangOpts().CPlusPlus;
Richard Smith0706df42011-10-19 21:33:05 +00001189
Richard Smith1c94c162012-01-09 22:31:44 +00001190 case tok::l_square: // Might be an attribute on an unnamed bit-field.
David Blaikie4e4d0842012-03-11 07:00:24 +00001191 return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x &&
Richard Smith1c94c162012-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 Blaikie4e4d0842012-03-11 07:00:24 +00001195 return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
Richard Smith1c94c162012-01-09 22:31:44 +00001196
Richard Smith0706df42011-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 Smith1c94c162012-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 Blaikie4e4d0842012-03-11 07:00:24 +00001222 (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
Richard Smith1c94c162012-01-09 22:31:44 +00001223
1224 case tok::identifier: // Possible virt-specifier.
David Blaikie4e4d0842012-03-11 07:00:24 +00001225 return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
Richard Smith0706df42011-10-19 21:33:05 +00001226
1227 default:
1228 return false;
1229 }
1230
1231 default:
1232 return false;
1233 }
1234}
1235
Richard Smith994d73f2012-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 Rose94f29f42012-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 Smith994d73f2012-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 Rose94f29f42012-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 Smith994d73f2012-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 McCalld8ac0572009-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 McCall54abf7d2009-11-04 02:18:39 +00001318Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1319 unsigned Context,
John McCalld8ac0572009-11-03 19:26:08 +00001320 bool AllowFunctionDefinitions,
Richard Smithad762fc2011-04-14 22:09:26 +00001321 SourceLocation *DeclEnd,
1322 ForRangeInit *FRI) {
John McCalld8ac0572009-11-03 19:26:08 +00001323 // Parse the first declarator.
John McCall54abf7d2009-11-04 02:18:39 +00001324 ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
John McCalld8ac0572009-11-03 19:26:08 +00001325 ParseDeclarator(D);
Chris Lattnercd147752009-03-29 17:27:48 +00001326
John McCalld8ac0572009-11-03 19:26:08 +00001327 // Bail out if the first declarator didn't seem well-formed.
1328 if (!D.hasName() && !D.mayOmitIdentifier()) {
Richard Smith994d73f2012-04-11 20:59:20 +00001329 SkipMalformedDecl();
John McCalld8ac0572009-11-03 19:26:08 +00001330 return DeclGroupPtrTy();
Chris Lattner23c4b182009-03-29 17:18:04 +00001331 }
Mike Stump1eb44332009-09-09 15:08:12 +00001332
DeLesley Hutchinsc24a2332012-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 Lattnerc82daef2010-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 Jahanianbe1d4ec2012-08-10 15:54:40 +00001344 !isDeclarationAfterDeclarator()) {
Chad Rosier8decdee2012-06-26 22:30:43 +00001345
Chris Lattner004659a2010-07-11 22:42:07 +00001346 if (isStartOfFunctionDefinition(D)) {
John McCalld8ac0572009-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 Hutchinsc24a2332012-02-16 16:50:43 +00001354 Decl *TheDecl =
1355 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
John McCalld8ac0572009-11-03 19:26:08 +00001356 return Actions.ConvertDeclToDeclGroup(TheDecl);
Chris Lattner004659a2010-07-11 22:42:07 +00001357 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001358
Chris Lattner004659a2010-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 McCalld8ac0572009-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 Hutchinsc24a2332012-02-16 16:50:43 +00001372 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-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 Redldbef1bb2011-06-05 12:23:16 +00001380 if (Tok.is(tok::l_brace))
1381 FRI->RangeExpr = ParseBraceInitializer();
1382 else
1383 FRI->RangeExpr = ParseExpression();
Richard Smithad762fc2011-04-14 22:09:26 +00001384 Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1385 Actions.ActOnCXXForRangeDecl(ThisDecl);
1386 Actions.FinalizeDeclaration(ThisDecl);
John McCall6895a642012-01-27 01:29:43 +00001387 D.complete(ThisDecl);
Richard Smithad762fc2011-04-14 22:09:26 +00001388 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1);
1389 }
1390
Chris Lattner5f9e2722011-07-23 10:55:15 +00001391 SmallVector<Decl *, 8> DeclsInGroup;
Richard Smithad762fc2011-04-14 22:09:26 +00001392 Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001393 if (LateParsedAttrs.size() > 0)
1394 ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
John McCall54abf7d2009-11-04 02:18:39 +00001395 D.complete(FirstDecl);
John McCalld226f652010-08-21 09:40:31 +00001396 if (FirstDecl)
John McCalld8ac0572009-11-03 19:26:08 +00001397 DeclsInGroup.push_back(FirstDecl);
1398
Richard Smith0706df42011-10-19 21:33:05 +00001399 bool ExpectSemi = Context != Declarator::ForContext;
Fariborz Jahanian6c89eaf2012-07-02 23:37:09 +00001400
John McCalld8ac0572009-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 Smith0706df42011-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 McCalld8ac0572009-11-03 19:26:08 +00001415
1416 // Parse the next declarator.
1417 D.clear();
Richard Smith7984de32012-01-12 23:53:29 +00001418 D.setCommaLoc(CommaLoc);
John McCalld8ac0572009-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 McCall7f040a92010-12-24 02:08:15 +00001427 MaybeParseGNUAttributes(D);
John McCalld8ac0572009-11-03 19:26:08 +00001428
1429 ParseDeclarator(D);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001430 if (!D.isInvalidType()) {
1431 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1432 D.complete(ThisDecl);
1433 if (ThisDecl)
Chad Rosier8decdee2012-06-26 22:30:43 +00001434 DeclsInGroup.push_back(ThisDecl);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001435 }
John McCalld8ac0572009-11-03 19:26:08 +00001436 }
1437
1438 if (DeclEnd)
1439 *DeclEnd = Tok.getLocation();
1440
Richard Smith0706df42011-10-19 21:33:05 +00001441 if (ExpectSemi &&
Chris Lattner8bb21d32012-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 Lattner004659a2010-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 McCalld8ac0572009-11-03 19:26:08 +00001453 }
1454
Douglas Gregor23c94db2010-07-02 17:43:08 +00001455 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
John McCalld8ac0572009-11-03 19:26:08 +00001456 DeclsInGroup.data(),
1457 DeclsInGroup.size());
Reid Spencer5f016e22007-07-11 17:01:13 +00001458}
1459
Richard Smithad762fc2011-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 Hutchinsc24a2332012-02-16 16:50:43 +00001462bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
Richard Smithad762fc2011-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 Gregor1426e532009-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.
Reid Spencer5f016e22007-07-11 17:01:13 +00001484///
Reid Spencer5f016e22007-07-11 17:01:13 +00001485/// init-declarator: [C99 6.7]
1486/// declarator
1487/// declarator '=' initializer
1488/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
1489/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00001490/// [C++] declarator initializer[opt]
1491///
1492/// [C++] initializer:
1493/// [C++] '=' initializer-clause
1494/// [C++] '(' expression-list ')'
Sebastian Redl50de12f2009-03-24 22:27:57 +00001495/// [C++0x] '=' 'default' [TODO]
1496/// [C++0x] '=' 'delete'
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001497/// [C++0x] braced-init-list
Sebastian Redl50de12f2009-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.
Reid Spencer5f016e22007-07-11 17:01:13 +00001501///
John McCalld226f652010-08-21 09:40:31 +00001502Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
Douglas Gregore542c862009-06-23 23:11:28 +00001503 const ParsedTemplateInfo &TemplateInfo) {
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001504 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-04-14 22:09:26 +00001505 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001506
Richard Smithad762fc2011-04-14 22:09:26 +00001507 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1508}
Mike Stump1eb44332009-09-09 15:08:12 +00001509
Richard Smithad762fc2011-04-14 22:09:26 +00001510Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1511 const ParsedTemplateInfo &TemplateInfo) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001512 // Inform the current actions module that we just parsed this declarator.
John McCalld226f652010-08-21 09:40:31 +00001513 Decl *ThisDecl = 0;
Douglas Gregord5a423b2009-09-25 18:43:00 +00001514 switch (TemplateInfo.Kind) {
1515 case ParsedTemplateInfo::NonTemplate:
Douglas Gregor23c94db2010-07-02 17:43:08 +00001516 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
Douglas Gregord5a423b2009-09-25 18:43:00 +00001517 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00001518
Douglas Gregord5a423b2009-09-25 18:43:00 +00001519 case ParsedTemplateInfo::Template:
1520 case ParsedTemplateInfo::ExplicitSpecialization:
Douglas Gregor23c94db2010-07-02 17:43:08 +00001521 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
John McCallf312b1e2010-08-26 23:41:50 +00001522 MultiTemplateParamsArg(Actions,
Douglas Gregore542c862009-06-23 23:11:28 +00001523 TemplateInfo.TemplateParams->data(),
1524 TemplateInfo.TemplateParams->size()),
Douglas Gregord5a423b2009-09-25 18:43:00 +00001525 D);
1526 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00001527
Douglas Gregord5a423b2009-09-25 18:43:00 +00001528 case ParsedTemplateInfo::ExplicitInstantiation: {
Chad Rosier8decdee2012-06-26 22:30:43 +00001529 DeclResult ThisRes
Douglas Gregor23c94db2010-07-02 17:43:08 +00001530 = Actions.ActOnExplicitInstantiation(getCurScope(),
Douglas Gregord5a423b2009-09-25 18:43:00 +00001531 TemplateInfo.ExternLoc,
1532 TemplateInfo.TemplateLoc,
1533 D);
1534 if (ThisRes.isInvalid()) {
1535 SkipUntil(tok::semi, true, true);
John McCalld226f652010-08-21 09:40:31 +00001536 return 0;
Douglas Gregord5a423b2009-09-25 18:43:00 +00001537 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001538
Douglas Gregord5a423b2009-09-25 18:43:00 +00001539 ThisDecl = ThisRes.get();
1540 break;
1541 }
1542 }
Mike Stump1eb44332009-09-09 15:08:12 +00001543
Richard Smith34b41d92011-02-20 03:19:35 +00001544 bool TypeContainsAuto =
1545 D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
1546
Douglas Gregor1426e532009-05-12 21:31:51 +00001547 // Parse declarator '=' initializer.
Richard Trieud6c7c672012-01-18 22:54:52 +00001548 // If a '==' or '+=' is found, suggest a fixit to '='.
Richard Trieufcaf27e2012-01-19 22:01:51 +00001549 if (isTokenEqualOrEqualTypo()) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001550 ConsumeToken();
Anders Carlsson37bf9d22010-09-24 21:25:25 +00001551 if (Tok.is(tok::kw_delete)) {
Sean Hunte4246a62011-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);
Sean Huntfe2695e2011-05-06 01:42:00 +00001557 } else if (Tok.is(tok::kw_default)) {
Sean Hunte4246a62011-05-12 06:15:49 +00001558 if (D.isFunctionDeclarator())
Sebastian Redlecfcd562012-02-11 23:51:21 +00001559 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1560 << 0 /* default */;
Sean Hunte4246a62011-05-12 06:15:49 +00001561 else
1562 Diag(ConsumeToken(), diag::err_default_special_members);
Douglas Gregor1426e532009-05-12 21:31:51 +00001563 } else {
David Blaikie4e4d0842012-03-11 07:00:24 +00001564 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
John McCall731ad842009-12-19 09:28:58 +00001565 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001566 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001567 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001568
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001569 if (Tok.is(tok::code_completion)) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001570 Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
Peter Collingbourneec98f2f2012-07-27 12:56:09 +00001571 Actions.FinalizeDeclaration(ThisDecl);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00001572 cutOffParsing();
1573 return 0;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001574 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001575
John McCall60d7b3a2010-08-24 06:29:42 +00001576 ExprResult Init(ParseInitializer());
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001577
David Blaikie4e4d0842012-03-11 07:00:24 +00001578 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001579 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001580 ExitScope();
1581 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001582
Douglas Gregor1426e532009-05-12 21:31:51 +00001583 if (Init.isInvalid()) {
Douglas Gregor00225542010-03-01 18:27:54 +00001584 SkipUntil(tok::comma, true, true);
1585 Actions.ActOnInitializerError(ThisDecl);
1586 } else
Richard Smith34b41d92011-02-20 03:19:35 +00001587 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1588 /*DirectInit=*/false, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001589 }
1590 } else if (Tok.is(tok::l_paren)) {
1591 // Parse C++ direct initializer: '(' expression-list ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001592 BalancedDelimiterTracker T(*this, tok::l_paren);
1593 T.consumeOpen();
1594
Douglas Gregor1426e532009-05-12 21:31:51 +00001595 ExprVector Exprs(Actions);
1596 CommaLocsTy CommaLocs;
1597
David Blaikie4e4d0842012-03-11 07:00:24 +00001598 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregorb4debae2009-12-22 17:47:17 +00001599 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001600 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001601 }
1602
Douglas Gregor1426e532009-05-12 21:31:51 +00001603 if (ParseExpressionList(Exprs, CommaLocs)) {
1604 SkipUntil(tok::r_paren);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001605
David Blaikie4e4d0842012-03-11 07:00:24 +00001606 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001607 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001608 ExitScope();
1609 }
Douglas Gregor1426e532009-05-12 21:31:51 +00001610 } else {
1611 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001612 T.consumeClose();
Douglas Gregor1426e532009-05-12 21:31:51 +00001613
1614 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1615 "Unexpected number of commas!");
Douglas Gregorb4debae2009-12-22 17:47:17 +00001616
David Blaikie4e4d0842012-03-11 07:00:24 +00001617 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001618 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001619 ExitScope();
1620 }
1621
Sebastian Redl5b9cc5d2012-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 Gregor1426e532009-05-12 21:31:51 +00001627 }
Fariborz Jahanian3b5f9dc2012-07-03 22:54:28 +00001628 } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace) &&
Fariborz Jahanianb0ed95c2012-07-03 23:22:13 +00001629 (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001630 // Parse C++0x braced-init-list.
Richard Smith7fe62082011-10-15 05:09:34 +00001631 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1632
Sebastian Redldbef1bb2011-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 Gregor1426e532009-05-12 21:31:51 +00001651 } else {
Richard Smith34b41d92011-02-20 03:19:35 +00001652 Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001653 }
1654
Richard Smith483b9f32011-02-21 20:05:19 +00001655 Actions.FinalizeDeclaration(ThisDecl);
1656
Douglas Gregor1426e532009-05-12 21:31:51 +00001657 return ThisDecl;
1658}
1659
Reid Spencer5f016e22007-07-11 17:01:13 +00001660/// ParseSpecifierQualifierList
1661/// specifier-qualifier-list:
1662/// type-specifier specifier-qualifier-list[opt]
1663/// type-qualifier specifier-qualifier-list[opt]
1664/// [GNU] attributes specifier-qualifier-list[opt]
1665///
Richard Smith69730c12012-03-12 07:56:15 +00001666void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1667 DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001668 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
1669 /// parse declaration-specifiers and complain about extra stuff.
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001670 /// TODO: diagnose attribute-specifiers and alignment-specifiers.
Richard Smith69730c12012-03-12 07:56:15 +00001671 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
Mike Stump1eb44332009-09-09 15:08:12 +00001672
Reid Spencer5f016e22007-07-11 17:01:13 +00001673 // Validate declspec for type-name.
1674 unsigned Specs = DS.getParsedSpecifiers();
Richard Smitha971d242012-05-09 20:55:26 +00001675 if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1676 !DS.hasTypeSpecifier()) {
Richard Smith69730c12012-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()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001681 Diag(Tok, diag::err_typename_requires_specqual);
Richard Smith69730c12012-03-12 07:56:15 +00001682 if (!DS.hasTypeSpecifier())
1683 DS.SetTypeSpecError();
1684 }
Mike Stump1eb44332009-09-09 15:08:12 +00001685
Reid Spencer5f016e22007-07-11 17:01:13 +00001686 // Issue diagnostic and remove storage class if present.
1687 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
1688 if (DS.getStorageClassSpecLoc().isValid())
1689 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1690 else
1691 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
1692 DS.ClearStorageClassSpecs();
1693 }
Mike Stump1eb44332009-09-09 15:08:12 +00001694
Reid Spencer5f016e22007-07-11 17:01:13 +00001695 // Issue diagnostic and remove function specfier if present.
1696 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregorb48fe382008-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);
Reid Spencer5f016e22007-07-11 17:01:13 +00001703 DS.ClearFunctionSpecs();
1704 }
Richard Smith69730c12012-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 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001711}
1712
Chris Lattnerc199ab32009-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 Lattnerb6645dd2009-04-14 21:16:09 +00001724/// int x : 4; // struct-declarator
Chris Lattnerc83c27a2009-04-12 22:29:43 +00001725/// int x { 5}; // C++'0x unified initializers
Chris Lattnerc199ab32009-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 Lattnerb6645dd2009-04-14 21:16:09 +00001734 T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
Chris Lattnerc199ab32009-04-12 20:42:31 +00001735}
1736
Chris Lattnere40c2952009-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 Lattnerf4382f52009-04-14 22:17:06 +00001747bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00001748 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00001749 AccessSpecifier AS, DeclSpecContext DSC) {
Chris Lattnerf4382f52009-04-14 22:17:06 +00001750 assert(Tok.is(tok::identifier) && "should have identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00001751
Chris Lattnere40c2952009-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 Stump1eb44332009-09-09 15:08:12 +00001766
Chris Lattnere40c2952009-04-14 21:34:55 +00001767 // Since we know that this either implicit int (which is rare) or an
Richard Smith827adaf2012-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 Smitha971d242012-05-09 20:55:26 +00001773 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
Richard Smith827adaf2012-05-15 21:01:51 +00001774 (!getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt) &&
Richard Smith69730c12012-03-12 07:56:15 +00001775 isValidAfterIdentifierInDeclarator(NextToken())) {
Chris Lattnere40c2952009-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 Stump1eb44332009-09-09 15:08:12 +00001781
Richard Smith827adaf2012-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 Lattnere40c2952009-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 Lattnerf4382f52009-04-14 22:17:06 +00001793 //
1794 // C++ doesn't need this, and isTagName doesn't take SS.
1795 if (SS == 0) {
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00001796 const char *TagName = 0, *FixitTagName = 0;
Chris Lattnerf4382f52009-04-14 22:17:06 +00001797 tok::TokenKind TagKind = tok::unknown;
Mike Stump1eb44332009-09-09 15:08:12 +00001798
Douglas Gregor23c94db2010-07-02 17:43:08 +00001799 switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
Chris Lattnere40c2952009-04-14 21:34:55 +00001800 default: break;
Argyrios Kyrtzidisb8a9d3b2011-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 Lattnere40c2952009-04-14 21:34:55 +00001809 }
Mike Stump1eb44332009-09-09 15:08:12 +00001810
Chris Lattnerf4382f52009-04-14 22:17:06 +00001811 if (TagName) {
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001812 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
1813 LookupResult R(Actions, TokenName, SourceLocation(),
1814 Sema::LookupOrdinaryName);
1815
Chris Lattnerf4382f52009-04-14 22:17:06 +00001816 Diag(Loc, diag::err_use_of_tag_name_without_tag)
Kaelyn Uhrainaec2ac62012-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 Uhrain392b3f52012-04-27 18:26:49 +00001823 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001824 << TokenName << TagName;
1825 }
Mike Stump1eb44332009-09-09 15:08:12 +00001826
Chris Lattnerf4382f52009-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 Smith69730c12012-03-12 07:56:15 +00001829 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
Chris Lattnerf4382f52009-04-14 22:17:06 +00001830 else
Richard Smith69730c12012-03-12 07:56:15 +00001831 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
1832 /*EnteringContext*/ false, DSC_normal);
Chris Lattnerf4382f52009-04-14 22:17:06 +00001833 return true;
1834 }
Chris Lattnere40c2952009-04-14 21:34:55 +00001835 }
Mike Stump1eb44332009-09-09 15:08:12 +00001836
Richard Smith8f0a7e72012-05-15 21:29:55 +00001837 // Determine whether this identifier could plausibly be the name of something
Richard Smith7514db22012-05-15 21:42:17 +00001838 // being declared (with a missing type).
Richard Smith8f0a7e72012-05-15 21:29:55 +00001839 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
1840 (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
Richard Smith827adaf2012-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 Rosier8decdee2012-06-26 22:30:43 +00001881 // This is almost certainly an invalid type name. Let the action emit a
Douglas Gregora786fdb2009-10-13 23:27:22 +00001882 // diagnostic and attempt to recover.
John McCallb3d87482010-08-24 05:47:05 +00001883 ParsedType T;
Kaelyn Uhrain50dc12a2012-06-15 23:45:58 +00001884 IdentifierInfo *II = Tok.getIdentifierInfo();
1885 if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
Douglas Gregora786fdb2009-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 McCallb3d87482010-08-24 05:47:05 +00001893 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
Douglas Gregora786fdb2009-10-13 23:27:22 +00001894 DS.SetRangeEnd(Tok.getLocation());
1895 ConsumeToken();
Kaelyn Uhrain50dc12a2012-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 Gregora786fdb2009-10-13 23:27:22 +00001901 // There may be other declaration specifiers after this.
1902 return true;
1903 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001904
Douglas Gregora786fdb2009-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 Stump1eb44332009-09-09 15:08:12 +00001912
Douglas Gregora786fdb2009-10-13 23:27:22 +00001913 // Mark this as an error.
Richard Smith69730c12012-03-12 07:56:15 +00001914 DS.SetTypeSpecError();
Chris Lattnere40c2952009-04-14 21:34:55 +00001915 DS.SetRangeEnd(Tok.getLocation());
1916 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00001917
Chris Lattnere40c2952009-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 Gregor0efc2c12010-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 Rosier8decdee2012-06-26 22:30:43 +00001929Parser::DeclSpecContext
Douglas Gregor0efc2c12010-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 Smith6d96d3a2012-03-15 01:02:11 +00001935 if (Context == Declarator::TrailingReturnContext)
1936 return DSC_trailing;
Douglas Gregor0efc2c12010-01-13 17:31:36 +00001937 return DSC_normal;
1938}
1939
Peter Collingbourne82d0b0a2011-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 Kramerffbe9b92011-12-23 17:00:35 +00001945/// [C11] type-id
1946/// [C11] constant-expression
Peter Collingbourne0b64ba92011-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 Collingbourne82d0b0a2011-09-29 18:04:28 +00001952 if (isTypeIdInParens()) {
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001953 SourceLocation TypeLoc = Tok.getLocation();
1954 ParsedType Ty = ParseTypeName().get();
1955 SourceRange TypeRange(Start, Tok.getLocation());
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001956 ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
1957 Ty.getAsOpaquePtr(), TypeRange);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001958 } else
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001959 ER = ParseConstantExpression();
1960
David Blaikie4e4d0842012-03-11 07:00:24 +00001961 if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis))
Peter Collingbournefe9b2a82011-10-24 17:56:00 +00001962 EllipsisLoc = ConsumeToken();
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001963
1964 return ER;
Peter Collingbourne82d0b0a2011-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 Kramerffbe9b92011-12-23 17:00:35 +00001971/// [C11] '_Alignas' '(' type-id ')'
1972/// [C11] '_Alignas' '(' constant-expression ')'
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001973/// [C++0x] 'alignas' '(' type-id ...[opt] ')'
1974/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')'
Peter Collingbourne82d0b0a2011-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 Gregor4a8dfb52011-10-12 16:37:45 +00001983 BalancedDelimiterTracker T(*this, tok::l_paren);
1984 if (T.expectAndConsume(diag::err_expected_lparen))
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001985 return;
1986
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001987 SourceLocation EllipsisLoc;
1988 ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001989 if (ArgExpr.isInvalid()) {
1990 SkipUntil(tok::r_paren);
1991 return;
1992 }
1993
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001994 T.consumeClose();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001995 if (endLoc)
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001996 *endLoc = T.getCloseLocation();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001997
Peter Collingbourne0b64ba92011-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 Collingbourne82d0b0a2011-09-29 18:04:28 +00002004 ExprVector ArgExprs(Actions);
2005 ArgExprs.push_back(ArgExpr.release());
Sean Hunt8e083e72012-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 Collingbourne82d0b0a2011-09-29 18:04:28 +00002009 Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
Sean Hunt93f95f22012-06-18 16:13:52 +00002010 0, T.getOpenLocation(), ArgExprs.take(), 1,
Sean Hunt8e083e72012-06-19 23:57:03 +00002011 AttributeList::AS_GNU);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002012}
2013
Reid Spencer5f016e22007-07-11 17:01:13 +00002014/// ParseDeclarationSpecifiers
2015/// declaration-specifiers: [C99 6.7]
2016/// storage-class-specifier declaration-specifiers[opt]
2017/// type-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002018/// [C99] function-specifier declaration-specifiers[opt]
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002019/// [C11] alignment-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002020/// [GNU] attributes declaration-specifiers[opt]
Douglas Gregor8d267c52011-09-09 02:06:17 +00002021/// [Clang] '__module_private__' declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002022///
2023/// storage-class-specifier: [C99 6.7.1]
2024/// 'typedef'
2025/// 'extern'
2026/// 'static'
2027/// 'auto'
2028/// 'register'
Sebastian Redl669d5d72008-11-14 23:42:31 +00002029/// [C++] 'mutable'
Reid Spencer5f016e22007-07-11 17:01:13 +00002030/// [GNU] '__thread'
Reid Spencer5f016e22007-07-11 17:01:13 +00002031/// function-specifier: [C99 6.7.4]
2032/// [C99] 'inline'
Douglas Gregorb48fe382008-10-31 09:07:45 +00002033/// [C++] 'virtual'
2034/// [C++] 'explicit'
Peter Collingbournef315fa82011-02-14 01:42:53 +00002035/// [OpenCL] '__kernel'
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002036/// 'friend': [C++ dcl.friend]
Sebastian Redl2ac67232009-11-05 15:47:02 +00002037/// 'constexpr': [C++0x dcl.constexpr]
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002038
Reid Spencer5f016e22007-07-11 17:01:13 +00002039///
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +00002040void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00002041 const ParsedTemplateInfo &TemplateInfo,
John McCall67d1a672009-08-06 02:15:43 +00002042 AccessSpecifier AS,
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002043 DeclSpecContext DSContext,
2044 LateParsedAttrList *LateAttrs) {
Douglas Gregor312eadb2011-04-24 05:37:28 +00002045 if (DS.getSourceRange().isInvalid()) {
2046 DS.SetRangeStart(Tok.getLocation());
2047 DS.SetRangeEnd(Tok.getLocation());
2048 }
Chad Rosier8decdee2012-06-26 22:30:43 +00002049
Douglas Gregorefaa93a2011-11-07 17:33:42 +00002050 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
Sean Hunt2edf0a22012-06-23 05:07:58 +00002051 bool AttrsLastTime = false;
2052 ParsedAttributesWithRange attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00002053 while (1) {
John McCallfec54012009-08-03 20:12:06 +00002054 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00002055 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00002056 unsigned DiagID = 0;
2057
Reid Spencer5f016e22007-07-11 17:01:13 +00002058 SourceLocation Loc = Tok.getLocation();
Douglas Gregor12e083c2008-11-07 15:42:26 +00002059
Reid Spencer5f016e22007-07-11 17:01:13 +00002060 switch (Tok.getKind()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002061 default:
Chris Lattnerbce61352008-07-26 00:20:22 +00002062 DoneWithDeclSpec:
Sean Hunt2edf0a22012-06-23 05:07:58 +00002063 if (!AttrsLastTime)
2064 ProhibitAttributes(attrs);
2065 else
2066 DS.takeAttributesFrom(attrs);
Peter Collingbournef1907682011-09-29 18:03:57 +00002067
Reid Spencer5f016e22007-07-11 17:01:13 +00002068 // If this is not a declaration specifier token, we're done reading decl
2069 // specifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00002070 DS.Finish(Diags, PP);
Reid Spencer5f016e22007-07-11 17:01:13 +00002071 return;
Mike Stump1eb44332009-09-09 15:08:12 +00002072
Sean Hunt2edf0a22012-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 Rosier8decdee2012-06-26 22:30:43 +00002087 continue;
Sean Hunt2edf0a22012-06-23 05:07:58 +00002088
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002089 case tok::code_completion: {
John McCallf312b1e2010-08-26 23:41:50 +00002090 Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
Douglas Gregor2ccccb32010-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 Rosier8decdee2012-06-26 22:30:43 +00002099 = DSContext == DSC_top_level ||
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002100 (DSContext == DSC_class && DS.isFriendSpecified());
2101
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002102 Actions.CodeCompleteDeclSpec(getCurScope(), DS,
Chad Rosier8decdee2012-06-26 22:30:43 +00002103 AllowNonIdentifiers,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002104 AllowNestedNameSpecifiers);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002105 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00002106 }
2107
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00002108 if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2109 CCC = Sema::PCC_LocalDeclarationSpecifiers;
2110 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
Chad Rosier8decdee2012-06-26 22:30:43 +00002111 CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
John McCallf312b1e2010-08-26 23:41:50 +00002112 : Sema::PCC_Template;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002113 else if (DSContext == DSC_class)
John McCallf312b1e2010-08-26 23:41:50 +00002114 CCC = Sema::PCC_Class;
Argyrios Kyrtzidis849639d2012-02-07 16:50:53 +00002115 else if (CurParsedObjCImpl)
John McCallf312b1e2010-08-26 23:41:50 +00002116 CCC = Sema::PCC_ObjCImplementation;
Chad Rosier8decdee2012-06-26 22:30:43 +00002117
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002118 Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002119 return cutOffParsing();
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002120 }
2121
Chris Lattner5e02c472009-01-05 00:07:25 +00002122 case tok::coloncolon: // ::foo::bar
John McCall9ba61662010-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 McCall2e0a7152010-03-01 18:20:46 +00002129 if (Tok.is(tok::coloncolon)) // ::new or ::delete
2130 goto DoneWithDeclSpec;
John McCall9ba61662010-02-26 08:45:28 +00002131 continue;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002132
2133 case tok::annot_cxxscope: {
Richard Smithf63eee72012-05-09 18:56:43 +00002134 if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002135 goto DoneWithDeclSpec;
2136
John McCallaa87d332009-12-12 11:40:51 +00002137 CXXScopeSpec SS;
Douglas Gregorc34348a2011-02-24 17:54:50 +00002138 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2139 Tok.getAnnotationRange(),
2140 SS);
John McCallaa87d332009-12-12 11:40:51 +00002141
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002142 // We are looking for a qualified typename.
Douglas Gregor9135c722009-03-25 15:40:00 +00002143 Token Next = NextToken();
Mike Stump1eb44332009-09-09 15:08:12 +00002144 if (Next.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002145 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
Douglas Gregorc45c2322009-03-31 00:43:58 +00002146 ->Kind == TNK_Type_template) {
Douglas Gregor9135c722009-03-25 15:40:00 +00002147 // We have a qualified template-id, e.g., N::A<int>
Douglas Gregor0efc2c12010-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 Rosier8decdee2012-06-26 22:30:43 +00002164 //
Douglas Gregor0efc2c12010-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 Rosier8decdee2012-06-26 22:30:43 +00002167 // reinforced by the NAD status of core issue 635.
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002168 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
John McCallba9d8532010-04-13 06:39:49 +00002169 if ((DSContext == DSC_top_level ||
2170 (DSContext == DSC_class && DS.isFriendSpecified())) &&
2171 TemplateId->Name &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002172 Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
Douglas Gregor0efc2c12010-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 McCallaa87d332009-12-12 11:40:51 +00002190 DS.getTypeSpecScope() = SS;
2191 ConsumeToken(); // The C++ scope.
Mike Stump1eb44332009-09-09 15:08:12 +00002192 assert(Tok.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002193 "ParseOptionalCXXScopeSpecifier not working");
Douglas Gregor059101f2011-03-02 00:47:37 +00002194 AnnotateTemplateIdTokenAsType();
Douglas Gregor9135c722009-03-25 15:40:00 +00002195 continue;
2196 }
2197
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002198 if (Next.is(tok::annot_typename)) {
John McCallaa87d332009-12-12 11:40:51 +00002199 DS.getTypeSpecScope() = SS;
2200 ConsumeToken(); // The C++ scope.
John McCallb3d87482010-08-24 05:47:05 +00002201 if (Tok.getAnnotationValue()) {
2202 ParsedType T = getTypeAnnotation(Tok);
Nico Weber253e80b2010-11-22 10:30:56 +00002203 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
Chad Rosier8decdee2012-06-26 22:30:43 +00002204 Tok.getAnnotationEndLoc(),
John McCallb3d87482010-08-24 05:47:05 +00002205 PrevSpec, DiagID, T);
2206 }
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002207 else
2208 DS.SetTypeSpecError();
2209 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2210 ConsumeToken(); // The typename
2211 }
2212
Douglas Gregor9135c722009-03-25 15:40:00 +00002213 if (Next.isNot(tok::identifier))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002214 goto DoneWithDeclSpec;
2215
Douglas Gregor0efc2c12010-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 McCallba9d8532010-04-13 06:39:49 +00002218 if ((DSContext == DSC_top_level ||
2219 (DSContext == DSC_class && DS.isFriendSpecified())) &&
Chad Rosier8decdee2012-06-26 22:30:43 +00002220 Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
Douglas Gregor0efc2c12010-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 Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002234
John McCallb3d87482010-08-24 05:47:05 +00002235 ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2236 Next.getLocation(),
Douglas Gregor9e876872011-03-01 18:12:44 +00002237 getCurScope(), &SS,
2238 false, false, ParsedType(),
Abramo Bagnarafad03b72012-01-27 08:46:19 +00002239 /*IsCtorOrDtorName=*/false,
Douglas Gregor9e876872011-03-01 18:12:44 +00002240 /*NonTrivialSourceInfo=*/true);
Douglas Gregor55f6b142009-02-09 18:46:07 +00002241
Chris Lattnerf4382f52009-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 Stump1eb44332009-09-09 15:08:12 +00002245 // typename.
Chris Lattnerf4382f52009-04-14 22:17:06 +00002246 if (TypeRep == 0) {
2247 ConsumeToken(); // Eat the scope spec so the identifier is current.
Richard Smith69730c12012-03-12 07:56:15 +00002248 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002249 goto DoneWithDeclSpec;
Chris Lattnerf4382f52009-04-14 22:17:06 +00002250 }
Mike Stump1eb44332009-09-09 15:08:12 +00002251
John McCallaa87d332009-12-12 11:40:51 +00002252 DS.getTypeSpecScope() = SS;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002253 ConsumeToken(); // The C++ scope.
2254
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002255 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002256 DiagID, TypeRep);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002257 if (isInvalid)
2258 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002259
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002260 DS.SetRangeEnd(Tok.getLocation());
2261 ConsumeToken(); // The typename.
2262
2263 continue;
2264 }
Mike Stump1eb44332009-09-09 15:08:12 +00002265
Chris Lattner80d0c892009-01-21 19:48:37 +00002266 case tok::annot_typename: {
John McCallb3d87482010-08-24 05:47:05 +00002267 if (Tok.getAnnotationValue()) {
2268 ParsedType T = getTypeAnnotation(Tok);
Nico Weberc43271e2010-11-22 12:50:03 +00002269 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00002270 DiagID, T);
2271 } else
Douglas Gregor31a19b62009-04-01 21:51:26 +00002272 DS.SetTypeSpecError();
Chad Rosier8decdee2012-06-26 22:30:43 +00002273
Chris Lattner5c5db552010-04-05 18:18:31 +00002274 if (isInvalid)
2275 break;
2276
Chris Lattner80d0c892009-01-21 19:48:37 +00002277 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2278 ConsumeToken(); // The typename
Mike Stump1eb44332009-09-09 15:08:12 +00002279
Chris Lattner80d0c892009-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 Rosier8decdee2012-06-26 22:30:43 +00002282 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002283 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002284 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002285
Chris Lattner80d0c892009-01-21 19:48:37 +00002286 continue;
2287 }
Mike Stump1eb44332009-09-09 15:08:12 +00002288
Douglas Gregorbfad9152011-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 Rosier8decdee2012-06-26 22:30:43 +00002306
Chris Lattner3bd934a2008-07-26 01:18:38 +00002307 // typedef-name
David Blaikie42d6d0c2011-12-04 05:04:18 +00002308 case tok::kw_decltype:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002309 case tok::identifier: {
Chris Lattner5e02c472009-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 Blaikie4e4d0842012-03-11 07:00:24 +00002312 if (getLangOpts().CPlusPlus) {
John McCall9ba61662010-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 Stump1eb44332009-09-09 15:08:12 +00002321
Chris Lattner3bd934a2008-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 Stump1eb44332009-09-09 15:08:12 +00002327
John Thompson82287d12010-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 Smithf63eee72012-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 McCallb3d87482010-08-24 05:47:05 +00002337 ParsedType TypeRep =
2338 Actions.getTypeName(*Tok.getIdentifierInfo(),
2339 Tok.getLocation(), getCurScope());
Douglas Gregor55f6b142009-02-09 18:46:07 +00002340
Chris Lattnerc199ab32009-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 McCallb3d87482010-08-24 05:47:05 +00002343 if (!TypeRep) {
Richard Smith69730c12012-03-12 07:56:15 +00002344 if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +00002345 goto DoneWithDeclSpec;
Chris Lattnerc199ab32009-04-12 20:42:31 +00002346 }
Douglas Gregor55f6b142009-02-09 18:46:07 +00002347
Douglas Gregor0efc2c12010-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 Blaikie4e4d0842012-03-11 07:00:24 +00002350 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002351 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002352 isConstructorDeclarator())
Douglas Gregorb48fe382008-10-31 09:07:45 +00002353 goto DoneWithDeclSpec;
2354
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002355 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002356 DiagID, TypeRep);
Chris Lattner3bd934a2008-07-26 01:18:38 +00002357 if (isInvalid)
2358 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002359
Chris Lattner3bd934a2008-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 Rosier8decdee2012-06-26 22:30:43 +00002365 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002366 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002367 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002368
Steve Naroff4f9b9f12008-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 Lattner3bd934a2008-07-26 01:18:38 +00002372 }
Douglas Gregor39a8de12009-02-25 19:37:18 +00002373
2374 // type-name
2375 case tok::annot_template_id: {
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002376 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
Douglas Gregorc45c2322009-03-31 00:43:58 +00002377 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor39a8de12009-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 Gregor0efc2c12010-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 Blaikie4e4d0842012-03-11 07:00:24 +00002386 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002387 Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002388 isConstructorDeclarator())
2389 goto DoneWithDeclSpec;
2390
Douglas Gregor39a8de12009-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 Gregor31a19b62009-04-01 21:51:26 +00002393 AnnotateTemplateIdTokenAsType();
Douglas Gregor39a8de12009-02-25 19:37:18 +00002394 continue;
2395 }
2396
Reid Spencer5f016e22007-07-11 17:01:13 +00002397 // GNU attributes support.
2398 case tok::kw___attribute:
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002399 ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
Reid Spencer5f016e22007-07-11 17:01:13 +00002400 continue;
Steve Narofff59e17e2008-12-24 20:59:21 +00002401
2402 // Microsoft declspec support.
2403 case tok::kw___declspec:
John McCall7f040a92010-12-24 02:08:15 +00002404 ParseMicrosoftDeclSpec(DS.getAttributes());
Steve Narofff59e17e2008-12-24 20:59:21 +00002405 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00002406
Steve Naroff239f0732008-12-25 14:16:32 +00002407 // Microsoft single token adornments.
Michael J. Spenceradc6cbf2012-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();
Sean Hunt93f95f22012-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. Spenceradc6cbf2012-06-18 07:00:48 +00002414 DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Sean Hunt93f95f22012-06-18 16:13:52 +00002415 SourceLocation(), 0, 0, AttributeList::AS_GNU);
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002416 continue;
2417 }
Eli Friedman290eeb02009-06-08 23:27:34 +00002418
2419 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00002420 case tok::kw___ptr32:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00002421 case tok::kw___w64:
Steve Naroff239f0732008-12-25 14:16:32 +00002422 case tok::kw___cdecl:
2423 case tok::kw___stdcall:
2424 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00002425 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00002426 case tok::kw___unaligned:
John McCall7f040a92010-12-24 02:08:15 +00002427 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00002428 continue;
2429
Dawn Perchik52fc3142010-09-03 01:29:35 +00002430 // Borland single token adornments.
2431 case tok::kw___pascal:
John McCall7f040a92010-12-24 02:08:15 +00002432 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00002433 continue;
2434
Peter Collingbournef315fa82011-02-14 01:42:53 +00002435 // OpenCL single token adornments.
2436 case tok::kw___kernel:
2437 ParseOpenCLAttributes(DS.getAttributes());
2438 continue;
2439
Reid Spencer5f016e22007-07-11 17:01:13 +00002440 // storage-class-specifier
2441 case tok::kw_typedef:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002442 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2443 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002444 break;
2445 case tok::kw_extern:
2446 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +00002447 Diag(Tok, diag::ext_thread_before) << "extern";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002448 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2449 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002450 break;
Steve Naroff8d54bf22007-12-18 00:16:02 +00002451 case tok::kw___private_extern__:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002452 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2453 Loc, PrevSpec, DiagID);
Steve Naroff8d54bf22007-12-18 00:16:02 +00002454 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002455 case tok::kw_static:
2456 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +00002457 Diag(Tok, diag::ext_thread_before) << "static";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002458 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2459 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002460 break;
2461 case tok::kw_auto:
David Blaikie4e4d0842012-03-11 07:00:24 +00002462 if (getLangOpts().CPlusPlus0x) {
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002463 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002464 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2465 PrevSpec, DiagID);
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002466 if (!isInvalid)
Richard Smith8f4fb192011-09-04 19:54:14 +00002467 Diag(Tok, diag::ext_auto_storage_class)
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002468 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
Richard Smith8f4fb192011-09-04 19:54:14 +00002469 } else
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002470 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2471 DiagID);
Richard Smith8f4fb192011-09-04 19:54:14 +00002472 } else
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002473 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2474 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002475 break;
2476 case tok::kw_register:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002477 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2478 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002479 break;
Sebastian Redl669d5d72008-11-14 23:42:31 +00002480 case tok::kw_mutable:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002481 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2482 PrevSpec, DiagID);
Sebastian Redl669d5d72008-11-14 23:42:31 +00002483 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002484 case tok::kw___thread:
John McCallfec54012009-08-03 20:12:06 +00002485 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002486 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002487
Reid Spencer5f016e22007-07-11 17:01:13 +00002488 // function-specifier
2489 case tok::kw_inline:
John McCallfec54012009-08-03 20:12:06 +00002490 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002491 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002492 case tok::kw_virtual:
John McCallfec54012009-08-03 20:12:06 +00002493 isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002494 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002495 case tok::kw_explicit:
John McCallfec54012009-08-03 20:12:06 +00002496 isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002497 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002498
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002499 // alignment-specifier
2500 case tok::kw__Alignas:
David Blaikie4e4d0842012-03-11 07:00:24 +00002501 if (!getLangOpts().C11)
Jordan Rosef70a8862012-06-30 21:33:57 +00002502 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002503 ParseAlignmentSpecifier(DS.getAttributes());
2504 continue;
2505
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002506 // friend
2507 case tok::kw_friend:
John McCall67d1a672009-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 Carlssonf47f7a12009-05-06 04:46:28 +00002515 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002516
Douglas Gregor8d267c52011-09-09 02:06:17 +00002517 // Modules
2518 case tok::kw___module_private__:
2519 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2520 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00002521
Sebastian Redl2ac67232009-11-05 15:47:02 +00002522 // constexpr
2523 case tok::kw_constexpr:
2524 isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2525 break;
2526
Chris Lattner80d0c892009-01-21 19:48:37 +00002527 // type-specifier
2528 case tok::kw_short:
John McCallfec54012009-08-03 20:12:06 +00002529 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2530 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002531 break;
2532 case tok::kw_long:
2533 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
John McCallfec54012009-08-03 20:12:06 +00002534 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2535 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002536 else
John McCallfec54012009-08-03 20:12:06 +00002537 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2538 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002539 break;
Francois Pichet338d7f72011-04-28 01:59:37 +00002540 case tok::kw___int64:
2541 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2542 DiagID);
2543 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002544 case tok::kw_signed:
John McCallfec54012009-08-03 20:12:06 +00002545 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2546 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002547 break;
2548 case tok::kw_unsigned:
John McCallfec54012009-08-03 20:12:06 +00002549 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
2550 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002551 break;
2552 case tok::kw__Complex:
John McCallfec54012009-08-03 20:12:06 +00002553 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
2554 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002555 break;
2556 case tok::kw__Imaginary:
John McCallfec54012009-08-03 20:12:06 +00002557 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
2558 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002559 break;
2560 case tok::kw_void:
John McCallfec54012009-08-03 20:12:06 +00002561 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
2562 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002563 break;
2564 case tok::kw_char:
John McCallfec54012009-08-03 20:12:06 +00002565 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
2566 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002567 break;
2568 case tok::kw_int:
John McCallfec54012009-08-03 20:12:06 +00002569 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
2570 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002571 break;
Richard Smith5a5a9712012-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 Lattner80d0c892009-01-21 19:48:37 +00002580 case tok::kw_float:
John McCallfec54012009-08-03 20:12:06 +00002581 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
2582 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002583 break;
2584 case tok::kw_double:
John McCallfec54012009-08-03 20:12:06 +00002585 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
2586 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002587 break;
2588 case tok::kw_wchar_t:
John McCallfec54012009-08-03 20:12:06 +00002589 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
2590 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002591 break;
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002592 case tok::kw_char16_t:
John McCallfec54012009-08-03 20:12:06 +00002593 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
2594 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002595 break;
2596 case tok::kw_char32_t:
John McCallfec54012009-08-03 20:12:06 +00002597 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
2598 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002599 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002600 case tok::kw_bool:
2601 case tok::kw__Bool:
Argyrios Kyrtzidis4383e182010-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 Jahaniane106a0b2011-04-19 21:42:37 +00002607 // For better error recovery.
2608 Tok.setKind(tok::identifier);
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00002609 isInvalid = true;
2610 } else {
2611 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
2612 DiagID);
2613 }
Chris Lattner80d0c892009-01-21 19:48:37 +00002614 break;
2615 case tok::kw__Decimal32:
John McCallfec54012009-08-03 20:12:06 +00002616 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
2617 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002618 break;
2619 case tok::kw__Decimal64:
John McCallfec54012009-08-03 20:12:06 +00002620 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
2621 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002622 break;
2623 case tok::kw__Decimal128:
John McCallfec54012009-08-03 20:12:06 +00002624 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
2625 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002626 break;
John Thompson82287d12010-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 McCalla5fc4722011-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 Lattner80d0c892009-01-21 19:48:37 +00002637
2638 // class-specifier:
2639 case tok::kw_class:
2640 case tok::kw_struct:
Chris Lattner4c97d762009-04-12 21:49:30 +00002641 case tok::kw_union: {
2642 tok::TokenKind Kind = Tok.getKind();
2643 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00002644 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
2645 EnteringContext, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00002646 continue;
Chris Lattner4c97d762009-04-12 21:49:30 +00002647 }
Chris Lattner80d0c892009-01-21 19:48:37 +00002648
2649 // enum-specifier:
2650 case tok::kw_enum:
Chris Lattner4c97d762009-04-12 21:49:30 +00002651 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00002652 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00002653 continue;
2654
2655 // cv-qualifier:
2656 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00002657 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00002658 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattner80d0c892009-01-21 19:48:37 +00002659 break;
2660 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00002661 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00002662 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattner80d0c892009-01-21 19:48:37 +00002663 break;
2664 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00002665 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00002666 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattner80d0c892009-01-21 19:48:37 +00002667 break;
2668
Douglas Gregord57959a2009-03-27 23:10:48 +00002669 // C++ typename-specifier:
2670 case tok::kw_typename:
John McCall9ba61662010-02-26 08:45:28 +00002671 if (TryAnnotateTypeOrScopeToken()) {
2672 DS.SetTypeSpecError();
2673 goto DoneWithDeclSpec;
2674 }
2675 if (!Tok.is(tok::kw_typename))
Douglas Gregord57959a2009-03-27 23:10:48 +00002676 continue;
2677 break;
2678
Chris Lattner80d0c892009-01-21 19:48:37 +00002679 // GNU typeof support.
2680 case tok::kw_typeof:
2681 ParseTypeofSpecifier(DS);
2682 continue;
2683
David Blaikie42d6d0c2011-12-04 05:04:18 +00002684 case tok::annot_decltype:
Anders Carlsson6fd634f2009-06-24 17:47:40 +00002685 ParseDecltypeSpecifier(DS);
2686 continue;
2687
Sean Huntdb5d44b2011-05-19 05:37:45 +00002688 case tok::kw___underlying_type:
2689 ParseUnderlyingTypeSpecifier(DS);
Eli Friedmanb001de72011-10-06 23:00:33 +00002690 continue;
2691
2692 case tok::kw__Atomic:
2693 ParseAtomicSpecifier(DS);
2694 continue;
Sean Huntdb5d44b2011-05-19 05:37:45 +00002695
Peter Collingbourne207f4d82011-03-18 22:38:29 +00002696 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00002697 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00002698 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-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 Rosier8decdee2012-06-26 22:30:43 +00002709
Steve Naroffd3ded1f2008-06-05 00:02:44 +00002710 case tok::less:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002711 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerbce61352008-07-26 00:20:22 +00002712 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
2713 // but we support it.
David Blaikie4e4d0842012-03-11 07:00:24 +00002714 if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
Chris Lattnerbce61352008-07-26 00:20:22 +00002715 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00002716
Douglas Gregor46f936e2010-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 Rosier8decdee2012-06-26 22:30:43 +00002721
Douglas Gregor9bd1d8d2010-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;
Reid Spencer5f016e22007-07-11 17:01:13 +00002725 }
John McCallfec54012009-08-03 20:12:06 +00002726 // If the specifier wasn't legal, issue a diagnostic.
Reid Spencer5f016e22007-07-11 17:01:13 +00002727 if (isInvalid) {
2728 assert(PrevSpec && "Method did not return previous specifier!");
John McCallfec54012009-08-03 20:12:06 +00002729 assert(DiagID);
Chad Rosier8decdee2012-06-26 22:30:43 +00002730
Douglas Gregorae2fb142010-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;
Reid Spencer5f016e22007-07-11 17:01:13 +00002736 }
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002737
Chris Lattner81c018d2008-03-13 06:29:04 +00002738 DS.SetRangeEnd(Tok.getLocation());
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00002739 if (DiagID != diag::err_bool_redeclaration)
2740 ConsumeToken();
Sean Hunt2edf0a22012-06-23 05:07:58 +00002741
2742 AttrsLastTime = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00002743 }
2744}
Douglas Gregoradcac882008-12-01 23:54:00 +00002745
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002746/// ParseStructDeclaration - Parse a struct declaration without the terminating
2747/// semicolon.
2748///
Reid Spencer5f016e22007-07-11 17:01:13 +00002749/// struct-declaration:
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002750/// specifier-qualifier-list struct-declarator-list
Reid Spencer5f016e22007-07-11 17:01:13 +00002751/// [GNU] __extension__ struct-declaration
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002752/// [GNU] specifier-qualifier-list
Reid Spencer5f016e22007-07-11 17:01:13 +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 Lattnere1359422008-04-10 06:46:29 +00002763void Parser::
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002764ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
Chad Rosier8decdee2012-06-26 22:30:43 +00002765
Chris Lattnerc46d1a12008-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 Naroff28a7ca82007-08-20 22:28:22 +00002769 ConsumeToken();
Chris Lattnerc46d1a12008-10-20 06:45:43 +00002770 return ParseStructDeclaration(DS, Fields);
2771 }
Mike Stump1eb44332009-09-09 15:08:12 +00002772
Steve Naroff28a7ca82007-08-20 22:28:22 +00002773 // Parse the common specifier-qualifiers-list piece.
Steve Naroff28a7ca82007-08-20 22:28:22 +00002774 ParseSpecifierQualifierList(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00002775
Douglas Gregor4920f1f2009-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 Lattner04d66662007-10-09 17:33:22 +00002778 if (Tok.is(tok::semi)) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002779 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
2780 DS);
2781 DS.complete(TheDecl);
Steve Naroff28a7ca82007-08-20 22:28:22 +00002782 return;
2783 }
2784
2785 // Read struct-declarators until we find the semicolon.
John McCallbdd563e2009-11-03 02:38:08 +00002786 bool FirstDeclarator = true;
Richard Smith7984de32012-01-12 23:53:29 +00002787 SourceLocation CommaLoc;
Steve Naroff28a7ca82007-08-20 22:28:22 +00002788 while (1) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002789 ParsingFieldDeclarator DeclaratorInfo(*this, DS);
Richard Smith7984de32012-01-12 23:53:29 +00002790 DeclaratorInfo.D.setCommaLoc(CommaLoc);
John McCallbdd563e2009-11-03 02:38:08 +00002791
2792 // Attributes are only allowed here on successive declarators.
John McCall7f040a92010-12-24 02:08:15 +00002793 if (!FirstDeclarator)
2794 MaybeParseGNUAttributes(DeclaratorInfo.D);
Mike Stump1eb44332009-09-09 15:08:12 +00002795
Steve Naroff28a7ca82007-08-20 22:28:22 +00002796 /// struct-declarator: declarator
2797 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattnera1efc8c2009-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 Lattnere1359422008-04-10 06:46:29 +00002801 ParseDeclarator(DeclaratorInfo.D);
Chris Lattnera1efc8c2009-12-10 01:59:24 +00002802 }
Mike Stump1eb44332009-09-09 15:08:12 +00002803
Chris Lattner04d66662007-10-09 17:33:22 +00002804 if (Tok.is(tok::colon)) {
Steve Naroff28a7ca82007-08-20 22:28:22 +00002805 ConsumeToken();
John McCall60d7b3a2010-08-24 06:29:42 +00002806 ExprResult Res(ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00002807 if (Res.isInvalid())
Steve Naroff28a7ca82007-08-20 22:28:22 +00002808 SkipUntil(tok::semi, true, true);
Chris Lattner60b1e3e2008-04-10 06:15:14 +00002809 else
Sebastian Redleffa8d12008-12-10 00:02:53 +00002810 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroff28a7ca82007-08-20 22:28:22 +00002811 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00002812
Steve Naroff28a7ca82007-08-20 22:28:22 +00002813 // If attributes exist after the declarator, parse them.
John McCall7f040a92010-12-24 02:08:15 +00002814 MaybeParseGNUAttributes(DeclaratorInfo.D);
Sebastian Redlab197ba2009-02-09 18:23:29 +00002815
John McCallbdd563e2009-11-03 02:38:08 +00002816 // We're done with this declarator; invoke the callback.
Eli Friedman817a8862012-08-08 23:35:12 +00002817 Fields.invoke(DeclaratorInfo);
John McCallbdd563e2009-11-03 02:38:08 +00002818
Steve Naroff28a7ca82007-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 Lattner04d66662007-10-09 17:33:22 +00002821 if (Tok.isNot(tok::comma))
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002822 return;
Sebastian Redlab197ba2009-02-09 18:23:29 +00002823
Steve Naroff28a7ca82007-08-20 22:28:22 +00002824 // Consume the comma.
Richard Smith7984de32012-01-12 23:53:29 +00002825 CommaLoc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00002826
John McCallbdd563e2009-11-03 02:38:08 +00002827 FirstDeclarator = false;
Steve Naroff28a7ca82007-08-20 22:28:22 +00002828 }
Steve Naroff28a7ca82007-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 Lattner5a6ddbf2008-06-21 19:39:06 +00002839/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroff28a7ca82007-08-20 22:28:22 +00002840///
Reid Spencer5f016e22007-07-11 17:01:13 +00002841void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
John McCalld226f652010-08-21 09:40:31 +00002842 unsigned TagType, Decl *TagDecl) {
John McCallf312b1e2010-08-26 23:41:50 +00002843 PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2844 "parsing struct/union body");
Mike Stump1eb44332009-09-09 15:08:12 +00002845
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002846 BalancedDelimiterTracker T(*this, tok::l_brace);
2847 if (T.consumeOpen())
2848 return;
Mike Stump1eb44332009-09-09 15:08:12 +00002849
Douglas Gregor3218c4b2009-01-09 22:42:13 +00002850 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00002851 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
Douglas Gregor72de6672009-01-08 20:45:30 +00002852
Reid Spencer5f016e22007-07-11 17:01:13 +00002853 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
2854 // C++.
David Blaikie4e4d0842012-03-11 07:00:24 +00002855 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {
Richard Smithd7c56e12011-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 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002859
Chris Lattner5f9e2722011-07-23 10:55:15 +00002860 SmallVector<Decl *, 32> FieldDecls;
Chris Lattnere1359422008-04-10 06:46:29 +00002861
Reid Spencer5f016e22007-07-11 17:01:13 +00002862 // While we still have something to read, read the declarations in the struct.
Chris Lattner04d66662007-10-09 17:33:22 +00002863 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002864 // Each iteration of this loop reads one struct-declaration.
Mike Stump1eb44332009-09-09 15:08:12 +00002865
Reid Spencer5f016e22007-07-11 17:01:13 +00002866 // Check for extraneous top-level semicolon.
Chris Lattner04d66662007-10-09 17:33:22 +00002867 if (Tok.is(tok::semi)) {
Richard Smitheab9d6f2012-07-23 05:45:25 +00002868 ConsumeExtraSemi(InsideStruct, TagType);
Reid Spencer5f016e22007-07-11 17:01:13 +00002869 continue;
2870 }
Chris Lattnere1359422008-04-10 06:46:29 +00002871
John McCallbdd563e2009-11-03 02:38:08 +00002872 if (!Tok.is(tok::at)) {
2873 struct CFieldCallback : FieldCallback {
2874 Parser &P;
John McCalld226f652010-08-21 09:40:31 +00002875 Decl *TagDecl;
Chris Lattner5f9e2722011-07-23 10:55:15 +00002876 SmallVectorImpl<Decl *> &FieldDecls;
John McCallbdd563e2009-11-03 02:38:08 +00002877
John McCalld226f652010-08-21 09:40:31 +00002878 CFieldCallback(Parser &P, Decl *TagDecl,
Chris Lattner5f9e2722011-07-23 10:55:15 +00002879 SmallVectorImpl<Decl *> &FieldDecls) :
John McCallbdd563e2009-11-03 02:38:08 +00002880 P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
2881
Eli Friedmandcdff462012-08-08 23:53:27 +00002882 void invoke(ParsingFieldDeclarator &FD) {
John McCallbdd563e2009-11-03 02:38:08 +00002883 // Install the declarator into the current TagDecl.
John McCalld226f652010-08-21 09:40:31 +00002884 Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
John McCall4ba39712009-11-03 21:13:47 +00002885 FD.D.getDeclSpec().getSourceRange().getBegin(),
2886 FD.D, FD.BitfieldSize);
John McCallbdd563e2009-11-03 02:38:08 +00002887 FieldDecls.push_back(Field);
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002888 FD.complete(Field);
Douglas Gregor91a28862009-08-26 14:27:30 +00002889 }
John McCallbdd563e2009-11-03 02:38:08 +00002890 } Callback(*this, TagDecl, FieldDecls);
2891
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002892 // Parse all the comma separated declarators.
2893 ParsingDeclSpec DS(*this);
John McCallbdd563e2009-11-03 02:38:08 +00002894 ParseStructDeclaration(DS, Callback);
Chris Lattner5a6ddbf2008-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 Lattner3e156ad2010-02-02 00:37:27 +00002899 SkipUntil(tok::semi, true);
Chris Lattner5a6ddbf2008-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 Lattner3e156ad2010-02-02 00:37:27 +00002906 SkipUntil(tok::semi, true);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002907 continue;
2908 }
Chris Lattner5f9e2722011-07-23 10:55:15 +00002909 SmallVector<Decl *, 16> Fields;
Douglas Gregor23c94db2010-07-02 17:43:08 +00002910 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
Douglas Gregor44b43212008-12-11 16:49:14 +00002911 Tok.getIdentifierInfo(), Fields);
Chris Lattner5a6ddbf2008-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 Stump1eb44332009-09-09 15:08:12 +00002915 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002916
Chris Lattner04d66662007-10-09 17:33:22 +00002917 if (Tok.is(tok::semi)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002918 ConsumeToken();
Chris Lattner04d66662007-10-09 17:33:22 +00002919 } else if (Tok.is(tok::r_brace)) {
Chris Lattner3e156ad2010-02-02 00:37:27 +00002920 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
Reid Spencer5f016e22007-07-11 17:01:13 +00002921 break;
2922 } else {
Chris Lattner3e156ad2010-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 ';'.
Reid Spencer5f016e22007-07-11 17:01:13 +00002925 SkipUntil(tok::r_brace, true, true);
Chris Lattner3e156ad2010-02-02 00:37:27 +00002926 // If we stopped at a ';', eat it.
2927 if (Tok.is(tok::semi)) ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00002928 }
2929 }
Mike Stump1eb44332009-09-09 15:08:12 +00002930
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002931 T.consumeClose();
Mike Stump1eb44332009-09-09 15:08:12 +00002932
John McCall0b7e6782011-03-24 11:26:52 +00002933 ParsedAttributes attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00002934 // If attributes exist after struct contents, parse them.
John McCall7f040a92010-12-24 02:08:15 +00002935 MaybeParseGNUAttributes(attrs);
Daniel Dunbar1bfe1c22008-10-03 02:03:53 +00002936
Douglas Gregor23c94db2010-07-02 17:43:08 +00002937 Actions.ActOnFields(getCurScope(),
David Blaikie77b6de02011-09-22 02:58:26 +00002938 RecordLoc, TagDecl, FieldDecls,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002939 T.getOpenLocation(), T.getCloseLocation(),
John McCall7f040a92010-12-24 02:08:15 +00002940 attrs.getList());
Douglas Gregor72de6672009-01-08 20:45:30 +00002941 StructScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002942 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
2943 T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00002944}
2945
Reid Spencer5f016e22007-07-11 17:01:13 +00002946/// ParseEnumSpecifier
2947/// enum-specifier: [C99 6.7.2.2]
2948/// 'enum' identifier[opt] '{' enumerator-list '}'
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002949///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00002950/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
2951/// '}' attributes[opt]
Aaron Ballman6454a022012-03-01 04:09:28 +00002952/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
2953/// '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00002954/// 'enum' identifier
2955/// [GNU] 'enum' attributes[opt] identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002956///
Richard Smith1af83c42012-03-23 03:33:32 +00002957/// [C++11] enum-head '{' enumerator-list[opt] '}'
2958/// [C++11] enum-head '{' enumerator-list ',' '}'
Douglas Gregor1274ccd2010-10-08 23:50:27 +00002959///
Richard Smith1af83c42012-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 Gregor1274ccd2010-10-08 23:50:27 +00002964///
Richard Smith1af83c42012-03-23 03:33:32 +00002965/// enum-key: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00002966/// 'enum'
2967/// 'enum' 'class'
2968/// 'enum' 'struct'
2969///
Richard Smith1af83c42012-03-23 03:33:32 +00002970/// enum-base: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00002971/// ':' type-specifier-seq
2972///
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002973/// [C++] elaborated-type-specifier:
2974/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
2975///
Chris Lattner4c97d762009-04-12 21:49:30 +00002976void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Douglas Gregor9b9edd62010-03-02 17:53:14 +00002977 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00002978 AccessSpecifier AS, DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002979 // Parse the tag portion of this.
Douglas Gregor374929f2009-09-18 15:37:17 +00002980 if (Tok.is(tok::code_completion)) {
2981 // Code completion for an enum name.
Douglas Gregor23c94db2010-07-02 17:43:08 +00002982 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002983 return cutOffParsing();
Douglas Gregor374929f2009-09-18 15:37:17 +00002984 }
John McCall57c13002011-07-06 05:58:41 +00002985
Sean Hunt2edf0a22012-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 Smithbdad7a22012-01-10 01:33:14 +00002995 SourceLocation ScopedEnumKWLoc;
John McCall57c13002011-07-06 05:58:41 +00002996 bool IsScopedUsingClassTag = false;
2997
John McCall1e12b3d2012-06-23 22:30:04 +00002998 // In C++11, recognize 'enum class' and 'enum struct'.
David Blaikie4e4d0842012-03-11 07:00:24 +00002999 if (getLangOpts().CPlusPlus0x &&
John McCall57c13002011-07-06 05:58:41 +00003000 (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
Richard Smith7fe62082011-10-15 05:09:34 +00003001 Diag(Tok, diag::warn_cxx98_compat_scoped_enum);
John McCall57c13002011-07-06 05:58:41 +00003002 IsScopedUsingClassTag = Tok.is(tok::kw_class);
Richard Smithbdad7a22012-01-10 01:33:14 +00003003 ScopedEnumKWLoc = ConsumeToken();
Chad Rosier8decdee2012-06-26 22:30:43 +00003004
John McCall1e12b3d2012-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.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003007 ProhibitAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003008
3009 // They are allowed afterwards, though.
3010 MaybeParseGNUAttributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003011 MaybeParseCXX0XAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003012 while (Tok.is(tok::kw___declspec))
3013 ParseMicrosoftDeclSpec(attrs);
John McCall57c13002011-07-06 05:58:41 +00003014 }
Richard Smith1af83c42012-03-23 03:33:32 +00003015
John McCall13489672012-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 Smith1af83c42012-03-23 03:33:32 +00003026
Richard Smith7796eb52012-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 McCall57c13002011-07-06 05:58:41 +00003033
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00003034 CXXScopeSpec &SS = DS.getTypeSpecScope();
David Blaikie4e4d0842012-03-11 07:00:24 +00003035 if (getLangOpts().CPlusPlus) {
John McCall57c13002011-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 Rosier8decdee2012-06-26 22:30:43 +00003039
3040 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003041 /*EnteringContext=*/false))
John McCall9ba61662010-02-26 08:45:28 +00003042 return;
3043
3044 if (SS.isSet() && Tok.isNot(tok::identifier)) {
Argyrios Kyrtzidiseb83ecd2008-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 Stump1eb44332009-09-09 15:08:12 +00003054
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003055 // Must have either 'enum name' or 'enum {...}'.
Douglas Gregorb9075602011-02-22 02:55:24 +00003056 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
Richard Smith7796eb52012-03-12 08:56:40 +00003057 !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003058 Diag(Tok, diag::err_expected_ident_lbrace);
Mike Stump1eb44332009-09-09 15:08:12 +00003059
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003060 // Skip the rest of this declarator, up until the comma or semicolon.
3061 SkipUntil(tok::comma, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00003062 return;
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003063 }
Mike Stump1eb44332009-09-09 15:08:12 +00003064
Argyrios Kyrtzidise281b4c2008-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 Stump1eb44332009-09-09 15:08:12 +00003072
Richard Smithbdad7a22012-01-10 01:33:14 +00003073 if (!Name && ScopedEnumKWLoc.isValid()) {
Douglas Gregor1274ccd2010-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 Smithbdad7a22012-01-10 01:33:14 +00003077 ScopedEnumKWLoc = SourceLocation();
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003078 IsScopedUsingClassTag = false;
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003079 }
3080
John McCall13489672012-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 Smith1af83c42012-03-23 03:33:32 +00003085
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003086 TypeResult BaseType;
3087
Douglas Gregora61b3e72010-12-01 17:42:47 +00003088 // Parse the fixed underlying type.
Richard Smith139be702012-07-02 19:14:01 +00003089 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
Douglas Gregorb9075602011-02-22 02:55:24 +00003090 if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003091 bool PossibleBitfield = false;
Richard Smith139be702012-07-02 19:14:01 +00003092 if (CanBeBitfield) {
Douglas Gregora61b3e72010-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 Rosier8decdee2012-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 Gregora61b3e72010-12-01 17:42:47 +00003099 // underlying types anyway.
3100 TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
Chad Rosier8decdee2012-06-26 22:30:43 +00003101 // If the next token starts an expression, we know we're parsing a
Douglas Gregora61b3e72010-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 Rosier8decdee2012-06-26 22:30:43 +00003107 // lookahead one more token to see if it's obvious that we have a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003108 // fixed underlying type.
Chad Rosier8decdee2012-06-26 22:30:43 +00003109 else if (TPR == TPResult::False() &&
Douglas Gregora61b3e72010-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 Smithd81e9612012-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 Blaikie4e4d0842012-03-11 07:00:24 +00003128 if ((getLangOpts().CPlusPlus &&
Richard Smithd81e9612012-02-23 01:36:12 +00003129 isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
David Blaikie4e4d0842012-03-11 07:00:24 +00003130 (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
Douglas Gregora61b3e72010-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 Rosier8decdee2012-06-26 22:30:43 +00003147
David Blaikie4e4d0842012-03-11 07:00:24 +00003148 if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2)
Douglas Gregor86f208c2011-02-22 20:32:04 +00003149 Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
3150 << Range;
David Blaikie4e4d0842012-03-11 07:00:24 +00003151 if (getLangOpts().CPlusPlus0x)
Richard Smith7fe62082011-10-15 05:09:34 +00003152 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
Douglas Gregora61b3e72010-12-01 17:42:47 +00003153 }
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003154 }
3155
Richard Smithbdad7a22012-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 Kyrtzidise281b4c2008-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 McCallf312b1e2010-08-26 23:41:50 +00003166 Sema::TagUseKind TUK;
John McCall13489672012-05-07 06:16:58 +00003167 if (!AllowDeclaration) {
Richard Smith7796eb52012-03-12 08:56:40 +00003168 TUK = Sema::TUK_Reference;
John McCall13489672012-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 Smithc9f35172012-06-25 21:37:02 +00003179 } else if (DSC != DSC_type_specifier &&
3180 (Tok.is(tok::semi) ||
Richard Smith139be702012-07-02 19:14:01 +00003181 (Tok.isAtStartOfLine() &&
3182 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
Richard Smithc9f35172012-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 McCall13489672012-05-07 06:16:58 +00003191 } else {
John McCallf312b1e2010-08-26 23:41:50 +00003192 TUK = Sema::TUK_Reference;
John McCall13489672012-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 Smith1af83c42012-03-23 03:33:32 +00003200
3201 MultiTemplateParamsArg TParams;
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003202 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
John McCallf312b1e2010-08-26 23:41:50 +00003203 TUK != Sema::TUK_Reference) {
Richard Smith1af83c42012-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 Gregor8fc6d232010-05-03 17:48:54 +00003221 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003222
Sean Hunt2edf0a22012-06-23 05:07:58 +00003223 if (TUK == Sema::TUK_Reference)
3224 ProhibitAttributes(attrs);
Richard Smith1af83c42012-03-23 03:33:32 +00003225
Douglas Gregorb9075602011-02-22 02:55:24 +00003226 if (!Name && TUK != Sema::TUK_Definition) {
3227 Diag(Tok, diag::err_enumerator_unnamed_no_def);
Richard Smith1af83c42012-03-23 03:33:32 +00003228
Douglas Gregorb9075602011-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 Smith1af83c42012-03-23 03:33:32 +00003233
Douglas Gregor402abb52009-05-28 23:31:59 +00003234 bool Owned = false;
John McCallc4e70192009-09-11 04:59:25 +00003235 bool IsDependent = false;
Douglas Gregor48c89f42010-04-24 16:38:41 +00003236 const char *PrevSpec = 0;
3237 unsigned DiagID;
John McCalld226f652010-08-21 09:40:31 +00003238 Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
John McCall7f040a92010-12-24 02:08:15 +00003239 StartLoc, SS, Name, NameLoc, attrs.getList(),
Richard Smith1af83c42012-03-23 03:33:32 +00003240 AS, DS.getModulePrivateSpecLoc(), TParams,
Richard Smithbdad7a22012-01-10 01:33:14 +00003241 Owned, IsDependent, ScopedEnumKWLoc,
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003242 IsScopedUsingClassTag, BaseType);
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003243
Douglas Gregor48c89f42010-04-24 16:38:41 +00003244 if (IsDependent) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003245 // This enum has a dependent nested-name-specifier. Handle it as a
Douglas Gregor48c89f42010-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 Rosier8decdee2012-06-26 22:30:43 +00003252
Douglas Gregor23c94db2010-07-02 17:43:08 +00003253 TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
Chad Rosier8decdee2012-06-26 22:30:43 +00003254 TUK, SS, Name, StartLoc,
Douglas Gregor48c89f42010-04-24 16:38:41 +00003255 NameLoc);
3256 if (Type.isInvalid()) {
3257 DS.SetTypeSpecError();
3258 return;
3259 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003260
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003261 if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3262 NameLoc.isValid() ? NameLoc : StartLoc,
3263 PrevSpec, DiagID, Type.get()))
Douglas Gregor48c89f42010-04-24 16:38:41 +00003264 Diag(StartLoc, DiagID) << PrevSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00003265
Douglas Gregor48c89f42010-04-24 16:38:41 +00003266 return;
3267 }
Mike Stump1eb44332009-09-09 15:08:12 +00003268
John McCalld226f652010-08-21 09:40:31 +00003269 if (!TagDecl) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003270 // The action failed to produce an enumeration tag. If this is a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003271 // definition, consume the entire definition.
Richard Smith7796eb52012-03-12 08:56:40 +00003272 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
Douglas Gregor48c89f42010-04-24 16:38:41 +00003273 ConsumeBrace();
3274 SkipUntil(tok::r_brace);
3275 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003276
Douglas Gregor48c89f42010-04-24 16:38:41 +00003277 DS.SetTypeSpecError();
3278 return;
3279 }
Richard Smithbdad7a22012-01-10 01:33:14 +00003280
Richard Smithc9f35172012-06-25 21:37:02 +00003281 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
John McCall13489672012-05-07 06:16:58 +00003282 ParseEnumBody(StartLoc, TagDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00003283
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003284 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3285 NameLoc.isValid() ? NameLoc : StartLoc,
3286 PrevSpec, DiagID, TagDecl, Owned))
John McCallfec54012009-08-03 20:12:06 +00003287 Diag(StartLoc, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003288}
3289
3290/// 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 McCalld226f652010-08-21 09:40:31 +00003300void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Douglas Gregor074149e2009-01-05 19:45:36 +00003301 // Enter the scope of the enum body and start the definition.
3302 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003303 Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
Douglas Gregor074149e2009-01-05 19:45:36 +00003304
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003305 BalancedDelimiterTracker T(*this, tok::l_brace);
3306 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00003307
Chris Lattner7946dd32007-08-27 17:24:30 +00003308 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
David Blaikie4e4d0842012-03-11 07:00:24 +00003309 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
Fariborz Jahanian05115522010-05-28 22:23:22 +00003310 Diag(Tok, diag::error_empty_enum);
Mike Stump1eb44332009-09-09 15:08:12 +00003311
Chris Lattner5f9e2722011-07-23 10:55:15 +00003312 SmallVector<Decl *, 32> EnumConstantDecls;
Reid Spencer5f016e22007-07-11 17:01:13 +00003313
John McCalld226f652010-08-21 09:40:31 +00003314 Decl *LastEnumConstDecl = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00003315
Reid Spencer5f016e22007-07-11 17:01:13 +00003316 // Parse the enumerator-list.
Chris Lattner04d66662007-10-09 17:33:22 +00003317 while (Tok.is(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003318 IdentifierInfo *Ident = Tok.getIdentifierInfo();
3319 SourceLocation IdentLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003320
John McCall5b629aa2010-10-22 23:36:17 +00003321 // If attributes exist after the enumerator, parse them.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003322 ParsedAttributesWithRange attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003323 MaybeParseGNUAttributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003324 MaybeParseCXX0XAttributes(attrs);
3325 ProhibitAttributes(attrs);
John McCall5b629aa2010-10-22 23:36:17 +00003326
Reid Spencer5f016e22007-07-11 17:01:13 +00003327 SourceLocation EqualLoc;
John McCall60d7b3a2010-08-24 06:29:42 +00003328 ExprResult AssignedVal;
John McCall92576642012-05-07 06:16:41 +00003329 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
Chad Rosier8decdee2012-06-26 22:30:43 +00003330
Chris Lattner04d66662007-10-09 17:33:22 +00003331 if (Tok.is(tok::equal)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003332 EqualLoc = ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00003333 AssignedVal = ParseConstantExpression();
3334 if (AssignedVal.isInvalid())
Reid Spencer5f016e22007-07-11 17:01:13 +00003335 SkipUntil(tok::comma, tok::r_brace, true, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00003336 }
Mike Stump1eb44332009-09-09 15:08:12 +00003337
Reid Spencer5f016e22007-07-11 17:01:13 +00003338 // Install the enumerator constant into EnumDecl.
John McCalld226f652010-08-21 09:40:31 +00003339 Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3340 LastEnumConstDecl,
3341 IdentLoc, Ident,
John McCall7f040a92010-12-24 02:08:15 +00003342 attrs.getList(), EqualLoc,
John McCalld226f652010-08-21 09:40:31 +00003343 AssignedVal.release());
Fariborz Jahanian5a477db2011-12-09 01:15:54 +00003344 PD.complete(EnumConstDecl);
Chad Rosier8decdee2012-06-26 22:30:43 +00003345
Reid Spencer5f016e22007-07-11 17:01:13 +00003346 EnumConstantDecls.push_back(EnumConstDecl);
3347 LastEnumConstDecl = EnumConstDecl;
Mike Stump1eb44332009-09-09 15:08:12 +00003348
Douglas Gregor751f6922010-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 Rosier8decdee2012-06-26 22:30:43 +00003352 Diag(Loc, diag::err_enumerator_list_missing_comma)
Douglas Gregor751f6922010-09-07 14:51:08 +00003353 << FixItHint::CreateInsertion(Loc, ", ");
3354 continue;
3355 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003356
Chris Lattner04d66662007-10-09 17:33:22 +00003357 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +00003358 break;
3359 SourceLocation CommaLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003360
Richard Smith7fe62082011-10-15 05:09:34 +00003361 if (Tok.isNot(tok::identifier)) {
David Blaikie4e4d0842012-03-11 07:00:24 +00003362 if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x)
Richard Smitheab9d6f2012-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 Smith7fe62082011-10-15 05:09:34 +00003366 << FixItHint::CreateRemoval(CommaLoc);
David Blaikie4e4d0842012-03-11 07:00:24 +00003367 else if (getLangOpts().CPlusPlus0x)
Richard Smith7fe62082011-10-15 05:09:34 +00003368 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3369 << FixItHint::CreateRemoval(CommaLoc);
3370 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003371 }
Mike Stump1eb44332009-09-09 15:08:12 +00003372
Reid Spencer5f016e22007-07-11 17:01:13 +00003373 // Eat the }.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003374 T.consumeClose();
Reid Spencer5f016e22007-07-11 17:01:13 +00003375
Reid Spencer5f016e22007-07-11 17:01:13 +00003376 // If attributes exist after the identifier list, parse them.
John McCall0b7e6782011-03-24 11:26:52 +00003377 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003378 MaybeParseGNUAttributes(attrs);
Douglas Gregor72de6672009-01-08 20:45:30 +00003379
Douglas Gregor4a8dfb52011-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 Stump1eb44332009-09-09 15:08:12 +00003384
Douglas Gregor72de6672009-01-08 20:45:30 +00003385 EnumScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003386 Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3387 T.getCloseLocation());
Richard Smithc9f35172012-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 Smith139be702012-07-02 19:14:01 +00003391 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3392 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
Richard Smithc9f35172012-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 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003400}
3401
3402/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff5f8aa692008-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 Collingbourne207f4d82011-03-18 22:38:29 +00003407
3408 // type-qualifier only in OpenCL
3409 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003410 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003411
Steve Naroff5f8aa692008-02-11 23:15:56 +00003412 // type-qualifier
3413 case tok::kw_const:
3414 case tok::kw_volatile:
3415 case tok::kw_restrict:
Peter Collingbourne207f4d82011-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 Naroff5f8aa692008-02-11 23:15:56 +00003423 return true;
3424 }
3425}
3426
Chris Lattnerb3a4e432010-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 Pichet338d7f72011-04-28 01:59:37 +00003436 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003437 case tok::kw___int128:
Chris Lattnerb3a4e432010-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 Korobeynikovaa4a99b2011-10-14 23:23:15 +00003448 case tok::kw_half:
Chris Lattnerb3a4e432010-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 Rosier8decdee2012-06-26 22:30:43 +00003457
Chris Lattnerb3a4e432010-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 Rosier8decdee2012-06-26 22:30:43 +00003464
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003465 // typedef-name
3466 case tok::annot_typename:
3467 return true;
3468 }
3469}
3470
Steve Naroff5f8aa692008-02-11 23:15:56 +00003471/// isTypeSpecifierQualifier - Return true if the current token could be the
Reid Spencer5f016e22007-07-11 17:01:13 +00003472/// start of a specifier-qualifier-list.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003473bool Parser::isTypeSpecifierQualifier() {
Reid Spencer5f016e22007-07-11 17:01:13 +00003474 switch (Tok.getKind()) {
3475 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003476
Chris Lattner166a8fc2009-01-04 23:41:41 +00003477 case tok::identifier: // foo::bar
John Thompson82287d12010-02-05 00:12:22 +00003478 if (TryAltiVecVectorToken())
3479 return true;
3480 // Fall through.
Douglas Gregord57959a2009-03-27 23:10:48 +00003481 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-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 McCall9ba61662010-02-26 08:45:28 +00003485 return true;
3486 if (Tok.is(tok::identifier))
3487 return false;
3488 return isTypeSpecifierQualifier();
Douglas Gregord57959a2009-03-27 23:10:48 +00003489
Chris Lattner166a8fc2009-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 Lattner166a8fc2009-01-04 23:41:41 +00003495 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003496 return true;
3497 return isTypeSpecifierQualifier();
Mike Stump1eb44332009-09-09 15:08:12 +00003498
Reid Spencer5f016e22007-07-11 17:01:13 +00003499 // GNU attributes support.
3500 case tok::kw___attribute:
Steve Naroffd1861fd2007-07-31 12:34:36 +00003501 // GNU typeof support.
3502 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00003503
Reid Spencer5f016e22007-07-11 17:01:13 +00003504 // type-specifiers
3505 case tok::kw_short:
3506 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003507 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003508 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +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 Kyrtzidis64c438a2008-08-09 16:51:54 +00003515 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003516 case tok::kw_char16_t:
3517 case tok::kw_char32_t:
Reid Spencer5f016e22007-07-11 17:01:13 +00003518 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003519 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00003520 case tok::kw_float:
3521 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00003522 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00003523 case tok::kw__Bool:
3524 case tok::kw__Decimal32:
3525 case tok::kw__Decimal64:
3526 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00003527 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00003528
Chris Lattner99dc9142008-04-13 18:59:07 +00003529 // struct-or-union-specifier (C99) or class-specifier (C++)
3530 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00003531 case tok::kw_struct:
3532 case tok::kw_union:
3533 // enum-specifier
3534 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00003535
Reid Spencer5f016e22007-07-11 17:01:13 +00003536 // type-qualifier
3537 case tok::kw_const:
3538 case tok::kw_volatile:
3539 case tok::kw_restrict:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003540
3541 // typedef-name
Chris Lattnerb31757b2009-01-06 05:06:21 +00003542 case tok::annot_typename:
Reid Spencer5f016e22007-07-11 17:01:13 +00003543 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00003544
Chris Lattner7c186be2008-10-20 00:25:30 +00003545 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3546 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00003547 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00003548
Steve Naroff239f0732008-12-25 14:16:32 +00003549 case tok::kw___cdecl:
3550 case tok::kw___stdcall:
3551 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003552 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00003553 case tok::kw___w64:
3554 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003555 case tok::kw___ptr32:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003556 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003557 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-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 Friedman290eeb02009-06-08 23:27:34 +00003567 return true;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003568
3569 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003570 return getLangOpts().OpenCL;
Eli Friedmanb001de72011-10-06 23:00:33 +00003571
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00003572 // C11 _Atomic()
Eli Friedmanb001de72011-10-06 23:00:33 +00003573 case tok::kw__Atomic:
3574 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00003575 }
3576}
3577
3578/// isDeclarationSpecifier() - Return true if the current token is part of a
3579/// declaration specifier.
Douglas Gregor9497a732010-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) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003584 switch (Tok.getKind()) {
3585 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003586
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003587 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003588 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003589
Chris Lattner166a8fc2009-01-04 23:41:41 +00003590 case tok::identifier: // foo::bar
Steve Naroff61f72cb2009-03-09 21:12:44 +00003591 // Unfortunate hack to support "Class.factoryMethod" notation.
David Blaikie4e4d0842012-03-11 07:00:24 +00003592 if (getLangOpts().ObjC1 && NextToken().is(tok::period))
Steve Naroff61f72cb2009-03-09 21:12:44 +00003593 return false;
John Thompson82287d12010-02-05 00:12:22 +00003594 if (TryAltiVecVectorToken())
3595 return true;
3596 // Fall through.
David Blaikie42d6d0c2011-12-04 05:04:18 +00003597 case tok::kw_decltype: // decltype(T())::type
Douglas Gregord57959a2009-03-27 23:10:48 +00003598 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-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 McCall9ba61662010-02-26 08:45:28 +00003602 return true;
3603 if (Tok.is(tok::identifier))
3604 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00003605
Douglas Gregor9497a732010-09-16 01:51:54 +00003606 // If we're in Objective-C and we have an Objective-C class type followed
Chad Rosier8decdee2012-06-26 22:30:43 +00003607 // by an identifier and then either ':' or ']', in a place where an
Douglas Gregor9497a732010-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 Rosier8decdee2012-06-26 22:30:43 +00003611 if (DisambiguatingWithExpression &&
Douglas Gregor9497a732010-09-16 01:51:54 +00003612 isStartOfObjCClassMessageMissingOpenBracket())
3613 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00003614
John McCall9ba61662010-02-26 08:45:28 +00003615 return isDeclarationSpecifier();
3616
Chris Lattner166a8fc2009-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 Stump1eb44332009-09-09 15:08:12 +00003621
Chris Lattner166a8fc2009-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 McCall9ba61662010-02-26 08:45:28 +00003625 return true;
3626 return isDeclarationSpecifier();
Mike Stump1eb44332009-09-09 15:08:12 +00003627
Reid Spencer5f016e22007-07-11 17:01:13 +00003628 // storage-class-specifier
3629 case tok::kw_typedef:
3630 case tok::kw_extern:
Steve Naroff8d54bf22007-12-18 00:16:02 +00003631 case tok::kw___private_extern__:
Reid Spencer5f016e22007-07-11 17:01:13 +00003632 case tok::kw_static:
3633 case tok::kw_auto:
3634 case tok::kw_register:
3635 case tok::kw___thread:
Mike Stump1eb44332009-09-09 15:08:12 +00003636
Douglas Gregor8d267c52011-09-09 02:06:17 +00003637 // Modules
3638 case tok::kw___module_private__:
Chad Rosier8decdee2012-06-26 22:30:43 +00003639
Reid Spencer5f016e22007-07-11 17:01:13 +00003640 // type-specifiers
3641 case tok::kw_short:
3642 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003643 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003644 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +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 Kyrtzidis64c438a2008-08-09 16:51:54 +00003651 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003652 case tok::kw_char16_t:
3653 case tok::kw_char32_t:
3654
Reid Spencer5f016e22007-07-11 17:01:13 +00003655 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003656 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00003657 case tok::kw_float:
3658 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00003659 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00003660 case tok::kw__Bool:
3661 case tok::kw__Decimal32:
3662 case tok::kw__Decimal64:
3663 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00003664 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00003665
Chris Lattner99dc9142008-04-13 18:59:07 +00003666 // struct-or-union-specifier (C99) or class-specifier (C++)
3667 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00003668 case tok::kw_struct:
3669 case tok::kw_union:
3670 // enum-specifier
3671 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00003672
Reid Spencer5f016e22007-07-11 17:01:13 +00003673 // type-qualifier
3674 case tok::kw_const:
3675 case tok::kw_volatile:
3676 case tok::kw_restrict:
Steve Naroffd1861fd2007-07-31 12:34:36 +00003677
Reid Spencer5f016e22007-07-11 17:01:13 +00003678 // function-specifier
3679 case tok::kw_inline:
Douglas Gregorb48fe382008-10-31 09:07:45 +00003680 case tok::kw_virtual:
3681 case tok::kw_explicit:
Chris Lattnerd6c7c182007-08-09 16:40:21 +00003682
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00003683 // static_assert-declaration
3684 case tok::kw__Static_assert:
3685
Chris Lattner1ef08762007-08-09 17:01:07 +00003686 // GNU typeof support.
3687 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00003688
Chris Lattner1ef08762007-08-09 17:01:07 +00003689 // GNU attributes.
Chris Lattnerd6c7c182007-08-09 16:40:21 +00003690 case tok::kw___attribute:
Reid Spencer5f016e22007-07-11 17:01:13 +00003691 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00003692
Francois Pichete3d49b42011-06-19 08:02:06 +00003693 // C++0x decltype.
David Blaikie42d6d0c2011-12-04 05:04:18 +00003694 case tok::annot_decltype:
Francois Pichete3d49b42011-06-19 08:02:06 +00003695 return true;
3696
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00003697 // C11 _Atomic()
Eli Friedmanb001de72011-10-06 23:00:33 +00003698 case tok::kw__Atomic:
3699 return true;
3700
Chris Lattnerf3948c42008-07-26 03:38:44 +00003701 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3702 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00003703 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00003704
Douglas Gregord9d75e52011-04-27 05:41:15 +00003705 // typedef-name
3706 case tok::annot_typename:
3707 return !DisambiguatingWithExpression ||
3708 !isStartOfObjCClassMessageMissingOpenBracket();
Chad Rosier8decdee2012-06-26 22:30:43 +00003709
Steve Naroff47f52092009-01-06 19:34:12 +00003710 case tok::kw___declspec:
Steve Naroff239f0732008-12-25 14:16:32 +00003711 case tok::kw___cdecl:
3712 case tok::kw___stdcall:
3713 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003714 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00003715 case tok::kw___w64:
3716 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003717 case tok::kw___ptr32:
Eli Friedman290eeb02009-06-08 23:27:34 +00003718 case tok::kw___forceinline:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003719 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003720 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-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 Friedman290eeb02009-06-08 23:27:34 +00003730 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00003731 }
3732}
3733
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003734bool Parser::isConstructorDeclarator() {
3735 TentativeParsingAction TPA(*this);
3736
3737 // Parse the C++ scope specifier.
3738 CXXScopeSpec SS;
Chad Rosier8decdee2012-06-26 22:30:43 +00003739 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003740 /*EnteringContext=*/true)) {
John McCall9ba61662010-02-26 08:45:28 +00003741 TPA.Revert();
3742 return false;
3743 }
Douglas Gregor0efc2c12010-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 Smith22592862012-03-27 23:05:05 +00003755 // Current class name must be followed by a left parenthesis.
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003756 if (Tok.isNot(tok::l_paren)) {
3757 TPA.Revert();
3758 return false;
3759 }
3760 ConsumeParen();
3761
Richard Smith22592862012-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 Gregor0efc2c12010-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 Gregor23c94db2010-07-02 17:43:08 +00003772 if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003773 DeclScopeObj.EnterDeclaratorScope();
3774
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00003775 // Optionally skip Microsoft attributes.
John McCall0b7e6782011-03-24 11:26:52 +00003776 ParsedAttributes Attrs(AttrFactory);
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00003777 MaybeParseMicrosoftAttributes(Attrs);
3778
Douglas Gregor0efc2c12010-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 Smith412e0cc2012-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 Smith5d8388c2012-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 Smith412e0cc2012-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 Gregor0efc2c12010-01-13 17:31:36 +00003819 TPA.Revert();
3820 return IsConstructor;
3821}
Reid Spencer5f016e22007-07-11 17:01:13 +00003822
3823/// ParseTypeQualifierListOpt
Dawn Perchik52fc3142010-09-03 01:29:35 +00003824/// type-qualifier-list: [C99 6.7.5]
3825/// type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00003826/// [vendor] attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00003827/// [ only if VendorAttributesAllowed=true ]
3828/// type-qualifier-list type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00003829/// [vendor] type-qualifier-list attributes
Dawn Perchik52fc3142010-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.
Reid Spencer5f016e22007-07-11 17:01:13 +00003834///
Dawn Perchik52fc3142010-09-03 01:29:35 +00003835void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
3836 bool VendorAttributesAllowed,
Richard Smithc56298d2012-04-10 03:25:07 +00003837 bool CXX11AttributesAllowed) {
3838 if (getLangOpts().CPlusPlus0x && CXX11AttributesAllowed &&
Richard Smith6ee326a2012-04-10 01:32:12 +00003839 isCXX11AttributeSpecifier()) {
John McCall0b7e6782011-03-24 11:26:52 +00003840 ParsedAttributesWithRange attrs(AttrFactory);
Richard Smithc56298d2012-04-10 03:25:07 +00003841 ParseCXX11Attributes(attrs);
Richard Smith6ee326a2012-04-10 01:32:12 +00003842 DS.takeAttributesFrom(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00003843 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00003844
3845 SourceLocation EndLoc;
3846
Reid Spencer5f016e22007-07-11 17:01:13 +00003847 while (1) {
John McCallfec54012009-08-03 20:12:06 +00003848 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00003849 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00003850 unsigned DiagID = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +00003851 SourceLocation Loc = Tok.getLocation();
3852
3853 switch (Tok.getKind()) {
Douglas Gregor1a480c42010-08-27 17:35:51 +00003854 case tok::code_completion:
3855 Actions.CodeCompleteTypeQualifiers(DS);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00003856 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00003857
Reid Spencer5f016e22007-07-11 17:01:13 +00003858 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00003859 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00003860 getLangOpts(), /*IsTypeSpec*/false);
Reid Spencer5f016e22007-07-11 17:01:13 +00003861 break;
3862 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00003863 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00003864 getLangOpts(), /*IsTypeSpec*/false);
Reid Spencer5f016e22007-07-11 17:01:13 +00003865 break;
3866 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00003867 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00003868 getLangOpts(), /*IsTypeSpec*/false);
Reid Spencer5f016e22007-07-11 17:01:13 +00003869 break;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003870
3871 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00003872 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003873 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-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 Friedman290eeb02009-06-08 23:27:34 +00003885 case tok::kw___w64:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00003886 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003887 case tok::kw___ptr32:
Steve Naroff239f0732008-12-25 14:16:32 +00003888 case tok::kw___cdecl:
3889 case tok::kw___stdcall:
3890 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003891 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003892 case tok::kw___unaligned:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003893 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003894 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00003895 continue;
3896 }
3897 goto DoneWithTypeQuals;
Dawn Perchik52fc3142010-09-03 01:29:35 +00003898 case tok::kw___pascal:
3899 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003900 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00003901 continue;
3902 }
3903 goto DoneWithTypeQuals;
Reid Spencer5f016e22007-07-11 17:01:13 +00003904 case tok::kw___attribute:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003905 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003906 ParseGNUAttributes(DS.getAttributes());
Chris Lattner5a69d1c2008-12-18 07:02:59 +00003907 continue; // do *not* consume the next token!
3908 }
3909 // otherwise, FALL THROUGH!
3910 default:
Steve Naroff239f0732008-12-25 14:16:32 +00003911 DoneWithTypeQuals:
Chris Lattner5a69d1c2008-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 Gregor9b3064b2009-04-01 22:41:11 +00003914 DS.Finish(Diags, PP);
Abramo Bagnara796aa442011-03-12 11:17:06 +00003915 if (EndLoc.isValid())
3916 DS.SetRangeEnd(EndLoc);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00003917 return;
Reid Spencer5f016e22007-07-11 17:01:13 +00003918 }
Chris Lattnera1fcbad2008-12-18 06:50:14 +00003919
Reid Spencer5f016e22007-07-11 17:01:13 +00003920 // If the specifier combination wasn't legal, issue a diagnostic.
3921 if (isInvalid) {
3922 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +00003923 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003924 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00003925 EndLoc = ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00003926 }
3927}
3928
3929
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 Redl4c5d3202008-11-21 19:14:01 +00003935 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Reid Spencer5f016e22007-07-11 17:01:13 +00003936}
3937
Richard Smith9988f282012-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 Redl4c5d3202008-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 Gregor2f1bc522008-11-07 20:08:42 +00003952/// ptr-operator production.
3953///
Richard Smith0706df42011-10-19 21:33:05 +00003954/// If the grammar of this construct is extended, matching changes must also be
Richard Smith5d8388c2012-03-27 01:42:32 +00003955/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
3956/// isConstructorDeclarator.
Richard Smith0706df42011-10-19 21:33:05 +00003957///
Sebastian Redlf30208a2009-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
Reid Spencer5f016e22007-07-11 17:01:13 +00003962///
3963/// pointer: [C99 6.7.5]
3964/// '*' type-qualifier-list[opt]
3965/// '*' type-qualifier-list[opt] pointer
3966///
Douglas Gregor2f1bc522008-11-07 20:08:42 +00003967/// ptr-operator:
3968/// '*' cv-qualifier-seq[opt]
3969/// '&'
Sebastian Redl05532f22009-03-15 22:02:01 +00003970/// [C++0x] '&&'
Douglas Gregor2f1bc522008-11-07 20:08:42 +00003971/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redl05532f22009-03-15 22:02:01 +00003972/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redlf30208a2009-01-24 21:16:55 +00003973/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +00003974void Parser::ParseDeclaratorInternal(Declarator &D,
3975 DirectDeclParseFunction DirectDeclParser) {
Douglas Gregor91a28862009-08-26 14:27:30 +00003976 if (Diags.hasAllExtensionsSilenced())
3977 D.setExtension();
Chad Rosier8decdee2012-06-26 22:30:43 +00003978
Sebastian Redlf30208a2009-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 Blaikie4e4d0842012-03-11 07:00:24 +00003982 if (getLangOpts().CPlusPlus &&
Chris Lattnerf919bfe2009-03-24 17:04:48 +00003983 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
3984 Tok.is(tok::annot_cxxscope))) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003985 bool EnteringContext = D.getContext() == Declarator::FileContext ||
3986 D.getContext() == Declarator::MemberContext;
Sebastian Redlf30208a2009-01-24 21:16:55 +00003987 CXXScopeSpec SS;
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003988 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00003989
Jeffrey Yasskinedc28772010-04-07 23:29:58 +00003990 if (SS.isNotEmpty()) {
Mike Stump1eb44332009-09-09 15:08:12 +00003991 if (Tok.isNot(tok::star)) {
Sebastian Redlf30208a2009-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 Redlab197ba2009-02-09 18:23:29 +00004000 D.SetRangeEnd(Loc);
John McCall0b7e6782011-03-24 11:26:52 +00004001 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004002 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004003 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-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 McCall0b7e6782011-03-24 11:26:52 +00004011 Loc),
4012 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004013 /* Don't replace range end. */SourceLocation());
Sebastian Redlf30208a2009-01-24 21:16:55 +00004014 return;
4015 }
4016 }
4017
4018 tok::TokenKind Kind = Tok.getKind();
Steve Naroff5618bd42008-08-27 16:04:49 +00004019 // Not a pointer, C++ reference, or block.
Richard Smith9988f282012-03-29 01:16:42 +00004020 if (!isPtrOperatorToken(Kind, getLangOpts())) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004021 if (DirectDeclParser)
4022 (this->*DirectDeclParser)(D);
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004023 return;
4024 }
Sebastian Redlf30208a2009-01-24 21:16:55 +00004025
Sebastian Redl05532f22009-03-15 22:02:01 +00004026 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4027 // '&&' -> rvalue reference
Sebastian Redl743de1f2009-03-23 00:00:23 +00004028 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redlab197ba2009-02-09 18:23:29 +00004029 D.SetRangeEnd(Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +00004030
Chris Lattner9af55002009-03-27 04:18:06 +00004031 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner76549142008-02-21 01:32:26 +00004032 // Is a pointer.
John McCall0b7e6782011-03-24 11:26:52 +00004033 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004034
Richard Smith6ee326a2012-04-10 01:32:12 +00004035 // FIXME: GNU attributes are not allowed here in a new-type-id.
Reid Spencer5f016e22007-07-11 17:01:13 +00004036 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004037 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004038
Reid Spencer5f016e22007-07-11 17:01:13 +00004039 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004040 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff5618bd42008-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 Carruthd067c072011-02-23 18:51:59 +00004044 DS.getConstSpecLoc(),
4045 DS.getVolatileSpecLoc(),
John McCall0b7e6782011-03-24 11:26:52 +00004046 DS.getRestrictSpecLoc()),
4047 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004048 SourceLocation());
Steve Naroff5618bd42008-08-27 16:04:49 +00004049 else
4050 // Remember that we parsed a Block type, and remember the type-quals.
Mike Stump1eb44332009-09-09 15:08:12 +00004051 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004052 Loc),
4053 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004054 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004055 } else {
4056 // Is a reference
John McCall0b7e6782011-03-24 11:26:52 +00004057 DeclSpec DS(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00004058
Sebastian Redl743de1f2009-03-23 00:00:23 +00004059 // Complain about rvalue references in C++03, but then go on and build
4060 // the declarator.
Richard Smith7fe62082011-10-15 05:09:34 +00004061 if (Kind == tok::ampamp)
David Blaikie4e4d0842012-03-11 07:00:24 +00004062 Diag(Loc, getLangOpts().CPlusPlus0x ?
Richard Smith7fe62082011-10-15 05:09:34 +00004063 diag::warn_cxx98_compat_rvalue_reference :
4064 diag::ext_rvalue_reference);
Sebastian Redl743de1f2009-03-23 00:00:23 +00004065
Richard Smith6ee326a2012-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
Reid Spencer5f016e22007-07-11 17:01:13 +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.
Reid Spencer5f016e22007-07-11 17:01:13 +00004073 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4074 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4075 Diag(DS.getConstSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004076 diag::err_invalid_reference_qualifier_application) << "const";
Reid Spencer5f016e22007-07-11 17:01:13 +00004077 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4078 Diag(DS.getVolatileSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004079 diag::err_invalid_reference_qualifier_application) << "volatile";
Reid Spencer5f016e22007-07-11 17:01:13 +00004080 }
4081
4082 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004083 ParseDeclaratorInternal(D, DirectDeclParser);
Reid Spencer5f016e22007-07-11 17:01:13 +00004084
Douglas Gregorf1f9b4e2008-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 Lattnerda83bac2008-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 Gregorf1f9b4e2008-11-03 15:51:28 +00004095
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004096 // Once we've complained about the reference-to-reference, we
Douglas Gregorf1f9b4e2008-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
Reid Spencer5f016e22007-07-11 17:01:13 +00004102 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner76549142008-02-21 01:32:26 +00004103 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redl05532f22009-03-15 22:02:01 +00004104 Kind == tok::amp),
John McCall0b7e6782011-03-24 11:26:52 +00004105 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004106 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004107 }
4108}
4109
Richard Smith9988f282012-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
Reid Spencer5f016e22007-07-11 17:01:13 +00004123/// ParseDirectDeclarator
4124/// direct-declarator: [C99 6.7.5]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004125/// [C99] identifier
Reid Spencer5f016e22007-07-11 17:01:13 +00004126/// '(' declarator ')'
4127/// [GNU] '(' attributes declarator ')'
4128/// [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 Smith6ee326a2012-04-10 01:32:12 +00004133/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4134/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +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 Kyrtzidis971c4fa2008-10-24 21:46:40 +00004139/// [C++] direct-declarator '(' parameter-declaration-clause ')'
4140/// cv-qualifier-seq[opt] exception-specification[opt]
Richard Smith6ee326a2012-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 Gregorb48fe382008-10-31 09:07:45 +00004144/// [C++] declarator-id
Richard Smith6ee326a2012-04-10 01:32:12 +00004145/// [C++11] declarator-id attribute-specifier-seq[opt]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004146///
4147/// declarator-id: [C++ 8]
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004148/// '...'[opt] id-expression
Douglas Gregor42a552f2008-11-05 20:51:48 +00004149/// '::'[opt] nested-name-specifier[opt] type-name
4150///
4151/// id-expression: [C++ 5.1]
4152/// unqualified-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004153/// qualified-id
Douglas Gregor42a552f2008-11-05 20:51:48 +00004154///
4155/// unqualified-id: [C++ 5.1]
Mike Stump1eb44332009-09-09 15:08:12 +00004156/// identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004157/// operator-function-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004158/// conversion-function-id
Mike Stump1eb44332009-09-09 15:08:12 +00004159/// '~' class-name
Douglas Gregor39a8de12009-02-25 19:37:18 +00004160/// template-id
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +00004161///
Richard Smith5d8388c2012-03-27 01:42:32 +00004162/// Note, any additional constructs added here may need corresponding changes
4163/// in isConstructorDeclarator.
Reid Spencer5f016e22007-07-11 17:01:13 +00004164void Parser::ParseDirectDeclarator(Declarator &D) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004165 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004166
David Blaikie4e4d0842012-03-11 07:00:24 +00004167 if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004168 // ParseDeclaratorInternal might already have parsed the scope.
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004169 if (D.getCXXScopeSpec().isEmpty()) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004170 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4171 D.getContext() == Declarator::MemberContext;
Chad Rosier8decdee2012-06-26 22:30:43 +00004172 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004173 EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004174 }
4175
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004176 if (D.getCXXScopeSpec().isValid()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00004177 if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
John McCalle7e278b2009-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 Yasskin9ab14542010-04-08 16:38:48 +00004181 }
4182
Douglas Gregora8bc8c92010-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 Rosier8decdee2012-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 Gregora8bc8c92010-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 Smith9988f282012-03-29 01:16:42 +00004190 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004191 !((D.getContext() == Declarator::PrototypeContext ||
4192 D.getContext() == Declarator::BlockLiteralContext) &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004193 NextToken().is(tok::r_paren) &&
Richard Smith9988f282012-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 Gregor3f9a0562009-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 McCallba9d8532010-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 Bagnarae4b92762012-01-27 09:46:47 +00004225 SourceLocation TemplateKWLoc;
Chad Rosier8decdee2012-06-26 22:30:43 +00004226 if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4227 /*EnteringContext=*/true,
4228 /*AllowDestructorName=*/true,
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004229 AllowConstructorName,
John McCallb3d87482010-08-24 05:47:05 +00004230 ParsedType(),
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004231 TemplateKWLoc,
Jeffrey Yasskin9ab14542010-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 Kyrtzidis314fe782008-11-26 22:40:03 +00004236 D.SetIdentifier(0, Tok.getLocation());
4237 D.setInvalidType(true);
Douglas Gregor3f9a0562009-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 Gregor2f1bc522008-11-07 20:08:42 +00004243 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004244 goto PastIdentifier;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00004245 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004246 } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004247 assert(!getLangOpts().CPlusPlus &&
Argyrios Kyrtzidis314fe782008-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 Gregor3f9a0562009-11-03 01:35:08 +00004252 goto PastIdentifier;
4253 }
Richard Smith9988f282012-03-29 01:16:42 +00004254
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004255 if (Tok.is(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004256 // direct-declarator: '(' declarator ')'
4257 // direct-declarator: '(' attributes declarator ')'
4258 // Example: 'char (*X)' or 'int (*XX)(void)'
4259 ParseParenDeclarator(D);
Douglas Gregor0efc2c12010-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 Jahanian46877cd2010-08-17 23:50:37 +00004265 // If there was an error parsing parenthesized declarator, declarator
Richard Smith9988f282012-03-29 01:16:42 +00004266 // scope may have been entered before. Don't do it again.
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004267 if (!D.isInvalidType() &&
4268 Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
Douglas Gregor0efc2c12010-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 Jahanian46877cd2010-08-17 23:50:37 +00004271 DeclScopeObj.EnterDeclaratorScope();
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004272 }
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004273 } else if (D.mayOmitIdentifier()) {
Reid Spencer5f016e22007-07-11 17:01:13 +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 Blaikiee75d9cf2012-06-29 22:03:56 +00004278 if (Tok.getKind() == tok::annot_pragma_parser_crash)
4279 *(volatile int*) 0x11 = 0;
Douglas Gregore950d4b2009-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 Blaikie4e4d0842012-03-11 07:00:24 +00004283 else if (getLangOpts().CPlusPlus)
4284 Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004285 else
Chris Lattner1ab3b962008-11-18 07:48:38 +00004286 Diag(Tok, diag::err_expected_ident_lparen);
Reid Spencer5f016e22007-07-11 17:01:13 +00004287 D.SetIdentifier(0, Tok.getLocation());
Chris Lattner1f6f54b2008-11-11 06:13:16 +00004288 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00004289 }
Mike Stump1eb44332009-09-09 15:08:12 +00004290
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004291 PastIdentifier:
Reid Spencer5f016e22007-07-11 17:01:13 +00004292 assert(D.isPastIdentifier() &&
4293 "Haven't past the location of the identifier yet?");
Mike Stump1eb44332009-09-09 15:08:12 +00004294
Richard Smith6ee326a2012-04-10 01:32:12 +00004295 // Don't parse attributes unless we have parsed an unparenthesized name.
4296 if (D.hasName() && !D.getNumTypeObjects())
John McCall7f040a92010-12-24 02:08:15 +00004297 MaybeParseCXX0XAttributes(D);
Sean Huntbbd37c62009-11-21 08:43:09 +00004298
Reid Spencer5f016e22007-07-11 17:01:13 +00004299 while (1) {
Chris Lattner04d66662007-10-09 17:33:22 +00004300 if (Tok.is(tok::l_paren)) {
David Blaikie42d6d0c2011-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 Kyrtzidis73a0d882008-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 Smithb9c62612012-07-30 21:30:52 +00004308 bool IsAmbiguous = false;
4309 if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit() &&
4310 !isCXXFunctionDeclarator(&IsAmbiguous))
4311 break;
John McCall0b7e6782011-03-24 11:26:52 +00004312 ParsedAttributes attrs(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004313 BalancedDelimiterTracker T(*this, tok::l_paren);
4314 T.consumeOpen();
Richard Smithb9c62612012-07-30 21:30:52 +00004315 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004316 PrototypeScope.Exit();
Chris Lattner04d66662007-10-09 17:33:22 +00004317 } else if (Tok.is(tok::l_square)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004318 ParseBracketDeclarator(D);
4319 } else {
4320 break;
4321 }
4322 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004323}
Reid Spencer5f016e22007-07-11 17:01:13 +00004324
Chris Lattneref4715c2008-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 Stump1eb44332009-09-09 15:08:12 +00004327/// parens for precedence. If we find that these are actually function
Chris Lattneref4715c2008-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 Lattner7399ee02008-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 Lattneref4715c2008-04-06 05:45:57 +00004337///
4338void Parser::ParseParenDeclarator(Declarator &D) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004339 BalancedDelimiterTracker T(*this, tok::l_paren);
4340 T.consumeOpen();
4341
Chris Lattneref4715c2008-04-06 05:45:57 +00004342 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00004343
Chris Lattner7399ee02008-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 McCall0b7e6782011-03-24 11:26:52 +00004354 ParsedAttributes attrs(AttrFactory);
Chris Lattner7399ee02008-10-20 02:05:46 +00004355 bool RequiresArg = false;
4356 if (Tok.is(tok::kw___attribute)) {
John McCall7f040a92010-12-24 02:08:15 +00004357 ParseGNUAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004358
Chris Lattner7399ee02008-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 Naroff239f0732008-12-25 14:16:32 +00004363 // Eat any Microsoft extensions.
Eli Friedman290eeb02009-06-08 23:27:34 +00004364 if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004365 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004366 Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64) ||
Francois Pichet58fd97a2011-08-25 00:36:46 +00004367 Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) {
John McCall7f040a92010-12-24 02:08:15 +00004368 ParseMicrosoftTypeAttributes(attrs);
Eli Friedman290eeb02009-06-08 23:27:34 +00004369 }
Dawn Perchik52fc3142010-09-03 01:29:35 +00004370 // Eat any Borland extensions.
Ted Kremenek8113ecf2010-11-10 05:59:39 +00004371 if (Tok.is(tok::kw___pascal))
John McCall7f040a92010-12-24 02:08:15 +00004372 ParseBorlandTypeAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004373
Chris Lattneref4715c2008-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 Stump1eb44332009-09-09 15:08:12 +00004379
Chris Lattneref4715c2008-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 Smith22592862012-03-27 23:05:05 +00004385 (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
4386 NextToken().is(tok::r_paren)) || // C++ int(...)
Richard Smith6ce48a72012-04-11 04:01:28 +00004387 isDeclarationSpecifier() || // 'int(int)' is a function.
4388 isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function.
Chris Lattneref4715c2008-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 Stump1eb44332009-09-09 15:08:12 +00004396
Chris Lattneref4715c2008-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 Smith9988f282012-03-29 01:16:42 +00004401 SourceLocation EllipsisLoc = D.getEllipsisLoc();
4402 D.setEllipsisLoc(SourceLocation());
4403
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00004404 bool hadGroupingParens = D.hasGroupingParens();
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00004405 D.setGroupingParens(true);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004406 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattneref4715c2008-04-06 05:45:57 +00004407 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004408 T.consumeClose();
Chad Rosier8decdee2012-06-26 22:30:43 +00004409 D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004410 T.getCloseLocation()),
4411 attrs, T.getCloseLocation());
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00004412
4413 D.setGroupingParens(hadGroupingParens);
Richard Smith9988f282012-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 Lattneref4715c2008-04-06 05:45:57 +00004419 return;
4420 }
Mike Stump1eb44332009-09-09 15:08:12 +00004421
Chris Lattneref4715c2008-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 Lattner7399ee02008-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 Lattneref4715c2008-04-06 05:45:57 +00004426 D.SetIdentifier(0, Tok.getLocation());
4427
David Blaikie42d6d0c2011-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 Smithb9c62612012-07-30 21:30:52 +00004432 ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004433 PrototypeScope.Exit();
Chris Lattneref4715c2008-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.
Reid Spencer5f016e22007-07-11 17:01:13 +00004439///
Richard Smith6ee326a2012-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 Lattner7399ee02008-10-20 02:05:46 +00004443///
Richard Smith6ee326a2012-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 Gregor3fd1ba02011-07-05 16:44:18 +00004446///
Richard Smith6ee326a2012-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 Gregor3fd1ba02011-07-05 16:44:18 +00004452/// dynamic-exception-specification
4453/// noexcept-specification
4454///
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004455void Parser::ParseFunctionDeclarator(Declarator &D,
Richard Smith6ee326a2012-04-10 01:32:12 +00004456 ParsedAttributes &FirstArgAttrs,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004457 BalancedDelimiterTracker &Tracker,
Richard Smithb9c62612012-07-30 21:30:52 +00004458 bool IsAmbiguous,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004459 bool RequiresArg) {
Chad Rosier8decdee2012-06-26 22:30:43 +00004460 assert(getCurScope()->isFunctionPrototypeScope() &&
David Blaikie42d6d0c2011-12-04 05:04:18 +00004461 "Should call from a Function scope");
Douglas Gregor3fd1ba02011-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 Lattner5f9e2722011-07-23 10:55:15 +00004469 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Douglas Gregor3fd1ba02011-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 Gregor43f51032011-10-19 06:04:55 +00004476 SourceLocation ConstQualifierLoc;
4477 SourceLocation VolatileQualifierLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004478 ExceptionSpecificationType ESpecType = EST_None;
4479 SourceRange ESpecRange;
Chris Lattner5f9e2722011-07-23 10:55:15 +00004480 SmallVector<ParsedType, 2> DynamicExceptions;
4481 SmallVector<SourceRange, 2> DynamicExceptionRanges;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004482 ExprResult NoexceptExpr;
Richard Smith6ee326a2012-04-10 01:32:12 +00004483 ParsedAttributes FnAttrs(AttrFactory);
Richard Smith54655be2012-06-12 01:51:59 +00004484 TypeResult TrailingReturnType;
Richard Smith6ee326a2012-04-10 01:32:12 +00004485
James Molloy16f1f712012-02-29 10:24:19 +00004486 Actions.ActOnStartFunctionDeclarator();
4487
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004488 SourceLocation EndLoc;
Douglas Gregor3fd1ba02011-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 Gregor4a8dfb52011-10-12 16:37:45 +00004495 Tracker.consumeClose();
4496 EndLoc = Tracker.getCloseLocation();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004497 } else {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004498 if (Tok.isNot(tok::r_paren))
Richard Smith6ee326a2012-04-10 01:32:12 +00004499 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004500 else if (RequiresArg)
4501 Diag(Tok, diag::err_argument_required_after_attribute);
4502
David Blaikie4e4d0842012-03-11 07:00:24 +00004503 HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004504
4505 // If we have the closing ')', eat it.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004506 Tracker.consumeClose();
4507 EndLoc = Tracker.getCloseLocation();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004508
David Blaikie4e4d0842012-03-11 07:00:24 +00004509 if (getLangOpts().CPlusPlus) {
Richard Smith6ee326a2012-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 Gregor3fd1ba02011-07-05 16:44:18 +00004513
4514 // Parse cv-qualifier-seq[opt].
Richard Smith6ee326a2012-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 Gregor3fd1ba02011-07-05 16:44:18 +00004521
4522 // Parse ref-qualifier[opt].
4523 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004524 Diag(Tok, getLangOpts().CPlusPlus0x ?
Richard Smith7fe62082011-10-15 05:09:34 +00004525 diag::warn_cxx98_compat_ref_qualifier :
4526 diag::ext_ref_qualifier);
Richard Smith6ee326a2012-04-10 01:32:12 +00004527
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004528 RefQualifierIsLValueRef = Tok.is(tok::amp);
4529 RefQualifierLoc = ConsumeToken();
4530 EndLoc = RefQualifierLoc;
4531 }
4532
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004533 // C++11 [expr.prim.general]p3:
Chad Rosier8decdee2012-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 Gregorcefc3af2012-04-16 07:05:22 +00004536 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
Chad Rosier8decdee2012-06-26 22:30:43 +00004537 // and the end of the function-definition, member-declarator, or
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004538 // declarator.
Chad Rosier8decdee2012-06-26 22:30:43 +00004539 bool IsCXX11MemberFunction =
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004540 getLangOpts().CPlusPlus0x &&
4541 (D.getContext() == Declarator::MemberContext ||
4542 (D.getContext() == Declarator::FileContext &&
Chad Rosier8decdee2012-06-26 22:30:43 +00004543 D.getCXXScopeSpec().isValid() &&
Douglas Gregorcefc3af2012-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 Smitha058fd42012-05-02 22:22:32 +00004549
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004550 // Parse exception-specification[opt].
Richard Smitha058fd42012-05-02 22:22:32 +00004551 ESpecType = tryParseExceptionSpecification(ESpecRange,
Douglas Gregor74e2fc32012-04-16 18:27:27 +00004552 DynamicExceptions,
4553 DynamicExceptionRanges,
Richard Smitha058fd42012-05-02 22:22:32 +00004554 NoexceptExpr);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004555 if (ESpecType != EST_None)
4556 EndLoc = ESpecRange.getEnd();
4557
Richard Smith6ee326a2012-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 Gregor3fd1ba02011-07-05 16:44:18 +00004562 // Parse trailing-return-type[opt].
David Blaikie4e4d0842012-03-11 07:00:24 +00004563 if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) {
Richard Smith7fe62082011-10-15 05:09:34 +00004564 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
Douglas Gregorae7902c2011-08-04 15:30:47 +00004565 SourceRange Range;
Richard Smith54655be2012-06-12 01:51:59 +00004566 TrailingReturnType = ParseTrailingReturnType(Range);
Douglas Gregorae7902c2011-08-04 15:30:47 +00004567 if (Range.getEnd().isValid())
4568 EndLoc = Range.getEnd();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004569 }
4570 }
Douglas Gregor3fd1ba02011-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 Smithb9c62612012-07-30 21:30:52 +00004576 IsAmbiguous, EllipsisLoc,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004577 ParamInfo.data(), ParamInfo.size(),
4578 DS.getTypeQualifiers(),
4579 RefQualifierIsLValueRef,
Douglas Gregor43f51032011-10-19 06:04:55 +00004580 RefQualifierLoc, ConstQualifierLoc,
4581 VolatileQualifierLoc,
Douglas Gregor90ebed02011-07-13 21:47:47 +00004582 /*MutableLoc=*/SourceLocation(),
Douglas Gregor3fd1ba02011-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 Rosier8decdee2012-06-26 22:30:43 +00004589 Tracker.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004590 EndLoc, D,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004591 TrailingReturnType),
Richard Smith6ee326a2012-04-10 01:32:12 +00004592 FnAttrs, EndLoc);
James Molloy16f1f712012-02-29 10:24:19 +00004593
4594 Actions.ActOnEndFunctionDeclarator();
Douglas Gregor3fd1ba02011-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 Blaikie4e4d0842012-03-11 07:00:24 +00004603 return !getLangOpts().CPlusPlus
Douglas Gregor3fd1ba02011-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 Lattner5f9e2722011-07-23 10:55:15 +00004635 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) {
Douglas Gregor3fd1ba02011-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 Smith6ce48a72012-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 Gregor3fd1ba02011-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///
Reid Spencer5f016e22007-07-11 17:01:13 +00004693/// parameter-type-list: [C99 6.7.5]
4694/// parameter-list
4695/// parameter-list ',' '...'
Douglas Gregored5d6512009-09-22 21:41:40 +00004696/// [C++] parameter-list '...'
Reid Spencer5f016e22007-07-11 17:01:13 +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 Lattner04421082008-04-08 04:40:51 +00004704/// [C++] declaration-specifiers declarator '=' assignment-expression
Sebastian Redl84407ba2012-03-14 15:54:00 +00004705/// [C++11] initializer-clause
Reid Spencer5f016e22007-07-11 17:01:13 +00004706/// [GNU] declaration-specifiers declarator attributes
Sebastian Redl50de12f2009-03-24 22:27:57 +00004707/// declaration-specifiers abstract-declarator[opt]
4708/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner8123a952008-04-10 02:22:51 +00004709/// '=' assignment-expression
Reid Spencer5f016e22007-07-11 17:01:13 +00004710/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
Richard Smith6ce48a72012-04-11 04:01:28 +00004711/// [C++11] attribute-specifier-seq parameter-declaration
Reid Spencer5f016e22007-07-11 17:01:13 +00004712///
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004713void Parser::ParseParameterDeclarationClause(
4714 Declarator &D,
Richard Smith6ce48a72012-04-11 04:01:28 +00004715 ParsedAttributes &FirstArgAttrs,
Chris Lattner5f9e2722011-07-23 10:55:15 +00004716 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004717 SourceLocation &EllipsisLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00004718
Chris Lattnerf97409f2008-04-06 06:57:35 +00004719 while (1) {
4720 if (Tok.is(tok::ellipsis)) {
Richard Smith6ce48a72012-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 Gregor965acbb2009-02-18 07:07:28 +00004723 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattnerf97409f2008-04-06 06:57:35 +00004724 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00004725 }
Mike Stump1eb44332009-09-09 15:08:12 +00004726
Chris Lattnerf97409f2008-04-06 06:57:35 +00004727 // Parse the declaration-specifiers.
John McCall54abf7d2009-11-04 02:18:39 +00004728 // Just use the ParsingDeclaration "scope" of the declarator.
John McCall0b7e6782011-03-24 11:26:52 +00004729 DeclSpec DS(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004730
Richard Smith6ce48a72012-04-11 04:01:28 +00004731 // Parse any C++11 attributes.
4732 MaybeParseCXX0XAttributes(DS.getAttributes());
4733
John McCall7f040a92010-12-24 02:08:15 +00004734 // Skip any Microsoft attributes before a param.
David Blaikie4e4d0842012-03-11 07:00:24 +00004735 if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
John McCall7f040a92010-12-24 02:08:15 +00004736 ParseMicrosoftAttributes(DS.getAttributes());
4737
4738 SourceLocation DSStart = Tok.getLocation();
Chris Lattner7399ee02008-10-20 02:05:46 +00004739
4740 // If the caller parsed attributes for the first argument, add them now.
John McCall7f040a92010-12-24 02:08:15 +00004741 // Take them so that we only apply the attributes to the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004742 // FIXME: If we can leave the attributes in the token stream somehow, we can
Richard Smith6ce48a72012-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 McCall7f040a92010-12-24 02:08:15 +00004746
Chris Lattnere64c5492009-02-27 18:38:20 +00004747 ParseDeclarationSpecifiers(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00004748
Chris Lattnerf97409f2008-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 McCall7f040a92010-12-24 02:08:15 +00004755 MaybeParseGNUAttributes(ParmDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00004756
Chris Lattnerf97409f2008-04-06 06:57:35 +00004757 // Remember this parsed parameter in ParamInfo.
4758 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
Mike Stump1eb44332009-09-09 15:08:12 +00004759
Douglas Gregor72b505b2008-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 Lattnerf97409f2008-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 Lattnere64c5492009-02-27 18:38:20 +00004766 if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
4767 ParmDecl.getNumTypeObjects() == 0) {
Chris Lattnerf97409f2008-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 Stump1eb44332009-09-09 15:08:12 +00004773
Chris Lattnerf97409f2008-04-06 06:57:35 +00004774 // Inform the actions module about the parameter declarator, so it gets
4775 // added to the current scope.
John McCalld226f652010-08-21 09:40:31 +00004776 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
Chris Lattner04421082008-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 Gregor61366e92008-12-24 00:01:03 +00004783 SourceLocation EqualLoc = Tok.getLocation();
4784
Chris Lattner04421082008-04-08 04:40:51 +00004785 // Parse the default argument
Douglas Gregor72b505b2008-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 Gregor72b505b2008-12-16 21:30:33 +00004790 // FIXME: Can we use a smart pointer for Toks?
4791 DefArgToks = new CachedTokens;
4792
Mike Stump1eb44332009-09-09 15:08:12 +00004793 if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
Argyrios Kyrtzidis14b91622010-04-23 21:20:12 +00004794 /*StopAtSemi=*/true,
4795 /*ConsumeFinalToken=*/false)) {
Douglas Gregor72b505b2008-12-16 21:30:33 +00004796 delete DefArgToks;
4797 DefArgToks = 0;
Douglas Gregor61366e92008-12-24 00:01:03 +00004798 Actions.ActOnParamDefaultArgumentError(Param);
Argyrios Kyrtzidis2b602ad2010-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 Stump1eb44332009-09-09 15:08:12 +00004807 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
Anders Carlsson5e300d12009-06-12 16:51:40 +00004808 (*DefArgToks)[1].getLocation());
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00004809 }
Chris Lattner04421082008-04-08 04:40:51 +00004810 } else {
Douglas Gregor72b505b2008-12-16 21:30:33 +00004811 // Consume the '='.
Douglas Gregor61366e92008-12-24 00:01:03 +00004812 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00004813
Chad Rosier8decdee2012-06-26 22:30:43 +00004814 // The argument isn't actually potentially evaluated unless it is
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00004815 // used.
4816 EnterExpressionEvaluationContext Eval(Actions,
Douglas Gregorccc1b5e2012-02-21 00:37:24 +00004817 Sema::PotentiallyEvaluatedIfUsed,
4818 Param);
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00004819
Sebastian Redl84407ba2012-03-14 15:54:00 +00004820 ExprResult DefArgResult;
Sebastian Redl3e280b52012-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 Redl84407ba2012-03-14 15:54:00 +00004823 DefArgResult = ParseBraceInitializer();
Sebastian Redl3e280b52012-03-18 22:25:45 +00004824 } else
Sebastian Redl84407ba2012-03-14 15:54:00 +00004825 DefArgResult = ParseAssignmentExpression();
Douglas Gregor72b505b2008-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 McCall9ae2f072010-08-23 23:25:46 +00004832 DefArgResult.take());
Douglas Gregor72b505b2008-12-16 21:30:33 +00004833 }
Chris Lattner04421082008-04-08 04:40:51 +00004834 }
4835 }
Mike Stump1eb44332009-09-09 15:08:12 +00004836
4837 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4838 ParmDecl.getIdentifierLoc(), Param,
Douglas Gregor72b505b2008-12-16 21:30:33 +00004839 DefArgToks));
Chris Lattnerf97409f2008-04-06 06:57:35 +00004840 }
4841
4842 // If the next token is a comma, consume it and keep reading arguments.
Douglas Gregored5d6512009-09-22 21:41:40 +00004843 if (Tok.isNot(tok::comma)) {
4844 if (Tok.is(tok::ellipsis)) {
Douglas Gregored5d6512009-09-22 21:41:40 +00004845 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chad Rosier8decdee2012-06-26 22:30:43 +00004846
David Blaikie4e4d0842012-03-11 07:00:24 +00004847 if (!getLangOpts().CPlusPlus) {
Douglas Gregored5d6512009-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 Gregor849b2432010-03-31 17:46:05 +00004851 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
Douglas Gregored5d6512009-09-22 21:41:40 +00004852 }
4853 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004854
Douglas Gregored5d6512009-09-22 21:41:40 +00004855 break;
4856 }
Mike Stump1eb44332009-09-09 15:08:12 +00004857
Chris Lattnerf97409f2008-04-06 06:57:35 +00004858 // Consume the comma.
4859 ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00004860 }
Mike Stump1eb44332009-09-09 15:08:12 +00004861
Chris Lattner66d28652008-04-06 06:34:08 +00004862}
Chris Lattneref4715c2008-04-06 05:45:57 +00004863
Reid Spencer5f016e22007-07-11 17:01:13 +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 Smith6ee326a2012-04-10 01:32:12 +00004869/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4870/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00004871void Parser::ParseBracketDeclarator(Declarator &D) {
Richard Smith6ee326a2012-04-10 01:32:12 +00004872 if (CheckProhibitedCXX11Attribute())
4873 return;
4874
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004875 BalancedDelimiterTracker T(*this, tok::l_square);
4876 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00004877
Chris Lattner378c7e42008-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 Gregor4a8dfb52011-10-12 16:37:45 +00004881 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00004882 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004883 MaybeParseCXX0XAttributes(attrs);
Chad Rosier8decdee2012-06-26 22:30:43 +00004884
Chris Lattner378c7e42008-12-18 07:27:21 +00004885 // Remember that we parsed the empty array type.
John McCall60d7b3a2010-08-24 06:29:42 +00004886 ExprResult NumElements;
John McCall0b7e6782011-03-24 11:26:52 +00004887 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004888 T.getOpenLocation(),
4889 T.getCloseLocation()),
4890 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-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 Smith36f5cfe2012-03-09 08:00:36 +00004895 ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
Chris Lattner378c7e42008-12-18 07:27:21 +00004896 ConsumeToken();
4897
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004898 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00004899 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004900 MaybeParseCXX0XAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004901
Chris Lattner378c7e42008-12-18 07:27:21 +00004902 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00004903 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
John McCall7f040a92010-12-24 02:08:15 +00004904 ExprRes.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004905 T.getOpenLocation(),
4906 T.getCloseLocation()),
4907 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00004908 return;
4909 }
Mike Stump1eb44332009-09-09 15:08:12 +00004910
Reid Spencer5f016e22007-07-11 17:01:13 +00004911 // If valid, this location is the position where we read the 'static' keyword.
4912 SourceLocation StaticLoc;
Chris Lattner04d66662007-10-09 17:33:22 +00004913 if (Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00004914 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00004915
Reid Spencer5f016e22007-07-11 17:01:13 +00004916 // If there is a type-qualifier-list, read it now.
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004917 // Type qualifiers in an array subscript are a C99 feature.
John McCall0b7e6782011-03-24 11:26:52 +00004918 DeclSpec DS(AttrFactory);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004919 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Mike Stump1eb44332009-09-09 15:08:12 +00004920
Reid Spencer5f016e22007-07-11 17:01:13 +00004921 // If we haven't already read 'static', check to see if there is one after the
4922 // type-qualifier-list.
Chris Lattner04d66662007-10-09 17:33:22 +00004923 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00004924 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00004925
Reid Spencer5f016e22007-07-11 17:01:13 +00004926 // Handle "direct-declarator [ type-qual-list[opt] * ]".
4927 bool isStar = false;
John McCall60d7b3a2010-08-24 06:29:42 +00004928 ExprResult NumElements;
Mike Stump1eb44332009-09-09 15:08:12 +00004929
Chris Lattner5dcc6ce2008-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 Ledrubed28ac2012-07-23 08:59:39 +00004932 // the token after the star is a ']'. Since stars in arrays are
Chris Lattner5dcc6ce2008-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 Lattnera711dd02008-04-06 05:27:21 +00004935 ConsumeToken(); // Eat the '*'.
Reid Spencer5f016e22007-07-11 17:01:13 +00004936
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004937 if (StaticLoc.isValid()) {
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00004938 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004939 StaticLoc = SourceLocation(); // Drop the static.
4940 }
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00004941 isStar = true;
Chris Lattner04d66662007-10-09 17:33:22 +00004942 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner378c7e42008-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 Stump1eb44332009-09-09 15:08:12 +00004947
Douglas Gregore0762c92009-06-19 23:52:42 +00004948 // Parse the constant-expression or assignment-expression now (depending
4949 // on dialect).
David Blaikie4e4d0842012-03-11 07:00:24 +00004950 if (getLangOpts().CPlusPlus) {
Douglas Gregore0762c92009-06-19 23:52:42 +00004951 NumElements = ParseConstantExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00004952 } else {
4953 EnterExpressionEvaluationContext Unevaluated(Actions,
4954 Sema::ConstantEvaluated);
Douglas Gregore0762c92009-06-19 23:52:42 +00004955 NumElements = ParseAssignmentExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00004956 }
Reid Spencer5f016e22007-07-11 17:01:13 +00004957 }
Mike Stump1eb44332009-09-09 15:08:12 +00004958
Reid Spencer5f016e22007-07-11 17:01:13 +00004959 // If there was an error parsing the assignment-expression, recover.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00004960 if (NumElements.isInvalid()) {
Chris Lattner5cb10d32009-04-24 22:30:50 +00004961 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00004962 // If the expression was invalid, skip it.
4963 SkipUntil(tok::r_square);
4964 return;
4965 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00004966
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004967 T.consumeClose();
Sebastian Redlab197ba2009-02-09 18:23:29 +00004968
John McCall0b7e6782011-03-24 11:26:52 +00004969 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004970 MaybeParseCXX0XAttributes(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00004971
Chris Lattner378c7e42008-12-18 07:27:21 +00004972 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00004973 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
Reid Spencer5f016e22007-07-11 17:01:13 +00004974 StaticLoc.isValid(), isStar,
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00004975 NumElements.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004976 T.getOpenLocation(),
4977 T.getCloseLocation()),
4978 attrs, T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004979}
4980
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00004981/// [GNU] typeof-specifier:
4982/// typeof ( expressions )
4983/// typeof ( type-name )
4984/// [GNU/C++] typeof unary-expression
Steve Naroffd1861fd2007-07-31 12:34:36 +00004985///
4986void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner04d66662007-10-09 17:33:22 +00004987 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00004988 Token OpTok = Tok;
Steve Naroffd1861fd2007-07-31 12:34:36 +00004989 SourceLocation StartLoc = ConsumeToken();
4990
John McCallcfb708c2010-01-13 20:03:27 +00004991 const bool hasParens = Tok.is(tok::l_paren);
4992
Eli Friedman71b8fb52012-01-21 01:01:51 +00004993 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
4994
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00004995 bool isCastExpr;
John McCallb3d87482010-08-24 05:47:05 +00004996 ParsedType CastTy;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00004997 SourceRange CastRange;
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00004998 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
4999 CastTy, CastRange);
John McCallcfb708c2010-01-13 20:03:27 +00005000 if (hasParens)
5001 DS.setTypeofParensRange(CastRange);
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005002
5003 if (CastRange.getEnd().isInvalid())
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005004 // FIXME: Not accurate, the range gets one token more than it should.
5005 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005006 else
5007 DS.SetRangeEnd(CastRange.getEnd());
Mike Stump1eb44332009-09-09 15:08:12 +00005008
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005009 if (isCastExpr) {
5010 if (!CastTy) {
5011 DS.SetTypeSpecError();
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005012 return;
Douglas Gregor809070a2009-02-18 17:45:20 +00005013 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005014
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005015 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005016 unsigned DiagID;
Argyrios Kyrtzidis5ab06402009-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 McCallfec54012009-08-03 20:12:06 +00005019 DiagID, CastTy))
5020 Diag(StartLoc, DiagID) << PrevSpec;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005021 return;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005022 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005023
Argyrios Kyrtzidis64096252009-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 Naroff9dfa7b42007-08-02 02:53:48 +00005027 return;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005028 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005029
Eli Friedman71b8fb52012-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 Kyrtzidis64096252009-05-22 10:22:18 +00005037 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005038 unsigned DiagID;
Argyrios Kyrtzidis64096252009-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 McCallb3d87482010-08-24 05:47:05 +00005041 DiagID, Operand.get()))
John McCallfec54012009-08-03 20:12:06 +00005042 Diag(StartLoc, DiagID) << PrevSpec;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005043}
Chris Lattner1b492422010-02-28 18:33:55 +00005044
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00005045/// [C11] atomic-specifier:
Eli Friedmanb001de72011-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 Gregor4a8dfb52011-10-12 16:37:45 +00005052 BalancedDelimiterTracker T(*this, tok::l_paren);
5053 if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) {
Eli Friedmanb001de72011-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 Gregor4a8dfb52011-10-12 16:37:45 +00005065 T.consumeClose();
Eli Friedmanb001de72011-10-06 23:00:33 +00005066
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005067 if (T.getCloseLocation().isInvalid())
Eli Friedmanb001de72011-10-06 23:00:33 +00005068 return;
5069
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005070 DS.setTypeofParensRange(T.getRange());
5071 DS.SetRangeEnd(T.getCloseLocation());
Eli Friedmanb001de72011-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 Lattner1b492422010-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 Gregora8f031f2010-06-16 15:28:57 +00005137 } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
Chris Lattner1b492422010-02-28 18:33:55 +00005138 DS.isTypeAltiVecVector()) {
5139 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5140 return true;
5141 }
5142 return false;
5143}