blob: 05d44a5af0ca15e340f2b84b7f4a5b6f52e306d2 [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 Hutchins2287c5e2012-03-02 22:12:59 +0000869 LAs[i]->addDecl(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000870 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
Benjamin Kramerd306cf72012-04-14 12:44:47 +0000871 delete LAs[i];
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000872 }
873 LAs.clear();
874}
875
876
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000877/// \brief Finish parsing an attribute for which parsing was delayed.
878/// This will be called at the end of parsing a class declaration
879/// for each LateParsedAttribute. We consume the saved tokens and
Chad Rosier8decdee2012-06-26 22:30:43 +0000880/// create an attribute with the arguments filled in. We add this
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000881/// to the Attribute list for the decl.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000882void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
883 bool EnterScope, bool OnDefinition) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000884 // Save the current token position.
885 SourceLocation OrigLoc = Tok.getLocation();
886
887 // Append the current token at the end of the new token stream so that it
888 // doesn't get lost.
889 LA.Toks.push_back(Tok);
890 PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
891 // Consume the previously pushed token.
892 ConsumeAnyToken();
893
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000894 if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
895 Diag(Tok, diag::warn_attribute_on_function_definition)
896 << LA.AttrName.getName();
897 }
898
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000899 ParsedAttributes Attrs(AttrFactory);
900 SourceLocation endLoc;
901
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000902 if (LA.Decls.size() == 1) {
903 Decl *D = LA.Decls[0];
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000904
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000905 // If the Decl is templatized, add template parameters to scope.
906 bool HasTemplateScope = EnterScope && D->isTemplateDecl();
907 ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
908 if (HasTemplateScope)
909 Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000910
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000911 // If the Decl is on a function, add function parameters to the scope.
912 bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate();
913 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope);
914 if (HasFunctionScope)
915 Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
916
917 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
918
919 if (HasFunctionScope) {
920 Actions.ActOnExitFunctionContext();
921 FnScope.Exit(); // Pop scope, and remove Decls from IdResolver
922 }
923 if (HasTemplateScope) {
924 TempScope.Exit();
925 }
DeLesley Hutchins7ec419a2012-03-02 22:29:50 +0000926 } else if (LA.Decls.size() > 0) {
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000927 // If there are multiple decls, then the decl cannot be within the
928 // function scope.
929 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
DeLesley Hutchins7ec419a2012-03-02 22:29:50 +0000930 } else {
931 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000932 }
933
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000934 for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
935 Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
936 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000937
938 if (Tok.getLocation() != OrigLoc) {
939 // Due to a parsing error, we either went over the cached tokens or
940 // there are still cached tokens left, so we skip the leftover tokens.
941 // Since this is an uncommon situation that should be avoided, use the
942 // expensive isBeforeInTranslationUnit call.
943 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
944 OrigLoc))
945 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
Douglas Gregord78ef5b2012-03-08 01:00:17 +0000946 ConsumeAnyToken();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000947 }
948}
949
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000950/// \brief Wrapper around a case statement checking if AttrName is
951/// one of the thread safety attributes
952bool Parser::IsThreadSafetyAttribute(llvm::StringRef AttrName){
953 return llvm::StringSwitch<bool>(AttrName)
954 .Case("guarded_by", true)
955 .Case("guarded_var", true)
956 .Case("pt_guarded_by", true)
957 .Case("pt_guarded_var", true)
958 .Case("lockable", true)
959 .Case("scoped_lockable", true)
960 .Case("no_thread_safety_analysis", true)
961 .Case("acquired_after", true)
962 .Case("acquired_before", true)
963 .Case("exclusive_lock_function", true)
964 .Case("shared_lock_function", true)
965 .Case("exclusive_trylock_function", true)
966 .Case("shared_trylock_function", true)
967 .Case("unlock_function", true)
968 .Case("lock_returned", true)
969 .Case("locks_excluded", true)
970 .Case("exclusive_locks_required", true)
971 .Case("shared_locks_required", true)
972 .Default(false);
973}
974
975/// \brief Parse the contents of thread safety attributes. These
976/// should always be parsed as an expression list.
977///
978/// We need to special case the parsing due to the fact that if the first token
979/// of the first argument is an identifier, the main parse loop will store
980/// that token as a "parameter" and the rest of
981/// the arguments will be added to a list of "arguments". However,
982/// subsequent tokens in the first argument are lost. We instead parse each
983/// argument as an expression and add all arguments to the list of "arguments".
984/// In future, we will take advantage of this special case to also
985/// deal with some argument scoping issues here (for example, referring to a
986/// function parameter in the attribute on that function).
987void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
988 SourceLocation AttrNameLoc,
989 ParsedAttributes &Attrs,
990 SourceLocation *EndLoc) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000991 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000992
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000993 BalancedDelimiterTracker T(*this, tok::l_paren);
994 T.consumeOpen();
Chad Rosier8decdee2012-06-26 22:30:43 +0000995
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000996 ExprVector ArgExprs(Actions);
997 bool ArgExprsOk = true;
Chad Rosier8decdee2012-06-26 22:30:43 +0000998
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000999 // now parse the list of expressions
DeLesley Hutchins4805f152011-12-14 19:36:06 +00001000 while (Tok.isNot(tok::r_paren)) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001001 ExprResult ArgExpr(ParseAssignmentExpression());
1002 if (ArgExpr.isInvalid()) {
1003 ArgExprsOk = false;
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001004 T.consumeClose();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001005 break;
1006 } else {
1007 ArgExprs.push_back(ArgExpr.release());
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001008 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001009 if (Tok.isNot(tok::comma))
1010 break;
1011 ConsumeToken(); // Eat the comma, move to the next argument
1012 }
1013 // Match the ')'.
DeLesley Hutchins23323e02012-01-20 22:50:54 +00001014 if (ArgExprsOk && !T.consumeClose()) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001015 Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Sean Hunt93f95f22012-06-18 16:13:52 +00001016 ArgExprs.take(), ArgExprs.size(), AttributeList::AS_GNU);
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001017 }
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001018 if (EndLoc)
1019 *EndLoc = T.getCloseLocation();
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001020}
1021
Richard Smith6ee326a2012-04-10 01:32:12 +00001022/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
1023/// of a C++11 attribute-specifier in a location where an attribute is not
1024/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
1025/// situation.
1026///
1027/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
1028/// this doesn't appear to actually be an attribute-specifier, and the caller
1029/// should try to parse it.
1030bool Parser::DiagnoseProhibitedCXX11Attribute() {
1031 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1032
1033 switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1034 case CAK_NotAttributeSpecifier:
1035 // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1036 return false;
1037
1038 case CAK_InvalidAttributeSpecifier:
1039 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1040 return false;
1041
1042 case CAK_AttributeSpecifier:
1043 // Parse and discard the attributes.
1044 SourceLocation BeginLoc = ConsumeBracket();
1045 ConsumeBracket();
1046 SkipUntil(tok::r_square, /*StopAtSemi*/ false);
1047 assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1048 SourceLocation EndLoc = ConsumeBracket();
1049 Diag(BeginLoc, diag::err_attributes_not_allowed)
1050 << SourceRange(BeginLoc, EndLoc);
1051 return true;
1052 }
Chandler Carruth2c6dbd72012-04-10 16:03:08 +00001053 llvm_unreachable("All cases handled above.");
Richard Smith6ee326a2012-04-10 01:32:12 +00001054}
1055
John McCall7f040a92010-12-24 02:08:15 +00001056void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1057 Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1058 << attrs.Range;
Dawn Perchik52fc3142010-09-03 01:29:35 +00001059}
1060
Reid Spencer5f016e22007-07-11 17:01:13 +00001061/// ParseDeclaration - Parse a full 'declaration', which consists of
1062/// declaration-specifiers, some number of declarators, and a semicolon.
Chris Lattner97144fc2009-04-02 04:16:50 +00001063/// 'Context' should be a Declarator::TheContext value. This returns the
1064/// location of the semicolon in DeclEnd.
Chris Lattner8f08cb72007-08-25 06:57:03 +00001065///
1066/// declaration: [C99 6.7]
1067/// block-declaration ->
1068/// simple-declaration
1069/// others [FIXME]
Douglas Gregoradcac882008-12-01 23:54:00 +00001070/// [C++] template-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001071/// [C++] namespace-definition
Douglas Gregorf780abc2008-12-30 03:27:21 +00001072/// [C++] using-directive
Douglas Gregord7f37bf2009-06-22 23:06:13 +00001073/// [C++] using-declaration
Richard Smith534986f2012-04-14 00:33:13 +00001074/// [C++11/C11] static_assert-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001075/// others... [FIXME]
1076///
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001077Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1078 unsigned Context,
Sean Huntbbd37c62009-11-21 08:43:09 +00001079 SourceLocation &DeclEnd,
John McCall7f040a92010-12-24 02:08:15 +00001080 ParsedAttributesWithRange &attrs) {
Argyrios Kyrtzidis36d36802010-06-17 10:52:18 +00001081 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Fariborz Jahaniane8cff362011-08-30 17:10:52 +00001082 // Must temporarily exit the objective-c container scope for
1083 // parsing c none objective-c decls.
1084 ObjCDeclContextSwitch ObjCDC(*this);
Chad Rosier8decdee2012-06-26 22:30:43 +00001085
John McCalld226f652010-08-21 09:40:31 +00001086 Decl *SingleDecl = 0;
Richard Smithc89edf52011-07-01 19:46:12 +00001087 Decl *OwnedType = 0;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001088 switch (Tok.getKind()) {
Douglas Gregoradcac882008-12-01 23:54:00 +00001089 case tok::kw_template:
Douglas Gregor1426e532009-05-12 21:31:51 +00001090 case tok::kw_export:
John McCall7f040a92010-12-24 02:08:15 +00001091 ProhibitAttributes(attrs);
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00001092 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001093 break;
Sebastian Redld078e642010-08-27 23:12:46 +00001094 case tok::kw_inline:
Sebastian Redl88e64ca2010-08-31 00:36:45 +00001095 // Could be the start of an inline namespace. Allowed as an ext in C++03.
David Blaikie4e4d0842012-03-11 07:00:24 +00001096 if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
John McCall7f040a92010-12-24 02:08:15 +00001097 ProhibitAttributes(attrs);
Sebastian Redld078e642010-08-27 23:12:46 +00001098 SourceLocation InlineLoc = ConsumeToken();
1099 SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1100 break;
1101 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001102 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001103 true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001104 case tok::kw_namespace:
John McCall7f040a92010-12-24 02:08:15 +00001105 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001106 SingleDecl = ParseNamespace(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001107 break;
Douglas Gregorf780abc2008-12-30 03:27:21 +00001108 case tok::kw_using:
John McCall78b81052010-11-10 02:40:36 +00001109 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
Richard Smithc89edf52011-07-01 19:46:12 +00001110 DeclEnd, attrs, &OwnedType);
Chris Lattner682bf922009-03-29 16:50:03 +00001111 break;
Anders Carlsson511d7ab2009-03-11 16:27:10 +00001112 case tok::kw_static_assert:
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00001113 case tok::kw__Static_assert:
John McCall7f040a92010-12-24 02:08:15 +00001114 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001115 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001116 break;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001117 default:
John McCall7f040a92010-12-24 02:08:15 +00001118 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001119 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001120
Chris Lattner682bf922009-03-29 16:50:03 +00001121 // This routine returns a DeclGroup, if the thing we parsed only contains a
Richard Smithc89edf52011-07-01 19:46:12 +00001122 // single decl, convert it now. Alias declarations can also declare a type;
1123 // include that too if it is present.
1124 return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001125}
1126
1127/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
1128/// declaration-specifiers init-declarator-list[opt] ';'
Sean Hunt2edf0a22012-06-23 05:07:58 +00001129/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1130/// init-declarator-list ';'
Chris Lattner8f08cb72007-08-25 06:57:03 +00001131///[C90/C++]init-declarator-list ';' [TODO]
1132/// [OMP] threadprivate-directive [TODO]
Chris Lattnercd147752009-03-29 17:27:48 +00001133///
Sean Hunt2edf0a22012-06-23 05:07:58 +00001134/// for-range-declaration: [C++11 6.5p1: stmt.ranged]
Richard Smithad762fc2011-04-14 22:09:26 +00001135/// attribute-specifier-seq[opt] type-specifier-seq declarator
1136///
Chris Lattnercd147752009-03-29 17:27:48 +00001137/// If RequireSemi is false, this does not check for a ';' at the end of the
Chris Lattner5c5db552010-04-05 18:18:31 +00001138/// declaration. If it is true, it checks for and eats it.
Richard Smithad762fc2011-04-14 22:09:26 +00001139///
1140/// If FRI is non-null, we might be parsing a for-range-declaration instead
1141/// of a simple-declaration. If we find that we are, we also parse the
1142/// for-range-initializer, and place it here.
Sean Hunt2edf0a22012-06-23 05:07:58 +00001143Parser::DeclGroupPtrTy
1144Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1145 SourceLocation &DeclEnd,
1146 ParsedAttributesWithRange &attrs,
1147 bool RequireSemi, ForRangeInit *FRI) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001148 // Parse the common declaration-specifiers piece.
John McCall54abf7d2009-11-04 02:18:39 +00001149 ParsingDeclSpec DS(*this);
John McCall7f040a92010-12-24 02:08:15 +00001150 DS.takeAttributesFrom(attrs);
Douglas Gregor312eadb2011-04-24 05:37:28 +00001151
Douglas Gregor0efc2c12010-01-13 17:31:36 +00001152 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
Richard Smith34b41d92011-02-20 03:19:35 +00001153 getDeclSpecContextFromDeclaratorContext(Context));
Abramo Bagnara06284c12012-01-07 10:52:36 +00001154
Reid Spencer5f016e22007-07-11 17:01:13 +00001155 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1156 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner04d66662007-10-09 17:33:22 +00001157 if (Tok.is(tok::semi)) {
Argyrios Kyrtzidis5641b0d2012-05-16 23:49:15 +00001158 DeclEnd = Tok.getLocation();
Chris Lattner5c5db552010-04-05 18:18:31 +00001159 if (RequireSemi) ConsumeToken();
John McCalld226f652010-08-21 09:40:31 +00001160 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
Douglas Gregor312eadb2011-04-24 05:37:28 +00001161 DS);
John McCall54abf7d2009-11-04 02:18:39 +00001162 DS.complete(TheDecl);
Chris Lattner682bf922009-03-29 16:50:03 +00001163 return Actions.ConvertDeclToDeclGroup(TheDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +00001164 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001165
1166 return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
John McCalld8ac0572009-11-03 19:26:08 +00001167}
Mike Stump1eb44332009-09-09 15:08:12 +00001168
Richard Smith0706df42011-10-19 21:33:05 +00001169/// Returns true if this might be the start of a declarator, or a common typo
1170/// for a declarator.
1171bool Parser::MightBeDeclarator(unsigned Context) {
1172 switch (Tok.getKind()) {
1173 case tok::annot_cxxscope:
1174 case tok::annot_template_id:
1175 case tok::caret:
1176 case tok::code_completion:
1177 case tok::coloncolon:
1178 case tok::ellipsis:
1179 case tok::kw___attribute:
1180 case tok::kw_operator:
1181 case tok::l_paren:
1182 case tok::star:
1183 return true;
1184
1185 case tok::amp:
1186 case tok::ampamp:
David Blaikie4e4d0842012-03-11 07:00:24 +00001187 return getLangOpts().CPlusPlus;
Richard Smith0706df42011-10-19 21:33:05 +00001188
Richard Smith1c94c162012-01-09 22:31:44 +00001189 case tok::l_square: // Might be an attribute on an unnamed bit-field.
David Blaikie4e4d0842012-03-11 07:00:24 +00001190 return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x &&
Richard Smith1c94c162012-01-09 22:31:44 +00001191 NextToken().is(tok::l_square);
1192
1193 case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
David Blaikie4e4d0842012-03-11 07:00:24 +00001194 return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
Richard Smith1c94c162012-01-09 22:31:44 +00001195
Richard Smith0706df42011-10-19 21:33:05 +00001196 case tok::identifier:
1197 switch (NextToken().getKind()) {
1198 case tok::code_completion:
1199 case tok::coloncolon:
1200 case tok::comma:
1201 case tok::equal:
1202 case tok::equalequal: // Might be a typo for '='.
1203 case tok::kw_alignas:
1204 case tok::kw_asm:
1205 case tok::kw___attribute:
1206 case tok::l_brace:
1207 case tok::l_paren:
1208 case tok::l_square:
1209 case tok::less:
1210 case tok::r_brace:
1211 case tok::r_paren:
1212 case tok::r_square:
1213 case tok::semi:
1214 return true;
1215
1216 case tok::colon:
1217 // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
Richard Smith1c94c162012-01-09 22:31:44 +00001218 // and in block scope it's probably a label. Inside a class definition,
1219 // this is a bit-field.
1220 return Context == Declarator::MemberContext ||
David Blaikie4e4d0842012-03-11 07:00:24 +00001221 (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
Richard Smith1c94c162012-01-09 22:31:44 +00001222
1223 case tok::identifier: // Possible virt-specifier.
David Blaikie4e4d0842012-03-11 07:00:24 +00001224 return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
Richard Smith0706df42011-10-19 21:33:05 +00001225
1226 default:
1227 return false;
1228 }
1229
1230 default:
1231 return false;
1232 }
1233}
1234
Richard Smith994d73f2012-04-11 20:59:20 +00001235/// Skip until we reach something which seems like a sensible place to pick
1236/// up parsing after a malformed declaration. This will sometimes stop sooner
1237/// than SkipUntil(tok::r_brace) would, but will never stop later.
1238void Parser::SkipMalformedDecl() {
1239 while (true) {
1240 switch (Tok.getKind()) {
1241 case tok::l_brace:
1242 // Skip until matching }, then stop. We've probably skipped over
1243 // a malformed class or function definition or similar.
1244 ConsumeBrace();
1245 SkipUntil(tok::r_brace, /*StopAtSemi*/false);
1246 if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
1247 // This declaration isn't over yet. Keep skipping.
1248 continue;
1249 }
1250 if (Tok.is(tok::semi))
1251 ConsumeToken();
1252 return;
1253
1254 case tok::l_square:
1255 ConsumeBracket();
1256 SkipUntil(tok::r_square, /*StopAtSemi*/false);
1257 continue;
1258
1259 case tok::l_paren:
1260 ConsumeParen();
1261 SkipUntil(tok::r_paren, /*StopAtSemi*/false);
1262 continue;
1263
1264 case tok::r_brace:
1265 return;
1266
1267 case tok::semi:
1268 ConsumeToken();
1269 return;
1270
1271 case tok::kw_inline:
1272 // 'inline namespace' at the start of a line is almost certainly
Jordan Rose94f29f42012-07-09 16:54:53 +00001273 // a good place to pick back up parsing, except in an Objective-C
1274 // @interface context.
1275 if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&
1276 (!ParsingInObjCContainer || CurParsedObjCImpl))
Richard Smith994d73f2012-04-11 20:59:20 +00001277 return;
1278 break;
1279
1280 case tok::kw_namespace:
1281 // 'namespace' at the start of a line is almost certainly a good
Jordan Rose94f29f42012-07-09 16:54:53 +00001282 // place to pick back up parsing, except in an Objective-C
1283 // @interface context.
1284 if (Tok.isAtStartOfLine() &&
1285 (!ParsingInObjCContainer || CurParsedObjCImpl))
1286 return;
1287 break;
1288
1289 case tok::at:
1290 // @end is very much like } in Objective-C contexts.
1291 if (NextToken().isObjCAtKeyword(tok::objc_end) &&
1292 ParsingInObjCContainer)
1293 return;
1294 break;
1295
1296 case tok::minus:
1297 case tok::plus:
1298 // - and + probably start new method declarations in Objective-C contexts.
1299 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
Richard Smith994d73f2012-04-11 20:59:20 +00001300 return;
1301 break;
1302
1303 case tok::eof:
1304 return;
1305
1306 default:
1307 break;
1308 }
1309
1310 ConsumeAnyToken();
1311 }
1312}
1313
John McCalld8ac0572009-11-03 19:26:08 +00001314/// ParseDeclGroup - Having concluded that this is either a function
1315/// definition or a group of object declarations, actually parse the
1316/// result.
John McCall54abf7d2009-11-04 02:18:39 +00001317Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1318 unsigned Context,
John McCalld8ac0572009-11-03 19:26:08 +00001319 bool AllowFunctionDefinitions,
Richard Smithad762fc2011-04-14 22:09:26 +00001320 SourceLocation *DeclEnd,
1321 ForRangeInit *FRI) {
John McCalld8ac0572009-11-03 19:26:08 +00001322 // Parse the first declarator.
John McCall54abf7d2009-11-04 02:18:39 +00001323 ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
John McCalld8ac0572009-11-03 19:26:08 +00001324 ParseDeclarator(D);
Chris Lattnercd147752009-03-29 17:27:48 +00001325
John McCalld8ac0572009-11-03 19:26:08 +00001326 // Bail out if the first declarator didn't seem well-formed.
1327 if (!D.hasName() && !D.mayOmitIdentifier()) {
Richard Smith994d73f2012-04-11 20:59:20 +00001328 SkipMalformedDecl();
John McCalld8ac0572009-11-03 19:26:08 +00001329 return DeclGroupPtrTy();
Chris Lattner23c4b182009-03-29 17:18:04 +00001330 }
Mike Stump1eb44332009-09-09 15:08:12 +00001331
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001332 // Save late-parsed attributes for now; they need to be parsed in the
1333 // appropriate function scope after the function Decl has been constructed.
1334 LateParsedAttrList LateParsedAttrs;
1335 if (D.isFunctionDeclarator())
1336 MaybeParseGNUAttributes(D, &LateParsedAttrs);
1337
Chris Lattnerc82daef2010-07-11 22:24:20 +00001338 // Check to see if we have a function *definition* which must have a body.
1339 if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
1340 // Look at the next token to make sure that this isn't a function
1341 // declaration. We have to check this because __attribute__ might be the
1342 // start of a function definition in GCC-extended K&R C.
Fariborz Jahanian39700f82012-07-05 19:34:20 +00001343 !isDeclarationAfterDeclarator() &&
1344 (!CurParsedObjCImpl || Tok.isNot(tok::l_brace) ||
1345 (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()))) {
Chad Rosier8decdee2012-06-26 22:30:43 +00001346
Chris Lattner004659a2010-07-11 22:42:07 +00001347 if (isStartOfFunctionDefinition(D)) {
John McCalld8ac0572009-11-03 19:26:08 +00001348 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
1349 Diag(Tok, diag::err_function_declared_typedef);
1350
1351 // Recover by treating the 'typedef' as spurious.
1352 DS.ClearStorageClassSpecs();
1353 }
1354
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001355 Decl *TheDecl =
1356 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
John McCalld8ac0572009-11-03 19:26:08 +00001357 return Actions.ConvertDeclToDeclGroup(TheDecl);
Chris Lattner004659a2010-07-11 22:42:07 +00001358 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001359
Chris Lattner004659a2010-07-11 22:42:07 +00001360 if (isDeclarationSpecifier()) {
1361 // If there is an invalid declaration specifier right after the function
1362 // prototype, then we must be in a missing semicolon case where this isn't
1363 // actually a body. Just fall through into the code that handles it as a
1364 // prototype, and let the top-level code handle the erroneous declspec
1365 // where it would otherwise expect a comma or semicolon.
John McCalld8ac0572009-11-03 19:26:08 +00001366 } else {
1367 Diag(Tok, diag::err_expected_fn_body);
1368 SkipUntil(tok::semi);
1369 return DeclGroupPtrTy();
1370 }
1371 }
1372
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001373 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-04-14 22:09:26 +00001374 return DeclGroupPtrTy();
1375
1376 // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
1377 // must parse and analyze the for-range-initializer before the declaration is
1378 // analyzed.
1379 if (FRI && Tok.is(tok::colon)) {
1380 FRI->ColonLoc = ConsumeToken();
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001381 if (Tok.is(tok::l_brace))
1382 FRI->RangeExpr = ParseBraceInitializer();
1383 else
1384 FRI->RangeExpr = ParseExpression();
Richard Smithad762fc2011-04-14 22:09:26 +00001385 Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1386 Actions.ActOnCXXForRangeDecl(ThisDecl);
1387 Actions.FinalizeDeclaration(ThisDecl);
John McCall6895a642012-01-27 01:29:43 +00001388 D.complete(ThisDecl);
Richard Smithad762fc2011-04-14 22:09:26 +00001389 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1);
1390 }
1391
Chris Lattner5f9e2722011-07-23 10:55:15 +00001392 SmallVector<Decl *, 8> DeclsInGroup;
Richard Smithad762fc2011-04-14 22:09:26 +00001393 Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001394 if (LateParsedAttrs.size() > 0)
1395 ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
John McCall54abf7d2009-11-04 02:18:39 +00001396 D.complete(FirstDecl);
John McCalld226f652010-08-21 09:40:31 +00001397 if (FirstDecl)
John McCalld8ac0572009-11-03 19:26:08 +00001398 DeclsInGroup.push_back(FirstDecl);
1399
Richard Smith0706df42011-10-19 21:33:05 +00001400 bool ExpectSemi = Context != Declarator::ForContext;
1401
Fariborz Jahanian6c89eaf2012-07-02 23:37:09 +00001402 if (CurParsedObjCImpl && D.isFunctionDeclarator() &&
Fariborz Jahanian3b5f9dc2012-07-03 22:54:28 +00001403 Tok.is(tok::l_brace)) {
Fariborz Jahanian6c89eaf2012-07-02 23:37:09 +00001404 // Consume the tokens and store them for later parsing.
1405 StashAwayMethodOrFunctionBodyTokens(FirstDecl);
1406 CurParsedObjCImpl->HasCFunction = true;
1407 ExpectSemi = false;
1408 }
1409
John McCalld8ac0572009-11-03 19:26:08 +00001410 // If we don't have a comma, it is either the end of the list (a ';') or an
1411 // error, bail out.
1412 while (Tok.is(tok::comma)) {
Richard Smith0706df42011-10-19 21:33:05 +00001413 SourceLocation CommaLoc = ConsumeToken();
1414
1415 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1416 // This comma was followed by a line-break and something which can't be
1417 // the start of a declarator. The comma was probably a typo for a
1418 // semicolon.
1419 Diag(CommaLoc, diag::err_expected_semi_declaration)
1420 << FixItHint::CreateReplacement(CommaLoc, ";");
1421 ExpectSemi = false;
1422 break;
1423 }
John McCalld8ac0572009-11-03 19:26:08 +00001424
1425 // Parse the next declarator.
1426 D.clear();
Richard Smith7984de32012-01-12 23:53:29 +00001427 D.setCommaLoc(CommaLoc);
John McCalld8ac0572009-11-03 19:26:08 +00001428
1429 // Accept attributes in an init-declarator. In the first declarator in a
1430 // declaration, these would be part of the declspec. In subsequent
1431 // declarators, they become part of the declarator itself, so that they
1432 // don't apply to declarators after *this* one. Examples:
1433 // short __attribute__((common)) var; -> declspec
1434 // short var __attribute__((common)); -> declarator
1435 // short x, __attribute__((common)) var; -> declarator
John McCall7f040a92010-12-24 02:08:15 +00001436 MaybeParseGNUAttributes(D);
John McCalld8ac0572009-11-03 19:26:08 +00001437
1438 ParseDeclarator(D);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001439 if (!D.isInvalidType()) {
1440 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1441 D.complete(ThisDecl);
1442 if (ThisDecl)
Chad Rosier8decdee2012-06-26 22:30:43 +00001443 DeclsInGroup.push_back(ThisDecl);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001444 }
John McCalld8ac0572009-11-03 19:26:08 +00001445 }
1446
1447 if (DeclEnd)
1448 *DeclEnd = Tok.getLocation();
1449
Richard Smith0706df42011-10-19 21:33:05 +00001450 if (ExpectSemi &&
Chris Lattner8bb21d32012-04-28 16:12:17 +00001451 ExpectAndConsumeSemi(Context == Declarator::FileContext
1452 ? diag::err_invalid_token_after_toplevel_declarator
1453 : diag::err_expected_semi_declaration)) {
Chris Lattner004659a2010-07-11 22:42:07 +00001454 // Okay, there was no semicolon and one was expected. If we see a
1455 // declaration specifier, just assume it was missing and continue parsing.
1456 // Otherwise things are very confused and we skip to recover.
1457 if (!isDeclarationSpecifier()) {
1458 SkipUntil(tok::r_brace, true, true);
1459 if (Tok.is(tok::semi))
1460 ConsumeToken();
1461 }
John McCalld8ac0572009-11-03 19:26:08 +00001462 }
1463
Douglas Gregor23c94db2010-07-02 17:43:08 +00001464 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
John McCalld8ac0572009-11-03 19:26:08 +00001465 DeclsInGroup.data(),
1466 DeclsInGroup.size());
Reid Spencer5f016e22007-07-11 17:01:13 +00001467}
1468
Richard Smithad762fc2011-04-14 22:09:26 +00001469/// Parse an optional simple-asm-expr and attributes, and attach them to a
1470/// declarator. Returns true on an error.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001471bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
Richard Smithad762fc2011-04-14 22:09:26 +00001472 // If a simple-asm-expr is present, parse it.
1473 if (Tok.is(tok::kw_asm)) {
1474 SourceLocation Loc;
1475 ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1476 if (AsmLabel.isInvalid()) {
1477 SkipUntil(tok::semi, true, true);
1478 return true;
1479 }
1480
1481 D.setAsmLabel(AsmLabel.release());
1482 D.SetRangeEnd(Loc);
1483 }
1484
1485 MaybeParseGNUAttributes(D);
1486 return false;
1487}
1488
Douglas Gregor1426e532009-05-12 21:31:51 +00001489/// \brief Parse 'declaration' after parsing 'declaration-specifiers
1490/// declarator'. This method parses the remainder of the declaration
1491/// (including any attributes or initializer, among other things) and
1492/// finalizes the declaration.
Reid Spencer5f016e22007-07-11 17:01:13 +00001493///
Reid Spencer5f016e22007-07-11 17:01:13 +00001494/// init-declarator: [C99 6.7]
1495/// declarator
1496/// declarator '=' initializer
1497/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
1498/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00001499/// [C++] declarator initializer[opt]
1500///
1501/// [C++] initializer:
1502/// [C++] '=' initializer-clause
1503/// [C++] '(' expression-list ')'
Sebastian Redl50de12f2009-03-24 22:27:57 +00001504/// [C++0x] '=' 'default' [TODO]
1505/// [C++0x] '=' 'delete'
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001506/// [C++0x] braced-init-list
Sebastian Redl50de12f2009-03-24 22:27:57 +00001507///
1508/// According to the standard grammar, =default and =delete are function
1509/// definitions, but that definitely doesn't fit with the parser here.
Reid Spencer5f016e22007-07-11 17:01:13 +00001510///
John McCalld226f652010-08-21 09:40:31 +00001511Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
Douglas Gregore542c862009-06-23 23:11:28 +00001512 const ParsedTemplateInfo &TemplateInfo) {
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001513 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-04-14 22:09:26 +00001514 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001515
Richard Smithad762fc2011-04-14 22:09:26 +00001516 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1517}
Mike Stump1eb44332009-09-09 15:08:12 +00001518
Richard Smithad762fc2011-04-14 22:09:26 +00001519Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1520 const ParsedTemplateInfo &TemplateInfo) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001521 // Inform the current actions module that we just parsed this declarator.
John McCalld226f652010-08-21 09:40:31 +00001522 Decl *ThisDecl = 0;
Douglas Gregord5a423b2009-09-25 18:43:00 +00001523 switch (TemplateInfo.Kind) {
1524 case ParsedTemplateInfo::NonTemplate:
Douglas Gregor23c94db2010-07-02 17:43:08 +00001525 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
Douglas Gregord5a423b2009-09-25 18:43:00 +00001526 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00001527
Douglas Gregord5a423b2009-09-25 18:43:00 +00001528 case ParsedTemplateInfo::Template:
1529 case ParsedTemplateInfo::ExplicitSpecialization:
Douglas Gregor23c94db2010-07-02 17:43:08 +00001530 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
John McCallf312b1e2010-08-26 23:41:50 +00001531 MultiTemplateParamsArg(Actions,
Douglas Gregore542c862009-06-23 23:11:28 +00001532 TemplateInfo.TemplateParams->data(),
1533 TemplateInfo.TemplateParams->size()),
Douglas Gregord5a423b2009-09-25 18:43:00 +00001534 D);
1535 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00001536
Douglas Gregord5a423b2009-09-25 18:43:00 +00001537 case ParsedTemplateInfo::ExplicitInstantiation: {
Chad Rosier8decdee2012-06-26 22:30:43 +00001538 DeclResult ThisRes
Douglas Gregor23c94db2010-07-02 17:43:08 +00001539 = Actions.ActOnExplicitInstantiation(getCurScope(),
Douglas Gregord5a423b2009-09-25 18:43:00 +00001540 TemplateInfo.ExternLoc,
1541 TemplateInfo.TemplateLoc,
1542 D);
1543 if (ThisRes.isInvalid()) {
1544 SkipUntil(tok::semi, true, true);
John McCalld226f652010-08-21 09:40:31 +00001545 return 0;
Douglas Gregord5a423b2009-09-25 18:43:00 +00001546 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001547
Douglas Gregord5a423b2009-09-25 18:43:00 +00001548 ThisDecl = ThisRes.get();
1549 break;
1550 }
1551 }
Mike Stump1eb44332009-09-09 15:08:12 +00001552
Richard Smith34b41d92011-02-20 03:19:35 +00001553 bool TypeContainsAuto =
1554 D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
1555
Douglas Gregor1426e532009-05-12 21:31:51 +00001556 // Parse declarator '=' initializer.
Richard Trieud6c7c672012-01-18 22:54:52 +00001557 // If a '==' or '+=' is found, suggest a fixit to '='.
Richard Trieufcaf27e2012-01-19 22:01:51 +00001558 if (isTokenEqualOrEqualTypo()) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001559 ConsumeToken();
Anders Carlsson37bf9d22010-09-24 21:25:25 +00001560 if (Tok.is(tok::kw_delete)) {
Sean Hunte4246a62011-05-12 06:15:49 +00001561 if (D.isFunctionDeclarator())
1562 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1563 << 1 /* delete */;
1564 else
1565 Diag(ConsumeToken(), diag::err_deleted_non_function);
Sean Huntfe2695e2011-05-06 01:42:00 +00001566 } else if (Tok.is(tok::kw_default)) {
Sean Hunte4246a62011-05-12 06:15:49 +00001567 if (D.isFunctionDeclarator())
Sebastian Redlecfcd562012-02-11 23:51:21 +00001568 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1569 << 0 /* default */;
Sean Hunte4246a62011-05-12 06:15:49 +00001570 else
1571 Diag(ConsumeToken(), diag::err_default_special_members);
Douglas Gregor1426e532009-05-12 21:31:51 +00001572 } else {
David Blaikie4e4d0842012-03-11 07:00:24 +00001573 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
John McCall731ad842009-12-19 09:28:58 +00001574 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001575 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001576 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001577
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001578 if (Tok.is(tok::code_completion)) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001579 Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00001580 cutOffParsing();
1581 return 0;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001582 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001583
John McCall60d7b3a2010-08-24 06:29:42 +00001584 ExprResult Init(ParseInitializer());
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001585
David Blaikie4e4d0842012-03-11 07:00:24 +00001586 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001587 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001588 ExitScope();
1589 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001590
Douglas Gregor1426e532009-05-12 21:31:51 +00001591 if (Init.isInvalid()) {
Douglas Gregor00225542010-03-01 18:27:54 +00001592 SkipUntil(tok::comma, true, true);
1593 Actions.ActOnInitializerError(ThisDecl);
1594 } else
Richard Smith34b41d92011-02-20 03:19:35 +00001595 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1596 /*DirectInit=*/false, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001597 }
1598 } else if (Tok.is(tok::l_paren)) {
1599 // Parse C++ direct initializer: '(' expression-list ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001600 BalancedDelimiterTracker T(*this, tok::l_paren);
1601 T.consumeOpen();
1602
Douglas Gregor1426e532009-05-12 21:31:51 +00001603 ExprVector Exprs(Actions);
1604 CommaLocsTy CommaLocs;
1605
David Blaikie4e4d0842012-03-11 07:00:24 +00001606 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregorb4debae2009-12-22 17:47:17 +00001607 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001608 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001609 }
1610
Douglas Gregor1426e532009-05-12 21:31:51 +00001611 if (ParseExpressionList(Exprs, CommaLocs)) {
1612 SkipUntil(tok::r_paren);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001613
David Blaikie4e4d0842012-03-11 07:00:24 +00001614 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001615 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001616 ExitScope();
1617 }
Douglas Gregor1426e532009-05-12 21:31:51 +00001618 } else {
1619 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001620 T.consumeClose();
Douglas Gregor1426e532009-05-12 21:31:51 +00001621
1622 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1623 "Unexpected number of commas!");
Douglas Gregorb4debae2009-12-22 17:47:17 +00001624
David Blaikie4e4d0842012-03-11 07:00:24 +00001625 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001626 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001627 ExitScope();
1628 }
1629
Sebastian Redl5b9cc5d2012-02-11 23:51:47 +00001630 ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
1631 T.getCloseLocation(),
1632 move_arg(Exprs));
1633 Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
1634 /*DirectInit=*/true, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001635 }
Fariborz Jahanian3b5f9dc2012-07-03 22:54:28 +00001636 } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace) &&
Fariborz Jahanianb0ed95c2012-07-03 23:22:13 +00001637 (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001638 // Parse C++0x braced-init-list.
Richard Smith7fe62082011-10-15 05:09:34 +00001639 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1640
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001641 if (D.getCXXScopeSpec().isSet()) {
1642 EnterScope(0);
1643 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1644 }
1645
1646 ExprResult Init(ParseBraceInitializer());
1647
1648 if (D.getCXXScopeSpec().isSet()) {
1649 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1650 ExitScope();
1651 }
1652
1653 if (Init.isInvalid()) {
1654 Actions.ActOnInitializerError(ThisDecl);
1655 } else
1656 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1657 /*DirectInit=*/true, TypeContainsAuto);
1658
Douglas Gregor1426e532009-05-12 21:31:51 +00001659 } else {
Richard Smith34b41d92011-02-20 03:19:35 +00001660 Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001661 }
1662
Richard Smith483b9f32011-02-21 20:05:19 +00001663 Actions.FinalizeDeclaration(ThisDecl);
1664
Douglas Gregor1426e532009-05-12 21:31:51 +00001665 return ThisDecl;
1666}
1667
Reid Spencer5f016e22007-07-11 17:01:13 +00001668/// ParseSpecifierQualifierList
1669/// specifier-qualifier-list:
1670/// type-specifier specifier-qualifier-list[opt]
1671/// type-qualifier specifier-qualifier-list[opt]
1672/// [GNU] attributes specifier-qualifier-list[opt]
1673///
Richard Smith69730c12012-03-12 07:56:15 +00001674void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1675 DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001676 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
1677 /// parse declaration-specifiers and complain about extra stuff.
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001678 /// TODO: diagnose attribute-specifiers and alignment-specifiers.
Richard Smith69730c12012-03-12 07:56:15 +00001679 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
Mike Stump1eb44332009-09-09 15:08:12 +00001680
Reid Spencer5f016e22007-07-11 17:01:13 +00001681 // Validate declspec for type-name.
1682 unsigned Specs = DS.getParsedSpecifiers();
Richard Smitha971d242012-05-09 20:55:26 +00001683 if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1684 !DS.hasTypeSpecifier()) {
Richard Smith69730c12012-03-12 07:56:15 +00001685 Diag(Tok, diag::err_expected_type);
1686 DS.SetTypeSpecError();
1687 } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
1688 !DS.hasAttributes()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001689 Diag(Tok, diag::err_typename_requires_specqual);
Richard Smith69730c12012-03-12 07:56:15 +00001690 if (!DS.hasTypeSpecifier())
1691 DS.SetTypeSpecError();
1692 }
Mike Stump1eb44332009-09-09 15:08:12 +00001693
Reid Spencer5f016e22007-07-11 17:01:13 +00001694 // Issue diagnostic and remove storage class if present.
1695 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
1696 if (DS.getStorageClassSpecLoc().isValid())
1697 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1698 else
1699 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
1700 DS.ClearStorageClassSpecs();
1701 }
Mike Stump1eb44332009-09-09 15:08:12 +00001702
Reid Spencer5f016e22007-07-11 17:01:13 +00001703 // Issue diagnostic and remove function specfier if present.
1704 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregorb48fe382008-10-31 09:07:45 +00001705 if (DS.isInlineSpecified())
1706 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
1707 if (DS.isVirtualSpecified())
1708 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
1709 if (DS.isExplicitSpecified())
1710 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
Reid Spencer5f016e22007-07-11 17:01:13 +00001711 DS.ClearFunctionSpecs();
1712 }
Richard Smith69730c12012-03-12 07:56:15 +00001713
1714 // Issue diagnostic and remove constexpr specfier if present.
1715 if (DS.isConstexprSpecified()) {
1716 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
1717 DS.ClearConstexprSpec();
1718 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001719}
1720
Chris Lattnerc199ab32009-04-12 20:42:31 +00001721/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
1722/// specified token is valid after the identifier in a declarator which
1723/// immediately follows the declspec. For example, these things are valid:
1724///
1725/// int x [ 4]; // direct-declarator
1726/// int x ( int y); // direct-declarator
1727/// int(int x ) // direct-declarator
1728/// int x ; // simple-declaration
1729/// int x = 17; // init-declarator-list
1730/// int x , y; // init-declarator-list
1731/// int x __asm__ ("foo"); // init-declarator-list
Chris Lattnerb6645dd2009-04-14 21:16:09 +00001732/// int x : 4; // struct-declarator
Chris Lattnerc83c27a2009-04-12 22:29:43 +00001733/// int x { 5}; // C++'0x unified initializers
Chris Lattnerc199ab32009-04-12 20:42:31 +00001734///
1735/// This is not, because 'x' does not immediately follow the declspec (though
1736/// ')' happens to be valid anyway).
1737/// int (x)
1738///
1739static bool isValidAfterIdentifierInDeclarator(const Token &T) {
1740 return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
1741 T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
Chris Lattnerb6645dd2009-04-14 21:16:09 +00001742 T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
Chris Lattnerc199ab32009-04-12 20:42:31 +00001743}
1744
Chris Lattnere40c2952009-04-14 21:34:55 +00001745
1746/// ParseImplicitInt - This method is called when we have an non-typename
1747/// identifier in a declspec (which normally terminates the decl spec) when
1748/// the declspec has no type specifier. In this case, the declspec is either
1749/// malformed or is "implicit int" (in K&R and C89).
1750///
1751/// This method handles diagnosing this prettily and returns false if the
1752/// declspec is done being processed. If it recovers and thinks there may be
1753/// other pieces of declspec after it, it returns true.
1754///
Chris Lattnerf4382f52009-04-14 22:17:06 +00001755bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00001756 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00001757 AccessSpecifier AS, DeclSpecContext DSC) {
Chris Lattnerf4382f52009-04-14 22:17:06 +00001758 assert(Tok.is(tok::identifier) && "should have identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00001759
Chris Lattnere40c2952009-04-14 21:34:55 +00001760 SourceLocation Loc = Tok.getLocation();
1761 // If we see an identifier that is not a type name, we normally would
1762 // parse it as the identifer being declared. However, when a typename
1763 // is typo'd or the definition is not included, this will incorrectly
1764 // parse the typename as the identifier name and fall over misparsing
1765 // later parts of the diagnostic.
1766 //
1767 // As such, we try to do some look-ahead in cases where this would
1768 // otherwise be an "implicit-int" case to see if this is invalid. For
1769 // example: "static foo_t x = 4;" In this case, if we parsed foo_t as
1770 // an identifier with implicit int, we'd get a parse error because the
1771 // next token is obviously invalid for a type. Parse these as a case
1772 // with an invalid type specifier.
1773 assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
Mike Stump1eb44332009-09-09 15:08:12 +00001774
Chris Lattnere40c2952009-04-14 21:34:55 +00001775 // Since we know that this either implicit int (which is rare) or an
Richard Smith827adaf2012-05-15 21:01:51 +00001776 // error, do lookahead to try to do better recovery. This never applies
1777 // within a type specifier. Outside of C++, we allow this even if the
1778 // language doesn't "officially" support implicit int -- we support
1779 // implicit int as an extension in C99 and C11. Allegedly, MS also
1780 // supports implicit int in C++ mode.
Richard Smitha971d242012-05-09 20:55:26 +00001781 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
Richard Smith827adaf2012-05-15 21:01:51 +00001782 (!getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt) &&
Richard Smith69730c12012-03-12 07:56:15 +00001783 isValidAfterIdentifierInDeclarator(NextToken())) {
Chris Lattnere40c2952009-04-14 21:34:55 +00001784 // If this token is valid for implicit int, e.g. "static x = 4", then
1785 // we just avoid eating the identifier, so it will be parsed as the
1786 // identifier in the declarator.
1787 return false;
1788 }
Mike Stump1eb44332009-09-09 15:08:12 +00001789
Richard Smith827adaf2012-05-15 21:01:51 +00001790 if (getLangOpts().CPlusPlus &&
1791 DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
1792 // Don't require a type specifier if we have the 'auto' storage class
1793 // specifier in C++98 -- we'll promote it to a type specifier.
1794 return false;
1795 }
1796
Chris Lattnere40c2952009-04-14 21:34:55 +00001797 // Otherwise, if we don't consume this token, we are going to emit an
1798 // error anyway. Try to recover from various common problems. Check
1799 // to see if this was a reference to a tag name without a tag specified.
1800 // This is a common problem in C (saying 'foo' instead of 'struct foo').
Chris Lattnerf4382f52009-04-14 22:17:06 +00001801 //
1802 // C++ doesn't need this, and isTagName doesn't take SS.
1803 if (SS == 0) {
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00001804 const char *TagName = 0, *FixitTagName = 0;
Chris Lattnerf4382f52009-04-14 22:17:06 +00001805 tok::TokenKind TagKind = tok::unknown;
Mike Stump1eb44332009-09-09 15:08:12 +00001806
Douglas Gregor23c94db2010-07-02 17:43:08 +00001807 switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
Chris Lattnere40c2952009-04-14 21:34:55 +00001808 default: break;
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00001809 case DeclSpec::TST_enum:
1810 TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break;
1811 case DeclSpec::TST_union:
1812 TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
1813 case DeclSpec::TST_struct:
1814 TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
1815 case DeclSpec::TST_class:
1816 TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
Chris Lattnere40c2952009-04-14 21:34:55 +00001817 }
Mike Stump1eb44332009-09-09 15:08:12 +00001818
Chris Lattnerf4382f52009-04-14 22:17:06 +00001819 if (TagName) {
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001820 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
1821 LookupResult R(Actions, TokenName, SourceLocation(),
1822 Sema::LookupOrdinaryName);
1823
Chris Lattnerf4382f52009-04-14 22:17:06 +00001824 Diag(Loc, diag::err_use_of_tag_name_without_tag)
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001825 << TokenName << TagName << getLangOpts().CPlusPlus
1826 << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
1827
1828 if (Actions.LookupParsedName(R, getCurScope(), SS)) {
1829 for (LookupResult::iterator I = R.begin(), IEnd = R.end();
1830 I != IEnd; ++I)
Kaelyn Uhrain392b3f52012-04-27 18:26:49 +00001831 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001832 << TokenName << TagName;
1833 }
Mike Stump1eb44332009-09-09 15:08:12 +00001834
Chris Lattnerf4382f52009-04-14 22:17:06 +00001835 // Parse this as a tag as if the missing tag were present.
1836 if (TagKind == tok::kw_enum)
Richard Smith69730c12012-03-12 07:56:15 +00001837 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
Chris Lattnerf4382f52009-04-14 22:17:06 +00001838 else
Richard Smith69730c12012-03-12 07:56:15 +00001839 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
1840 /*EnteringContext*/ false, DSC_normal);
Chris Lattnerf4382f52009-04-14 22:17:06 +00001841 return true;
1842 }
Chris Lattnere40c2952009-04-14 21:34:55 +00001843 }
Mike Stump1eb44332009-09-09 15:08:12 +00001844
Richard Smith8f0a7e72012-05-15 21:29:55 +00001845 // Determine whether this identifier could plausibly be the name of something
Richard Smith7514db22012-05-15 21:42:17 +00001846 // being declared (with a missing type).
Richard Smith8f0a7e72012-05-15 21:29:55 +00001847 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
1848 (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
Richard Smith827adaf2012-05-15 21:01:51 +00001849 // Look ahead to the next token to try to figure out what this declaration
1850 // was supposed to be.
1851 switch (NextToken().getKind()) {
1852 case tok::comma:
1853 case tok::equal:
1854 case tok::kw_asm:
1855 case tok::l_brace:
1856 case tok::l_square:
1857 case tok::semi:
1858 // This looks like a variable declaration. The type is probably missing.
1859 // We're done parsing decl-specifiers.
1860 return false;
1861
1862 case tok::l_paren: {
1863 // static x(4); // 'x' is not a type
1864 // x(int n); // 'x' is not a type
1865 // x (*p)[]; // 'x' is a type
1866 //
1867 // Since we're in an error case (or the rare 'implicit int in C++' MS
1868 // extension), we can afford to perform a tentative parse to determine
1869 // which case we're in.
1870 TentativeParsingAction PA(*this);
1871 ConsumeToken();
1872 TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
1873 PA.Revert();
1874 if (TPR == TPResult::False())
1875 return false;
1876 // The identifier is followed by a parenthesized declarator.
1877 // It's supposed to be a type.
1878 break;
1879 }
1880
1881 default:
1882 // This is probably supposed to be a type. This includes cases like:
1883 // int f(itn);
1884 // struct S { unsinged : 4; };
1885 break;
1886 }
1887 }
1888
Chad Rosier8decdee2012-06-26 22:30:43 +00001889 // This is almost certainly an invalid type name. Let the action emit a
Douglas Gregora786fdb2009-10-13 23:27:22 +00001890 // diagnostic and attempt to recover.
John McCallb3d87482010-08-24 05:47:05 +00001891 ParsedType T;
Kaelyn Uhrain50dc12a2012-06-15 23:45:58 +00001892 IdentifierInfo *II = Tok.getIdentifierInfo();
1893 if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
Douglas Gregora786fdb2009-10-13 23:27:22 +00001894 // The action emitted a diagnostic, so we don't have to.
1895 if (T) {
1896 // The action has suggested that the type T could be used. Set that as
1897 // the type in the declaration specifiers, consume the would-be type
1898 // name token, and we're done.
1899 const char *PrevSpec;
1900 unsigned DiagID;
John McCallb3d87482010-08-24 05:47:05 +00001901 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
Douglas Gregora786fdb2009-10-13 23:27:22 +00001902 DS.SetRangeEnd(Tok.getLocation());
1903 ConsumeToken();
Kaelyn Uhrain50dc12a2012-06-15 23:45:58 +00001904 // There may be other declaration specifiers after this.
1905 return true;
1906 } else if (II != Tok.getIdentifierInfo()) {
1907 // If no type was suggested, the correction is to a keyword
1908 Tok.setKind(II->getTokenID());
Douglas Gregora786fdb2009-10-13 23:27:22 +00001909 // There may be other declaration specifiers after this.
1910 return true;
1911 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001912
Douglas Gregora786fdb2009-10-13 23:27:22 +00001913 // Fall through; the action had no suggestion for us.
1914 } else {
1915 // The action did not emit a diagnostic, so emit one now.
1916 SourceRange R;
1917 if (SS) R = SS->getRange();
1918 Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
1919 }
Mike Stump1eb44332009-09-09 15:08:12 +00001920
Douglas Gregora786fdb2009-10-13 23:27:22 +00001921 // Mark this as an error.
Richard Smith69730c12012-03-12 07:56:15 +00001922 DS.SetTypeSpecError();
Chris Lattnere40c2952009-04-14 21:34:55 +00001923 DS.SetRangeEnd(Tok.getLocation());
1924 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00001925
Chris Lattnere40c2952009-04-14 21:34:55 +00001926 // TODO: Could inject an invalid typedef decl in an enclosing scope to
1927 // avoid rippling error messages on subsequent uses of the same type,
1928 // could be useful if #include was forgotten.
1929 return false;
1930}
1931
Douglas Gregor0efc2c12010-01-13 17:31:36 +00001932/// \brief Determine the declaration specifier context from the declarator
1933/// context.
1934///
1935/// \param Context the declarator context, which is one of the
1936/// Declarator::TheContext enumerator values.
Chad Rosier8decdee2012-06-26 22:30:43 +00001937Parser::DeclSpecContext
Douglas Gregor0efc2c12010-01-13 17:31:36 +00001938Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
1939 if (Context == Declarator::MemberContext)
1940 return DSC_class;
1941 if (Context == Declarator::FileContext)
1942 return DSC_top_level;
Richard Smith6d96d3a2012-03-15 01:02:11 +00001943 if (Context == Declarator::TrailingReturnContext)
1944 return DSC_trailing;
Douglas Gregor0efc2c12010-01-13 17:31:36 +00001945 return DSC_normal;
1946}
1947
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001948/// ParseAlignArgument - Parse the argument to an alignment-specifier.
1949///
1950/// FIXME: Simply returns an alignof() expression if the argument is a
1951/// type. Ideally, the type should be propagated directly into Sema.
1952///
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00001953/// [C11] type-id
1954/// [C11] constant-expression
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001955/// [C++0x] type-id ...[opt]
1956/// [C++0x] assignment-expression ...[opt]
1957ExprResult Parser::ParseAlignArgument(SourceLocation Start,
1958 SourceLocation &EllipsisLoc) {
1959 ExprResult ER;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001960 if (isTypeIdInParens()) {
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001961 SourceLocation TypeLoc = Tok.getLocation();
1962 ParsedType Ty = ParseTypeName().get();
1963 SourceRange TypeRange(Start, Tok.getLocation());
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001964 ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
1965 Ty.getAsOpaquePtr(), TypeRange);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001966 } else
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001967 ER = ParseConstantExpression();
1968
David Blaikie4e4d0842012-03-11 07:00:24 +00001969 if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis))
Peter Collingbournefe9b2a82011-10-24 17:56:00 +00001970 EllipsisLoc = ConsumeToken();
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001971
1972 return ER;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001973}
1974
1975/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
1976/// attribute to Attrs.
1977///
1978/// alignment-specifier:
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00001979/// [C11] '_Alignas' '(' type-id ')'
1980/// [C11] '_Alignas' '(' constant-expression ')'
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001981/// [C++0x] 'alignas' '(' type-id ...[opt] ')'
1982/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')'
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001983void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
1984 SourceLocation *endLoc) {
1985 assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
1986 "Not an alignment-specifier!");
1987
1988 SourceLocation KWLoc = Tok.getLocation();
1989 ConsumeToken();
1990
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001991 BalancedDelimiterTracker T(*this, tok::l_paren);
1992 if (T.expectAndConsume(diag::err_expected_lparen))
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001993 return;
1994
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00001995 SourceLocation EllipsisLoc;
1996 ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001997 if (ArgExpr.isInvalid()) {
1998 SkipUntil(tok::r_paren);
1999 return;
2000 }
2001
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002002 T.consumeClose();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002003 if (endLoc)
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002004 *endLoc = T.getCloseLocation();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002005
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002006 // FIXME: Handle pack-expansions here.
2007 if (EllipsisLoc.isValid()) {
2008 Diag(EllipsisLoc, diag::err_alignas_pack_exp_unsupported);
2009 return;
2010 }
2011
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002012 ExprVector ArgExprs(Actions);
2013 ArgExprs.push_back(ArgExpr.release());
Sean Hunt8e083e72012-06-19 23:57:03 +00002014 // FIXME: This should not be GNU, but we since the attribute used is
2015 // based on the spelling, and there is no true spelling for
2016 // C++11 attributes, this isn't accepted.
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002017 Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
Sean Hunt93f95f22012-06-18 16:13:52 +00002018 0, T.getOpenLocation(), ArgExprs.take(), 1,
Sean Hunt8e083e72012-06-19 23:57:03 +00002019 AttributeList::AS_GNU);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002020}
2021
Reid Spencer5f016e22007-07-11 17:01:13 +00002022/// ParseDeclarationSpecifiers
2023/// declaration-specifiers: [C99 6.7]
2024/// storage-class-specifier declaration-specifiers[opt]
2025/// type-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002026/// [C99] function-specifier declaration-specifiers[opt]
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002027/// [C11] alignment-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002028/// [GNU] attributes declaration-specifiers[opt]
Douglas Gregor8d267c52011-09-09 02:06:17 +00002029/// [Clang] '__module_private__' declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002030///
2031/// storage-class-specifier: [C99 6.7.1]
2032/// 'typedef'
2033/// 'extern'
2034/// 'static'
2035/// 'auto'
2036/// 'register'
Sebastian Redl669d5d72008-11-14 23:42:31 +00002037/// [C++] 'mutable'
Reid Spencer5f016e22007-07-11 17:01:13 +00002038/// [GNU] '__thread'
Reid Spencer5f016e22007-07-11 17:01:13 +00002039/// function-specifier: [C99 6.7.4]
2040/// [C99] 'inline'
Douglas Gregorb48fe382008-10-31 09:07:45 +00002041/// [C++] 'virtual'
2042/// [C++] 'explicit'
Peter Collingbournef315fa82011-02-14 01:42:53 +00002043/// [OpenCL] '__kernel'
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002044/// 'friend': [C++ dcl.friend]
Sebastian Redl2ac67232009-11-05 15:47:02 +00002045/// 'constexpr': [C++0x dcl.constexpr]
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002046
Reid Spencer5f016e22007-07-11 17:01:13 +00002047///
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +00002048void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00002049 const ParsedTemplateInfo &TemplateInfo,
John McCall67d1a672009-08-06 02:15:43 +00002050 AccessSpecifier AS,
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002051 DeclSpecContext DSContext,
2052 LateParsedAttrList *LateAttrs) {
Douglas Gregor312eadb2011-04-24 05:37:28 +00002053 if (DS.getSourceRange().isInvalid()) {
2054 DS.SetRangeStart(Tok.getLocation());
2055 DS.SetRangeEnd(Tok.getLocation());
2056 }
Chad Rosier8decdee2012-06-26 22:30:43 +00002057
Douglas Gregorefaa93a2011-11-07 17:33:42 +00002058 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
Sean Hunt2edf0a22012-06-23 05:07:58 +00002059 bool AttrsLastTime = false;
2060 ParsedAttributesWithRange attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00002061 while (1) {
John McCallfec54012009-08-03 20:12:06 +00002062 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00002063 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00002064 unsigned DiagID = 0;
2065
Reid Spencer5f016e22007-07-11 17:01:13 +00002066 SourceLocation Loc = Tok.getLocation();
Douglas Gregor12e083c2008-11-07 15:42:26 +00002067
Reid Spencer5f016e22007-07-11 17:01:13 +00002068 switch (Tok.getKind()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002069 default:
Chris Lattnerbce61352008-07-26 00:20:22 +00002070 DoneWithDeclSpec:
Sean Hunt2edf0a22012-06-23 05:07:58 +00002071 if (!AttrsLastTime)
2072 ProhibitAttributes(attrs);
2073 else
2074 DS.takeAttributesFrom(attrs);
Peter Collingbournef1907682011-09-29 18:03:57 +00002075
Reid Spencer5f016e22007-07-11 17:01:13 +00002076 // If this is not a declaration specifier token, we're done reading decl
2077 // specifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00002078 DS.Finish(Diags, PP);
Reid Spencer5f016e22007-07-11 17:01:13 +00002079 return;
Mike Stump1eb44332009-09-09 15:08:12 +00002080
Sean Hunt2edf0a22012-06-23 05:07:58 +00002081 case tok::l_square:
2082 case tok::kw_alignas:
2083 if (!isCXX11AttributeSpecifier())
2084 goto DoneWithDeclSpec;
2085
2086 ProhibitAttributes(attrs);
2087 // FIXME: It would be good to recover by accepting the attributes,
2088 // but attempting to do that now would cause serious
2089 // madness in terms of diagnostics.
2090 attrs.clear();
2091 attrs.Range = SourceRange();
2092
2093 ParseCXX11Attributes(attrs);
2094 AttrsLastTime = true;
Chad Rosier8decdee2012-06-26 22:30:43 +00002095 continue;
Sean Hunt2edf0a22012-06-23 05:07:58 +00002096
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002097 case tok::code_completion: {
John McCallf312b1e2010-08-26 23:41:50 +00002098 Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002099 if (DS.hasTypeSpecifier()) {
2100 bool AllowNonIdentifiers
2101 = (getCurScope()->getFlags() & (Scope::ControlScope |
2102 Scope::BlockScope |
2103 Scope::TemplateParamScope |
2104 Scope::FunctionPrototypeScope |
2105 Scope::AtCatchScope)) == 0;
2106 bool AllowNestedNameSpecifiers
Chad Rosier8decdee2012-06-26 22:30:43 +00002107 = DSContext == DSC_top_level ||
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002108 (DSContext == DSC_class && DS.isFriendSpecified());
2109
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002110 Actions.CodeCompleteDeclSpec(getCurScope(), DS,
Chad Rosier8decdee2012-06-26 22:30:43 +00002111 AllowNonIdentifiers,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002112 AllowNestedNameSpecifiers);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002113 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00002114 }
2115
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00002116 if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2117 CCC = Sema::PCC_LocalDeclarationSpecifiers;
2118 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
Chad Rosier8decdee2012-06-26 22:30:43 +00002119 CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
John McCallf312b1e2010-08-26 23:41:50 +00002120 : Sema::PCC_Template;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002121 else if (DSContext == DSC_class)
John McCallf312b1e2010-08-26 23:41:50 +00002122 CCC = Sema::PCC_Class;
Argyrios Kyrtzidis849639d2012-02-07 16:50:53 +00002123 else if (CurParsedObjCImpl)
John McCallf312b1e2010-08-26 23:41:50 +00002124 CCC = Sema::PCC_ObjCImplementation;
Chad Rosier8decdee2012-06-26 22:30:43 +00002125
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002126 Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002127 return cutOffParsing();
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002128 }
2129
Chris Lattner5e02c472009-01-05 00:07:25 +00002130 case tok::coloncolon: // ::foo::bar
John McCall9ba61662010-02-26 08:45:28 +00002131 // C++ scope specifier. Annotate and loop, or bail out on error.
2132 if (TryAnnotateCXXScopeToken(true)) {
2133 if (!DS.hasTypeSpecifier())
2134 DS.SetTypeSpecError();
2135 goto DoneWithDeclSpec;
2136 }
John McCall2e0a7152010-03-01 18:20:46 +00002137 if (Tok.is(tok::coloncolon)) // ::new or ::delete
2138 goto DoneWithDeclSpec;
John McCall9ba61662010-02-26 08:45:28 +00002139 continue;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002140
2141 case tok::annot_cxxscope: {
Richard Smithf63eee72012-05-09 18:56:43 +00002142 if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002143 goto DoneWithDeclSpec;
2144
John McCallaa87d332009-12-12 11:40:51 +00002145 CXXScopeSpec SS;
Douglas Gregorc34348a2011-02-24 17:54:50 +00002146 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2147 Tok.getAnnotationRange(),
2148 SS);
John McCallaa87d332009-12-12 11:40:51 +00002149
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002150 // We are looking for a qualified typename.
Douglas Gregor9135c722009-03-25 15:40:00 +00002151 Token Next = NextToken();
Mike Stump1eb44332009-09-09 15:08:12 +00002152 if (Next.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002153 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
Douglas Gregorc45c2322009-03-31 00:43:58 +00002154 ->Kind == TNK_Type_template) {
Douglas Gregor9135c722009-03-25 15:40:00 +00002155 // We have a qualified template-id, e.g., N::A<int>
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002156
2157 // C++ [class.qual]p2:
2158 // In a lookup in which the constructor is an acceptable lookup
2159 // result and the nested-name-specifier nominates a class C:
2160 //
2161 // - if the name specified after the
2162 // nested-name-specifier, when looked up in C, is the
2163 // injected-class-name of C (Clause 9), or
2164 //
2165 // - if the name specified after the nested-name-specifier
2166 // is the same as the identifier or the
2167 // simple-template-id's template-name in the last
2168 // component of the nested-name-specifier,
2169 //
2170 // the name is instead considered to name the constructor of
2171 // class C.
Chad Rosier8decdee2012-06-26 22:30:43 +00002172 //
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002173 // Thus, if the template-name is actually the constructor
2174 // name, then the code is ill-formed; this interpretation is
Chad Rosier8decdee2012-06-26 22:30:43 +00002175 // reinforced by the NAD status of core issue 635.
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002176 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
John McCallba9d8532010-04-13 06:39:49 +00002177 if ((DSContext == DSC_top_level ||
2178 (DSContext == DSC_class && DS.isFriendSpecified())) &&
2179 TemplateId->Name &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002180 Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002181 if (isConstructorDeclarator()) {
2182 // The user meant this to be an out-of-line constructor
2183 // definition, but template arguments are not allowed
2184 // there. Just allow this as a constructor; we'll
2185 // complain about it later.
2186 goto DoneWithDeclSpec;
2187 }
2188
2189 // The user meant this to name a type, but it actually names
2190 // a constructor with some extraneous template
2191 // arguments. Complain, then parse it as a type as the user
2192 // intended.
2193 Diag(TemplateId->TemplateNameLoc,
2194 diag::err_out_of_line_template_id_names_constructor)
2195 << TemplateId->Name;
2196 }
2197
John McCallaa87d332009-12-12 11:40:51 +00002198 DS.getTypeSpecScope() = SS;
2199 ConsumeToken(); // The C++ scope.
Mike Stump1eb44332009-09-09 15:08:12 +00002200 assert(Tok.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002201 "ParseOptionalCXXScopeSpecifier not working");
Douglas Gregor059101f2011-03-02 00:47:37 +00002202 AnnotateTemplateIdTokenAsType();
Douglas Gregor9135c722009-03-25 15:40:00 +00002203 continue;
2204 }
2205
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002206 if (Next.is(tok::annot_typename)) {
John McCallaa87d332009-12-12 11:40:51 +00002207 DS.getTypeSpecScope() = SS;
2208 ConsumeToken(); // The C++ scope.
John McCallb3d87482010-08-24 05:47:05 +00002209 if (Tok.getAnnotationValue()) {
2210 ParsedType T = getTypeAnnotation(Tok);
Nico Weber253e80b2010-11-22 10:30:56 +00002211 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
Chad Rosier8decdee2012-06-26 22:30:43 +00002212 Tok.getAnnotationEndLoc(),
John McCallb3d87482010-08-24 05:47:05 +00002213 PrevSpec, DiagID, T);
2214 }
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002215 else
2216 DS.SetTypeSpecError();
2217 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2218 ConsumeToken(); // The typename
2219 }
2220
Douglas Gregor9135c722009-03-25 15:40:00 +00002221 if (Next.isNot(tok::identifier))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002222 goto DoneWithDeclSpec;
2223
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002224 // If we're in a context where the identifier could be a class name,
2225 // check whether this is a constructor declaration.
John McCallba9d8532010-04-13 06:39:49 +00002226 if ((DSContext == DSC_top_level ||
2227 (DSContext == DSC_class && DS.isFriendSpecified())) &&
Chad Rosier8decdee2012-06-26 22:30:43 +00002228 Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002229 &SS)) {
2230 if (isConstructorDeclarator())
2231 goto DoneWithDeclSpec;
2232
2233 // As noted in C++ [class.qual]p2 (cited above), when the name
2234 // of the class is qualified in a context where it could name
2235 // a constructor, its a constructor name. However, we've
2236 // looked at the declarator, and the user probably meant this
2237 // to be a type. Complain that it isn't supposed to be treated
2238 // as a type, then proceed to parse it as a type.
2239 Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
2240 << Next.getIdentifierInfo();
2241 }
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002242
John McCallb3d87482010-08-24 05:47:05 +00002243 ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2244 Next.getLocation(),
Douglas Gregor9e876872011-03-01 18:12:44 +00002245 getCurScope(), &SS,
2246 false, false, ParsedType(),
Abramo Bagnarafad03b72012-01-27 08:46:19 +00002247 /*IsCtorOrDtorName=*/false,
Douglas Gregor9e876872011-03-01 18:12:44 +00002248 /*NonTrivialSourceInfo=*/true);
Douglas Gregor55f6b142009-02-09 18:46:07 +00002249
Chris Lattnerf4382f52009-04-14 22:17:06 +00002250 // If the referenced identifier is not a type, then this declspec is
2251 // erroneous: We already checked about that it has no type specifier, and
2252 // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
Mike Stump1eb44332009-09-09 15:08:12 +00002253 // typename.
Chris Lattnerf4382f52009-04-14 22:17:06 +00002254 if (TypeRep == 0) {
2255 ConsumeToken(); // Eat the scope spec so the identifier is current.
Richard Smith69730c12012-03-12 07:56:15 +00002256 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002257 goto DoneWithDeclSpec;
Chris Lattnerf4382f52009-04-14 22:17:06 +00002258 }
Mike Stump1eb44332009-09-09 15:08:12 +00002259
John McCallaa87d332009-12-12 11:40:51 +00002260 DS.getTypeSpecScope() = SS;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002261 ConsumeToken(); // The C++ scope.
2262
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002263 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002264 DiagID, TypeRep);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002265 if (isInvalid)
2266 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002267
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002268 DS.SetRangeEnd(Tok.getLocation());
2269 ConsumeToken(); // The typename.
2270
2271 continue;
2272 }
Mike Stump1eb44332009-09-09 15:08:12 +00002273
Chris Lattner80d0c892009-01-21 19:48:37 +00002274 case tok::annot_typename: {
John McCallb3d87482010-08-24 05:47:05 +00002275 if (Tok.getAnnotationValue()) {
2276 ParsedType T = getTypeAnnotation(Tok);
Nico Weberc43271e2010-11-22 12:50:03 +00002277 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00002278 DiagID, T);
2279 } else
Douglas Gregor31a19b62009-04-01 21:51:26 +00002280 DS.SetTypeSpecError();
Chad Rosier8decdee2012-06-26 22:30:43 +00002281
Chris Lattner5c5db552010-04-05 18:18:31 +00002282 if (isInvalid)
2283 break;
2284
Chris Lattner80d0c892009-01-21 19:48:37 +00002285 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2286 ConsumeToken(); // The typename
Mike Stump1eb44332009-09-09 15:08:12 +00002287
Chris Lattner80d0c892009-01-21 19:48:37 +00002288 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2289 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosier8decdee2012-06-26 22:30:43 +00002290 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002291 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002292 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002293
Chris Lattner80d0c892009-01-21 19:48:37 +00002294 continue;
2295 }
Mike Stump1eb44332009-09-09 15:08:12 +00002296
Douglas Gregorbfad9152011-04-28 15:48:45 +00002297 case tok::kw___is_signed:
2298 // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
2299 // typically treats it as a trait. If we see __is_signed as it appears
2300 // in libstdc++, e.g.,
2301 //
2302 // static const bool __is_signed;
2303 //
2304 // then treat __is_signed as an identifier rather than as a keyword.
2305 if (DS.getTypeSpecType() == TST_bool &&
2306 DS.getTypeQualifiers() == DeclSpec::TQ_const &&
2307 DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2308 Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
2309 Tok.setKind(tok::identifier);
2310 }
2311
2312 // We're done with the declaration-specifiers.
2313 goto DoneWithDeclSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00002314
Chris Lattner3bd934a2008-07-26 01:18:38 +00002315 // typedef-name
David Blaikie42d6d0c2011-12-04 05:04:18 +00002316 case tok::kw_decltype:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002317 case tok::identifier: {
Chris Lattner5e02c472009-01-05 00:07:25 +00002318 // In C++, check to see if this is a scope specifier like foo::bar::, if
2319 // so handle it as such. This is important for ctor parsing.
David Blaikie4e4d0842012-03-11 07:00:24 +00002320 if (getLangOpts().CPlusPlus) {
John McCall9ba61662010-02-26 08:45:28 +00002321 if (TryAnnotateCXXScopeToken(true)) {
2322 if (!DS.hasTypeSpecifier())
2323 DS.SetTypeSpecError();
2324 goto DoneWithDeclSpec;
2325 }
2326 if (!Tok.is(tok::identifier))
2327 continue;
2328 }
Mike Stump1eb44332009-09-09 15:08:12 +00002329
Chris Lattner3bd934a2008-07-26 01:18:38 +00002330 // This identifier can only be a typedef name if we haven't already seen
2331 // a type-specifier. Without this check we misparse:
2332 // typedef int X; struct Y { short X; }; as 'short int'.
2333 if (DS.hasTypeSpecifier())
2334 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00002335
John Thompson82287d12010-02-05 00:12:22 +00002336 // Check for need to substitute AltiVec keyword tokens.
2337 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2338 break;
2339
Richard Smithf63eee72012-05-09 18:56:43 +00002340 // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2341 // allow the use of a typedef name as a type specifier.
2342 if (DS.isTypeAltiVecVector())
2343 goto DoneWithDeclSpec;
2344
John McCallb3d87482010-08-24 05:47:05 +00002345 ParsedType TypeRep =
2346 Actions.getTypeName(*Tok.getIdentifierInfo(),
2347 Tok.getLocation(), getCurScope());
Douglas Gregor55f6b142009-02-09 18:46:07 +00002348
Chris Lattnerc199ab32009-04-12 20:42:31 +00002349 // If this is not a typedef name, don't parse it as part of the declspec,
2350 // it must be an implicit int or an error.
John McCallb3d87482010-08-24 05:47:05 +00002351 if (!TypeRep) {
Richard Smith69730c12012-03-12 07:56:15 +00002352 if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +00002353 goto DoneWithDeclSpec;
Chris Lattnerc199ab32009-04-12 20:42:31 +00002354 }
Douglas Gregor55f6b142009-02-09 18:46:07 +00002355
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002356 // If we're in a context where the identifier could be a class name,
2357 // check whether this is a constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002358 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002359 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002360 isConstructorDeclarator())
Douglas Gregorb48fe382008-10-31 09:07:45 +00002361 goto DoneWithDeclSpec;
2362
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002363 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002364 DiagID, TypeRep);
Chris Lattner3bd934a2008-07-26 01:18:38 +00002365 if (isInvalid)
2366 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002367
Chris Lattner3bd934a2008-07-26 01:18:38 +00002368 DS.SetRangeEnd(Tok.getLocation());
2369 ConsumeToken(); // The identifier
2370
2371 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2372 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosier8decdee2012-06-26 22:30:43 +00002373 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002374 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002375 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002376
Steve Naroff4f9b9f12008-09-22 10:28:57 +00002377 // Need to support trailing type qualifiers (e.g. "id<p> const").
2378 // If a type specifier follows, it will be diagnosed elsewhere.
2379 continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +00002380 }
Douglas Gregor39a8de12009-02-25 19:37:18 +00002381
2382 // type-name
2383 case tok::annot_template_id: {
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002384 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
Douglas Gregorc45c2322009-03-31 00:43:58 +00002385 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor39a8de12009-02-25 19:37:18 +00002386 // This template-id does not refer to a type name, so we're
2387 // done with the type-specifiers.
2388 goto DoneWithDeclSpec;
2389 }
2390
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002391 // If we're in a context where the template-id could be a
2392 // constructor name or specialization, check whether this is a
2393 // constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002394 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002395 Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002396 isConstructorDeclarator())
2397 goto DoneWithDeclSpec;
2398
Douglas Gregor39a8de12009-02-25 19:37:18 +00002399 // Turn the template-id annotation token into a type annotation
2400 // token, then try again to parse it as a type-specifier.
Douglas Gregor31a19b62009-04-01 21:51:26 +00002401 AnnotateTemplateIdTokenAsType();
Douglas Gregor39a8de12009-02-25 19:37:18 +00002402 continue;
2403 }
2404
Reid Spencer5f016e22007-07-11 17:01:13 +00002405 // GNU attributes support.
2406 case tok::kw___attribute:
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002407 ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
Reid Spencer5f016e22007-07-11 17:01:13 +00002408 continue;
Steve Narofff59e17e2008-12-24 20:59:21 +00002409
2410 // Microsoft declspec support.
2411 case tok::kw___declspec:
John McCall7f040a92010-12-24 02:08:15 +00002412 ParseMicrosoftDeclSpec(DS.getAttributes());
Steve Narofff59e17e2008-12-24 20:59:21 +00002413 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00002414
Steve Naroff239f0732008-12-25 14:16:32 +00002415 // Microsoft single token adornments.
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002416 case tok::kw___forceinline: {
2417 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
2418 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
2419 SourceLocation AttrNameLoc = ConsumeToken();
Sean Hunt93f95f22012-06-18 16:13:52 +00002420 // FIXME: This does not work correctly if it is set to be a declspec
2421 // attribute, and a GNU attribute is simply incorrect.
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002422 DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Sean Hunt93f95f22012-06-18 16:13:52 +00002423 SourceLocation(), 0, 0, AttributeList::AS_GNU);
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002424 continue;
2425 }
Eli Friedman290eeb02009-06-08 23:27:34 +00002426
2427 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00002428 case tok::kw___ptr32:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00002429 case tok::kw___w64:
Steve Naroff239f0732008-12-25 14:16:32 +00002430 case tok::kw___cdecl:
2431 case tok::kw___stdcall:
2432 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00002433 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00002434 case tok::kw___unaligned:
John McCall7f040a92010-12-24 02:08:15 +00002435 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00002436 continue;
2437
Dawn Perchik52fc3142010-09-03 01:29:35 +00002438 // Borland single token adornments.
2439 case tok::kw___pascal:
John McCall7f040a92010-12-24 02:08:15 +00002440 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00002441 continue;
2442
Peter Collingbournef315fa82011-02-14 01:42:53 +00002443 // OpenCL single token adornments.
2444 case tok::kw___kernel:
2445 ParseOpenCLAttributes(DS.getAttributes());
2446 continue;
2447
Reid Spencer5f016e22007-07-11 17:01:13 +00002448 // storage-class-specifier
2449 case tok::kw_typedef:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002450 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2451 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002452 break;
2453 case tok::kw_extern:
2454 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +00002455 Diag(Tok, diag::ext_thread_before) << "extern";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002456 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2457 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002458 break;
Steve Naroff8d54bf22007-12-18 00:16:02 +00002459 case tok::kw___private_extern__:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002460 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2461 Loc, PrevSpec, DiagID);
Steve Naroff8d54bf22007-12-18 00:16:02 +00002462 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002463 case tok::kw_static:
2464 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +00002465 Diag(Tok, diag::ext_thread_before) << "static";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002466 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2467 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002468 break;
2469 case tok::kw_auto:
David Blaikie4e4d0842012-03-11 07:00:24 +00002470 if (getLangOpts().CPlusPlus0x) {
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002471 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002472 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2473 PrevSpec, DiagID);
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002474 if (!isInvalid)
Richard Smith8f4fb192011-09-04 19:54:14 +00002475 Diag(Tok, diag::ext_auto_storage_class)
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002476 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
Richard Smith8f4fb192011-09-04 19:54:14 +00002477 } else
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002478 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2479 DiagID);
Richard Smith8f4fb192011-09-04 19:54:14 +00002480 } else
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002481 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2482 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002483 break;
2484 case tok::kw_register:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002485 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2486 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002487 break;
Sebastian Redl669d5d72008-11-14 23:42:31 +00002488 case tok::kw_mutable:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002489 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2490 PrevSpec, DiagID);
Sebastian Redl669d5d72008-11-14 23:42:31 +00002491 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002492 case tok::kw___thread:
John McCallfec54012009-08-03 20:12:06 +00002493 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002494 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002495
Reid Spencer5f016e22007-07-11 17:01:13 +00002496 // function-specifier
2497 case tok::kw_inline:
John McCallfec54012009-08-03 20:12:06 +00002498 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002499 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002500 case tok::kw_virtual:
John McCallfec54012009-08-03 20:12:06 +00002501 isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002502 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002503 case tok::kw_explicit:
John McCallfec54012009-08-03 20:12:06 +00002504 isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002505 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002506
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002507 // alignment-specifier
2508 case tok::kw__Alignas:
David Blaikie4e4d0842012-03-11 07:00:24 +00002509 if (!getLangOpts().C11)
Jordan Rosef70a8862012-06-30 21:33:57 +00002510 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002511 ParseAlignmentSpecifier(DS.getAttributes());
2512 continue;
2513
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002514 // friend
2515 case tok::kw_friend:
John McCall67d1a672009-08-06 02:15:43 +00002516 if (DSContext == DSC_class)
2517 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2518 else {
2519 PrevSpec = ""; // not actually used by the diagnostic
2520 DiagID = diag::err_friend_invalid_in_context;
2521 isInvalid = true;
2522 }
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002523 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002524
Douglas Gregor8d267c52011-09-09 02:06:17 +00002525 // Modules
2526 case tok::kw___module_private__:
2527 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2528 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00002529
Sebastian Redl2ac67232009-11-05 15:47:02 +00002530 // constexpr
2531 case tok::kw_constexpr:
2532 isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2533 break;
2534
Chris Lattner80d0c892009-01-21 19:48:37 +00002535 // type-specifier
2536 case tok::kw_short:
John McCallfec54012009-08-03 20:12:06 +00002537 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2538 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002539 break;
2540 case tok::kw_long:
2541 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
John McCallfec54012009-08-03 20:12:06 +00002542 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2543 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002544 else
John McCallfec54012009-08-03 20:12:06 +00002545 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2546 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002547 break;
Francois Pichet338d7f72011-04-28 01:59:37 +00002548 case tok::kw___int64:
2549 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2550 DiagID);
2551 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002552 case tok::kw_signed:
John McCallfec54012009-08-03 20:12:06 +00002553 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2554 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002555 break;
2556 case tok::kw_unsigned:
John McCallfec54012009-08-03 20:12:06 +00002557 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
2558 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002559 break;
2560 case tok::kw__Complex:
John McCallfec54012009-08-03 20:12:06 +00002561 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
2562 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002563 break;
2564 case tok::kw__Imaginary:
John McCallfec54012009-08-03 20:12:06 +00002565 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
2566 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002567 break;
2568 case tok::kw_void:
John McCallfec54012009-08-03 20:12:06 +00002569 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
2570 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002571 break;
2572 case tok::kw_char:
John McCallfec54012009-08-03 20:12:06 +00002573 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
2574 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002575 break;
2576 case tok::kw_int:
John McCallfec54012009-08-03 20:12:06 +00002577 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
2578 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002579 break;
Richard Smith5a5a9712012-04-04 06:24:32 +00002580 case tok::kw___int128:
2581 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
2582 DiagID);
2583 break;
2584 case tok::kw_half:
2585 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
2586 DiagID);
2587 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002588 case tok::kw_float:
John McCallfec54012009-08-03 20:12:06 +00002589 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
2590 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002591 break;
2592 case tok::kw_double:
John McCallfec54012009-08-03 20:12:06 +00002593 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
2594 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002595 break;
2596 case tok::kw_wchar_t:
John McCallfec54012009-08-03 20:12:06 +00002597 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
2598 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002599 break;
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002600 case tok::kw_char16_t:
John McCallfec54012009-08-03 20:12:06 +00002601 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
2602 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002603 break;
2604 case tok::kw_char32_t:
John McCallfec54012009-08-03 20:12:06 +00002605 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
2606 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002607 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002608 case tok::kw_bool:
2609 case tok::kw__Bool:
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00002610 if (Tok.is(tok::kw_bool) &&
2611 DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
2612 DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
2613 PrevSpec = ""; // Not used by the diagnostic.
2614 DiagID = diag::err_bool_redeclaration;
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00002615 // For better error recovery.
2616 Tok.setKind(tok::identifier);
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00002617 isInvalid = true;
2618 } else {
2619 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
2620 DiagID);
2621 }
Chris Lattner80d0c892009-01-21 19:48:37 +00002622 break;
2623 case tok::kw__Decimal32:
John McCallfec54012009-08-03 20:12:06 +00002624 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
2625 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002626 break;
2627 case tok::kw__Decimal64:
John McCallfec54012009-08-03 20:12:06 +00002628 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
2629 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002630 break;
2631 case tok::kw__Decimal128:
John McCallfec54012009-08-03 20:12:06 +00002632 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
2633 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002634 break;
John Thompson82287d12010-02-05 00:12:22 +00002635 case tok::kw___vector:
2636 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
2637 break;
2638 case tok::kw___pixel:
2639 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
2640 break;
John McCalla5fc4722011-04-09 22:50:59 +00002641 case tok::kw___unknown_anytype:
2642 isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
2643 PrevSpec, DiagID);
2644 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002645
2646 // class-specifier:
2647 case tok::kw_class:
2648 case tok::kw_struct:
Chris Lattner4c97d762009-04-12 21:49:30 +00002649 case tok::kw_union: {
2650 tok::TokenKind Kind = Tok.getKind();
2651 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00002652 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
2653 EnteringContext, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00002654 continue;
Chris Lattner4c97d762009-04-12 21:49:30 +00002655 }
Chris Lattner80d0c892009-01-21 19:48:37 +00002656
2657 // enum-specifier:
2658 case tok::kw_enum:
Chris Lattner4c97d762009-04-12 21:49:30 +00002659 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00002660 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00002661 continue;
2662
2663 // cv-qualifier:
2664 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00002665 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
David Blaikie4e4d0842012-03-11 07:00:24 +00002666 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00002667 break;
2668 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00002669 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
David Blaikie4e4d0842012-03-11 07:00:24 +00002670 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00002671 break;
2672 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00002673 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
David Blaikie4e4d0842012-03-11 07:00:24 +00002674 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00002675 break;
2676
Douglas Gregord57959a2009-03-27 23:10:48 +00002677 // C++ typename-specifier:
2678 case tok::kw_typename:
John McCall9ba61662010-02-26 08:45:28 +00002679 if (TryAnnotateTypeOrScopeToken()) {
2680 DS.SetTypeSpecError();
2681 goto DoneWithDeclSpec;
2682 }
2683 if (!Tok.is(tok::kw_typename))
Douglas Gregord57959a2009-03-27 23:10:48 +00002684 continue;
2685 break;
2686
Chris Lattner80d0c892009-01-21 19:48:37 +00002687 // GNU typeof support.
2688 case tok::kw_typeof:
2689 ParseTypeofSpecifier(DS);
2690 continue;
2691
David Blaikie42d6d0c2011-12-04 05:04:18 +00002692 case tok::annot_decltype:
Anders Carlsson6fd634f2009-06-24 17:47:40 +00002693 ParseDecltypeSpecifier(DS);
2694 continue;
2695
Sean Huntdb5d44b2011-05-19 05:37:45 +00002696 case tok::kw___underlying_type:
2697 ParseUnderlyingTypeSpecifier(DS);
Eli Friedmanb001de72011-10-06 23:00:33 +00002698 continue;
2699
2700 case tok::kw__Atomic:
2701 ParseAtomicSpecifier(DS);
2702 continue;
Sean Huntdb5d44b2011-05-19 05:37:45 +00002703
Peter Collingbourne207f4d82011-03-18 22:38:29 +00002704 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00002705 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00002706 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00002707 goto DoneWithDeclSpec;
2708 case tok::kw___private:
2709 case tok::kw___global:
2710 case tok::kw___local:
2711 case tok::kw___constant:
2712 case tok::kw___read_only:
2713 case tok::kw___write_only:
2714 case tok::kw___read_write:
2715 ParseOpenCLQualifiers(DS);
2716 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00002717
Steve Naroffd3ded1f2008-06-05 00:02:44 +00002718 case tok::less:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002719 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerbce61352008-07-26 00:20:22 +00002720 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
2721 // but we support it.
David Blaikie4e4d0842012-03-11 07:00:24 +00002722 if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
Chris Lattnerbce61352008-07-26 00:20:22 +00002723 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00002724
Douglas Gregor46f936e2010-11-19 17:10:50 +00002725 if (!ParseObjCProtocolQualifiers(DS))
2726 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
2727 << FixItHint::CreateInsertion(Loc, "id")
2728 << SourceRange(Loc, DS.getSourceRange().getEnd());
Chad Rosier8decdee2012-06-26 22:30:43 +00002729
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002730 // Need to support trailing type qualifiers (e.g. "id<p> const").
2731 // If a type specifier follows, it will be diagnosed elsewhere.
2732 continue;
Reid Spencer5f016e22007-07-11 17:01:13 +00002733 }
John McCallfec54012009-08-03 20:12:06 +00002734 // If the specifier wasn't legal, issue a diagnostic.
Reid Spencer5f016e22007-07-11 17:01:13 +00002735 if (isInvalid) {
2736 assert(PrevSpec && "Method did not return previous specifier!");
John McCallfec54012009-08-03 20:12:06 +00002737 assert(DiagID);
Chad Rosier8decdee2012-06-26 22:30:43 +00002738
Douglas Gregorae2fb142010-08-23 14:34:43 +00002739 if (DiagID == diag::ext_duplicate_declspec)
2740 Diag(Tok, DiagID)
2741 << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
2742 else
2743 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00002744 }
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002745
Chris Lattner81c018d2008-03-13 06:29:04 +00002746 DS.SetRangeEnd(Tok.getLocation());
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00002747 if (DiagID != diag::err_bool_redeclaration)
2748 ConsumeToken();
Sean Hunt2edf0a22012-06-23 05:07:58 +00002749
2750 AttrsLastTime = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00002751 }
2752}
Douglas Gregoradcac882008-12-01 23:54:00 +00002753
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002754/// ParseStructDeclaration - Parse a struct declaration without the terminating
2755/// semicolon.
2756///
Reid Spencer5f016e22007-07-11 17:01:13 +00002757/// struct-declaration:
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002758/// specifier-qualifier-list struct-declarator-list
Reid Spencer5f016e22007-07-11 17:01:13 +00002759/// [GNU] __extension__ struct-declaration
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002760/// [GNU] specifier-qualifier-list
Reid Spencer5f016e22007-07-11 17:01:13 +00002761/// struct-declarator-list:
2762/// struct-declarator
2763/// struct-declarator-list ',' struct-declarator
2764/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
2765/// struct-declarator:
2766/// declarator
2767/// [GNU] declarator attributes[opt]
2768/// declarator[opt] ':' constant-expression
2769/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
2770///
Chris Lattnere1359422008-04-10 06:46:29 +00002771void Parser::
John McCallbdd563e2009-11-03 02:38:08 +00002772ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
Chad Rosier8decdee2012-06-26 22:30:43 +00002773
Chris Lattnerc46d1a12008-10-20 06:45:43 +00002774 if (Tok.is(tok::kw___extension__)) {
2775 // __extension__ silences extension warnings in the subexpression.
2776 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroff28a7ca82007-08-20 22:28:22 +00002777 ConsumeToken();
Chris Lattnerc46d1a12008-10-20 06:45:43 +00002778 return ParseStructDeclaration(DS, Fields);
2779 }
Mike Stump1eb44332009-09-09 15:08:12 +00002780
Steve Naroff28a7ca82007-08-20 22:28:22 +00002781 // Parse the common specifier-qualifiers-list piece.
Steve Naroff28a7ca82007-08-20 22:28:22 +00002782 ParseSpecifierQualifierList(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00002783
Douglas Gregor4920f1f2009-01-12 22:49:06 +00002784 // If there are no declarators, this is a free-standing declaration
2785 // specifier. Let the actions module cope with it.
Chris Lattner04d66662007-10-09 17:33:22 +00002786 if (Tok.is(tok::semi)) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00002787 Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, DS);
Steve Naroff28a7ca82007-08-20 22:28:22 +00002788 return;
2789 }
2790
2791 // Read struct-declarators until we find the semicolon.
John McCallbdd563e2009-11-03 02:38:08 +00002792 bool FirstDeclarator = true;
Richard Smith7984de32012-01-12 23:53:29 +00002793 SourceLocation CommaLoc;
Steve Naroff28a7ca82007-08-20 22:28:22 +00002794 while (1) {
John McCall92576642012-05-07 06:16:41 +00002795 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
John McCallbdd563e2009-11-03 02:38:08 +00002796 FieldDeclarator DeclaratorInfo(DS);
Richard Smith7984de32012-01-12 23:53:29 +00002797 DeclaratorInfo.D.setCommaLoc(CommaLoc);
John McCallbdd563e2009-11-03 02:38:08 +00002798
2799 // Attributes are only allowed here on successive declarators.
John McCall7f040a92010-12-24 02:08:15 +00002800 if (!FirstDeclarator)
2801 MaybeParseGNUAttributes(DeclaratorInfo.D);
Mike Stump1eb44332009-09-09 15:08:12 +00002802
Steve Naroff28a7ca82007-08-20 22:28:22 +00002803 /// struct-declarator: declarator
2804 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattnera1efc8c2009-12-10 01:59:24 +00002805 if (Tok.isNot(tok::colon)) {
2806 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
2807 ColonProtectionRAIIObject X(*this);
Chris Lattnere1359422008-04-10 06:46:29 +00002808 ParseDeclarator(DeclaratorInfo.D);
Chris Lattnera1efc8c2009-12-10 01:59:24 +00002809 }
Mike Stump1eb44332009-09-09 15:08:12 +00002810
Chris Lattner04d66662007-10-09 17:33:22 +00002811 if (Tok.is(tok::colon)) {
Steve Naroff28a7ca82007-08-20 22:28:22 +00002812 ConsumeToken();
John McCall60d7b3a2010-08-24 06:29:42 +00002813 ExprResult Res(ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00002814 if (Res.isInvalid())
Steve Naroff28a7ca82007-08-20 22:28:22 +00002815 SkipUntil(tok::semi, true, true);
Chris Lattner60b1e3e2008-04-10 06:15:14 +00002816 else
Sebastian Redleffa8d12008-12-10 00:02:53 +00002817 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroff28a7ca82007-08-20 22:28:22 +00002818 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00002819
Steve Naroff28a7ca82007-08-20 22:28:22 +00002820 // If attributes exist after the declarator, parse them.
John McCall7f040a92010-12-24 02:08:15 +00002821 MaybeParseGNUAttributes(DeclaratorInfo.D);
Sebastian Redlab197ba2009-02-09 18:23:29 +00002822
John McCallbdd563e2009-11-03 02:38:08 +00002823 // We're done with this declarator; invoke the callback.
John McCalld226f652010-08-21 09:40:31 +00002824 Decl *D = Fields.invoke(DeclaratorInfo);
John McCall54abf7d2009-11-04 02:18:39 +00002825 PD.complete(D);
John McCallbdd563e2009-11-03 02:38:08 +00002826
Steve Naroff28a7ca82007-08-20 22:28:22 +00002827 // If we don't have a comma, it is either the end of the list (a ';')
2828 // or an error, bail out.
Chris Lattner04d66662007-10-09 17:33:22 +00002829 if (Tok.isNot(tok::comma))
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002830 return;
Sebastian Redlab197ba2009-02-09 18:23:29 +00002831
Steve Naroff28a7ca82007-08-20 22:28:22 +00002832 // Consume the comma.
Richard Smith7984de32012-01-12 23:53:29 +00002833 CommaLoc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00002834
John McCallbdd563e2009-11-03 02:38:08 +00002835 FirstDeclarator = false;
Steve Naroff28a7ca82007-08-20 22:28:22 +00002836 }
Steve Naroff28a7ca82007-08-20 22:28:22 +00002837}
2838
2839/// ParseStructUnionBody
2840/// struct-contents:
2841/// struct-declaration-list
2842/// [EXT] empty
2843/// [GNU] "struct-declaration-list" without terminatoring ';'
2844/// struct-declaration-list:
2845/// struct-declaration
2846/// struct-declaration-list struct-declaration
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002847/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroff28a7ca82007-08-20 22:28:22 +00002848///
Reid Spencer5f016e22007-07-11 17:01:13 +00002849void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
John McCalld226f652010-08-21 09:40:31 +00002850 unsigned TagType, Decl *TagDecl) {
John McCallf312b1e2010-08-26 23:41:50 +00002851 PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2852 "parsing struct/union body");
Mike Stump1eb44332009-09-09 15:08:12 +00002853
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002854 BalancedDelimiterTracker T(*this, tok::l_brace);
2855 if (T.consumeOpen())
2856 return;
Mike Stump1eb44332009-09-09 15:08:12 +00002857
Douglas Gregor3218c4b2009-01-09 22:42:13 +00002858 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00002859 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
Douglas Gregor72de6672009-01-08 20:45:30 +00002860
Reid Spencer5f016e22007-07-11 17:01:13 +00002861 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
2862 // C++.
David Blaikie4e4d0842012-03-11 07:00:24 +00002863 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {
Richard Smithd7c56e12011-12-29 21:57:33 +00002864 Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union);
2865 Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union);
2866 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002867
Chris Lattner5f9e2722011-07-23 10:55:15 +00002868 SmallVector<Decl *, 32> FieldDecls;
Chris Lattnere1359422008-04-10 06:46:29 +00002869
Reid Spencer5f016e22007-07-11 17:01:13 +00002870 // While we still have something to read, read the declarations in the struct.
Chris Lattner04d66662007-10-09 17:33:22 +00002871 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002872 // Each iteration of this loop reads one struct-declaration.
Mike Stump1eb44332009-09-09 15:08:12 +00002873
Reid Spencer5f016e22007-07-11 17:01:13 +00002874 // Check for extraneous top-level semicolon.
Chris Lattner04d66662007-10-09 17:33:22 +00002875 if (Tok.is(tok::semi)) {
Richard Trieu4b0e6f12012-05-16 19:04:59 +00002876 ConsumeExtraSemi(InsideStruct,
2877 DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
Reid Spencer5f016e22007-07-11 17:01:13 +00002878 continue;
2879 }
Chris Lattnere1359422008-04-10 06:46:29 +00002880
2881 // Parse all the comma separated declarators.
John McCall0b7e6782011-03-24 11:26:52 +00002882 DeclSpec DS(AttrFactory);
Mike Stump1eb44332009-09-09 15:08:12 +00002883
John McCallbdd563e2009-11-03 02:38:08 +00002884 if (!Tok.is(tok::at)) {
2885 struct CFieldCallback : FieldCallback {
2886 Parser &P;
John McCalld226f652010-08-21 09:40:31 +00002887 Decl *TagDecl;
Chris Lattner5f9e2722011-07-23 10:55:15 +00002888 SmallVectorImpl<Decl *> &FieldDecls;
John McCallbdd563e2009-11-03 02:38:08 +00002889
John McCalld226f652010-08-21 09:40:31 +00002890 CFieldCallback(Parser &P, Decl *TagDecl,
Chris Lattner5f9e2722011-07-23 10:55:15 +00002891 SmallVectorImpl<Decl *> &FieldDecls) :
John McCallbdd563e2009-11-03 02:38:08 +00002892 P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
2893
John McCalld226f652010-08-21 09:40:31 +00002894 virtual Decl *invoke(FieldDeclarator &FD) {
John McCallbdd563e2009-11-03 02:38:08 +00002895 // Install the declarator into the current TagDecl.
John McCalld226f652010-08-21 09:40:31 +00002896 Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
John McCall4ba39712009-11-03 21:13:47 +00002897 FD.D.getDeclSpec().getSourceRange().getBegin(),
2898 FD.D, FD.BitfieldSize);
John McCallbdd563e2009-11-03 02:38:08 +00002899 FieldDecls.push_back(Field);
2900 return Field;
Douglas Gregor91a28862009-08-26 14:27:30 +00002901 }
John McCallbdd563e2009-11-03 02:38:08 +00002902 } Callback(*this, TagDecl, FieldDecls);
2903
2904 ParseStructDeclaration(DS, Callback);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002905 } else { // Handle @defs
2906 ConsumeToken();
2907 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
2908 Diag(Tok, diag::err_unexpected_at);
Chris Lattner3e156ad2010-02-02 00:37:27 +00002909 SkipUntil(tok::semi, true);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002910 continue;
2911 }
2912 ConsumeToken();
2913 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
2914 if (!Tok.is(tok::identifier)) {
2915 Diag(Tok, diag::err_expected_ident);
Chris Lattner3e156ad2010-02-02 00:37:27 +00002916 SkipUntil(tok::semi, true);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002917 continue;
2918 }
Chris Lattner5f9e2722011-07-23 10:55:15 +00002919 SmallVector<Decl *, 16> Fields;
Douglas Gregor23c94db2010-07-02 17:43:08 +00002920 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
Douglas Gregor44b43212008-12-11 16:49:14 +00002921 Tok.getIdentifierInfo(), Fields);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002922 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
2923 ConsumeToken();
2924 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
Mike Stump1eb44332009-09-09 15:08:12 +00002925 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002926
Chris Lattner04d66662007-10-09 17:33:22 +00002927 if (Tok.is(tok::semi)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002928 ConsumeToken();
Chris Lattner04d66662007-10-09 17:33:22 +00002929 } else if (Tok.is(tok::r_brace)) {
Chris Lattner3e156ad2010-02-02 00:37:27 +00002930 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
Reid Spencer5f016e22007-07-11 17:01:13 +00002931 break;
2932 } else {
Chris Lattner3e156ad2010-02-02 00:37:27 +00002933 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
2934 // Skip to end of block or statement to avoid ext-warning on extra ';'.
Reid Spencer5f016e22007-07-11 17:01:13 +00002935 SkipUntil(tok::r_brace, true, true);
Chris Lattner3e156ad2010-02-02 00:37:27 +00002936 // If we stopped at a ';', eat it.
2937 if (Tok.is(tok::semi)) ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00002938 }
2939 }
Mike Stump1eb44332009-09-09 15:08:12 +00002940
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002941 T.consumeClose();
Mike Stump1eb44332009-09-09 15:08:12 +00002942
John McCall0b7e6782011-03-24 11:26:52 +00002943 ParsedAttributes attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00002944 // If attributes exist after struct contents, parse them.
John McCall7f040a92010-12-24 02:08:15 +00002945 MaybeParseGNUAttributes(attrs);
Daniel Dunbar1bfe1c22008-10-03 02:03:53 +00002946
Douglas Gregor23c94db2010-07-02 17:43:08 +00002947 Actions.ActOnFields(getCurScope(),
David Blaikie77b6de02011-09-22 02:58:26 +00002948 RecordLoc, TagDecl, FieldDecls,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002949 T.getOpenLocation(), T.getCloseLocation(),
John McCall7f040a92010-12-24 02:08:15 +00002950 attrs.getList());
Douglas Gregor72de6672009-01-08 20:45:30 +00002951 StructScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002952 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
2953 T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00002954}
2955
Reid Spencer5f016e22007-07-11 17:01:13 +00002956/// ParseEnumSpecifier
2957/// enum-specifier: [C99 6.7.2.2]
2958/// 'enum' identifier[opt] '{' enumerator-list '}'
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002959///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00002960/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
2961/// '}' attributes[opt]
Aaron Ballman6454a022012-03-01 04:09:28 +00002962/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
2963/// '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00002964/// 'enum' identifier
2965/// [GNU] 'enum' attributes[opt] identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002966///
Richard Smith1af83c42012-03-23 03:33:32 +00002967/// [C++11] enum-head '{' enumerator-list[opt] '}'
2968/// [C++11] enum-head '{' enumerator-list ',' '}'
Douglas Gregor1274ccd2010-10-08 23:50:27 +00002969///
Richard Smith1af83c42012-03-23 03:33:32 +00002970/// enum-head: [C++11]
2971/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
2972/// enum-key attribute-specifier-seq[opt] nested-name-specifier
2973/// identifier enum-base[opt]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00002974///
Richard Smith1af83c42012-03-23 03:33:32 +00002975/// enum-key: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00002976/// 'enum'
2977/// 'enum' 'class'
2978/// 'enum' 'struct'
2979///
Richard Smith1af83c42012-03-23 03:33:32 +00002980/// enum-base: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00002981/// ':' type-specifier-seq
2982///
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002983/// [C++] elaborated-type-specifier:
2984/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
2985///
Chris Lattner4c97d762009-04-12 21:49:30 +00002986void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Douglas Gregor9b9edd62010-03-02 17:53:14 +00002987 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00002988 AccessSpecifier AS, DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002989 // Parse the tag portion of this.
Douglas Gregor374929f2009-09-18 15:37:17 +00002990 if (Tok.is(tok::code_completion)) {
2991 // Code completion for an enum name.
Douglas Gregor23c94db2010-07-02 17:43:08 +00002992 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002993 return cutOffParsing();
Douglas Gregor374929f2009-09-18 15:37:17 +00002994 }
John McCall57c13002011-07-06 05:58:41 +00002995
Sean Hunt2edf0a22012-06-23 05:07:58 +00002996 // If attributes exist after tag, parse them.
2997 ParsedAttributesWithRange attrs(AttrFactory);
2998 MaybeParseGNUAttributes(attrs);
2999 MaybeParseCXX0XAttributes(attrs);
3000
3001 // If declspecs exist after tag, parse them.
3002 while (Tok.is(tok::kw___declspec))
3003 ParseMicrosoftDeclSpec(attrs);
3004
Richard Smithbdad7a22012-01-10 01:33:14 +00003005 SourceLocation ScopedEnumKWLoc;
John McCall57c13002011-07-06 05:58:41 +00003006 bool IsScopedUsingClassTag = false;
3007
John McCall1e12b3d2012-06-23 22:30:04 +00003008 // In C++11, recognize 'enum class' and 'enum struct'.
David Blaikie4e4d0842012-03-11 07:00:24 +00003009 if (getLangOpts().CPlusPlus0x &&
John McCall57c13002011-07-06 05:58:41 +00003010 (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
Richard Smith7fe62082011-10-15 05:09:34 +00003011 Diag(Tok, diag::warn_cxx98_compat_scoped_enum);
John McCall57c13002011-07-06 05:58:41 +00003012 IsScopedUsingClassTag = Tok.is(tok::kw_class);
Richard Smithbdad7a22012-01-10 01:33:14 +00003013 ScopedEnumKWLoc = ConsumeToken();
Chad Rosier8decdee2012-06-26 22:30:43 +00003014
John McCall1e12b3d2012-06-23 22:30:04 +00003015 // Attributes are not allowed between these keywords. Diagnose,
3016 // but then just treat them like they appeared in the right place.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003017 ProhibitAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003018
3019 // They are allowed afterwards, though.
3020 MaybeParseGNUAttributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003021 MaybeParseCXX0XAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003022 while (Tok.is(tok::kw___declspec))
3023 ParseMicrosoftDeclSpec(attrs);
John McCall57c13002011-07-06 05:58:41 +00003024 }
Richard Smith1af83c42012-03-23 03:33:32 +00003025
John McCall13489672012-05-07 06:16:58 +00003026 // C++11 [temp.explicit]p12:
3027 // The usual access controls do not apply to names used to specify
3028 // explicit instantiations.
3029 // We extend this to also cover explicit specializations. Note that
3030 // we don't suppress if this turns out to be an elaborated type
3031 // specifier.
3032 bool shouldDelayDiagsInTag =
3033 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3034 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3035 SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
Richard Smith1af83c42012-03-23 03:33:32 +00003036
Richard Smith7796eb52012-03-12 08:56:40 +00003037 // Enum definitions should not be parsed in a trailing-return-type.
3038 bool AllowDeclaration = DSC != DSC_trailing;
3039
3040 bool AllowFixedUnderlyingType = AllowDeclaration &&
3041 (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt ||
3042 getLangOpts().ObjC2);
John McCall57c13002011-07-06 05:58:41 +00003043
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00003044 CXXScopeSpec &SS = DS.getTypeSpecScope();
David Blaikie4e4d0842012-03-11 07:00:24 +00003045 if (getLangOpts().CPlusPlus) {
John McCall57c13002011-07-06 05:58:41 +00003046 // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3047 // if a fixed underlying type is allowed.
3048 ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
Chad Rosier8decdee2012-06-26 22:30:43 +00003049
3050 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003051 /*EnteringContext=*/false))
John McCall9ba61662010-02-26 08:45:28 +00003052 return;
3053
3054 if (SS.isSet() && Tok.isNot(tok::identifier)) {
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003055 Diag(Tok, diag::err_expected_ident);
3056 if (Tok.isNot(tok::l_brace)) {
3057 // Has no name and is not a definition.
3058 // Skip the rest of this declarator, up until the comma or semicolon.
3059 SkipUntil(tok::comma, true);
3060 return;
3061 }
3062 }
3063 }
Mike Stump1eb44332009-09-09 15:08:12 +00003064
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003065 // Must have either 'enum name' or 'enum {...}'.
Douglas Gregorb9075602011-02-22 02:55:24 +00003066 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
Richard Smith7796eb52012-03-12 08:56:40 +00003067 !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003068 Diag(Tok, diag::err_expected_ident_lbrace);
Mike Stump1eb44332009-09-09 15:08:12 +00003069
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003070 // Skip the rest of this declarator, up until the comma or semicolon.
3071 SkipUntil(tok::comma, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00003072 return;
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003073 }
Mike Stump1eb44332009-09-09 15:08:12 +00003074
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003075 // If an identifier is present, consume and remember it.
3076 IdentifierInfo *Name = 0;
3077 SourceLocation NameLoc;
3078 if (Tok.is(tok::identifier)) {
3079 Name = Tok.getIdentifierInfo();
3080 NameLoc = ConsumeToken();
3081 }
Mike Stump1eb44332009-09-09 15:08:12 +00003082
Richard Smithbdad7a22012-01-10 01:33:14 +00003083 if (!Name && ScopedEnumKWLoc.isValid()) {
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003084 // C++0x 7.2p2: The optional identifier shall not be omitted in the
3085 // declaration of a scoped enumeration.
3086 Diag(Tok, diag::err_scoped_enum_missing_identifier);
Richard Smithbdad7a22012-01-10 01:33:14 +00003087 ScopedEnumKWLoc = SourceLocation();
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003088 IsScopedUsingClassTag = false;
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003089 }
3090
John McCall13489672012-05-07 06:16:58 +00003091 // Okay, end the suppression area. We'll decide whether to emit the
3092 // diagnostics in a second.
3093 if (shouldDelayDiagsInTag)
3094 diagsFromTag.done();
Richard Smith1af83c42012-03-23 03:33:32 +00003095
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003096 TypeResult BaseType;
3097
Douglas Gregora61b3e72010-12-01 17:42:47 +00003098 // Parse the fixed underlying type.
Richard Smith139be702012-07-02 19:14:01 +00003099 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
Douglas Gregorb9075602011-02-22 02:55:24 +00003100 if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003101 bool PossibleBitfield = false;
Richard Smith139be702012-07-02 19:14:01 +00003102 if (CanBeBitfield) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003103 // If we're in class scope, this can either be an enum declaration with
3104 // an underlying type, or a declaration of a bitfield member. We try to
3105 // use a simple disambiguation scheme first to catch the common cases
Chad Rosier8decdee2012-06-26 22:30:43 +00003106 // (integer literal, sizeof); if it's still ambiguous, we then consider
3107 // anything that's a simple-type-specifier followed by '(' as an
3108 // expression. This suffices because function types are not valid
Douglas Gregora61b3e72010-12-01 17:42:47 +00003109 // underlying types anyway.
3110 TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
Chad Rosier8decdee2012-06-26 22:30:43 +00003111 // If the next token starts an expression, we know we're parsing a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003112 // bit-field. This is the common case.
3113 if (TPR == TPResult::True())
3114 PossibleBitfield = true;
3115 // If the next token starts a type-specifier-seq, it may be either a
3116 // a fixed underlying type or the start of a function-style cast in C++;
Chad Rosier8decdee2012-06-26 22:30:43 +00003117 // lookahead one more token to see if it's obvious that we have a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003118 // fixed underlying type.
Chad Rosier8decdee2012-06-26 22:30:43 +00003119 else if (TPR == TPResult::False() &&
Douglas Gregora61b3e72010-12-01 17:42:47 +00003120 GetLookAheadToken(2).getKind() == tok::semi) {
3121 // Consume the ':'.
3122 ConsumeToken();
3123 } else {
3124 // We have the start of a type-specifier-seq, so we have to perform
3125 // tentative parsing to determine whether we have an expression or a
3126 // type.
3127 TentativeParsingAction TPA(*this);
3128
3129 // Consume the ':'.
3130 ConsumeToken();
Richard Smithd81e9612012-02-23 01:36:12 +00003131
3132 // If we see a type specifier followed by an open-brace, we have an
3133 // ambiguity between an underlying type and a C++11 braced
3134 // function-style cast. Resolve this by always treating it as an
3135 // underlying type.
3136 // FIXME: The standard is not entirely clear on how to disambiguate in
3137 // this case.
David Blaikie4e4d0842012-03-11 07:00:24 +00003138 if ((getLangOpts().CPlusPlus &&
Richard Smithd81e9612012-02-23 01:36:12 +00003139 isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
David Blaikie4e4d0842012-03-11 07:00:24 +00003140 (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003141 // We'll parse this as a bitfield later.
3142 PossibleBitfield = true;
3143 TPA.Revert();
3144 } else {
3145 // We have a type-specifier-seq.
3146 TPA.Commit();
3147 }
3148 }
3149 } else {
3150 // Consume the ':'.
3151 ConsumeToken();
3152 }
3153
3154 if (!PossibleBitfield) {
3155 SourceRange Range;
3156 BaseType = ParseTypeName(&Range);
Chad Rosier8decdee2012-06-26 22:30:43 +00003157
David Blaikie4e4d0842012-03-11 07:00:24 +00003158 if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2)
Douglas Gregor86f208c2011-02-22 20:32:04 +00003159 Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
3160 << Range;
David Blaikie4e4d0842012-03-11 07:00:24 +00003161 if (getLangOpts().CPlusPlus0x)
Richard Smith7fe62082011-10-15 05:09:34 +00003162 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
Douglas Gregora61b3e72010-12-01 17:42:47 +00003163 }
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003164 }
3165
Richard Smithbdad7a22012-01-10 01:33:14 +00003166 // There are four options here. If we have 'friend enum foo;' then this is a
3167 // friend declaration, and cannot have an accompanying definition. If we have
3168 // 'enum foo;', then this is a forward declaration. If we have
3169 // 'enum foo {...' then this is a definition. Otherwise we have something
3170 // like 'enum foo xyz', a reference.
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003171 //
3172 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3173 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
3174 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
3175 //
John McCallf312b1e2010-08-26 23:41:50 +00003176 Sema::TagUseKind TUK;
John McCall13489672012-05-07 06:16:58 +00003177 if (!AllowDeclaration) {
Richard Smith7796eb52012-03-12 08:56:40 +00003178 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003179 } else if (Tok.is(tok::l_brace)) {
3180 if (DS.isFriendSpecified()) {
3181 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3182 << SourceRange(DS.getFriendSpecLoc());
3183 ConsumeBrace();
3184 SkipUntil(tok::r_brace);
3185 TUK = Sema::TUK_Friend;
3186 } else {
3187 TUK = Sema::TUK_Definition;
3188 }
Richard Smithc9f35172012-06-25 21:37:02 +00003189 } else if (DSC != DSC_type_specifier &&
3190 (Tok.is(tok::semi) ||
Richard Smith139be702012-07-02 19:14:01 +00003191 (Tok.isAtStartOfLine() &&
3192 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
Richard Smithc9f35172012-06-25 21:37:02 +00003193 TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3194 if (Tok.isNot(tok::semi)) {
3195 // A semicolon was missing after this declaration. Diagnose and recover.
3196 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3197 "enum");
3198 PP.EnterToken(Tok);
3199 Tok.setKind(tok::semi);
3200 }
John McCall13489672012-05-07 06:16:58 +00003201 } else {
John McCallf312b1e2010-08-26 23:41:50 +00003202 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003203 }
3204
3205 // If this is an elaborated type specifier, and we delayed
3206 // diagnostics before, just merge them into the current pool.
3207 if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3208 diagsFromTag.redelay();
3209 }
Richard Smith1af83c42012-03-23 03:33:32 +00003210
3211 MultiTemplateParamsArg TParams;
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003212 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
John McCallf312b1e2010-08-26 23:41:50 +00003213 TUK != Sema::TUK_Reference) {
Richard Smith1af83c42012-03-23 03:33:32 +00003214 if (!getLangOpts().CPlusPlus0x || !SS.isSet()) {
3215 // Skip the rest of this declarator, up until the comma or semicolon.
3216 Diag(Tok, diag::err_enum_template);
3217 SkipUntil(tok::comma, true);
3218 return;
3219 }
3220
3221 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3222 // Enumerations can't be explicitly instantiated.
3223 DS.SetTypeSpecError();
3224 Diag(StartLoc, diag::err_explicit_instantiation_enum);
3225 return;
3226 }
3227
3228 assert(TemplateInfo.TemplateParams && "no template parameters");
3229 TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3230 TemplateInfo.TemplateParams->size());
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003231 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003232
Sean Hunt2edf0a22012-06-23 05:07:58 +00003233 if (TUK == Sema::TUK_Reference)
3234 ProhibitAttributes(attrs);
Richard Smith1af83c42012-03-23 03:33:32 +00003235
Douglas Gregorb9075602011-02-22 02:55:24 +00003236 if (!Name && TUK != Sema::TUK_Definition) {
3237 Diag(Tok, diag::err_enumerator_unnamed_no_def);
Richard Smith1af83c42012-03-23 03:33:32 +00003238
Douglas Gregorb9075602011-02-22 02:55:24 +00003239 // Skip the rest of this declarator, up until the comma or semicolon.
3240 SkipUntil(tok::comma, true);
3241 return;
3242 }
Richard Smith1af83c42012-03-23 03:33:32 +00003243
Douglas Gregor402abb52009-05-28 23:31:59 +00003244 bool Owned = false;
John McCallc4e70192009-09-11 04:59:25 +00003245 bool IsDependent = false;
Douglas Gregor48c89f42010-04-24 16:38:41 +00003246 const char *PrevSpec = 0;
3247 unsigned DiagID;
John McCalld226f652010-08-21 09:40:31 +00003248 Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
John McCall7f040a92010-12-24 02:08:15 +00003249 StartLoc, SS, Name, NameLoc, attrs.getList(),
Richard Smith1af83c42012-03-23 03:33:32 +00003250 AS, DS.getModulePrivateSpecLoc(), TParams,
Richard Smithbdad7a22012-01-10 01:33:14 +00003251 Owned, IsDependent, ScopedEnumKWLoc,
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003252 IsScopedUsingClassTag, BaseType);
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003253
Douglas Gregor48c89f42010-04-24 16:38:41 +00003254 if (IsDependent) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003255 // This enum has a dependent nested-name-specifier. Handle it as a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003256 // dependent tag.
3257 if (!Name) {
3258 DS.SetTypeSpecError();
3259 Diag(Tok, diag::err_expected_type_name_after_typename);
3260 return;
3261 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003262
Douglas Gregor23c94db2010-07-02 17:43:08 +00003263 TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
Chad Rosier8decdee2012-06-26 22:30:43 +00003264 TUK, SS, Name, StartLoc,
Douglas Gregor48c89f42010-04-24 16:38:41 +00003265 NameLoc);
3266 if (Type.isInvalid()) {
3267 DS.SetTypeSpecError();
3268 return;
3269 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003270
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003271 if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3272 NameLoc.isValid() ? NameLoc : StartLoc,
3273 PrevSpec, DiagID, Type.get()))
Douglas Gregor48c89f42010-04-24 16:38:41 +00003274 Diag(StartLoc, DiagID) << PrevSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00003275
Douglas Gregor48c89f42010-04-24 16:38:41 +00003276 return;
3277 }
Mike Stump1eb44332009-09-09 15:08:12 +00003278
John McCalld226f652010-08-21 09:40:31 +00003279 if (!TagDecl) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003280 // The action failed to produce an enumeration tag. If this is a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003281 // definition, consume the entire definition.
Richard Smith7796eb52012-03-12 08:56:40 +00003282 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
Douglas Gregor48c89f42010-04-24 16:38:41 +00003283 ConsumeBrace();
3284 SkipUntil(tok::r_brace);
3285 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003286
Douglas Gregor48c89f42010-04-24 16:38:41 +00003287 DS.SetTypeSpecError();
3288 return;
3289 }
Richard Smithbdad7a22012-01-10 01:33:14 +00003290
Richard Smithc9f35172012-06-25 21:37:02 +00003291 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
John McCall13489672012-05-07 06:16:58 +00003292 ParseEnumBody(StartLoc, TagDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00003293
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003294 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3295 NameLoc.isValid() ? NameLoc : StartLoc,
3296 PrevSpec, DiagID, TagDecl, Owned))
John McCallfec54012009-08-03 20:12:06 +00003297 Diag(StartLoc, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003298}
3299
3300/// ParseEnumBody - Parse a {} enclosed enumerator-list.
3301/// enumerator-list:
3302/// enumerator
3303/// enumerator-list ',' enumerator
3304/// enumerator:
3305/// enumeration-constant
3306/// enumeration-constant '=' constant-expression
3307/// enumeration-constant:
3308/// identifier
3309///
John McCalld226f652010-08-21 09:40:31 +00003310void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Douglas Gregor074149e2009-01-05 19:45:36 +00003311 // Enter the scope of the enum body and start the definition.
3312 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003313 Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
Douglas Gregor074149e2009-01-05 19:45:36 +00003314
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003315 BalancedDelimiterTracker T(*this, tok::l_brace);
3316 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00003317
Chris Lattner7946dd32007-08-27 17:24:30 +00003318 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
David Blaikie4e4d0842012-03-11 07:00:24 +00003319 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
Fariborz Jahanian05115522010-05-28 22:23:22 +00003320 Diag(Tok, diag::error_empty_enum);
Mike Stump1eb44332009-09-09 15:08:12 +00003321
Chris Lattner5f9e2722011-07-23 10:55:15 +00003322 SmallVector<Decl *, 32> EnumConstantDecls;
Reid Spencer5f016e22007-07-11 17:01:13 +00003323
John McCalld226f652010-08-21 09:40:31 +00003324 Decl *LastEnumConstDecl = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00003325
Reid Spencer5f016e22007-07-11 17:01:13 +00003326 // Parse the enumerator-list.
Chris Lattner04d66662007-10-09 17:33:22 +00003327 while (Tok.is(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003328 IdentifierInfo *Ident = Tok.getIdentifierInfo();
3329 SourceLocation IdentLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003330
John McCall5b629aa2010-10-22 23:36:17 +00003331 // If attributes exist after the enumerator, parse them.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003332 ParsedAttributesWithRange attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003333 MaybeParseGNUAttributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003334 MaybeParseCXX0XAttributes(attrs);
3335 ProhibitAttributes(attrs);
John McCall5b629aa2010-10-22 23:36:17 +00003336
Reid Spencer5f016e22007-07-11 17:01:13 +00003337 SourceLocation EqualLoc;
John McCall60d7b3a2010-08-24 06:29:42 +00003338 ExprResult AssignedVal;
John McCall92576642012-05-07 06:16:41 +00003339 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
Chad Rosier8decdee2012-06-26 22:30:43 +00003340
Chris Lattner04d66662007-10-09 17:33:22 +00003341 if (Tok.is(tok::equal)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003342 EqualLoc = ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00003343 AssignedVal = ParseConstantExpression();
3344 if (AssignedVal.isInvalid())
Reid Spencer5f016e22007-07-11 17:01:13 +00003345 SkipUntil(tok::comma, tok::r_brace, true, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00003346 }
Mike Stump1eb44332009-09-09 15:08:12 +00003347
Reid Spencer5f016e22007-07-11 17:01:13 +00003348 // Install the enumerator constant into EnumDecl.
John McCalld226f652010-08-21 09:40:31 +00003349 Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3350 LastEnumConstDecl,
3351 IdentLoc, Ident,
John McCall7f040a92010-12-24 02:08:15 +00003352 attrs.getList(), EqualLoc,
John McCalld226f652010-08-21 09:40:31 +00003353 AssignedVal.release());
Fariborz Jahanian5a477db2011-12-09 01:15:54 +00003354 PD.complete(EnumConstDecl);
Chad Rosier8decdee2012-06-26 22:30:43 +00003355
Reid Spencer5f016e22007-07-11 17:01:13 +00003356 EnumConstantDecls.push_back(EnumConstDecl);
3357 LastEnumConstDecl = EnumConstDecl;
Mike Stump1eb44332009-09-09 15:08:12 +00003358
Douglas Gregor751f6922010-09-07 14:51:08 +00003359 if (Tok.is(tok::identifier)) {
3360 // We're missing a comma between enumerators.
3361 SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
Chad Rosier8decdee2012-06-26 22:30:43 +00003362 Diag(Loc, diag::err_enumerator_list_missing_comma)
Douglas Gregor751f6922010-09-07 14:51:08 +00003363 << FixItHint::CreateInsertion(Loc, ", ");
3364 continue;
3365 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003366
Chris Lattner04d66662007-10-09 17:33:22 +00003367 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +00003368 break;
3369 SourceLocation CommaLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003370
Richard Smith7fe62082011-10-15 05:09:34 +00003371 if (Tok.isNot(tok::identifier)) {
David Blaikie4e4d0842012-03-11 07:00:24 +00003372 if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x)
Richard Smith7fe62082011-10-15 05:09:34 +00003373 Diag(CommaLoc, diag::ext_enumerator_list_comma)
David Blaikie4e4d0842012-03-11 07:00:24 +00003374 << getLangOpts().CPlusPlus
Richard Smith7fe62082011-10-15 05:09:34 +00003375 << FixItHint::CreateRemoval(CommaLoc);
David Blaikie4e4d0842012-03-11 07:00:24 +00003376 else if (getLangOpts().CPlusPlus0x)
Richard Smith7fe62082011-10-15 05:09:34 +00003377 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3378 << FixItHint::CreateRemoval(CommaLoc);
3379 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003380 }
Mike Stump1eb44332009-09-09 15:08:12 +00003381
Reid Spencer5f016e22007-07-11 17:01:13 +00003382 // Eat the }.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003383 T.consumeClose();
Reid Spencer5f016e22007-07-11 17:01:13 +00003384
Reid Spencer5f016e22007-07-11 17:01:13 +00003385 // If attributes exist after the identifier list, parse them.
John McCall0b7e6782011-03-24 11:26:52 +00003386 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003387 MaybeParseGNUAttributes(attrs);
Douglas Gregor72de6672009-01-08 20:45:30 +00003388
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003389 Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
3390 EnumDecl, EnumConstantDecls.data(),
3391 EnumConstantDecls.size(), getCurScope(),
3392 attrs.getList());
Mike Stump1eb44332009-09-09 15:08:12 +00003393
Douglas Gregor72de6672009-01-08 20:45:30 +00003394 EnumScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003395 Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3396 T.getCloseLocation());
Richard Smithc9f35172012-06-25 21:37:02 +00003397
3398 // The next token must be valid after an enum definition. If not, a ';'
3399 // was probably forgotten.
Richard Smith139be702012-07-02 19:14:01 +00003400 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3401 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
Richard Smithc9f35172012-06-25 21:37:02 +00003402 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3403 // Push this token back into the preprocessor and change our current token
3404 // to ';' so that the rest of the code recovers as though there were an
3405 // ';' after the definition.
3406 PP.EnterToken(Tok);
3407 Tok.setKind(tok::semi);
3408 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003409}
3410
3411/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff5f8aa692008-02-11 23:15:56 +00003412/// start of a type-qualifier-list.
3413bool Parser::isTypeQualifier() const {
3414 switch (Tok.getKind()) {
3415 default: return false;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003416
3417 // type-qualifier only in OpenCL
3418 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003419 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003420
Steve Naroff5f8aa692008-02-11 23:15:56 +00003421 // type-qualifier
3422 case tok::kw_const:
3423 case tok::kw_volatile:
3424 case tok::kw_restrict:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003425 case tok::kw___private:
3426 case tok::kw___local:
3427 case tok::kw___global:
3428 case tok::kw___constant:
3429 case tok::kw___read_only:
3430 case tok::kw___read_write:
3431 case tok::kw___write_only:
Steve Naroff5f8aa692008-02-11 23:15:56 +00003432 return true;
3433 }
3434}
3435
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003436/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3437/// is definitely a type-specifier. Return false if it isn't part of a type
3438/// specifier or if we're not sure.
3439bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3440 switch (Tok.getKind()) {
3441 default: return false;
3442 // type-specifiers
3443 case tok::kw_short:
3444 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003445 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003446 case tok::kw___int128:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003447 case tok::kw_signed:
3448 case tok::kw_unsigned:
3449 case tok::kw__Complex:
3450 case tok::kw__Imaginary:
3451 case tok::kw_void:
3452 case tok::kw_char:
3453 case tok::kw_wchar_t:
3454 case tok::kw_char16_t:
3455 case tok::kw_char32_t:
3456 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003457 case tok::kw_half:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003458 case tok::kw_float:
3459 case tok::kw_double:
3460 case tok::kw_bool:
3461 case tok::kw__Bool:
3462 case tok::kw__Decimal32:
3463 case tok::kw__Decimal64:
3464 case tok::kw__Decimal128:
3465 case tok::kw___vector:
Chad Rosier8decdee2012-06-26 22:30:43 +00003466
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003467 // struct-or-union-specifier (C99) or class-specifier (C++)
3468 case tok::kw_class:
3469 case tok::kw_struct:
3470 case tok::kw_union:
3471 // enum-specifier
3472 case tok::kw_enum:
Chad Rosier8decdee2012-06-26 22:30:43 +00003473
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003474 // typedef-name
3475 case tok::annot_typename:
3476 return true;
3477 }
3478}
3479
Steve Naroff5f8aa692008-02-11 23:15:56 +00003480/// isTypeSpecifierQualifier - Return true if the current token could be the
Reid Spencer5f016e22007-07-11 17:01:13 +00003481/// start of a specifier-qualifier-list.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003482bool Parser::isTypeSpecifierQualifier() {
Reid Spencer5f016e22007-07-11 17:01:13 +00003483 switch (Tok.getKind()) {
3484 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003485
Chris Lattner166a8fc2009-01-04 23:41:41 +00003486 case tok::identifier: // foo::bar
John Thompson82287d12010-02-05 00:12:22 +00003487 if (TryAltiVecVectorToken())
3488 return true;
3489 // Fall through.
Douglas Gregord57959a2009-03-27 23:10:48 +00003490 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00003491 // Annotate typenames and C++ scope specifiers. If we get one, just
3492 // recurse to handle whatever we get.
3493 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003494 return true;
3495 if (Tok.is(tok::identifier))
3496 return false;
3497 return isTypeSpecifierQualifier();
Douglas Gregord57959a2009-03-27 23:10:48 +00003498
Chris Lattner166a8fc2009-01-04 23:41:41 +00003499 case tok::coloncolon: // ::foo::bar
3500 if (NextToken().is(tok::kw_new) || // ::new
3501 NextToken().is(tok::kw_delete)) // ::delete
3502 return false;
3503
Chris Lattner166a8fc2009-01-04 23:41:41 +00003504 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003505 return true;
3506 return isTypeSpecifierQualifier();
Mike Stump1eb44332009-09-09 15:08:12 +00003507
Reid Spencer5f016e22007-07-11 17:01:13 +00003508 // GNU attributes support.
3509 case tok::kw___attribute:
Steve Naroffd1861fd2007-07-31 12:34:36 +00003510 // GNU typeof support.
3511 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00003512
Reid Spencer5f016e22007-07-11 17:01:13 +00003513 // type-specifiers
3514 case tok::kw_short:
3515 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003516 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003517 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00003518 case tok::kw_signed:
3519 case tok::kw_unsigned:
3520 case tok::kw__Complex:
3521 case tok::kw__Imaginary:
3522 case tok::kw_void:
3523 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00003524 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003525 case tok::kw_char16_t:
3526 case tok::kw_char32_t:
Reid Spencer5f016e22007-07-11 17:01:13 +00003527 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003528 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00003529 case tok::kw_float:
3530 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00003531 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00003532 case tok::kw__Bool:
3533 case tok::kw__Decimal32:
3534 case tok::kw__Decimal64:
3535 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00003536 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00003537
Chris Lattner99dc9142008-04-13 18:59:07 +00003538 // struct-or-union-specifier (C99) or class-specifier (C++)
3539 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00003540 case tok::kw_struct:
3541 case tok::kw_union:
3542 // enum-specifier
3543 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00003544
Reid Spencer5f016e22007-07-11 17:01:13 +00003545 // type-qualifier
3546 case tok::kw_const:
3547 case tok::kw_volatile:
3548 case tok::kw_restrict:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003549
3550 // typedef-name
Chris Lattnerb31757b2009-01-06 05:06:21 +00003551 case tok::annot_typename:
Reid Spencer5f016e22007-07-11 17:01:13 +00003552 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00003553
Chris Lattner7c186be2008-10-20 00:25:30 +00003554 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3555 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00003556 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00003557
Steve Naroff239f0732008-12-25 14:16:32 +00003558 case tok::kw___cdecl:
3559 case tok::kw___stdcall:
3560 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003561 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00003562 case tok::kw___w64:
3563 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003564 case tok::kw___ptr32:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003565 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003566 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003567
3568 case tok::kw___private:
3569 case tok::kw___local:
3570 case tok::kw___global:
3571 case tok::kw___constant:
3572 case tok::kw___read_only:
3573 case tok::kw___read_write:
3574 case tok::kw___write_only:
3575
Eli Friedman290eeb02009-06-08 23:27:34 +00003576 return true;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003577
3578 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003579 return getLangOpts().OpenCL;
Eli Friedmanb001de72011-10-06 23:00:33 +00003580
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00003581 // C11 _Atomic()
Eli Friedmanb001de72011-10-06 23:00:33 +00003582 case tok::kw__Atomic:
3583 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00003584 }
3585}
3586
3587/// isDeclarationSpecifier() - Return true if the current token is part of a
3588/// declaration specifier.
Douglas Gregor9497a732010-09-16 01:51:54 +00003589///
3590/// \param DisambiguatingWithExpression True to indicate that the purpose of
3591/// this check is to disambiguate between an expression and a declaration.
3592bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003593 switch (Tok.getKind()) {
3594 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003595
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003596 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003597 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003598
Chris Lattner166a8fc2009-01-04 23:41:41 +00003599 case tok::identifier: // foo::bar
Steve Naroff61f72cb2009-03-09 21:12:44 +00003600 // Unfortunate hack to support "Class.factoryMethod" notation.
David Blaikie4e4d0842012-03-11 07:00:24 +00003601 if (getLangOpts().ObjC1 && NextToken().is(tok::period))
Steve Naroff61f72cb2009-03-09 21:12:44 +00003602 return false;
John Thompson82287d12010-02-05 00:12:22 +00003603 if (TryAltiVecVectorToken())
3604 return true;
3605 // Fall through.
David Blaikie42d6d0c2011-12-04 05:04:18 +00003606 case tok::kw_decltype: // decltype(T())::type
Douglas Gregord57959a2009-03-27 23:10:48 +00003607 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00003608 // Annotate typenames and C++ scope specifiers. If we get one, just
3609 // recurse to handle whatever we get.
3610 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003611 return true;
3612 if (Tok.is(tok::identifier))
3613 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00003614
Douglas Gregor9497a732010-09-16 01:51:54 +00003615 // If we're in Objective-C and we have an Objective-C class type followed
Chad Rosier8decdee2012-06-26 22:30:43 +00003616 // by an identifier and then either ':' or ']', in a place where an
Douglas Gregor9497a732010-09-16 01:51:54 +00003617 // expression is permitted, then this is probably a class message send
3618 // missing the initial '['. In this case, we won't consider this to be
3619 // the start of a declaration.
Chad Rosier8decdee2012-06-26 22:30:43 +00003620 if (DisambiguatingWithExpression &&
Douglas Gregor9497a732010-09-16 01:51:54 +00003621 isStartOfObjCClassMessageMissingOpenBracket())
3622 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00003623
John McCall9ba61662010-02-26 08:45:28 +00003624 return isDeclarationSpecifier();
3625
Chris Lattner166a8fc2009-01-04 23:41:41 +00003626 case tok::coloncolon: // ::foo::bar
3627 if (NextToken().is(tok::kw_new) || // ::new
3628 NextToken().is(tok::kw_delete)) // ::delete
3629 return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003630
Chris Lattner166a8fc2009-01-04 23:41:41 +00003631 // Annotate typenames and C++ scope specifiers. If we get one, just
3632 // recurse to handle whatever we get.
3633 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003634 return true;
3635 return isDeclarationSpecifier();
Mike Stump1eb44332009-09-09 15:08:12 +00003636
Reid Spencer5f016e22007-07-11 17:01:13 +00003637 // storage-class-specifier
3638 case tok::kw_typedef:
3639 case tok::kw_extern:
Steve Naroff8d54bf22007-12-18 00:16:02 +00003640 case tok::kw___private_extern__:
Reid Spencer5f016e22007-07-11 17:01:13 +00003641 case tok::kw_static:
3642 case tok::kw_auto:
3643 case tok::kw_register:
3644 case tok::kw___thread:
Mike Stump1eb44332009-09-09 15:08:12 +00003645
Douglas Gregor8d267c52011-09-09 02:06:17 +00003646 // Modules
3647 case tok::kw___module_private__:
Chad Rosier8decdee2012-06-26 22:30:43 +00003648
Reid Spencer5f016e22007-07-11 17:01:13 +00003649 // type-specifiers
3650 case tok::kw_short:
3651 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003652 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003653 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00003654 case tok::kw_signed:
3655 case tok::kw_unsigned:
3656 case tok::kw__Complex:
3657 case tok::kw__Imaginary:
3658 case tok::kw_void:
3659 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00003660 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003661 case tok::kw_char16_t:
3662 case tok::kw_char32_t:
3663
Reid Spencer5f016e22007-07-11 17:01:13 +00003664 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003665 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00003666 case tok::kw_float:
3667 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00003668 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00003669 case tok::kw__Bool:
3670 case tok::kw__Decimal32:
3671 case tok::kw__Decimal64:
3672 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00003673 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00003674
Chris Lattner99dc9142008-04-13 18:59:07 +00003675 // struct-or-union-specifier (C99) or class-specifier (C++)
3676 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00003677 case tok::kw_struct:
3678 case tok::kw_union:
3679 // enum-specifier
3680 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00003681
Reid Spencer5f016e22007-07-11 17:01:13 +00003682 // type-qualifier
3683 case tok::kw_const:
3684 case tok::kw_volatile:
3685 case tok::kw_restrict:
Steve Naroffd1861fd2007-07-31 12:34:36 +00003686
Reid Spencer5f016e22007-07-11 17:01:13 +00003687 // function-specifier
3688 case tok::kw_inline:
Douglas Gregorb48fe382008-10-31 09:07:45 +00003689 case tok::kw_virtual:
3690 case tok::kw_explicit:
Chris Lattnerd6c7c182007-08-09 16:40:21 +00003691
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00003692 // static_assert-declaration
3693 case tok::kw__Static_assert:
3694
Chris Lattner1ef08762007-08-09 17:01:07 +00003695 // GNU typeof support.
3696 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00003697
Chris Lattner1ef08762007-08-09 17:01:07 +00003698 // GNU attributes.
Chris Lattnerd6c7c182007-08-09 16:40:21 +00003699 case tok::kw___attribute:
Reid Spencer5f016e22007-07-11 17:01:13 +00003700 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00003701
Francois Pichete3d49b42011-06-19 08:02:06 +00003702 // C++0x decltype.
David Blaikie42d6d0c2011-12-04 05:04:18 +00003703 case tok::annot_decltype:
Francois Pichete3d49b42011-06-19 08:02:06 +00003704 return true;
3705
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00003706 // C11 _Atomic()
Eli Friedmanb001de72011-10-06 23:00:33 +00003707 case tok::kw__Atomic:
3708 return true;
3709
Chris Lattnerf3948c42008-07-26 03:38:44 +00003710 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3711 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00003712 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00003713
Douglas Gregord9d75e52011-04-27 05:41:15 +00003714 // typedef-name
3715 case tok::annot_typename:
3716 return !DisambiguatingWithExpression ||
3717 !isStartOfObjCClassMessageMissingOpenBracket();
Chad Rosier8decdee2012-06-26 22:30:43 +00003718
Steve Naroff47f52092009-01-06 19:34:12 +00003719 case tok::kw___declspec:
Steve Naroff239f0732008-12-25 14:16:32 +00003720 case tok::kw___cdecl:
3721 case tok::kw___stdcall:
3722 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003723 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00003724 case tok::kw___w64:
3725 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003726 case tok::kw___ptr32:
Eli Friedman290eeb02009-06-08 23:27:34 +00003727 case tok::kw___forceinline:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003728 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003729 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003730
3731 case tok::kw___private:
3732 case tok::kw___local:
3733 case tok::kw___global:
3734 case tok::kw___constant:
3735 case tok::kw___read_only:
3736 case tok::kw___read_write:
3737 case tok::kw___write_only:
3738
Eli Friedman290eeb02009-06-08 23:27:34 +00003739 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00003740 }
3741}
3742
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003743bool Parser::isConstructorDeclarator() {
3744 TentativeParsingAction TPA(*this);
3745
3746 // Parse the C++ scope specifier.
3747 CXXScopeSpec SS;
Chad Rosier8decdee2012-06-26 22:30:43 +00003748 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003749 /*EnteringContext=*/true)) {
John McCall9ba61662010-02-26 08:45:28 +00003750 TPA.Revert();
3751 return false;
3752 }
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003753
3754 // Parse the constructor name.
3755 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
3756 // We already know that we have a constructor name; just consume
3757 // the token.
3758 ConsumeToken();
3759 } else {
3760 TPA.Revert();
3761 return false;
3762 }
3763
Richard Smith22592862012-03-27 23:05:05 +00003764 // Current class name must be followed by a left parenthesis.
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003765 if (Tok.isNot(tok::l_paren)) {
3766 TPA.Revert();
3767 return false;
3768 }
3769 ConsumeParen();
3770
Richard Smith22592862012-03-27 23:05:05 +00003771 // A right parenthesis, or ellipsis followed by a right parenthesis signals
3772 // that we have a constructor.
3773 if (Tok.is(tok::r_paren) ||
3774 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003775 TPA.Revert();
3776 return true;
3777 }
3778
3779 // If we need to, enter the specified scope.
3780 DeclaratorScopeObj DeclScopeObj(*this, SS);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003781 if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003782 DeclScopeObj.EnterDeclaratorScope();
3783
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00003784 // Optionally skip Microsoft attributes.
John McCall0b7e6782011-03-24 11:26:52 +00003785 ParsedAttributes Attrs(AttrFactory);
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00003786 MaybeParseMicrosoftAttributes(Attrs);
3787
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003788 // Check whether the next token(s) are part of a declaration
3789 // specifier, in which case we have the start of a parameter and,
3790 // therefore, we know that this is a constructor.
Richard Smith412e0cc2012-03-27 00:56:56 +00003791 bool IsConstructor = false;
3792 if (isDeclarationSpecifier())
3793 IsConstructor = true;
3794 else if (Tok.is(tok::identifier) ||
3795 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
3796 // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
3797 // This might be a parenthesized member name, but is more likely to
3798 // be a constructor declaration with an invalid argument type. Keep
3799 // looking.
3800 if (Tok.is(tok::annot_cxxscope))
3801 ConsumeToken();
3802 ConsumeToken();
3803
3804 // If this is not a constructor, we must be parsing a declarator,
Richard Smith5d8388c2012-03-27 01:42:32 +00003805 // which must have one of the following syntactic forms (see the
3806 // grammar extract at the start of ParseDirectDeclarator):
Richard Smith412e0cc2012-03-27 00:56:56 +00003807 switch (Tok.getKind()) {
3808 case tok::l_paren:
3809 // C(X ( int));
3810 case tok::l_square:
3811 // C(X [ 5]);
3812 // C(X [ [attribute]]);
3813 case tok::coloncolon:
3814 // C(X :: Y);
3815 // C(X :: *p);
3816 case tok::r_paren:
3817 // C(X )
3818 // Assume this isn't a constructor, rather than assuming it's a
3819 // constructor with an unnamed parameter of an ill-formed type.
3820 break;
3821
3822 default:
3823 IsConstructor = true;
3824 break;
3825 }
3826 }
3827
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003828 TPA.Revert();
3829 return IsConstructor;
3830}
Reid Spencer5f016e22007-07-11 17:01:13 +00003831
3832/// ParseTypeQualifierListOpt
Dawn Perchik52fc3142010-09-03 01:29:35 +00003833/// type-qualifier-list: [C99 6.7.5]
3834/// type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00003835/// [vendor] attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00003836/// [ only if VendorAttributesAllowed=true ]
3837/// type-qualifier-list type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00003838/// [vendor] type-qualifier-list attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00003839/// [ only if VendorAttributesAllowed=true ]
3840/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
3841/// [ only if CXX0XAttributesAllowed=true ]
3842/// Note: vendor can be GNU, MS, etc.
Reid Spencer5f016e22007-07-11 17:01:13 +00003843///
Dawn Perchik52fc3142010-09-03 01:29:35 +00003844void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
3845 bool VendorAttributesAllowed,
Richard Smithc56298d2012-04-10 03:25:07 +00003846 bool CXX11AttributesAllowed) {
3847 if (getLangOpts().CPlusPlus0x && CXX11AttributesAllowed &&
Richard Smith6ee326a2012-04-10 01:32:12 +00003848 isCXX11AttributeSpecifier()) {
John McCall0b7e6782011-03-24 11:26:52 +00003849 ParsedAttributesWithRange attrs(AttrFactory);
Richard Smithc56298d2012-04-10 03:25:07 +00003850 ParseCXX11Attributes(attrs);
Richard Smith6ee326a2012-04-10 01:32:12 +00003851 DS.takeAttributesFrom(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00003852 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00003853
3854 SourceLocation EndLoc;
3855
Reid Spencer5f016e22007-07-11 17:01:13 +00003856 while (1) {
John McCallfec54012009-08-03 20:12:06 +00003857 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00003858 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00003859 unsigned DiagID = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +00003860 SourceLocation Loc = Tok.getLocation();
3861
3862 switch (Tok.getKind()) {
Douglas Gregor1a480c42010-08-27 17:35:51 +00003863 case tok::code_completion:
3864 Actions.CodeCompleteTypeQualifiers(DS);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00003865 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00003866
Reid Spencer5f016e22007-07-11 17:01:13 +00003867 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00003868 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
David Blaikie4e4d0842012-03-11 07:00:24 +00003869 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00003870 break;
3871 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00003872 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
David Blaikie4e4d0842012-03-11 07:00:24 +00003873 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00003874 break;
3875 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00003876 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
David Blaikie4e4d0842012-03-11 07:00:24 +00003877 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00003878 break;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003879
3880 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00003881 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003882 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003883 goto DoneWithTypeQuals;
3884 case tok::kw___private:
3885 case tok::kw___global:
3886 case tok::kw___local:
3887 case tok::kw___constant:
3888 case tok::kw___read_only:
3889 case tok::kw___write_only:
3890 case tok::kw___read_write:
3891 ParseOpenCLQualifiers(DS);
3892 break;
3893
Eli Friedman290eeb02009-06-08 23:27:34 +00003894 case tok::kw___w64:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00003895 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003896 case tok::kw___ptr32:
Steve Naroff239f0732008-12-25 14:16:32 +00003897 case tok::kw___cdecl:
3898 case tok::kw___stdcall:
3899 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003900 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003901 case tok::kw___unaligned:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003902 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003903 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00003904 continue;
3905 }
3906 goto DoneWithTypeQuals;
Dawn Perchik52fc3142010-09-03 01:29:35 +00003907 case tok::kw___pascal:
3908 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003909 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00003910 continue;
3911 }
3912 goto DoneWithTypeQuals;
Reid Spencer5f016e22007-07-11 17:01:13 +00003913 case tok::kw___attribute:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003914 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003915 ParseGNUAttributes(DS.getAttributes());
Chris Lattner5a69d1c2008-12-18 07:02:59 +00003916 continue; // do *not* consume the next token!
3917 }
3918 // otherwise, FALL THROUGH!
3919 default:
Steve Naroff239f0732008-12-25 14:16:32 +00003920 DoneWithTypeQuals:
Chris Lattner5a69d1c2008-12-18 07:02:59 +00003921 // If this is not a type-qualifier token, we're done reading type
3922 // qualifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00003923 DS.Finish(Diags, PP);
Abramo Bagnara796aa442011-03-12 11:17:06 +00003924 if (EndLoc.isValid())
3925 DS.SetRangeEnd(EndLoc);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00003926 return;
Reid Spencer5f016e22007-07-11 17:01:13 +00003927 }
Chris Lattnera1fcbad2008-12-18 06:50:14 +00003928
Reid Spencer5f016e22007-07-11 17:01:13 +00003929 // If the specifier combination wasn't legal, issue a diagnostic.
3930 if (isInvalid) {
3931 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +00003932 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003933 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00003934 EndLoc = ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00003935 }
3936}
3937
3938
3939/// ParseDeclarator - Parse and verify a newly-initialized declarator.
3940///
3941void Parser::ParseDeclarator(Declarator &D) {
3942 /// This implements the 'declarator' production in the C grammar, then checks
3943 /// for well-formedness and issues diagnostics.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00003944 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Reid Spencer5f016e22007-07-11 17:01:13 +00003945}
3946
Richard Smith9988f282012-03-29 01:16:42 +00003947static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
3948 if (Kind == tok::star || Kind == tok::caret)
3949 return true;
3950
3951 // We parse rvalue refs in C++03, because otherwise the errors are scary.
3952 if (!Lang.CPlusPlus)
3953 return false;
3954
3955 return Kind == tok::amp || Kind == tok::ampamp;
3956}
3957
Sebastian Redl4c5d3202008-11-21 19:14:01 +00003958/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
3959/// is parsed by the function passed to it. Pass null, and the direct-declarator
3960/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregor2f1bc522008-11-07 20:08:42 +00003961/// ptr-operator production.
3962///
Richard Smith0706df42011-10-19 21:33:05 +00003963/// If the grammar of this construct is extended, matching changes must also be
Richard Smith5d8388c2012-03-27 01:42:32 +00003964/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
3965/// isConstructorDeclarator.
Richard Smith0706df42011-10-19 21:33:05 +00003966///
Sebastian Redlf30208a2009-01-24 21:16:55 +00003967/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
3968/// [C] pointer[opt] direct-declarator
3969/// [C++] direct-declarator
3970/// [C++] ptr-operator declarator
Reid Spencer5f016e22007-07-11 17:01:13 +00003971///
3972/// pointer: [C99 6.7.5]
3973/// '*' type-qualifier-list[opt]
3974/// '*' type-qualifier-list[opt] pointer
3975///
Douglas Gregor2f1bc522008-11-07 20:08:42 +00003976/// ptr-operator:
3977/// '*' cv-qualifier-seq[opt]
3978/// '&'
Sebastian Redl05532f22009-03-15 22:02:01 +00003979/// [C++0x] '&&'
Douglas Gregor2f1bc522008-11-07 20:08:42 +00003980/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redl05532f22009-03-15 22:02:01 +00003981/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redlf30208a2009-01-24 21:16:55 +00003982/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +00003983void Parser::ParseDeclaratorInternal(Declarator &D,
3984 DirectDeclParseFunction DirectDeclParser) {
Douglas Gregor91a28862009-08-26 14:27:30 +00003985 if (Diags.hasAllExtensionsSilenced())
3986 D.setExtension();
Chad Rosier8decdee2012-06-26 22:30:43 +00003987
Sebastian Redlf30208a2009-01-24 21:16:55 +00003988 // C++ member pointers start with a '::' or a nested-name.
3989 // Member pointers get special handling, since there's no place for the
3990 // scope spec in the generic path below.
David Blaikie4e4d0842012-03-11 07:00:24 +00003991 if (getLangOpts().CPlusPlus &&
Chris Lattnerf919bfe2009-03-24 17:04:48 +00003992 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
3993 Tok.is(tok::annot_cxxscope))) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003994 bool EnteringContext = D.getContext() == Declarator::FileContext ||
3995 D.getContext() == Declarator::MemberContext;
Sebastian Redlf30208a2009-01-24 21:16:55 +00003996 CXXScopeSpec SS;
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003997 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00003998
Jeffrey Yasskinedc28772010-04-07 23:29:58 +00003999 if (SS.isNotEmpty()) {
Mike Stump1eb44332009-09-09 15:08:12 +00004000 if (Tok.isNot(tok::star)) {
Sebastian Redlf30208a2009-01-24 21:16:55 +00004001 // The scope spec really belongs to the direct-declarator.
4002 D.getCXXScopeSpec() = SS;
4003 if (DirectDeclParser)
4004 (this->*DirectDeclParser)(D);
4005 return;
4006 }
4007
4008 SourceLocation Loc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00004009 D.SetRangeEnd(Loc);
John McCall0b7e6782011-03-24 11:26:52 +00004010 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004011 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004012 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004013
4014 // Recurse to parse whatever is left.
4015 ParseDeclaratorInternal(D, DirectDeclParser);
4016
4017 // Sema will have to catch (syntactically invalid) pointers into global
4018 // scope. It has to catch pointers into namespace scope anyway.
4019 D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004020 Loc),
4021 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004022 /* Don't replace range end. */SourceLocation());
Sebastian Redlf30208a2009-01-24 21:16:55 +00004023 return;
4024 }
4025 }
4026
4027 tok::TokenKind Kind = Tok.getKind();
Steve Naroff5618bd42008-08-27 16:04:49 +00004028 // Not a pointer, C++ reference, or block.
Richard Smith9988f282012-03-29 01:16:42 +00004029 if (!isPtrOperatorToken(Kind, getLangOpts())) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004030 if (DirectDeclParser)
4031 (this->*DirectDeclParser)(D);
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004032 return;
4033 }
Sebastian Redlf30208a2009-01-24 21:16:55 +00004034
Sebastian Redl05532f22009-03-15 22:02:01 +00004035 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4036 // '&&' -> rvalue reference
Sebastian Redl743de1f2009-03-23 00:00:23 +00004037 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redlab197ba2009-02-09 18:23:29 +00004038 D.SetRangeEnd(Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +00004039
Chris Lattner9af55002009-03-27 04:18:06 +00004040 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner76549142008-02-21 01:32:26 +00004041 // Is a pointer.
John McCall0b7e6782011-03-24 11:26:52 +00004042 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004043
Richard Smith6ee326a2012-04-10 01:32:12 +00004044 // FIXME: GNU attributes are not allowed here in a new-type-id.
Reid Spencer5f016e22007-07-11 17:01:13 +00004045 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004046 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004047
Reid Spencer5f016e22007-07-11 17:01:13 +00004048 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004049 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff5618bd42008-08-27 16:04:49 +00004050 if (Kind == tok::star)
4051 // Remember that we parsed a pointer type, and remember the type-quals.
4052 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
Chandler Carruthd067c072011-02-23 18:51:59 +00004053 DS.getConstSpecLoc(),
4054 DS.getVolatileSpecLoc(),
John McCall0b7e6782011-03-24 11:26:52 +00004055 DS.getRestrictSpecLoc()),
4056 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004057 SourceLocation());
Steve Naroff5618bd42008-08-27 16:04:49 +00004058 else
4059 // Remember that we parsed a Block type, and remember the type-quals.
Mike Stump1eb44332009-09-09 15:08:12 +00004060 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004061 Loc),
4062 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004063 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004064 } else {
4065 // Is a reference
John McCall0b7e6782011-03-24 11:26:52 +00004066 DeclSpec DS(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00004067
Sebastian Redl743de1f2009-03-23 00:00:23 +00004068 // Complain about rvalue references in C++03, but then go on and build
4069 // the declarator.
Richard Smith7fe62082011-10-15 05:09:34 +00004070 if (Kind == tok::ampamp)
David Blaikie4e4d0842012-03-11 07:00:24 +00004071 Diag(Loc, getLangOpts().CPlusPlus0x ?
Richard Smith7fe62082011-10-15 05:09:34 +00004072 diag::warn_cxx98_compat_rvalue_reference :
4073 diag::ext_rvalue_reference);
Sebastian Redl743de1f2009-03-23 00:00:23 +00004074
Richard Smith6ee326a2012-04-10 01:32:12 +00004075 // GNU-style and C++11 attributes are allowed here, as is restrict.
4076 ParseTypeQualifierListOpt(DS);
4077 D.ExtendWithDeclSpec(DS);
4078
Reid Spencer5f016e22007-07-11 17:01:13 +00004079 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4080 // cv-qualifiers are introduced through the use of a typedef or of a
4081 // template type argument, in which case the cv-qualifiers are ignored.
Reid Spencer5f016e22007-07-11 17:01:13 +00004082 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4083 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4084 Diag(DS.getConstSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004085 diag::err_invalid_reference_qualifier_application) << "const";
Reid Spencer5f016e22007-07-11 17:01:13 +00004086 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4087 Diag(DS.getVolatileSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004088 diag::err_invalid_reference_qualifier_application) << "volatile";
Reid Spencer5f016e22007-07-11 17:01:13 +00004089 }
4090
4091 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004092 ParseDeclaratorInternal(D, DirectDeclParser);
Reid Spencer5f016e22007-07-11 17:01:13 +00004093
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004094 if (D.getNumTypeObjects() > 0) {
4095 // C++ [dcl.ref]p4: There shall be no references to references.
4096 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4097 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattnerda83bac2008-11-19 07:37:42 +00004098 if (const IdentifierInfo *II = D.getIdentifier())
4099 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4100 << II;
4101 else
4102 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4103 << "type name";
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004104
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004105 // Once we've complained about the reference-to-reference, we
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004106 // can go ahead and build the (technically ill-formed)
4107 // declarator: reference collapsing will take care of it.
4108 }
4109 }
4110
Reid Spencer5f016e22007-07-11 17:01:13 +00004111 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner76549142008-02-21 01:32:26 +00004112 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redl05532f22009-03-15 22:02:01 +00004113 Kind == tok::amp),
John McCall0b7e6782011-03-24 11:26:52 +00004114 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004115 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004116 }
4117}
4118
Richard Smith9988f282012-03-29 01:16:42 +00004119static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4120 SourceLocation EllipsisLoc) {
4121 if (EllipsisLoc.isValid()) {
4122 FixItHint Insertion;
4123 if (!D.getEllipsisLoc().isValid()) {
4124 Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4125 D.setEllipsisLoc(EllipsisLoc);
4126 }
4127 P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4128 << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4129 }
4130}
4131
Reid Spencer5f016e22007-07-11 17:01:13 +00004132/// ParseDirectDeclarator
4133/// direct-declarator: [C99 6.7.5]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004134/// [C99] identifier
Reid Spencer5f016e22007-07-11 17:01:13 +00004135/// '(' declarator ')'
4136/// [GNU] '(' attributes declarator ')'
4137/// [C90] direct-declarator '[' constant-expression[opt] ']'
4138/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4139/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4140/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4141/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00004142/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4143/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00004144/// direct-declarator '(' parameter-type-list ')'
4145/// direct-declarator '(' identifier-list[opt] ')'
4146/// [GNU] direct-declarator '(' parameter-forward-declarations
4147/// parameter-type-list[opt] ')'
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00004148/// [C++] direct-declarator '(' parameter-declaration-clause ')'
4149/// cv-qualifier-seq[opt] exception-specification[opt]
Richard Smith6ee326a2012-04-10 01:32:12 +00004150/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4151/// attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4152/// ref-qualifier[opt] exception-specification[opt]
Douglas Gregorb48fe382008-10-31 09:07:45 +00004153/// [C++] declarator-id
Richard Smith6ee326a2012-04-10 01:32:12 +00004154/// [C++11] declarator-id attribute-specifier-seq[opt]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004155///
4156/// declarator-id: [C++ 8]
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004157/// '...'[opt] id-expression
Douglas Gregor42a552f2008-11-05 20:51:48 +00004158/// '::'[opt] nested-name-specifier[opt] type-name
4159///
4160/// id-expression: [C++ 5.1]
4161/// unqualified-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004162/// qualified-id
Douglas Gregor42a552f2008-11-05 20:51:48 +00004163///
4164/// unqualified-id: [C++ 5.1]
Mike Stump1eb44332009-09-09 15:08:12 +00004165/// identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004166/// operator-function-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004167/// conversion-function-id
Mike Stump1eb44332009-09-09 15:08:12 +00004168/// '~' class-name
Douglas Gregor39a8de12009-02-25 19:37:18 +00004169/// template-id
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +00004170///
Richard Smith5d8388c2012-03-27 01:42:32 +00004171/// Note, any additional constructs added here may need corresponding changes
4172/// in isConstructorDeclarator.
Reid Spencer5f016e22007-07-11 17:01:13 +00004173void Parser::ParseDirectDeclarator(Declarator &D) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004174 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004175
David Blaikie4e4d0842012-03-11 07:00:24 +00004176 if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004177 // ParseDeclaratorInternal might already have parsed the scope.
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004178 if (D.getCXXScopeSpec().isEmpty()) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004179 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4180 D.getContext() == Declarator::MemberContext;
Chad Rosier8decdee2012-06-26 22:30:43 +00004181 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004182 EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004183 }
4184
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004185 if (D.getCXXScopeSpec().isValid()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00004186 if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
John McCalle7e278b2009-12-11 20:04:54 +00004187 // Change the declaration context for name lookup, until this function
4188 // is exited (and the declarator has been parsed).
4189 DeclScopeObj.EnterDeclaratorScope();
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004190 }
4191
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004192 // C++0x [dcl.fct]p14:
4193 // There is a syntactic ambiguity when an ellipsis occurs at the end
Chad Rosier8decdee2012-06-26 22:30:43 +00004194 // of a parameter-declaration-clause without a preceding comma. In
4195 // this case, the ellipsis is parsed as part of the
4196 // abstract-declarator if the type of the parameter names a template
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004197 // parameter pack that has not been expanded; otherwise, it is parsed
4198 // as part of the parameter-declaration-clause.
Richard Smith9988f282012-03-29 01:16:42 +00004199 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004200 !((D.getContext() == Declarator::PrototypeContext ||
4201 D.getContext() == Declarator::BlockLiteralContext) &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004202 NextToken().is(tok::r_paren) &&
Richard Smith9988f282012-03-29 01:16:42 +00004203 !Actions.containsUnexpandedParameterPacks(D))) {
4204 SourceLocation EllipsisLoc = ConsumeToken();
4205 if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4206 // The ellipsis was put in the wrong place. Recover, and explain to
4207 // the user what they should have done.
4208 ParseDeclarator(D);
4209 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4210 return;
4211 } else
4212 D.setEllipsisLoc(EllipsisLoc);
4213
4214 // The ellipsis can't be followed by a parenthesized declarator. We
4215 // check for that in ParseParenDeclarator, after we have disambiguated
4216 // the l_paren token.
4217 }
4218
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004219 if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4220 Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4221 // We found something that indicates the start of an unqualified-id.
4222 // Parse that unqualified-id.
John McCallba9d8532010-04-13 06:39:49 +00004223 bool AllowConstructorName;
4224 if (D.getDeclSpec().hasTypeSpecifier())
4225 AllowConstructorName = false;
4226 else if (D.getCXXScopeSpec().isSet())
4227 AllowConstructorName =
4228 (D.getContext() == Declarator::FileContext ||
4229 (D.getContext() == Declarator::MemberContext &&
4230 D.getDeclSpec().isFriendSpecified()));
4231 else
4232 AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4233
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004234 SourceLocation TemplateKWLoc;
Chad Rosier8decdee2012-06-26 22:30:43 +00004235 if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4236 /*EnteringContext=*/true,
4237 /*AllowDestructorName=*/true,
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004238 AllowConstructorName,
John McCallb3d87482010-08-24 05:47:05 +00004239 ParsedType(),
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004240 TemplateKWLoc,
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004241 D.getName()) ||
4242 // Once we're past the identifier, if the scope was bad, mark the
4243 // whole declarator bad.
4244 D.getCXXScopeSpec().isInvalid()) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004245 D.SetIdentifier(0, Tok.getLocation());
4246 D.setInvalidType(true);
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004247 } else {
4248 // Parsed the unqualified-id; update range information and move along.
4249 if (D.getSourceRange().getBegin().isInvalid())
4250 D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4251 D.SetRangeEnd(D.getName().getSourceRange().getEnd());
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004252 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004253 goto PastIdentifier;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00004254 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004255 } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004256 assert(!getLangOpts().CPlusPlus &&
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004257 "There's a C++-specific check for tok::identifier above");
4258 assert(Tok.getIdentifierInfo() && "Not an identifier?");
4259 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4260 ConsumeToken();
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004261 goto PastIdentifier;
4262 }
Richard Smith9988f282012-03-29 01:16:42 +00004263
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004264 if (Tok.is(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004265 // direct-declarator: '(' declarator ')'
4266 // direct-declarator: '(' attributes declarator ')'
4267 // Example: 'char (*X)' or 'int (*XX)(void)'
4268 ParseParenDeclarator(D);
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004269
4270 // If the declarator was parenthesized, we entered the declarator
4271 // scope when parsing the parenthesized declarator, then exited
4272 // the scope already. Re-enter the scope, if we need to.
4273 if (D.getCXXScopeSpec().isSet()) {
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004274 // If there was an error parsing parenthesized declarator, declarator
Richard Smith9988f282012-03-29 01:16:42 +00004275 // scope may have been entered before. Don't do it again.
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004276 if (!D.isInvalidType() &&
4277 Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004278 // Change the declaration context for name lookup, until this function
4279 // is exited (and the declarator has been parsed).
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004280 DeclScopeObj.EnterDeclaratorScope();
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004281 }
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004282 } else if (D.mayOmitIdentifier()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004283 // This could be something simple like "int" (in which case the declarator
4284 // portion is empty), if an abstract-declarator is allowed.
4285 D.SetIdentifier(0, Tok.getLocation());
4286 } else {
David Blaikiee75d9cf2012-06-29 22:03:56 +00004287 if (Tok.getKind() == tok::annot_pragma_parser_crash)
4288 *(volatile int*) 0x11 = 0;
Douglas Gregore950d4b2009-03-06 23:28:18 +00004289 if (D.getContext() == Declarator::MemberContext)
4290 Diag(Tok, diag::err_expected_member_name_or_semi)
4291 << D.getDeclSpec().getSourceRange();
David Blaikie4e4d0842012-03-11 07:00:24 +00004292 else if (getLangOpts().CPlusPlus)
4293 Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004294 else
Chris Lattner1ab3b962008-11-18 07:48:38 +00004295 Diag(Tok, diag::err_expected_ident_lparen);
Reid Spencer5f016e22007-07-11 17:01:13 +00004296 D.SetIdentifier(0, Tok.getLocation());
Chris Lattner1f6f54b2008-11-11 06:13:16 +00004297 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00004298 }
Mike Stump1eb44332009-09-09 15:08:12 +00004299
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004300 PastIdentifier:
Reid Spencer5f016e22007-07-11 17:01:13 +00004301 assert(D.isPastIdentifier() &&
4302 "Haven't past the location of the identifier yet?");
Mike Stump1eb44332009-09-09 15:08:12 +00004303
Richard Smith6ee326a2012-04-10 01:32:12 +00004304 // Don't parse attributes unless we have parsed an unparenthesized name.
4305 if (D.hasName() && !D.getNumTypeObjects())
John McCall7f040a92010-12-24 02:08:15 +00004306 MaybeParseCXX0XAttributes(D);
Sean Huntbbd37c62009-11-21 08:43:09 +00004307
Reid Spencer5f016e22007-07-11 17:01:13 +00004308 while (1) {
Chris Lattner04d66662007-10-09 17:33:22 +00004309 if (Tok.is(tok::l_paren)) {
David Blaikie42d6d0c2011-12-04 05:04:18 +00004310 // Enter function-declaration scope, limiting any declarators to the
4311 // function prototype scope, including parameter declarators.
4312 ParseScope PrototypeScope(this,
4313 Scope::FunctionPrototypeScope|Scope::DeclScope);
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00004314 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4315 // In such a case, check if we actually have a function declarator; if it
4316 // is not, the declarator has been fully parsed.
David Blaikie4e4d0842012-03-11 07:00:24 +00004317 if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
Chris Lattner7399ee02008-10-20 02:05:46 +00004318 // When not in file scope, warn for ambiguous function declarators, just
4319 // in case the author intended it as a variable definition.
4320 bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
4321 if (!isCXXFunctionDeclarator(warnIfAmbiguous))
4322 break;
4323 }
John McCall0b7e6782011-03-24 11:26:52 +00004324 ParsedAttributes attrs(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004325 BalancedDelimiterTracker T(*this, tok::l_paren);
4326 T.consumeOpen();
4327 ParseFunctionDeclarator(D, attrs, T);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004328 PrototypeScope.Exit();
Chris Lattner04d66662007-10-09 17:33:22 +00004329 } else if (Tok.is(tok::l_square)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004330 ParseBracketDeclarator(D);
4331 } else {
4332 break;
4333 }
4334 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004335}
Reid Spencer5f016e22007-07-11 17:01:13 +00004336
Chris Lattneref4715c2008-04-06 05:45:57 +00004337/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
4338/// only called before the identifier, so these are most likely just grouping
Mike Stump1eb44332009-09-09 15:08:12 +00004339/// parens for precedence. If we find that these are actually function
Chris Lattneref4715c2008-04-06 05:45:57 +00004340/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4341///
4342/// direct-declarator:
4343/// '(' declarator ')'
4344/// [GNU] '(' attributes declarator ')'
Chris Lattner7399ee02008-10-20 02:05:46 +00004345/// direct-declarator '(' parameter-type-list ')'
4346/// direct-declarator '(' identifier-list[opt] ')'
4347/// [GNU] direct-declarator '(' parameter-forward-declarations
4348/// parameter-type-list[opt] ')'
Chris Lattneref4715c2008-04-06 05:45:57 +00004349///
4350void Parser::ParseParenDeclarator(Declarator &D) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004351 BalancedDelimiterTracker T(*this, tok::l_paren);
4352 T.consumeOpen();
4353
Chris Lattneref4715c2008-04-06 05:45:57 +00004354 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00004355
Chris Lattner7399ee02008-10-20 02:05:46 +00004356 // Eat any attributes before we look at whether this is a grouping or function
4357 // declarator paren. If this is a grouping paren, the attribute applies to
4358 // the type being built up, for example:
4359 // int (__attribute__(()) *x)(long y)
4360 // If this ends up not being a grouping paren, the attribute applies to the
4361 // first argument, for example:
4362 // int (__attribute__(()) int x)
4363 // In either case, we need to eat any attributes to be able to determine what
4364 // sort of paren this is.
4365 //
John McCall0b7e6782011-03-24 11:26:52 +00004366 ParsedAttributes attrs(AttrFactory);
Chris Lattner7399ee02008-10-20 02:05:46 +00004367 bool RequiresArg = false;
4368 if (Tok.is(tok::kw___attribute)) {
John McCall7f040a92010-12-24 02:08:15 +00004369 ParseGNUAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004370
Chris Lattner7399ee02008-10-20 02:05:46 +00004371 // We require that the argument list (if this is a non-grouping paren) be
4372 // present even if the attribute list was empty.
4373 RequiresArg = true;
4374 }
Steve Naroff239f0732008-12-25 14:16:32 +00004375 // Eat any Microsoft extensions.
Eli Friedman290eeb02009-06-08 23:27:34 +00004376 if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004377 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004378 Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64) ||
Francois Pichet58fd97a2011-08-25 00:36:46 +00004379 Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) {
John McCall7f040a92010-12-24 02:08:15 +00004380 ParseMicrosoftTypeAttributes(attrs);
Eli Friedman290eeb02009-06-08 23:27:34 +00004381 }
Dawn Perchik52fc3142010-09-03 01:29:35 +00004382 // Eat any Borland extensions.
Ted Kremenek8113ecf2010-11-10 05:59:39 +00004383 if (Tok.is(tok::kw___pascal))
John McCall7f040a92010-12-24 02:08:15 +00004384 ParseBorlandTypeAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004385
Chris Lattneref4715c2008-04-06 05:45:57 +00004386 // If we haven't past the identifier yet (or where the identifier would be
4387 // stored, if this is an abstract declarator), then this is probably just
4388 // grouping parens. However, if this could be an abstract-declarator, then
4389 // this could also be the start of function arguments (consider 'void()').
4390 bool isGrouping;
Mike Stump1eb44332009-09-09 15:08:12 +00004391
Chris Lattneref4715c2008-04-06 05:45:57 +00004392 if (!D.mayOmitIdentifier()) {
4393 // If this can't be an abstract-declarator, this *must* be a grouping
4394 // paren, because we haven't seen the identifier yet.
4395 isGrouping = true;
4396 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Richard Smith22592862012-03-27 23:05:05 +00004397 (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
4398 NextToken().is(tok::r_paren)) || // C++ int(...)
Richard Smith6ce48a72012-04-11 04:01:28 +00004399 isDeclarationSpecifier() || // 'int(int)' is a function.
4400 isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function.
Chris Lattneref4715c2008-04-06 05:45:57 +00004401 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
4402 // considered to be a type, not a K&R identifier-list.
4403 isGrouping = false;
4404 } else {
4405 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
4406 isGrouping = true;
4407 }
Mike Stump1eb44332009-09-09 15:08:12 +00004408
Chris Lattneref4715c2008-04-06 05:45:57 +00004409 // If this is a grouping paren, handle:
4410 // direct-declarator: '(' declarator ')'
4411 // direct-declarator: '(' attributes declarator ')'
4412 if (isGrouping) {
Richard Smith9988f282012-03-29 01:16:42 +00004413 SourceLocation EllipsisLoc = D.getEllipsisLoc();
4414 D.setEllipsisLoc(SourceLocation());
4415
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00004416 bool hadGroupingParens = D.hasGroupingParens();
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00004417 D.setGroupingParens(true);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004418 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattneref4715c2008-04-06 05:45:57 +00004419 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004420 T.consumeClose();
Chad Rosier8decdee2012-06-26 22:30:43 +00004421 D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004422 T.getCloseLocation()),
4423 attrs, T.getCloseLocation());
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00004424
4425 D.setGroupingParens(hadGroupingParens);
Richard Smith9988f282012-03-29 01:16:42 +00004426
4427 // An ellipsis cannot be placed outside parentheses.
4428 if (EllipsisLoc.isValid())
4429 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4430
Chris Lattneref4715c2008-04-06 05:45:57 +00004431 return;
4432 }
Mike Stump1eb44332009-09-09 15:08:12 +00004433
Chris Lattneref4715c2008-04-06 05:45:57 +00004434 // Okay, if this wasn't a grouping paren, it must be the start of a function
4435 // argument list. Recognize that this declarator will never have an
Chris Lattner7399ee02008-10-20 02:05:46 +00004436 // identifier (and remember where it would have been), then call into
4437 // ParseFunctionDeclarator to handle of argument list.
Chris Lattneref4715c2008-04-06 05:45:57 +00004438 D.SetIdentifier(0, Tok.getLocation());
4439
David Blaikie42d6d0c2011-12-04 05:04:18 +00004440 // Enter function-declaration scope, limiting any declarators to the
4441 // function prototype scope, including parameter declarators.
4442 ParseScope PrototypeScope(this,
4443 Scope::FunctionPrototypeScope|Scope::DeclScope);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004444 ParseFunctionDeclarator(D, attrs, T, RequiresArg);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004445 PrototypeScope.Exit();
Chris Lattneref4715c2008-04-06 05:45:57 +00004446}
4447
4448/// ParseFunctionDeclarator - We are after the identifier and have parsed the
4449/// declarator D up to a paren, which indicates that we are parsing function
4450/// arguments.
Reid Spencer5f016e22007-07-11 17:01:13 +00004451///
Richard Smith6ee326a2012-04-10 01:32:12 +00004452/// If FirstArgAttrs is non-null, then the caller parsed those arguments
4453/// immediately after the open paren - they should be considered to be the
4454/// first argument of a parameter.
Chris Lattner7399ee02008-10-20 02:05:46 +00004455///
Richard Smith6ee326a2012-04-10 01:32:12 +00004456/// If RequiresArg is true, then the first argument of the function is required
4457/// to be present and required to not be an identifier list.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004458///
Richard Smith6ee326a2012-04-10 01:32:12 +00004459/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
4460/// (C++11) ref-qualifier[opt], exception-specification[opt],
4461/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
4462///
4463/// [C++11] exception-specification:
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004464/// dynamic-exception-specification
4465/// noexcept-specification
4466///
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004467void Parser::ParseFunctionDeclarator(Declarator &D,
Richard Smith6ee326a2012-04-10 01:32:12 +00004468 ParsedAttributes &FirstArgAttrs,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004469 BalancedDelimiterTracker &Tracker,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004470 bool RequiresArg) {
Chad Rosier8decdee2012-06-26 22:30:43 +00004471 assert(getCurScope()->isFunctionPrototypeScope() &&
David Blaikie42d6d0c2011-12-04 05:04:18 +00004472 "Should call from a Function scope");
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004473 // lparen is already consumed!
4474 assert(D.isPastIdentifier() && "Should not call before identifier!");
4475
4476 // This should be true when the function has typed arguments.
4477 // Otherwise, it is treated as a K&R-style function.
4478 bool HasProto = false;
4479 // Build up an array of information about the parsed arguments.
Chris Lattner5f9e2722011-07-23 10:55:15 +00004480 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004481 // Remember where we see an ellipsis, if any.
4482 SourceLocation EllipsisLoc;
4483
4484 DeclSpec DS(AttrFactory);
4485 bool RefQualifierIsLValueRef = true;
4486 SourceLocation RefQualifierLoc;
Douglas Gregor43f51032011-10-19 06:04:55 +00004487 SourceLocation ConstQualifierLoc;
4488 SourceLocation VolatileQualifierLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004489 ExceptionSpecificationType ESpecType = EST_None;
4490 SourceRange ESpecRange;
Chris Lattner5f9e2722011-07-23 10:55:15 +00004491 SmallVector<ParsedType, 2> DynamicExceptions;
4492 SmallVector<SourceRange, 2> DynamicExceptionRanges;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004493 ExprResult NoexceptExpr;
Richard Smith6ee326a2012-04-10 01:32:12 +00004494 ParsedAttributes FnAttrs(AttrFactory);
Richard Smith54655be2012-06-12 01:51:59 +00004495 TypeResult TrailingReturnType;
Richard Smith6ee326a2012-04-10 01:32:12 +00004496
James Molloy16f1f712012-02-29 10:24:19 +00004497 Actions.ActOnStartFunctionDeclarator();
4498
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004499 SourceLocation EndLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004500 if (isFunctionDeclaratorIdentifierList()) {
4501 if (RequiresArg)
4502 Diag(Tok, diag::err_argument_required_after_attribute);
4503
4504 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
4505
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004506 Tracker.consumeClose();
4507 EndLoc = Tracker.getCloseLocation();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004508 } else {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004509 if (Tok.isNot(tok::r_paren))
Richard Smith6ee326a2012-04-10 01:32:12 +00004510 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004511 else if (RequiresArg)
4512 Diag(Tok, diag::err_argument_required_after_attribute);
4513
David Blaikie4e4d0842012-03-11 07:00:24 +00004514 HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004515
4516 // If we have the closing ')', eat it.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004517 Tracker.consumeClose();
4518 EndLoc = Tracker.getCloseLocation();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004519
David Blaikie4e4d0842012-03-11 07:00:24 +00004520 if (getLangOpts().CPlusPlus) {
Richard Smith6ee326a2012-04-10 01:32:12 +00004521 // FIXME: Accept these components in any order, and produce fixits to
4522 // correct the order if the user gets it wrong. Ideally we should deal
4523 // with the virt-specifier-seq and pure-specifier in the same way.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004524
4525 // Parse cv-qualifier-seq[opt].
Richard Smith6ee326a2012-04-10 01:32:12 +00004526 ParseTypeQualifierListOpt(DS, false /*no attributes*/, false);
4527 if (!DS.getSourceRange().getEnd().isInvalid()) {
4528 EndLoc = DS.getSourceRange().getEnd();
4529 ConstQualifierLoc = DS.getConstSpecLoc();
4530 VolatileQualifierLoc = DS.getVolatileSpecLoc();
4531 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004532
4533 // Parse ref-qualifier[opt].
4534 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004535 Diag(Tok, getLangOpts().CPlusPlus0x ?
Richard Smith7fe62082011-10-15 05:09:34 +00004536 diag::warn_cxx98_compat_ref_qualifier :
4537 diag::ext_ref_qualifier);
Richard Smith6ee326a2012-04-10 01:32:12 +00004538
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004539 RefQualifierIsLValueRef = Tok.is(tok::amp);
4540 RefQualifierLoc = ConsumeToken();
4541 EndLoc = RefQualifierLoc;
4542 }
4543
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004544 // C++11 [expr.prim.general]p3:
Chad Rosier8decdee2012-06-26 22:30:43 +00004545 // If a declaration declares a member function or member function
4546 // template of a class X, the expression this is a prvalue of type
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004547 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
Chad Rosier8decdee2012-06-26 22:30:43 +00004548 // and the end of the function-definition, member-declarator, or
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004549 // declarator.
Chad Rosier8decdee2012-06-26 22:30:43 +00004550 bool IsCXX11MemberFunction =
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004551 getLangOpts().CPlusPlus0x &&
4552 (D.getContext() == Declarator::MemberContext ||
4553 (D.getContext() == Declarator::FileContext &&
Chad Rosier8decdee2012-06-26 22:30:43 +00004554 D.getCXXScopeSpec().isValid() &&
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004555 Actions.CurContext->isRecord()));
4556 Sema::CXXThisScopeRAII ThisScope(Actions,
4557 dyn_cast<CXXRecordDecl>(Actions.CurContext),
4558 DS.getTypeQualifiers(),
4559 IsCXX11MemberFunction);
Richard Smitha058fd42012-05-02 22:22:32 +00004560
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004561 // Parse exception-specification[opt].
Richard Smitha058fd42012-05-02 22:22:32 +00004562 ESpecType = tryParseExceptionSpecification(ESpecRange,
Douglas Gregor74e2fc32012-04-16 18:27:27 +00004563 DynamicExceptions,
4564 DynamicExceptionRanges,
Richard Smitha058fd42012-05-02 22:22:32 +00004565 NoexceptExpr);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004566 if (ESpecType != EST_None)
4567 EndLoc = ESpecRange.getEnd();
4568
Richard Smith6ee326a2012-04-10 01:32:12 +00004569 // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
4570 // after the exception-specification.
4571 MaybeParseCXX0XAttributes(FnAttrs);
4572
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004573 // Parse trailing-return-type[opt].
David Blaikie4e4d0842012-03-11 07:00:24 +00004574 if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) {
Richard Smith7fe62082011-10-15 05:09:34 +00004575 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
Douglas Gregorae7902c2011-08-04 15:30:47 +00004576 SourceRange Range;
Richard Smith54655be2012-06-12 01:51:59 +00004577 TrailingReturnType = ParseTrailingReturnType(Range);
Douglas Gregorae7902c2011-08-04 15:30:47 +00004578 if (Range.getEnd().isValid())
4579 EndLoc = Range.getEnd();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004580 }
4581 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004582 }
4583
4584 // Remember that we parsed a function type, and remember the attributes.
4585 D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
4586 /*isVariadic=*/EllipsisLoc.isValid(),
4587 EllipsisLoc,
4588 ParamInfo.data(), ParamInfo.size(),
4589 DS.getTypeQualifiers(),
4590 RefQualifierIsLValueRef,
Douglas Gregor43f51032011-10-19 06:04:55 +00004591 RefQualifierLoc, ConstQualifierLoc,
4592 VolatileQualifierLoc,
Douglas Gregor90ebed02011-07-13 21:47:47 +00004593 /*MutableLoc=*/SourceLocation(),
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004594 ESpecType, ESpecRange.getBegin(),
4595 DynamicExceptions.data(),
4596 DynamicExceptionRanges.data(),
4597 DynamicExceptions.size(),
4598 NoexceptExpr.isUsable() ?
4599 NoexceptExpr.get() : 0,
Chad Rosier8decdee2012-06-26 22:30:43 +00004600 Tracker.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004601 EndLoc, D,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004602 TrailingReturnType),
Richard Smith6ee326a2012-04-10 01:32:12 +00004603 FnAttrs, EndLoc);
James Molloy16f1f712012-02-29 10:24:19 +00004604
4605 Actions.ActOnEndFunctionDeclarator();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004606}
4607
4608/// isFunctionDeclaratorIdentifierList - This parameter list may have an
4609/// identifier list form for a K&R-style function: void foo(a,b,c)
4610///
4611/// Note that identifier-lists are only allowed for normal declarators, not for
4612/// abstract-declarators.
4613bool Parser::isFunctionDeclaratorIdentifierList() {
David Blaikie4e4d0842012-03-11 07:00:24 +00004614 return !getLangOpts().CPlusPlus
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004615 && Tok.is(tok::identifier)
4616 && !TryAltiVecVectorToken()
4617 // K&R identifier lists can't have typedefs as identifiers, per C99
4618 // 6.7.5.3p11.
4619 && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
4620 // Identifier lists follow a really simple grammar: the identifiers can
4621 // be followed *only* by a ", identifier" or ")". However, K&R
4622 // identifier lists are really rare in the brave new modern world, and
4623 // it is very common for someone to typo a type in a non-K&R style
4624 // list. If we are presented with something like: "void foo(intptr x,
4625 // float y)", we don't want to start parsing the function declarator as
4626 // though it is a K&R style declarator just because intptr is an
4627 // invalid type.
4628 //
4629 // To handle this, we check to see if the token after the first
4630 // identifier is a "," or ")". Only then do we parse it as an
4631 // identifier list.
4632 && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
4633}
4634
4635/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
4636/// we found a K&R-style identifier list instead of a typed parameter list.
4637///
4638/// After returning, ParamInfo will hold the parsed parameters.
4639///
4640/// identifier-list: [C99 6.7.5]
4641/// identifier
4642/// identifier-list ',' identifier
4643///
4644void Parser::ParseFunctionDeclaratorIdentifierList(
4645 Declarator &D,
Chris Lattner5f9e2722011-07-23 10:55:15 +00004646 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004647 // If there was no identifier specified for the declarator, either we are in
4648 // an abstract-declarator, or we are in a parameter declarator which was found
4649 // to be abstract. In abstract-declarators, identifier lists are not valid:
4650 // diagnose this.
4651 if (!D.getIdentifier())
4652 Diag(Tok, diag::ext_ident_list_in_param);
4653
4654 // Maintain an efficient lookup of params we have seen so far.
4655 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
4656
4657 while (1) {
4658 // If this isn't an identifier, report the error and skip until ')'.
4659 if (Tok.isNot(tok::identifier)) {
4660 Diag(Tok, diag::err_expected_ident);
4661 SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true);
4662 // Forget we parsed anything.
4663 ParamInfo.clear();
4664 return;
4665 }
4666
4667 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
4668
4669 // Reject 'typedef int y; int test(x, y)', but continue parsing.
4670 if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
4671 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
4672
4673 // Verify that the argument identifier has not already been mentioned.
4674 if (!ParamsSoFar.insert(ParmII)) {
4675 Diag(Tok, diag::err_param_redefinition) << ParmII;
4676 } else {
4677 // Remember this identifier in ParamInfo.
4678 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4679 Tok.getLocation(),
4680 0));
4681 }
4682
4683 // Eat the identifier.
4684 ConsumeToken();
4685
4686 // The list continues if we see a comma.
4687 if (Tok.isNot(tok::comma))
4688 break;
4689 ConsumeToken();
4690 }
4691}
4692
4693/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
4694/// after the opening parenthesis. This function will not parse a K&R-style
4695/// identifier list.
4696///
Richard Smith6ce48a72012-04-11 04:01:28 +00004697/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the
4698/// caller parsed those arguments immediately after the open paren - they should
4699/// be considered to be part of the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004700///
4701/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
4702/// be the location of the ellipsis, if any was parsed.
4703///
Reid Spencer5f016e22007-07-11 17:01:13 +00004704/// parameter-type-list: [C99 6.7.5]
4705/// parameter-list
4706/// parameter-list ',' '...'
Douglas Gregored5d6512009-09-22 21:41:40 +00004707/// [C++] parameter-list '...'
Reid Spencer5f016e22007-07-11 17:01:13 +00004708///
4709/// parameter-list: [C99 6.7.5]
4710/// parameter-declaration
4711/// parameter-list ',' parameter-declaration
4712///
4713/// parameter-declaration: [C99 6.7.5]
4714/// declaration-specifiers declarator
Chris Lattner04421082008-04-08 04:40:51 +00004715/// [C++] declaration-specifiers declarator '=' assignment-expression
Sebastian Redl84407ba2012-03-14 15:54:00 +00004716/// [C++11] initializer-clause
Reid Spencer5f016e22007-07-11 17:01:13 +00004717/// [GNU] declaration-specifiers declarator attributes
Sebastian Redl50de12f2009-03-24 22:27:57 +00004718/// declaration-specifiers abstract-declarator[opt]
4719/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner8123a952008-04-10 02:22:51 +00004720/// '=' assignment-expression
Reid Spencer5f016e22007-07-11 17:01:13 +00004721/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
Richard Smith6ce48a72012-04-11 04:01:28 +00004722/// [C++11] attribute-specifier-seq parameter-declaration
Reid Spencer5f016e22007-07-11 17:01:13 +00004723///
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004724void Parser::ParseParameterDeclarationClause(
4725 Declarator &D,
Richard Smith6ce48a72012-04-11 04:01:28 +00004726 ParsedAttributes &FirstArgAttrs,
Chris Lattner5f9e2722011-07-23 10:55:15 +00004727 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004728 SourceLocation &EllipsisLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00004729
Chris Lattnerf97409f2008-04-06 06:57:35 +00004730 while (1) {
4731 if (Tok.is(tok::ellipsis)) {
Richard Smith6ce48a72012-04-11 04:01:28 +00004732 // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
4733 // before deciding this was a parameter-declaration-clause.
Douglas Gregor965acbb2009-02-18 07:07:28 +00004734 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattnerf97409f2008-04-06 06:57:35 +00004735 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00004736 }
Mike Stump1eb44332009-09-09 15:08:12 +00004737
Chris Lattnerf97409f2008-04-06 06:57:35 +00004738 // Parse the declaration-specifiers.
John McCall54abf7d2009-11-04 02:18:39 +00004739 // Just use the ParsingDeclaration "scope" of the declarator.
John McCall0b7e6782011-03-24 11:26:52 +00004740 DeclSpec DS(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004741
Richard Smith6ce48a72012-04-11 04:01:28 +00004742 // Parse any C++11 attributes.
4743 MaybeParseCXX0XAttributes(DS.getAttributes());
4744
John McCall7f040a92010-12-24 02:08:15 +00004745 // Skip any Microsoft attributes before a param.
David Blaikie4e4d0842012-03-11 07:00:24 +00004746 if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
John McCall7f040a92010-12-24 02:08:15 +00004747 ParseMicrosoftAttributes(DS.getAttributes());
4748
4749 SourceLocation DSStart = Tok.getLocation();
Chris Lattner7399ee02008-10-20 02:05:46 +00004750
4751 // If the caller parsed attributes for the first argument, add them now.
John McCall7f040a92010-12-24 02:08:15 +00004752 // Take them so that we only apply the attributes to the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004753 // FIXME: If we can leave the attributes in the token stream somehow, we can
Richard Smith6ce48a72012-04-11 04:01:28 +00004754 // get rid of a parameter (FirstArgAttrs) and this statement. It might be
4755 // too much hassle.
4756 DS.takeAttributesFrom(FirstArgAttrs);
John McCall7f040a92010-12-24 02:08:15 +00004757
Chris Lattnere64c5492009-02-27 18:38:20 +00004758 ParseDeclarationSpecifiers(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00004759
Chris Lattnerf97409f2008-04-06 06:57:35 +00004760 // Parse the declarator. This is "PrototypeContext", because we must
4761 // accept either 'declarator' or 'abstract-declarator' here.
4762 Declarator ParmDecl(DS, Declarator::PrototypeContext);
4763 ParseDeclarator(ParmDecl);
4764
4765 // Parse GNU attributes, if present.
John McCall7f040a92010-12-24 02:08:15 +00004766 MaybeParseGNUAttributes(ParmDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00004767
Chris Lattnerf97409f2008-04-06 06:57:35 +00004768 // Remember this parsed parameter in ParamInfo.
4769 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
Mike Stump1eb44332009-09-09 15:08:12 +00004770
Douglas Gregor72b505b2008-12-16 21:30:33 +00004771 // DefArgToks is used when the parsing of default arguments needs
4772 // to be delayed.
4773 CachedTokens *DefArgToks = 0;
4774
Chris Lattnerf97409f2008-04-06 06:57:35 +00004775 // If no parameter was specified, verify that *something* was specified,
4776 // otherwise we have a missing type and identifier.
Chris Lattnere64c5492009-02-27 18:38:20 +00004777 if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
4778 ParmDecl.getNumTypeObjects() == 0) {
Chris Lattnerf97409f2008-04-06 06:57:35 +00004779 // Completely missing, emit error.
4780 Diag(DSStart, diag::err_missing_param);
4781 } else {
4782 // Otherwise, we have something. Add it and let semantic analysis try
4783 // to grok it and add the result to the ParamInfo we are building.
Mike Stump1eb44332009-09-09 15:08:12 +00004784
Chris Lattnerf97409f2008-04-06 06:57:35 +00004785 // Inform the actions module about the parameter declarator, so it gets
4786 // added to the current scope.
John McCalld226f652010-08-21 09:40:31 +00004787 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
Chris Lattner04421082008-04-08 04:40:51 +00004788
4789 // Parse the default argument, if any. We parse the default
4790 // arguments in all dialects; the semantic analysis in
4791 // ActOnParamDefaultArgument will reject the default argument in
4792 // C.
4793 if (Tok.is(tok::equal)) {
Douglas Gregor61366e92008-12-24 00:01:03 +00004794 SourceLocation EqualLoc = Tok.getLocation();
4795
Chris Lattner04421082008-04-08 04:40:51 +00004796 // Parse the default argument
Douglas Gregor72b505b2008-12-16 21:30:33 +00004797 if (D.getContext() == Declarator::MemberContext) {
4798 // If we're inside a class definition, cache the tokens
4799 // corresponding to the default argument. We'll actually parse
4800 // them when we see the end of the class definition.
Douglas Gregor72b505b2008-12-16 21:30:33 +00004801 // FIXME: Can we use a smart pointer for Toks?
4802 DefArgToks = new CachedTokens;
4803
Mike Stump1eb44332009-09-09 15:08:12 +00004804 if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
Argyrios Kyrtzidis14b91622010-04-23 21:20:12 +00004805 /*StopAtSemi=*/true,
4806 /*ConsumeFinalToken=*/false)) {
Douglas Gregor72b505b2008-12-16 21:30:33 +00004807 delete DefArgToks;
4808 DefArgToks = 0;
Douglas Gregor61366e92008-12-24 00:01:03 +00004809 Actions.ActOnParamDefaultArgumentError(Param);
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00004810 } else {
4811 // Mark the end of the default argument so that we know when to
4812 // stop when we parse it later on.
4813 Token DefArgEnd;
4814 DefArgEnd.startToken();
4815 DefArgEnd.setKind(tok::cxx_defaultarg_end);
4816 DefArgEnd.setLocation(Tok.getLocation());
4817 DefArgToks->push_back(DefArgEnd);
Mike Stump1eb44332009-09-09 15:08:12 +00004818 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
Anders Carlsson5e300d12009-06-12 16:51:40 +00004819 (*DefArgToks)[1].getLocation());
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00004820 }
Chris Lattner04421082008-04-08 04:40:51 +00004821 } else {
Douglas Gregor72b505b2008-12-16 21:30:33 +00004822 // Consume the '='.
Douglas Gregor61366e92008-12-24 00:01:03 +00004823 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00004824
Chad Rosier8decdee2012-06-26 22:30:43 +00004825 // The argument isn't actually potentially evaluated unless it is
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00004826 // used.
4827 EnterExpressionEvaluationContext Eval(Actions,
Douglas Gregorccc1b5e2012-02-21 00:37:24 +00004828 Sema::PotentiallyEvaluatedIfUsed,
4829 Param);
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00004830
Sebastian Redl84407ba2012-03-14 15:54:00 +00004831 ExprResult DefArgResult;
Sebastian Redl3e280b52012-03-18 22:25:45 +00004832 if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
4833 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Sebastian Redl84407ba2012-03-14 15:54:00 +00004834 DefArgResult = ParseBraceInitializer();
Sebastian Redl3e280b52012-03-18 22:25:45 +00004835 } else
Sebastian Redl84407ba2012-03-14 15:54:00 +00004836 DefArgResult = ParseAssignmentExpression();
Douglas Gregor72b505b2008-12-16 21:30:33 +00004837 if (DefArgResult.isInvalid()) {
4838 Actions.ActOnParamDefaultArgumentError(Param);
4839 SkipUntil(tok::comma, tok::r_paren, true, true);
4840 } else {
4841 // Inform the actions module about the default argument
4842 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
John McCall9ae2f072010-08-23 23:25:46 +00004843 DefArgResult.take());
Douglas Gregor72b505b2008-12-16 21:30:33 +00004844 }
Chris Lattner04421082008-04-08 04:40:51 +00004845 }
4846 }
Mike Stump1eb44332009-09-09 15:08:12 +00004847
4848 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4849 ParmDecl.getIdentifierLoc(), Param,
Douglas Gregor72b505b2008-12-16 21:30:33 +00004850 DefArgToks));
Chris Lattnerf97409f2008-04-06 06:57:35 +00004851 }
4852
4853 // If the next token is a comma, consume it and keep reading arguments.
Douglas Gregored5d6512009-09-22 21:41:40 +00004854 if (Tok.isNot(tok::comma)) {
4855 if (Tok.is(tok::ellipsis)) {
Douglas Gregored5d6512009-09-22 21:41:40 +00004856 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chad Rosier8decdee2012-06-26 22:30:43 +00004857
David Blaikie4e4d0842012-03-11 07:00:24 +00004858 if (!getLangOpts().CPlusPlus) {
Douglas Gregored5d6512009-09-22 21:41:40 +00004859 // We have ellipsis without a preceding ',', which is ill-formed
4860 // in C. Complain and provide the fix.
4861 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
Douglas Gregor849b2432010-03-31 17:46:05 +00004862 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
Douglas Gregored5d6512009-09-22 21:41:40 +00004863 }
4864 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004865
Douglas Gregored5d6512009-09-22 21:41:40 +00004866 break;
4867 }
Mike Stump1eb44332009-09-09 15:08:12 +00004868
Chris Lattnerf97409f2008-04-06 06:57:35 +00004869 // Consume the comma.
4870 ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00004871 }
Mike Stump1eb44332009-09-09 15:08:12 +00004872
Chris Lattner66d28652008-04-06 06:34:08 +00004873}
Chris Lattneref4715c2008-04-06 05:45:57 +00004874
Reid Spencer5f016e22007-07-11 17:01:13 +00004875/// [C90] direct-declarator '[' constant-expression[opt] ']'
4876/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4877/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4878/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4879/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00004880/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4881/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00004882void Parser::ParseBracketDeclarator(Declarator &D) {
Richard Smith6ee326a2012-04-10 01:32:12 +00004883 if (CheckProhibitedCXX11Attribute())
4884 return;
4885
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004886 BalancedDelimiterTracker T(*this, tok::l_square);
4887 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00004888
Chris Lattner378c7e42008-12-18 07:27:21 +00004889 // C array syntax has many features, but by-far the most common is [] and [4].
4890 // This code does a fast path to handle some of the most obvious cases.
4891 if (Tok.getKind() == tok::r_square) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004892 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00004893 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004894 MaybeParseCXX0XAttributes(attrs);
Chad Rosier8decdee2012-06-26 22:30:43 +00004895
Chris Lattner378c7e42008-12-18 07:27:21 +00004896 // Remember that we parsed the empty array type.
John McCall60d7b3a2010-08-24 06:29:42 +00004897 ExprResult NumElements;
John McCall0b7e6782011-03-24 11:26:52 +00004898 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004899 T.getOpenLocation(),
4900 T.getCloseLocation()),
4901 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00004902 return;
4903 } else if (Tok.getKind() == tok::numeric_constant &&
4904 GetLookAheadToken(1).is(tok::r_square)) {
4905 // [4] is very common. Parse the numeric constant expression.
Richard Smith36f5cfe2012-03-09 08:00:36 +00004906 ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
Chris Lattner378c7e42008-12-18 07:27:21 +00004907 ConsumeToken();
4908
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004909 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00004910 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004911 MaybeParseCXX0XAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004912
Chris Lattner378c7e42008-12-18 07:27:21 +00004913 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00004914 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
John McCall7f040a92010-12-24 02:08:15 +00004915 ExprRes.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004916 T.getOpenLocation(),
4917 T.getCloseLocation()),
4918 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00004919 return;
4920 }
Mike Stump1eb44332009-09-09 15:08:12 +00004921
Reid Spencer5f016e22007-07-11 17:01:13 +00004922 // If valid, this location is the position where we read the 'static' keyword.
4923 SourceLocation StaticLoc;
Chris Lattner04d66662007-10-09 17:33:22 +00004924 if (Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00004925 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00004926
Reid Spencer5f016e22007-07-11 17:01:13 +00004927 // If there is a type-qualifier-list, read it now.
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004928 // Type qualifiers in an array subscript are a C99 feature.
John McCall0b7e6782011-03-24 11:26:52 +00004929 DeclSpec DS(AttrFactory);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004930 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Mike Stump1eb44332009-09-09 15:08:12 +00004931
Reid Spencer5f016e22007-07-11 17:01:13 +00004932 // If we haven't already read 'static', check to see if there is one after the
4933 // type-qualifier-list.
Chris Lattner04d66662007-10-09 17:33:22 +00004934 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00004935 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00004936
Reid Spencer5f016e22007-07-11 17:01:13 +00004937 // Handle "direct-declarator [ type-qual-list[opt] * ]".
4938 bool isStar = false;
John McCall60d7b3a2010-08-24 06:29:42 +00004939 ExprResult NumElements;
Mike Stump1eb44332009-09-09 15:08:12 +00004940
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00004941 // Handle the case where we have '[*]' as the array size. However, a leading
4942 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
4943 // the the token after the star is a ']'. Since stars in arrays are
4944 // infrequent, use of lookahead is not costly here.
4945 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattnera711dd02008-04-06 05:27:21 +00004946 ConsumeToken(); // Eat the '*'.
Reid Spencer5f016e22007-07-11 17:01:13 +00004947
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004948 if (StaticLoc.isValid()) {
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00004949 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004950 StaticLoc = SourceLocation(); // Drop the static.
4951 }
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00004952 isStar = true;
Chris Lattner04d66662007-10-09 17:33:22 +00004953 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner378c7e42008-12-18 07:27:21 +00004954 // Note, in C89, this production uses the constant-expr production instead
4955 // of assignment-expr. The only difference is that assignment-expr allows
4956 // things like '=' and '*='. Sema rejects these in C89 mode because they
4957 // are not i-c-e's, so we don't need to distinguish between the two here.
Mike Stump1eb44332009-09-09 15:08:12 +00004958
Douglas Gregore0762c92009-06-19 23:52:42 +00004959 // Parse the constant-expression or assignment-expression now (depending
4960 // on dialect).
David Blaikie4e4d0842012-03-11 07:00:24 +00004961 if (getLangOpts().CPlusPlus) {
Douglas Gregore0762c92009-06-19 23:52:42 +00004962 NumElements = ParseConstantExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00004963 } else {
4964 EnterExpressionEvaluationContext Unevaluated(Actions,
4965 Sema::ConstantEvaluated);
Douglas Gregore0762c92009-06-19 23:52:42 +00004966 NumElements = ParseAssignmentExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00004967 }
Reid Spencer5f016e22007-07-11 17:01:13 +00004968 }
Mike Stump1eb44332009-09-09 15:08:12 +00004969
Reid Spencer5f016e22007-07-11 17:01:13 +00004970 // If there was an error parsing the assignment-expression, recover.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00004971 if (NumElements.isInvalid()) {
Chris Lattner5cb10d32009-04-24 22:30:50 +00004972 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00004973 // If the expression was invalid, skip it.
4974 SkipUntil(tok::r_square);
4975 return;
4976 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00004977
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004978 T.consumeClose();
Sebastian Redlab197ba2009-02-09 18:23:29 +00004979
John McCall0b7e6782011-03-24 11:26:52 +00004980 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004981 MaybeParseCXX0XAttributes(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00004982
Chris Lattner378c7e42008-12-18 07:27:21 +00004983 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00004984 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
Reid Spencer5f016e22007-07-11 17:01:13 +00004985 StaticLoc.isValid(), isStar,
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00004986 NumElements.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004987 T.getOpenLocation(),
4988 T.getCloseLocation()),
4989 attrs, T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004990}
4991
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00004992/// [GNU] typeof-specifier:
4993/// typeof ( expressions )
4994/// typeof ( type-name )
4995/// [GNU/C++] typeof unary-expression
Steve Naroffd1861fd2007-07-31 12:34:36 +00004996///
4997void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner04d66662007-10-09 17:33:22 +00004998 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00004999 Token OpTok = Tok;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005000 SourceLocation StartLoc = ConsumeToken();
5001
John McCallcfb708c2010-01-13 20:03:27 +00005002 const bool hasParens = Tok.is(tok::l_paren);
5003
Eli Friedman71b8fb52012-01-21 01:01:51 +00005004 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
5005
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005006 bool isCastExpr;
John McCallb3d87482010-08-24 05:47:05 +00005007 ParsedType CastTy;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005008 SourceRange CastRange;
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00005009 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
5010 CastTy, CastRange);
John McCallcfb708c2010-01-13 20:03:27 +00005011 if (hasParens)
5012 DS.setTypeofParensRange(CastRange);
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005013
5014 if (CastRange.getEnd().isInvalid())
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005015 // FIXME: Not accurate, the range gets one token more than it should.
5016 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005017 else
5018 DS.SetRangeEnd(CastRange.getEnd());
Mike Stump1eb44332009-09-09 15:08:12 +00005019
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005020 if (isCastExpr) {
5021 if (!CastTy) {
5022 DS.SetTypeSpecError();
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005023 return;
Douglas Gregor809070a2009-02-18 17:45:20 +00005024 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005025
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005026 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005027 unsigned DiagID;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005028 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5029 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00005030 DiagID, CastTy))
5031 Diag(StartLoc, DiagID) << PrevSpec;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005032 return;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005033 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005034
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005035 // If we get here, the operand to the typeof was an expresion.
5036 if (Operand.isInvalid()) {
5037 DS.SetTypeSpecError();
Steve Naroff9dfa7b42007-08-02 02:53:48 +00005038 return;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005039 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005040
Eli Friedman71b8fb52012-01-21 01:01:51 +00005041 // We might need to transform the operand if it is potentially evaluated.
5042 Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5043 if (Operand.isInvalid()) {
5044 DS.SetTypeSpecError();
5045 return;
5046 }
5047
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005048 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005049 unsigned DiagID;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005050 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5051 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00005052 DiagID, Operand.get()))
John McCallfec54012009-08-03 20:12:06 +00005053 Diag(StartLoc, DiagID) << PrevSpec;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005054}
Chris Lattner1b492422010-02-28 18:33:55 +00005055
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00005056/// [C11] atomic-specifier:
Eli Friedmanb001de72011-10-06 23:00:33 +00005057/// _Atomic ( type-name )
5058///
5059void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
5060 assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier");
5061
5062 SourceLocation StartLoc = ConsumeToken();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005063 BalancedDelimiterTracker T(*this, tok::l_paren);
5064 if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) {
Eli Friedmanb001de72011-10-06 23:00:33 +00005065 SkipUntil(tok::r_paren);
5066 return;
5067 }
5068
5069 TypeResult Result = ParseTypeName();
5070 if (Result.isInvalid()) {
5071 SkipUntil(tok::r_paren);
5072 return;
5073 }
5074
5075 // Match the ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005076 T.consumeClose();
Eli Friedmanb001de72011-10-06 23:00:33 +00005077
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005078 if (T.getCloseLocation().isInvalid())
Eli Friedmanb001de72011-10-06 23:00:33 +00005079 return;
5080
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005081 DS.setTypeofParensRange(T.getRange());
5082 DS.SetRangeEnd(T.getCloseLocation());
Eli Friedmanb001de72011-10-06 23:00:33 +00005083
5084 const char *PrevSpec = 0;
5085 unsigned DiagID;
5086 if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5087 DiagID, Result.release()))
5088 Diag(StartLoc, DiagID) << PrevSpec;
5089}
5090
Chris Lattner1b492422010-02-28 18:33:55 +00005091
5092/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5093/// from TryAltiVecVectorToken.
5094bool Parser::TryAltiVecVectorTokenOutOfLine() {
5095 Token Next = NextToken();
5096 switch (Next.getKind()) {
5097 default: return false;
5098 case tok::kw_short:
5099 case tok::kw_long:
5100 case tok::kw_signed:
5101 case tok::kw_unsigned:
5102 case tok::kw_void:
5103 case tok::kw_char:
5104 case tok::kw_int:
5105 case tok::kw_float:
5106 case tok::kw_double:
5107 case tok::kw_bool:
5108 case tok::kw___pixel:
5109 Tok.setKind(tok::kw___vector);
5110 return true;
5111 case tok::identifier:
5112 if (Next.getIdentifierInfo() == Ident_pixel) {
5113 Tok.setKind(tok::kw___vector);
5114 return true;
5115 }
5116 return false;
5117 }
5118}
5119
5120bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5121 const char *&PrevSpec, unsigned &DiagID,
5122 bool &isInvalid) {
5123 if (Tok.getIdentifierInfo() == Ident_vector) {
5124 Token Next = NextToken();
5125 switch (Next.getKind()) {
5126 case tok::kw_short:
5127 case tok::kw_long:
5128 case tok::kw_signed:
5129 case tok::kw_unsigned:
5130 case tok::kw_void:
5131 case tok::kw_char:
5132 case tok::kw_int:
5133 case tok::kw_float:
5134 case tok::kw_double:
5135 case tok::kw_bool:
5136 case tok::kw___pixel:
5137 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5138 return true;
5139 case tok::identifier:
5140 if (Next.getIdentifierInfo() == Ident_pixel) {
5141 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5142 return true;
5143 }
5144 break;
5145 default:
5146 break;
5147 }
Douglas Gregora8f031f2010-06-16 15:28:57 +00005148 } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
Chris Lattner1b492422010-02-28 18:33:55 +00005149 DS.isTypeAltiVecVector()) {
5150 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5151 return true;
5152 }
5153 return false;
5154}