blob: e90d0eb9fe47c83a777c410550b678c2aa33b0d0 [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
Sean Huntbbd37c62009-11-21 08:43:09 +000071/// ParseGNUAttributes - Parse a non-empty attributes list.
Reid Spencer5f016e22007-07-11 17:01:13 +000072///
73/// [GNU] attributes:
74/// attribute
75/// attributes attribute
76///
77/// [GNU] attribute:
78/// '__attribute__' '(' '(' attribute-list ')' ')'
79///
80/// [GNU] attribute-list:
81/// attrib
82/// attribute_list ',' attrib
83///
84/// [GNU] attrib:
85/// empty
86/// attrib-name
87/// attrib-name '(' identifier ')'
88/// attrib-name '(' identifier ',' nonempty-expr-list ')'
89/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
90///
91/// [GNU] attrib-name:
92/// identifier
93/// typespec
94/// typequal
95/// storageclass
Mike Stump1eb44332009-09-09 15:08:12 +000096///
Reid Spencer5f016e22007-07-11 17:01:13 +000097/// FIXME: The GCC grammar/code for this construct implies we need two
Mike Stump1eb44332009-09-09 15:08:12 +000098/// token lookahead. Comment from gcc: "If they start with an identifier
99/// which is followed by a comma or close parenthesis, then the arguments
Reid Spencer5f016e22007-07-11 17:01:13 +0000100/// start with that identifier; otherwise they are an expression list."
101///
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000102/// GCC does not require the ',' between attribs in an attribute-list.
103///
Reid Spencer5f016e22007-07-11 17:01:13 +0000104/// At the moment, I am not doing 2 token lookahead. I am also unaware of
105/// any attributes that don't work (based on my limited testing). Most
106/// attributes are very simple in practice. Until we find a bug, I don't see
107/// a pressing need to implement the 2 token lookahead.
108
John McCall7f040a92010-12-24 02:08:15 +0000109void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000110 SourceLocation *endLoc,
111 LateParsedAttrList *LateAttrs) {
Sean Huntbbd37c62009-11-21 08:43:09 +0000112 assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
Mike Stump1eb44332009-09-09 15:08:12 +0000113
Chris Lattner04d66662007-10-09 17:33:22 +0000114 while (Tok.is(tok::kw___attribute)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000115 ConsumeToken();
116 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
117 "attribute")) {
118 SkipUntil(tok::r_paren, true); // skip until ) or ;
John McCall7f040a92010-12-24 02:08:15 +0000119 return;
Reid Spencer5f016e22007-07-11 17:01:13 +0000120 }
121 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
122 SkipUntil(tok::r_paren, true); // skip until ) or ;
John McCall7f040a92010-12-24 02:08:15 +0000123 return;
Reid Spencer5f016e22007-07-11 17:01:13 +0000124 }
125 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner04d66662007-10-09 17:33:22 +0000126 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
127 Tok.is(tok::comma)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000128 if (Tok.is(tok::comma)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000129 // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
130 ConsumeToken();
131 continue;
132 }
133 // we have an identifier or declaration specifier (const, int, etc.)
134 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
135 SourceLocation AttrNameLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +0000136
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000137 if (Tok.is(tok::l_paren)) {
138 // handle "parameterized" attributes
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000139 if (LateAttrs && isAttributeLateParsed(*AttrName)) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000140 LateParsedAttribute *LA =
141 new LateParsedAttribute(this, *AttrName, AttrNameLoc);
142 LateAttrs->push_back(LA);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000143
144 // Attributes in a class are parsed at the end of the class, along
145 // with other late-parsed declarations.
146 if (!ClassStack.empty())
147 getCurrentClass().LateParsedDeclarations.push_back(LA);
Mike Stump1eb44332009-09-09 15:08:12 +0000148
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000149 // consume everything up to and including the matching right parens
150 ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
Mike Stump1eb44332009-09-09 15:08:12 +0000151
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000152 Token Eof;
153 Eof.startToken();
154 Eof.setLocation(Tok.getLocation());
155 LA->Toks.push_back(Eof);
156 } else {
Michael Han6880f492012-10-03 01:56:22 +0000157 ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
158 0, AttrNameLoc, AttributeList::AS_GNU);
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
Michael Han6880f492012-10-03 01:56:22 +0000177/// Parse the arguments to a parameterized GNU attribute or
178/// a C++11 attribute in "gnu" namespace.
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000179void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
180 SourceLocation AttrNameLoc,
181 ParsedAttributes &Attrs,
Michael Han6880f492012-10-03 01:56:22 +0000182 SourceLocation *EndLoc,
183 IdentifierInfo *ScopeName,
184 SourceLocation ScopeLoc,
185 AttributeList::Syntax Syntax) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000186
187 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
188
189 // Availability attributes have their own grammar.
190 if (AttrName->isStr("availability")) {
191 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
192 return;
193 }
194 // Thread safety attributes fit into the FIXME case above, so we
195 // just parse the arguments as a list of expressions
196 if (IsThreadSafetyAttribute(AttrName->getName())) {
197 ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
198 return;
199 }
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +0000200 // Type safety attributes have their own grammar.
201 if (AttrName->isStr("type_tag_for_datatype")) {
202 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
203 return;
204 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000205
206 ConsumeParen(); // ignore the left paren loc for now
207
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000208 IdentifierInfo *ParmName = 0;
209 SourceLocation ParmLoc;
210 bool BuiltinType = false;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000211
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000212 switch (Tok.getKind()) {
213 case tok::kw_char:
214 case tok::kw_wchar_t:
215 case tok::kw_char16_t:
216 case tok::kw_char32_t:
217 case tok::kw_bool:
218 case tok::kw_short:
219 case tok::kw_int:
220 case tok::kw_long:
221 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +0000222 case tok::kw___int128:
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000223 case tok::kw_signed:
224 case tok::kw_unsigned:
225 case tok::kw_float:
226 case tok::kw_double:
227 case tok::kw_void:
228 case tok::kw_typeof:
229 // __attribute__(( vec_type_hint(char) ))
230 // FIXME: Don't just discard the builtin type token.
231 ConsumeToken();
232 BuiltinType = true;
233 break;
234
235 case tok::identifier:
236 ParmName = Tok.getIdentifierInfo();
237 ParmLoc = ConsumeToken();
238 break;
239
240 default:
241 break;
242 }
243
Benjamin Kramer4e28d9e2012-08-23 22:51:59 +0000244 ExprVector ArgExprs;
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000245
246 if (!BuiltinType &&
247 (ParmLoc.isValid() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) {
248 // Eat the comma.
249 if (ParmLoc.isValid())
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000250 ConsumeToken();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000251
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000252 // Parse the non-empty comma-separated list of expressions.
253 while (1) {
254 ExprResult ArgExpr(ParseAssignmentExpression());
255 if (ArgExpr.isInvalid()) {
256 SkipUntil(tok::r_paren);
257 return;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000258 }
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000259 ArgExprs.push_back(ArgExpr.release());
260 if (Tok.isNot(tok::comma))
261 break;
262 ConsumeToken(); // Eat the comma, move to the next argument
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000263 }
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000264 }
Fariborz Jahanian7a81e412011-10-18 17:11:10 +0000265 else if (Tok.is(tok::less) && AttrName->isStr("iboutletcollection")) {
266 if (!ExpectAndConsume(tok::less, diag::err_expected_less_after, "<",
267 tok::greater)) {
Fariborz Jahanianb2243432011-10-18 23:13:50 +0000268 while (Tok.is(tok::identifier)) {
269 ConsumeToken();
270 if (Tok.is(tok::greater))
271 break;
272 if (Tok.is(tok::comma)) {
273 ConsumeToken();
274 continue;
275 }
276 }
277 if (Tok.isNot(tok::greater))
278 Diag(Tok, diag::err_iboutletcollection_with_protocol);
Fariborz Jahanian7a81e412011-10-18 17:11:10 +0000279 SkipUntil(tok::r_paren, false, true); // skip until ')'
280 }
281 }
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000282
283 SourceLocation RParen = Tok.getLocation();
284 if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
285 AttributeList *attr =
Michael Han6880f492012-10-03 01:56:22 +0000286 Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen),
287 ScopeName, ScopeLoc, ParmName, ParmLoc,
288 ArgExprs.data(), ArgExprs.size(), Syntax);
Sean Hunt8e083e72012-06-19 23:57:03 +0000289 if (BuiltinType && attr->getKind() == AttributeList::AT_IBOutletCollection)
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000290 Diag(Tok, diag::err_iboutletcollection_builtintype);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000291 }
292}
293
Chad Rosier8decdee2012-06-26 22:30:43 +0000294/// \brief Parses a single argument for a declspec, including the
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000295/// surrounding parens.
Chad Rosier8decdee2012-06-26 22:30:43 +0000296void Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000297 SourceLocation AttrNameLoc,
298 ParsedAttributes &Attrs)
299{
300 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosier8decdee2012-06-26 22:30:43 +0000301 if (T.expectAndConsume(diag::err_expected_lparen_after,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000302 AttrName->getNameStart(), tok::r_paren))
303 return;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000304
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000305 ExprResult ArgExpr(ParseConstantExpression());
306 if (ArgExpr.isInvalid()) {
307 T.skipToEnd();
308 return;
309 }
310 Expr *ExprList = ArgExpr.take();
Chad Rosier8decdee2012-06-26 22:30:43 +0000311 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000312 &ExprList, 1, AttributeList::AS_Declspec);
313
314 T.consumeClose();
315}
316
Chad Rosier8decdee2012-06-26 22:30:43 +0000317/// \brief Determines whether a declspec is a "simple" one requiring no
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000318/// arguments.
319bool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) {
320 return llvm::StringSwitch<bool>(Ident->getName())
321 .Case("dllimport", true)
322 .Case("dllexport", true)
323 .Case("noreturn", true)
324 .Case("nothrow", true)
325 .Case("noinline", true)
326 .Case("naked", true)
327 .Case("appdomain", true)
328 .Case("process", true)
329 .Case("jitintrinsic", true)
330 .Case("noalias", true)
331 .Case("restrict", true)
332 .Case("novtable", true)
333 .Case("selectany", true)
334 .Case("thread", true)
335 .Default(false);
336}
337
Chad Rosier8decdee2012-06-26 22:30:43 +0000338/// \brief Attempts to parse a declspec which is not simple (one that takes
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000339/// parameters). Will return false if we properly handled the declspec, or
340/// true if it is an unknown declspec.
Chad Rosier8decdee2012-06-26 22:30:43 +0000341void Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000342 SourceLocation Loc,
343 ParsedAttributes &Attrs) {
344 // Try to handle the easy case first -- these declspecs all take a single
345 // parameter as their argument.
346 if (llvm::StringSwitch<bool>(Ident->getName())
347 .Case("uuid", true)
348 .Case("align", true)
349 .Case("allocate", true)
350 .Default(false)) {
351 ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
352 } else if (Ident->getName() == "deprecated") {
Chad Rosier8decdee2012-06-26 22:30:43 +0000353 // The deprecated declspec has an optional single argument, so we will
354 // check for a l-paren to decide whether we should parse an argument or
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000355 // not.
356 if (Tok.getKind() == tok::l_paren)
357 ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
358 else
Chad Rosier8decdee2012-06-26 22:30:43 +0000359 Attrs.addNew(Ident, Loc, 0, Loc, 0, SourceLocation(), 0, 0,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000360 AttributeList::AS_Declspec);
361 } else if (Ident->getName() == "property") {
362 // The property declspec is more complex in that it can take one or two
Chad Rosier8decdee2012-06-26 22:30:43 +0000363 // assignment expressions as a parameter, but the lhs of the assignment
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000364 // must be named get or put.
365 //
Chad Rosier8decdee2012-06-26 22:30:43 +0000366 // For right now, we will just skip to the closing right paren of the
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000367 // property expression.
368 //
369 // FIXME: we should deal with __declspec(property) at some point because it
370 // is used in the platform SDK headers for the Parallel Patterns Library
371 // and ATL.
372 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosier8decdee2012-06-26 22:30:43 +0000373 if (T.expectAndConsume(diag::err_expected_lparen_after,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000374 Ident->getNameStart(), tok::r_paren))
375 return;
376 T.skipToEnd();
377 } else {
378 // We don't recognize this as a valid declspec, but instead of creating the
379 // attribute and allowing sema to warn about it, we will warn here instead.
380 // This is because some attributes have multiple spellings, but we need to
381 // disallow that for declspecs (such as align vs aligned). If we made the
Chad Rosier8decdee2012-06-26 22:30:43 +0000382 // attribute, we'd have to split the valid declspec spelling logic into
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000383 // both locations.
384 Diag(Loc, diag::warn_ms_declspec_unknown) << Ident;
385
386 // If there's an open paren, we should eat the open and close parens under
387 // the assumption that this unknown declspec has parameters.
388 BalancedDelimiterTracker T(*this, tok::l_paren);
389 if (!T.consumeOpen())
390 T.skipToEnd();
391 }
392}
393
Eli Friedmana23b4852009-06-08 07:21:15 +0000394/// [MS] decl-specifier:
395/// __declspec ( extended-decl-modifier-seq )
396///
397/// [MS] extended-decl-modifier-seq:
398/// extended-decl-modifier[opt]
399/// extended-decl-modifier extended-decl-modifier-seq
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000400void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
Steve Narofff59e17e2008-12-24 20:59:21 +0000401 assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
Eli Friedmana23b4852009-06-08 07:21:15 +0000402
Steve Narofff59e17e2008-12-24 20:59:21 +0000403 ConsumeToken();
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000404 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosier8decdee2012-06-26 22:30:43 +0000405 if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000406 tok::r_paren))
John McCall7f040a92010-12-24 02:08:15 +0000407 return;
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000408
Chad Rosier8decdee2012-06-26 22:30:43 +0000409 // An empty declspec is perfectly legal and should not warn. Additionally,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000410 // you can specify multiple attributes per declspec.
411 while (Tok.getKind() != tok::r_paren) {
412 // We expect either a well-known identifier or a generic string. Anything
413 // else is a malformed declspec.
414 bool IsString = Tok.getKind() == tok::string_literal ? true : false;
Chad Rosier8decdee2012-06-26 22:30:43 +0000415 if (!IsString && Tok.getKind() != tok::identifier &&
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000416 Tok.getKind() != tok::kw_restrict) {
417 Diag(Tok, diag::err_ms_declspec_type);
418 T.skipToEnd();
419 return;
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000420 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000421
422 IdentifierInfo *AttrName;
423 SourceLocation AttrNameLoc;
424 if (IsString) {
425 SmallString<8> StrBuffer;
426 bool Invalid = false;
427 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
428 if (Invalid) {
429 T.skipToEnd();
430 return;
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000431 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000432 AttrName = PP.getIdentifierInfo(Str);
433 AttrNameLoc = ConsumeStringToken();
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000434 } else {
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000435 AttrName = Tok.getIdentifierInfo();
436 AttrNameLoc = ConsumeToken();
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000437 }
Chad Rosier8decdee2012-06-26 22:30:43 +0000438
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000439 if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
Chad Rosier8decdee2012-06-26 22:30:43 +0000440 // If we have a generic string, we will allow it because there is no
441 // documented list of allowable string declspecs, but we know they exist
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000442 // (for instance, SAL declspecs in older versions of MSVC).
443 //
Chad Rosier8decdee2012-06-26 22:30:43 +0000444 // Alternatively, if the identifier is a simple one, then it requires no
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000445 // arguments and can be turned into an attribute directly.
Chad Rosier8decdee2012-06-26 22:30:43 +0000446 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000447 0, 0, AttributeList::AS_Declspec);
448 else
449 ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000450 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000451 T.consumeClose();
Eli Friedman290eeb02009-06-08 23:27:34 +0000452}
453
John McCall7f040a92010-12-24 02:08:15 +0000454void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
Eli Friedman290eeb02009-06-08 23:27:34 +0000455 // Treat these like attributes
Eli Friedman290eeb02009-06-08 23:27:34 +0000456 while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
Douglas Gregorf813a2c2010-05-18 16:57:00 +0000457 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +0000458 Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
Francois Pichet58fd97a2011-08-25 00:36:46 +0000459 Tok.is(tok::kw___ptr32) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +0000460 Tok.is(tok::kw___unaligned)) {
Eli Friedman290eeb02009-06-08 23:27:34 +0000461 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
462 SourceLocation AttrNameLoc = ConsumeToken();
John McCall0b7e6782011-03-24 11:26:52 +0000463 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000464 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
Eli Friedman290eeb02009-06-08 23:27:34 +0000465 }
Steve Narofff59e17e2008-12-24 20:59:21 +0000466}
467
John McCall7f040a92010-12-24 02:08:15 +0000468void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
Dawn Perchik52fc3142010-09-03 01:29:35 +0000469 // Treat these like attributes
470 while (Tok.is(tok::kw___pascal)) {
471 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
472 SourceLocation AttrNameLoc = ConsumeToken();
John McCall0b7e6782011-03-24 11:26:52 +0000473 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000474 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
Dawn Perchik52fc3142010-09-03 01:29:35 +0000475 }
John McCall7f040a92010-12-24 02:08:15 +0000476}
477
Peter Collingbournef315fa82011-02-14 01:42:53 +0000478void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
479 // Treat these like attributes
480 while (Tok.is(tok::kw___kernel)) {
481 SourceLocation AttrNameLoc = ConsumeToken();
John McCall0b7e6782011-03-24 11:26:52 +0000482 attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
483 AttrNameLoc, 0, AttrNameLoc, 0,
Sean Hunt93f95f22012-06-18 16:13:52 +0000484 SourceLocation(), 0, 0, AttributeList::AS_GNU);
Peter Collingbournef315fa82011-02-14 01:42:53 +0000485 }
486}
487
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000488void Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
489 SourceLocation Loc = Tok.getLocation();
490 switch(Tok.getKind()) {
491 // OpenCL qualifiers:
492 case tok::kw___private:
Chad Rosier8decdee2012-06-26 22:30:43 +0000493 case tok::kw_private:
John McCall0b7e6782011-03-24 11:26:52 +0000494 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000495 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000496 PP.getIdentifierInfo("address_space"), Loc, 0);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000497 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000498
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000499 case tok::kw___global:
John McCall0b7e6782011-03-24 11:26:52 +0000500 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000501 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000502 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000503 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000504
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000505 case tok::kw___local:
John McCall0b7e6782011-03-24 11:26:52 +0000506 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000507 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000508 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000509 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000510
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000511 case tok::kw___constant:
John McCall0b7e6782011-03-24 11:26:52 +0000512 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000513 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000514 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000515 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000516
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000517 case tok::kw___read_only:
John McCall0b7e6782011-03-24 11:26:52 +0000518 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000519 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000520 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000521 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000522
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000523 case tok::kw___write_only:
John McCall0b7e6782011-03-24 11:26:52 +0000524 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000525 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000526 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000527 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000528
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000529 case tok::kw___read_write:
John McCall0b7e6782011-03-24 11:26:52 +0000530 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000531 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000532 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000533 break;
534 default: break;
535 }
536}
537
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000538/// \brief Parse a version number.
539///
540/// version:
541/// simple-integer
542/// simple-integer ',' simple-integer
543/// simple-integer ',' simple-integer ',' simple-integer
544VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
545 Range = Tok.getLocation();
546
547 if (!Tok.is(tok::numeric_constant)) {
548 Diag(Tok, diag::err_expected_version);
549 SkipUntil(tok::comma, tok::r_paren, true, true, true);
550 return VersionTuple();
551 }
552
553 // Parse the major (and possibly minor and subminor) versions, which
554 // are stored in the numeric constant. We utilize a quirk of the
555 // lexer, which is that it handles something like 1.2.3 as a single
556 // numeric constant, rather than two separate tokens.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000557 SmallString<512> Buffer;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000558 Buffer.resize(Tok.getLength()+1);
559 const char *ThisTokBegin = &Buffer[0];
560
561 // Get the spelling of the token, which eliminates trigraphs, etc.
562 bool Invalid = false;
563 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
564 if (Invalid)
565 return VersionTuple();
566
567 // Parse the major version.
568 unsigned AfterMajor = 0;
569 unsigned Major = 0;
570 while (AfterMajor < ActualLength && isdigit(ThisTokBegin[AfterMajor])) {
571 Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';
572 ++AfterMajor;
573 }
574
575 if (AfterMajor == 0) {
576 Diag(Tok, diag::err_expected_version);
577 SkipUntil(tok::comma, tok::r_paren, true, true, true);
578 return VersionTuple();
579 }
580
581 if (AfterMajor == ActualLength) {
582 ConsumeToken();
583
584 // We only had a single version component.
585 if (Major == 0) {
586 Diag(Tok, diag::err_zero_version);
587 return VersionTuple();
588 }
589
590 return VersionTuple(Major);
591 }
592
593 if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) {
594 Diag(Tok, diag::err_expected_version);
595 SkipUntil(tok::comma, tok::r_paren, true, true, true);
596 return VersionTuple();
597 }
598
599 // Parse the minor version.
600 unsigned AfterMinor = AfterMajor + 1;
601 unsigned Minor = 0;
602 while (AfterMinor < ActualLength && isdigit(ThisTokBegin[AfterMinor])) {
603 Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';
604 ++AfterMinor;
605 }
606
607 if (AfterMinor == ActualLength) {
608 ConsumeToken();
Chad Rosier8decdee2012-06-26 22:30:43 +0000609
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000610 // We had major.minor.
611 if (Major == 0 && Minor == 0) {
612 Diag(Tok, diag::err_zero_version);
613 return VersionTuple();
614 }
615
Chad Rosier8decdee2012-06-26 22:30:43 +0000616 return VersionTuple(Major, Minor);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000617 }
618
619 // If what follows is not a '.', we have a problem.
620 if (ThisTokBegin[AfterMinor] != '.') {
621 Diag(Tok, diag::err_expected_version);
622 SkipUntil(tok::comma, tok::r_paren, true, true, true);
Chad Rosier8decdee2012-06-26 22:30:43 +0000623 return VersionTuple();
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000624 }
625
626 // Parse the subminor version.
627 unsigned AfterSubminor = AfterMinor + 1;
628 unsigned Subminor = 0;
629 while (AfterSubminor < ActualLength && isdigit(ThisTokBegin[AfterSubminor])) {
630 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';
631 ++AfterSubminor;
632 }
633
634 if (AfterSubminor != ActualLength) {
635 Diag(Tok, diag::err_expected_version);
636 SkipUntil(tok::comma, tok::r_paren, true, true, true);
637 return VersionTuple();
638 }
639 ConsumeToken();
640 return VersionTuple(Major, Minor, Subminor);
641}
642
643/// \brief Parse the contents of the "availability" attribute.
644///
645/// availability-attribute:
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000646/// 'availability' '(' platform ',' version-arg-list, opt-message')'
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000647///
648/// platform:
649/// identifier
650///
651/// version-arg-list:
652/// version-arg
653/// version-arg ',' version-arg-list
654///
655/// version-arg:
656/// 'introduced' '=' version
657/// 'deprecated' '=' version
Douglas Gregor93a70672012-03-11 04:53:21 +0000658/// 'obsoleted' = version
Douglas Gregorb53e4172011-03-26 03:35:55 +0000659/// 'unavailable'
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000660/// opt-message:
661/// 'message' '=' <string>
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000662void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
663 SourceLocation AvailabilityLoc,
664 ParsedAttributes &attrs,
665 SourceLocation *endLoc) {
666 SourceLocation PlatformLoc;
667 IdentifierInfo *Platform = 0;
668
669 enum { Introduced, Deprecated, Obsoleted, Unknown };
670 AvailabilityChange Changes[Unknown];
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000671 ExprResult MessageExpr;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000672
673 // Opening '('.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000674 BalancedDelimiterTracker T(*this, tok::l_paren);
675 if (T.consumeOpen()) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000676 Diag(Tok, diag::err_expected_lparen);
677 return;
678 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000679
680 // Parse the platform name,
681 if (Tok.isNot(tok::identifier)) {
682 Diag(Tok, diag::err_availability_expected_platform);
683 SkipUntil(tok::r_paren);
684 return;
685 }
686 Platform = Tok.getIdentifierInfo();
687 PlatformLoc = ConsumeToken();
688
689 // Parse the ',' following the platform name.
690 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
691 return;
692
693 // If we haven't grabbed the pointers for the identifiers
694 // "introduced", "deprecated", and "obsoleted", do so now.
695 if (!Ident_introduced) {
696 Ident_introduced = PP.getIdentifierInfo("introduced");
697 Ident_deprecated = PP.getIdentifierInfo("deprecated");
698 Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
Douglas Gregorb53e4172011-03-26 03:35:55 +0000699 Ident_unavailable = PP.getIdentifierInfo("unavailable");
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000700 Ident_message = PP.getIdentifierInfo("message");
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000701 }
702
703 // Parse the set of introductions/deprecations/removals.
Douglas Gregorb53e4172011-03-26 03:35:55 +0000704 SourceLocation UnavailableLoc;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000705 do {
706 if (Tok.isNot(tok::identifier)) {
707 Diag(Tok, diag::err_availability_expected_change);
708 SkipUntil(tok::r_paren);
709 return;
710 }
711 IdentifierInfo *Keyword = Tok.getIdentifierInfo();
712 SourceLocation KeywordLoc = ConsumeToken();
713
Douglas Gregorb53e4172011-03-26 03:35:55 +0000714 if (Keyword == Ident_unavailable) {
715 if (UnavailableLoc.isValid()) {
716 Diag(KeywordLoc, diag::err_availability_redundant)
717 << Keyword << SourceRange(UnavailableLoc);
Chad Rosier8decdee2012-06-26 22:30:43 +0000718 }
Douglas Gregorb53e4172011-03-26 03:35:55 +0000719 UnavailableLoc = KeywordLoc;
720
721 if (Tok.isNot(tok::comma))
722 break;
723
724 ConsumeToken();
725 continue;
Chad Rosier8decdee2012-06-26 22:30:43 +0000726 }
727
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000728 if (Tok.isNot(tok::equal)) {
729 Diag(Tok, diag::err_expected_equal_after)
730 << Keyword;
731 SkipUntil(tok::r_paren);
732 return;
733 }
734 ConsumeToken();
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000735 if (Keyword == Ident_message) {
736 if (!isTokenStringLiteral()) {
737 Diag(Tok, diag::err_expected_string_literal);
738 SkipUntil(tok::r_paren);
739 return;
740 }
741 MessageExpr = ParseStringLiteralExpression();
742 break;
743 }
Chad Rosier8decdee2012-06-26 22:30:43 +0000744
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000745 SourceRange VersionRange;
746 VersionTuple Version = ParseVersionTuple(VersionRange);
Chad Rosier8decdee2012-06-26 22:30:43 +0000747
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000748 if (Version.empty()) {
749 SkipUntil(tok::r_paren);
750 return;
751 }
752
753 unsigned Index;
754 if (Keyword == Ident_introduced)
755 Index = Introduced;
756 else if (Keyword == Ident_deprecated)
757 Index = Deprecated;
758 else if (Keyword == Ident_obsoleted)
759 Index = Obsoleted;
Chad Rosier8decdee2012-06-26 22:30:43 +0000760 else
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000761 Index = Unknown;
762
763 if (Index < Unknown) {
764 if (!Changes[Index].KeywordLoc.isInvalid()) {
765 Diag(KeywordLoc, diag::err_availability_redundant)
Chad Rosier8decdee2012-06-26 22:30:43 +0000766 << Keyword
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000767 << SourceRange(Changes[Index].KeywordLoc,
768 Changes[Index].VersionRange.getEnd());
769 }
770
771 Changes[Index].KeywordLoc = KeywordLoc;
772 Changes[Index].Version = Version;
773 Changes[Index].VersionRange = VersionRange;
774 } else {
775 Diag(KeywordLoc, diag::err_availability_unknown_change)
776 << Keyword << VersionRange;
777 }
778
779 if (Tok.isNot(tok::comma))
780 break;
781
782 ConsumeToken();
783 } while (true);
784
785 // Closing ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000786 if (T.consumeClose())
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000787 return;
788
789 if (endLoc)
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000790 *endLoc = T.getCloseLocation();
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000791
Douglas Gregorb53e4172011-03-26 03:35:55 +0000792 // The 'unavailable' availability cannot be combined with any other
793 // availability changes. Make sure that hasn't happened.
794 if (UnavailableLoc.isValid()) {
795 bool Complained = false;
796 for (unsigned Index = Introduced; Index != Unknown; ++Index) {
797 if (Changes[Index].KeywordLoc.isValid()) {
798 if (!Complained) {
799 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
800 << SourceRange(Changes[Index].KeywordLoc,
801 Changes[Index].VersionRange.getEnd());
802 Complained = true;
803 }
804
805 // Clear out the availability.
806 Changes[Index] = AvailabilityChange();
807 }
808 }
809 }
810
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000811 // Record this attribute
Chad Rosier8decdee2012-06-26 22:30:43 +0000812 attrs.addNew(&Availability,
813 SourceRange(AvailabilityLoc, T.getCloseLocation()),
Fariborz Jahanianf96708d2012-01-23 23:38:32 +0000814 0, AvailabilityLoc,
John McCall0b7e6782011-03-24 11:26:52 +0000815 Platform, PlatformLoc,
816 Changes[Introduced],
817 Changes[Deprecated],
Chad Rosier8decdee2012-06-26 22:30:43 +0000818 Changes[Obsoleted],
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000819 UnavailableLoc, MessageExpr.take(),
Sean Hunt93f95f22012-06-18 16:13:52 +0000820 AttributeList::AS_GNU);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000821}
822
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000823
824// Late Parsed Attributes:
825// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
826
827void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
828
829void Parser::LateParsedClass::ParseLexedAttributes() {
830 Self->ParseLexedAttributes(*Class);
831}
832
833void Parser::LateParsedAttribute::ParseLexedAttributes() {
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000834 Self->ParseLexedAttribute(*this, true, false);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000835}
836
837/// Wrapper class which calls ParseLexedAttribute, after setting up the
838/// scope appropriately.
839void Parser::ParseLexedAttributes(ParsingClass &Class) {
840 // Deal with templates
841 // FIXME: Test cases to make sure this does the right thing for templates.
842 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
843 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
844 HasTemplateScope);
845 if (HasTemplateScope)
846 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
847
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000848 // Set or update the scope flags.
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000849 bool AlreadyHasClassScope = Class.TopLevelClass;
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000850 unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000851 ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
852 ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
853
DeLesley Hutchinscf2fa2f2012-04-06 15:10:17 +0000854 // Enter the scope of nested classes
855 if (!AlreadyHasClassScope)
856 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
857 Class.TagOrTemplate);
Benjamin Kramer268efba2012-05-17 12:01:52 +0000858 if (!Class.LateParsedDeclarations.empty()) {
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000859 for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
860 Class.LateParsedDeclarations[i]->ParseLexedAttributes();
861 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000862 }
Chad Rosier8decdee2012-06-26 22:30:43 +0000863
DeLesley Hutchinscf2fa2f2012-04-06 15:10:17 +0000864 if (!AlreadyHasClassScope)
865 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
866 Class.TagOrTemplate);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000867}
868
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000869
870/// \brief Parse all attributes in LAs, and attach them to Decl D.
871void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
872 bool EnterScope, bool OnDefinition) {
873 for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
DeLesley Hutchins95526a42012-08-15 22:41:04 +0000874 if (D)
875 LAs[i]->addDecl(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000876 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
Benjamin Kramerd306cf72012-04-14 12:44:47 +0000877 delete LAs[i];
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000878 }
879 LAs.clear();
880}
881
882
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000883/// \brief Finish parsing an attribute for which parsing was delayed.
884/// This will be called at the end of parsing a class declaration
885/// for each LateParsedAttribute. We consume the saved tokens and
Chad Rosier8decdee2012-06-26 22:30:43 +0000886/// create an attribute with the arguments filled in. We add this
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000887/// to the Attribute list for the decl.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000888void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
889 bool EnterScope, bool OnDefinition) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000890 // Save the current token position.
891 SourceLocation OrigLoc = Tok.getLocation();
892
893 // Append the current token at the end of the new token stream so that it
894 // doesn't get lost.
895 LA.Toks.push_back(Tok);
896 PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
897 // Consume the previously pushed token.
898 ConsumeAnyToken();
899
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000900 if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
901 Diag(Tok, diag::warn_attribute_on_function_definition)
902 << LA.AttrName.getName();
903 }
904
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000905 ParsedAttributes Attrs(AttrFactory);
906 SourceLocation endLoc;
907
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +0000908 if (LA.Decls.size() > 0) {
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000909 Decl *D = LA.Decls[0];
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +0000910 NamedDecl *ND = dyn_cast<NamedDecl>(D);
911 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000912
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +0000913 // Allow 'this' within late-parsed attributes.
914 Sema::CXXThisScopeRAII ThisScope(Actions, RD,
915 /*TypeQuals=*/0,
916 ND && RD && ND->isCXXInstanceMember());
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000917
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +0000918 if (LA.Decls.size() == 1) {
919 // If the Decl is templatized, add template parameters to scope.
920 bool HasTemplateScope = EnterScope && D->isTemplateDecl();
921 ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
922 if (HasTemplateScope)
923 Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000924
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +0000925 // If the Decl is on a function, add function parameters to the scope.
926 bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
927 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope);
928 if (HasFunScope)
929 Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000930
Michael Han6880f492012-10-03 01:56:22 +0000931 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
932 0, LA.AttrNameLoc, AttributeList::AS_GNU);
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +0000933
934 if (HasFunScope) {
935 Actions.ActOnExitFunctionContext();
936 FnScope.Exit(); // Pop scope, and remove Decls from IdResolver
937 }
938 if (HasTemplateScope) {
939 TempScope.Exit();
940 }
941 } else {
942 // If there are multiple decls, then the decl cannot be within the
943 // function scope.
Michael Han6880f492012-10-03 01:56:22 +0000944 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
945 0, LA.AttrNameLoc, AttributeList::AS_GNU);
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000946 }
DeLesley Hutchins7ec419a2012-03-02 22:29:50 +0000947 } else {
948 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +0000949 }
950
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +0000951 for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
952 Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
953 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000954
955 if (Tok.getLocation() != OrigLoc) {
956 // Due to a parsing error, we either went over the cached tokens or
957 // there are still cached tokens left, so we skip the leftover tokens.
958 // Since this is an uncommon situation that should be avoided, use the
959 // expensive isBeforeInTranslationUnit call.
960 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
961 OrigLoc))
962 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
Douglas Gregord78ef5b2012-03-08 01:00:17 +0000963 ConsumeAnyToken();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000964 }
965}
966
Caitlin Sadowskib51e0312011-08-09 17:59:31 +0000967/// \brief Wrapper around a case statement checking if AttrName is
968/// one of the thread safety attributes
969bool Parser::IsThreadSafetyAttribute(llvm::StringRef AttrName){
970 return llvm::StringSwitch<bool>(AttrName)
971 .Case("guarded_by", true)
972 .Case("guarded_var", true)
973 .Case("pt_guarded_by", true)
974 .Case("pt_guarded_var", true)
975 .Case("lockable", true)
976 .Case("scoped_lockable", true)
977 .Case("no_thread_safety_analysis", true)
978 .Case("acquired_after", true)
979 .Case("acquired_before", true)
980 .Case("exclusive_lock_function", true)
981 .Case("shared_lock_function", true)
982 .Case("exclusive_trylock_function", true)
983 .Case("shared_trylock_function", true)
984 .Case("unlock_function", true)
985 .Case("lock_returned", true)
986 .Case("locks_excluded", true)
987 .Case("exclusive_locks_required", true)
988 .Case("shared_locks_required", true)
989 .Default(false);
990}
991
992/// \brief Parse the contents of thread safety attributes. These
993/// should always be parsed as an expression list.
994///
995/// We need to special case the parsing due to the fact that if the first token
996/// of the first argument is an identifier, the main parse loop will store
997/// that token as a "parameter" and the rest of
998/// the arguments will be added to a list of "arguments". However,
999/// subsequent tokens in the first argument are lost. We instead parse each
1000/// argument as an expression and add all arguments to the list of "arguments".
1001/// In future, we will take advantage of this special case to also
1002/// deal with some argument scoping issues here (for example, referring to a
1003/// function parameter in the attribute on that function).
1004void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
1005 SourceLocation AttrNameLoc,
1006 ParsedAttributes &Attrs,
1007 SourceLocation *EndLoc) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001008 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001009
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001010 BalancedDelimiterTracker T(*this, tok::l_paren);
1011 T.consumeOpen();
Chad Rosier8decdee2012-06-26 22:30:43 +00001012
Benjamin Kramer4e28d9e2012-08-23 22:51:59 +00001013 ExprVector ArgExprs;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001014 bool ArgExprsOk = true;
Chad Rosier8decdee2012-06-26 22:30:43 +00001015
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001016 // now parse the list of expressions
DeLesley Hutchins4805f152011-12-14 19:36:06 +00001017 while (Tok.isNot(tok::r_paren)) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001018 ExprResult ArgExpr(ParseAssignmentExpression());
1019 if (ArgExpr.isInvalid()) {
1020 ArgExprsOk = false;
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001021 T.consumeClose();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001022 break;
1023 } else {
1024 ArgExprs.push_back(ArgExpr.release());
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001025 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001026 if (Tok.isNot(tok::comma))
1027 break;
1028 ConsumeToken(); // Eat the comma, move to the next argument
1029 }
1030 // Match the ')'.
DeLesley Hutchins23323e02012-01-20 22:50:54 +00001031 if (ArgExprsOk && !T.consumeClose()) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001032 Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
Benjamin Kramer4e28d9e2012-08-23 22:51:59 +00001033 ArgExprs.data(), ArgExprs.size(), AttributeList::AS_GNU);
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001034 }
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001035 if (EndLoc)
1036 *EndLoc = T.getCloseLocation();
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001037}
1038
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00001039void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
1040 SourceLocation AttrNameLoc,
1041 ParsedAttributes &Attrs,
1042 SourceLocation *EndLoc) {
1043 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1044
1045 BalancedDelimiterTracker T(*this, tok::l_paren);
1046 T.consumeOpen();
1047
1048 if (Tok.isNot(tok::identifier)) {
1049 Diag(Tok, diag::err_expected_ident);
1050 T.skipToEnd();
1051 return;
1052 }
1053 IdentifierInfo *ArgumentKind = Tok.getIdentifierInfo();
1054 SourceLocation ArgumentKindLoc = ConsumeToken();
1055
1056 if (Tok.isNot(tok::comma)) {
1057 Diag(Tok, diag::err_expected_comma);
1058 T.skipToEnd();
1059 return;
1060 }
1061 ConsumeToken();
1062
1063 SourceRange MatchingCTypeRange;
1064 TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);
1065 if (MatchingCType.isInvalid()) {
1066 T.skipToEnd();
1067 return;
1068 }
1069
1070 bool LayoutCompatible = false;
1071 bool MustBeNull = false;
1072 while (Tok.is(tok::comma)) {
1073 ConsumeToken();
1074 if (Tok.isNot(tok::identifier)) {
1075 Diag(Tok, diag::err_expected_ident);
1076 T.skipToEnd();
1077 return;
1078 }
1079 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1080 if (Flag->isStr("layout_compatible"))
1081 LayoutCompatible = true;
1082 else if (Flag->isStr("must_be_null"))
1083 MustBeNull = true;
1084 else {
1085 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1086 T.skipToEnd();
1087 return;
1088 }
1089 ConsumeToken(); // consume flag
1090 }
1091
1092 if (!T.consumeClose()) {
1093 Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
1094 ArgumentKind, ArgumentKindLoc,
1095 MatchingCType.release(), LayoutCompatible,
1096 MustBeNull, AttributeList::AS_GNU);
1097 }
1098
1099 if (EndLoc)
1100 *EndLoc = T.getCloseLocation();
1101}
1102
Richard Smith6ee326a2012-04-10 01:32:12 +00001103/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
1104/// of a C++11 attribute-specifier in a location where an attribute is not
1105/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
1106/// situation.
1107///
1108/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
1109/// this doesn't appear to actually be an attribute-specifier, and the caller
1110/// should try to parse it.
1111bool Parser::DiagnoseProhibitedCXX11Attribute() {
1112 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1113
1114 switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1115 case CAK_NotAttributeSpecifier:
1116 // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1117 return false;
1118
1119 case CAK_InvalidAttributeSpecifier:
1120 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1121 return false;
1122
1123 case CAK_AttributeSpecifier:
1124 // Parse and discard the attributes.
1125 SourceLocation BeginLoc = ConsumeBracket();
1126 ConsumeBracket();
1127 SkipUntil(tok::r_square, /*StopAtSemi*/ false);
1128 assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1129 SourceLocation EndLoc = ConsumeBracket();
1130 Diag(BeginLoc, diag::err_attributes_not_allowed)
1131 << SourceRange(BeginLoc, EndLoc);
1132 return true;
1133 }
Chandler Carruth2c6dbd72012-04-10 16:03:08 +00001134 llvm_unreachable("All cases handled above.");
Richard Smith6ee326a2012-04-10 01:32:12 +00001135}
1136
John McCall7f040a92010-12-24 02:08:15 +00001137void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1138 Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1139 << attrs.Range;
Dawn Perchik52fc3142010-09-03 01:29:35 +00001140}
1141
Reid Spencer5f016e22007-07-11 17:01:13 +00001142/// ParseDeclaration - Parse a full 'declaration', which consists of
1143/// declaration-specifiers, some number of declarators, and a semicolon.
Chris Lattner97144fc2009-04-02 04:16:50 +00001144/// 'Context' should be a Declarator::TheContext value. This returns the
1145/// location of the semicolon in DeclEnd.
Chris Lattner8f08cb72007-08-25 06:57:03 +00001146///
1147/// declaration: [C99 6.7]
1148/// block-declaration ->
1149/// simple-declaration
1150/// others [FIXME]
Douglas Gregoradcac882008-12-01 23:54:00 +00001151/// [C++] template-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001152/// [C++] namespace-definition
Douglas Gregorf780abc2008-12-30 03:27:21 +00001153/// [C++] using-directive
Douglas Gregord7f37bf2009-06-22 23:06:13 +00001154/// [C++] using-declaration
Richard Smith534986f2012-04-14 00:33:13 +00001155/// [C++11/C11] static_assert-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001156/// others... [FIXME]
1157///
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001158Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1159 unsigned Context,
Sean Huntbbd37c62009-11-21 08:43:09 +00001160 SourceLocation &DeclEnd,
John McCall7f040a92010-12-24 02:08:15 +00001161 ParsedAttributesWithRange &attrs) {
Argyrios Kyrtzidis36d36802010-06-17 10:52:18 +00001162 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Fariborz Jahaniane8cff362011-08-30 17:10:52 +00001163 // Must temporarily exit the objective-c container scope for
1164 // parsing c none objective-c decls.
1165 ObjCDeclContextSwitch ObjCDC(*this);
Chad Rosier8decdee2012-06-26 22:30:43 +00001166
John McCalld226f652010-08-21 09:40:31 +00001167 Decl *SingleDecl = 0;
Richard Smithc89edf52011-07-01 19:46:12 +00001168 Decl *OwnedType = 0;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001169 switch (Tok.getKind()) {
Douglas Gregoradcac882008-12-01 23:54:00 +00001170 case tok::kw_template:
Douglas Gregor1426e532009-05-12 21:31:51 +00001171 case tok::kw_export:
John McCall7f040a92010-12-24 02:08:15 +00001172 ProhibitAttributes(attrs);
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00001173 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001174 break;
Sebastian Redld078e642010-08-27 23:12:46 +00001175 case tok::kw_inline:
Sebastian Redl88e64ca2010-08-31 00:36:45 +00001176 // Could be the start of an inline namespace. Allowed as an ext in C++03.
David Blaikie4e4d0842012-03-11 07:00:24 +00001177 if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
John McCall7f040a92010-12-24 02:08:15 +00001178 ProhibitAttributes(attrs);
Sebastian Redld078e642010-08-27 23:12:46 +00001179 SourceLocation InlineLoc = ConsumeToken();
1180 SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1181 break;
1182 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001183 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001184 true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001185 case tok::kw_namespace:
John McCall7f040a92010-12-24 02:08:15 +00001186 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001187 SingleDecl = ParseNamespace(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001188 break;
Douglas Gregorf780abc2008-12-30 03:27:21 +00001189 case tok::kw_using:
John McCall78b81052010-11-10 02:40:36 +00001190 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
Richard Smithc89edf52011-07-01 19:46:12 +00001191 DeclEnd, attrs, &OwnedType);
Chris Lattner682bf922009-03-29 16:50:03 +00001192 break;
Anders Carlsson511d7ab2009-03-11 16:27:10 +00001193 case tok::kw_static_assert:
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00001194 case tok::kw__Static_assert:
John McCall7f040a92010-12-24 02:08:15 +00001195 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001196 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001197 break;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001198 default:
John McCall7f040a92010-12-24 02:08:15 +00001199 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001200 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001201
Chris Lattner682bf922009-03-29 16:50:03 +00001202 // This routine returns a DeclGroup, if the thing we parsed only contains a
Richard Smithc89edf52011-07-01 19:46:12 +00001203 // single decl, convert it now. Alias declarations can also declare a type;
1204 // include that too if it is present.
1205 return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001206}
1207
1208/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
1209/// declaration-specifiers init-declarator-list[opt] ';'
Sean Hunt2edf0a22012-06-23 05:07:58 +00001210/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1211/// init-declarator-list ';'
Chris Lattner8f08cb72007-08-25 06:57:03 +00001212///[C90/C++]init-declarator-list ';' [TODO]
1213/// [OMP] threadprivate-directive [TODO]
Chris Lattnercd147752009-03-29 17:27:48 +00001214///
Sean Hunt2edf0a22012-06-23 05:07:58 +00001215/// for-range-declaration: [C++11 6.5p1: stmt.ranged]
Richard Smithad762fc2011-04-14 22:09:26 +00001216/// attribute-specifier-seq[opt] type-specifier-seq declarator
1217///
Chris Lattnercd147752009-03-29 17:27:48 +00001218/// If RequireSemi is false, this does not check for a ';' at the end of the
Chris Lattner5c5db552010-04-05 18:18:31 +00001219/// declaration. If it is true, it checks for and eats it.
Richard Smithad762fc2011-04-14 22:09:26 +00001220///
1221/// If FRI is non-null, we might be parsing a for-range-declaration instead
1222/// of a simple-declaration. If we find that we are, we also parse the
1223/// for-range-initializer, and place it here.
Sean Hunt2edf0a22012-06-23 05:07:58 +00001224Parser::DeclGroupPtrTy
1225Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1226 SourceLocation &DeclEnd,
1227 ParsedAttributesWithRange &attrs,
1228 bool RequireSemi, ForRangeInit *FRI) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001229 // Parse the common declaration-specifiers piece.
John McCall54abf7d2009-11-04 02:18:39 +00001230 ParsingDeclSpec DS(*this);
John McCall7f040a92010-12-24 02:08:15 +00001231 DS.takeAttributesFrom(attrs);
Douglas Gregor312eadb2011-04-24 05:37:28 +00001232
Douglas Gregor0efc2c12010-01-13 17:31:36 +00001233 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
Richard Smith34b41d92011-02-20 03:19:35 +00001234 getDeclSpecContextFromDeclaratorContext(Context));
Abramo Bagnara06284c12012-01-07 10:52:36 +00001235
Reid Spencer5f016e22007-07-11 17:01:13 +00001236 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1237 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner04d66662007-10-09 17:33:22 +00001238 if (Tok.is(tok::semi)) {
Argyrios Kyrtzidis5641b0d2012-05-16 23:49:15 +00001239 DeclEnd = Tok.getLocation();
Chris Lattner5c5db552010-04-05 18:18:31 +00001240 if (RequireSemi) ConsumeToken();
John McCalld226f652010-08-21 09:40:31 +00001241 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
Douglas Gregor312eadb2011-04-24 05:37:28 +00001242 DS);
John McCall54abf7d2009-11-04 02:18:39 +00001243 DS.complete(TheDecl);
Chris Lattner682bf922009-03-29 16:50:03 +00001244 return Actions.ConvertDeclToDeclGroup(TheDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +00001245 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001246
1247 return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
John McCalld8ac0572009-11-03 19:26:08 +00001248}
Mike Stump1eb44332009-09-09 15:08:12 +00001249
Richard Smith0706df42011-10-19 21:33:05 +00001250/// Returns true if this might be the start of a declarator, or a common typo
1251/// for a declarator.
1252bool Parser::MightBeDeclarator(unsigned Context) {
1253 switch (Tok.getKind()) {
1254 case tok::annot_cxxscope:
1255 case tok::annot_template_id:
1256 case tok::caret:
1257 case tok::code_completion:
1258 case tok::coloncolon:
1259 case tok::ellipsis:
1260 case tok::kw___attribute:
1261 case tok::kw_operator:
1262 case tok::l_paren:
1263 case tok::star:
1264 return true;
1265
1266 case tok::amp:
1267 case tok::ampamp:
David Blaikie4e4d0842012-03-11 07:00:24 +00001268 return getLangOpts().CPlusPlus;
Richard Smith0706df42011-10-19 21:33:05 +00001269
Richard Smith1c94c162012-01-09 22:31:44 +00001270 case tok::l_square: // Might be an attribute on an unnamed bit-field.
David Blaikie4e4d0842012-03-11 07:00:24 +00001271 return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x &&
Richard Smith1c94c162012-01-09 22:31:44 +00001272 NextToken().is(tok::l_square);
1273
1274 case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
David Blaikie4e4d0842012-03-11 07:00:24 +00001275 return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
Richard Smith1c94c162012-01-09 22:31:44 +00001276
Richard Smith0706df42011-10-19 21:33:05 +00001277 case tok::identifier:
1278 switch (NextToken().getKind()) {
1279 case tok::code_completion:
1280 case tok::coloncolon:
1281 case tok::comma:
1282 case tok::equal:
1283 case tok::equalequal: // Might be a typo for '='.
1284 case tok::kw_alignas:
1285 case tok::kw_asm:
1286 case tok::kw___attribute:
1287 case tok::l_brace:
1288 case tok::l_paren:
1289 case tok::l_square:
1290 case tok::less:
1291 case tok::r_brace:
1292 case tok::r_paren:
1293 case tok::r_square:
1294 case tok::semi:
1295 return true;
1296
1297 case tok::colon:
1298 // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
Richard Smith1c94c162012-01-09 22:31:44 +00001299 // and in block scope it's probably a label. Inside a class definition,
1300 // this is a bit-field.
1301 return Context == Declarator::MemberContext ||
David Blaikie4e4d0842012-03-11 07:00:24 +00001302 (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
Richard Smith1c94c162012-01-09 22:31:44 +00001303
1304 case tok::identifier: // Possible virt-specifier.
David Blaikie4e4d0842012-03-11 07:00:24 +00001305 return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
Richard Smith0706df42011-10-19 21:33:05 +00001306
1307 default:
1308 return false;
1309 }
1310
1311 default:
1312 return false;
1313 }
1314}
1315
Richard Smith994d73f2012-04-11 20:59:20 +00001316/// Skip until we reach something which seems like a sensible place to pick
1317/// up parsing after a malformed declaration. This will sometimes stop sooner
1318/// than SkipUntil(tok::r_brace) would, but will never stop later.
1319void Parser::SkipMalformedDecl() {
1320 while (true) {
1321 switch (Tok.getKind()) {
1322 case tok::l_brace:
1323 // Skip until matching }, then stop. We've probably skipped over
1324 // a malformed class or function definition or similar.
1325 ConsumeBrace();
1326 SkipUntil(tok::r_brace, /*StopAtSemi*/false);
1327 if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
1328 // This declaration isn't over yet. Keep skipping.
1329 continue;
1330 }
1331 if (Tok.is(tok::semi))
1332 ConsumeToken();
1333 return;
1334
1335 case tok::l_square:
1336 ConsumeBracket();
1337 SkipUntil(tok::r_square, /*StopAtSemi*/false);
1338 continue;
1339
1340 case tok::l_paren:
1341 ConsumeParen();
1342 SkipUntil(tok::r_paren, /*StopAtSemi*/false);
1343 continue;
1344
1345 case tok::r_brace:
1346 return;
1347
1348 case tok::semi:
1349 ConsumeToken();
1350 return;
1351
1352 case tok::kw_inline:
1353 // 'inline namespace' at the start of a line is almost certainly
Jordan Rose94f29f42012-07-09 16:54:53 +00001354 // a good place to pick back up parsing, except in an Objective-C
1355 // @interface context.
1356 if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&
1357 (!ParsingInObjCContainer || CurParsedObjCImpl))
Richard Smith994d73f2012-04-11 20:59:20 +00001358 return;
1359 break;
1360
1361 case tok::kw_namespace:
1362 // 'namespace' at the start of a line is almost certainly a good
Jordan Rose94f29f42012-07-09 16:54:53 +00001363 // place to pick back up parsing, except in an Objective-C
1364 // @interface context.
1365 if (Tok.isAtStartOfLine() &&
1366 (!ParsingInObjCContainer || CurParsedObjCImpl))
1367 return;
1368 break;
1369
1370 case tok::at:
1371 // @end is very much like } in Objective-C contexts.
1372 if (NextToken().isObjCAtKeyword(tok::objc_end) &&
1373 ParsingInObjCContainer)
1374 return;
1375 break;
1376
1377 case tok::minus:
1378 case tok::plus:
1379 // - and + probably start new method declarations in Objective-C contexts.
1380 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
Richard Smith994d73f2012-04-11 20:59:20 +00001381 return;
1382 break;
1383
1384 case tok::eof:
1385 return;
1386
1387 default:
1388 break;
1389 }
1390
1391 ConsumeAnyToken();
1392 }
1393}
1394
John McCalld8ac0572009-11-03 19:26:08 +00001395/// ParseDeclGroup - Having concluded that this is either a function
1396/// definition or a group of object declarations, actually parse the
1397/// result.
John McCall54abf7d2009-11-04 02:18:39 +00001398Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1399 unsigned Context,
John McCalld8ac0572009-11-03 19:26:08 +00001400 bool AllowFunctionDefinitions,
Richard Smithad762fc2011-04-14 22:09:26 +00001401 SourceLocation *DeclEnd,
1402 ForRangeInit *FRI) {
John McCalld8ac0572009-11-03 19:26:08 +00001403 // Parse the first declarator.
John McCall54abf7d2009-11-04 02:18:39 +00001404 ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
John McCalld8ac0572009-11-03 19:26:08 +00001405 ParseDeclarator(D);
Chris Lattnercd147752009-03-29 17:27:48 +00001406
John McCalld8ac0572009-11-03 19:26:08 +00001407 // Bail out if the first declarator didn't seem well-formed.
1408 if (!D.hasName() && !D.mayOmitIdentifier()) {
Richard Smith994d73f2012-04-11 20:59:20 +00001409 SkipMalformedDecl();
John McCalld8ac0572009-11-03 19:26:08 +00001410 return DeclGroupPtrTy();
Chris Lattner23c4b182009-03-29 17:18:04 +00001411 }
Mike Stump1eb44332009-09-09 15:08:12 +00001412
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001413 // Save late-parsed attributes for now; they need to be parsed in the
1414 // appropriate function scope after the function Decl has been constructed.
1415 LateParsedAttrList LateParsedAttrs;
1416 if (D.isFunctionDeclarator())
1417 MaybeParseGNUAttributes(D, &LateParsedAttrs);
1418
Chris Lattnerc82daef2010-07-11 22:24:20 +00001419 // Check to see if we have a function *definition* which must have a body.
1420 if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
1421 // Look at the next token to make sure that this isn't a function
1422 // declaration. We have to check this because __attribute__ might be the
1423 // start of a function definition in GCC-extended K&R C.
Fariborz Jahanianbe1d4ec2012-08-10 15:54:40 +00001424 !isDeclarationAfterDeclarator()) {
Chad Rosier8decdee2012-06-26 22:30:43 +00001425
Chris Lattner004659a2010-07-11 22:42:07 +00001426 if (isStartOfFunctionDefinition(D)) {
John McCalld8ac0572009-11-03 19:26:08 +00001427 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
1428 Diag(Tok, diag::err_function_declared_typedef);
1429
1430 // Recover by treating the 'typedef' as spurious.
1431 DS.ClearStorageClassSpecs();
1432 }
1433
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001434 Decl *TheDecl =
1435 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
John McCalld8ac0572009-11-03 19:26:08 +00001436 return Actions.ConvertDeclToDeclGroup(TheDecl);
Chris Lattner004659a2010-07-11 22:42:07 +00001437 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001438
Chris Lattner004659a2010-07-11 22:42:07 +00001439 if (isDeclarationSpecifier()) {
1440 // If there is an invalid declaration specifier right after the function
1441 // prototype, then we must be in a missing semicolon case where this isn't
1442 // actually a body. Just fall through into the code that handles it as a
1443 // prototype, and let the top-level code handle the erroneous declspec
1444 // where it would otherwise expect a comma or semicolon.
John McCalld8ac0572009-11-03 19:26:08 +00001445 } else {
1446 Diag(Tok, diag::err_expected_fn_body);
1447 SkipUntil(tok::semi);
1448 return DeclGroupPtrTy();
1449 }
1450 }
1451
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001452 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-04-14 22:09:26 +00001453 return DeclGroupPtrTy();
1454
1455 // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
1456 // must parse and analyze the for-range-initializer before the declaration is
1457 // analyzed.
1458 if (FRI && Tok.is(tok::colon)) {
1459 FRI->ColonLoc = ConsumeToken();
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001460 if (Tok.is(tok::l_brace))
1461 FRI->RangeExpr = ParseBraceInitializer();
1462 else
1463 FRI->RangeExpr = ParseExpression();
Richard Smithad762fc2011-04-14 22:09:26 +00001464 Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1465 Actions.ActOnCXXForRangeDecl(ThisDecl);
1466 Actions.FinalizeDeclaration(ThisDecl);
John McCall6895a642012-01-27 01:29:43 +00001467 D.complete(ThisDecl);
Richard Smithad762fc2011-04-14 22:09:26 +00001468 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1);
1469 }
1470
Chris Lattner5f9e2722011-07-23 10:55:15 +00001471 SmallVector<Decl *, 8> DeclsInGroup;
Richard Smithad762fc2011-04-14 22:09:26 +00001472 Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001473 if (LateParsedAttrs.size() > 0)
1474 ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
John McCall54abf7d2009-11-04 02:18:39 +00001475 D.complete(FirstDecl);
John McCalld226f652010-08-21 09:40:31 +00001476 if (FirstDecl)
John McCalld8ac0572009-11-03 19:26:08 +00001477 DeclsInGroup.push_back(FirstDecl);
1478
Richard Smith0706df42011-10-19 21:33:05 +00001479 bool ExpectSemi = Context != Declarator::ForContext;
Fariborz Jahanian6c89eaf2012-07-02 23:37:09 +00001480
John McCalld8ac0572009-11-03 19:26:08 +00001481 // If we don't have a comma, it is either the end of the list (a ';') or an
1482 // error, bail out.
1483 while (Tok.is(tok::comma)) {
Richard Smith0706df42011-10-19 21:33:05 +00001484 SourceLocation CommaLoc = ConsumeToken();
1485
1486 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1487 // This comma was followed by a line-break and something which can't be
1488 // the start of a declarator. The comma was probably a typo for a
1489 // semicolon.
1490 Diag(CommaLoc, diag::err_expected_semi_declaration)
1491 << FixItHint::CreateReplacement(CommaLoc, ";");
1492 ExpectSemi = false;
1493 break;
1494 }
John McCalld8ac0572009-11-03 19:26:08 +00001495
1496 // Parse the next declarator.
1497 D.clear();
Richard Smith7984de32012-01-12 23:53:29 +00001498 D.setCommaLoc(CommaLoc);
John McCalld8ac0572009-11-03 19:26:08 +00001499
1500 // Accept attributes in an init-declarator. In the first declarator in a
1501 // declaration, these would be part of the declspec. In subsequent
1502 // declarators, they become part of the declarator itself, so that they
1503 // don't apply to declarators after *this* one. Examples:
1504 // short __attribute__((common)) var; -> declspec
1505 // short var __attribute__((common)); -> declarator
1506 // short x, __attribute__((common)) var; -> declarator
John McCall7f040a92010-12-24 02:08:15 +00001507 MaybeParseGNUAttributes(D);
John McCalld8ac0572009-11-03 19:26:08 +00001508
1509 ParseDeclarator(D);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001510 if (!D.isInvalidType()) {
1511 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1512 D.complete(ThisDecl);
1513 if (ThisDecl)
Chad Rosier8decdee2012-06-26 22:30:43 +00001514 DeclsInGroup.push_back(ThisDecl);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001515 }
John McCalld8ac0572009-11-03 19:26:08 +00001516 }
1517
1518 if (DeclEnd)
1519 *DeclEnd = Tok.getLocation();
1520
Richard Smith0706df42011-10-19 21:33:05 +00001521 if (ExpectSemi &&
Chris Lattner8bb21d32012-04-28 16:12:17 +00001522 ExpectAndConsumeSemi(Context == Declarator::FileContext
1523 ? diag::err_invalid_token_after_toplevel_declarator
1524 : diag::err_expected_semi_declaration)) {
Chris Lattner004659a2010-07-11 22:42:07 +00001525 // Okay, there was no semicolon and one was expected. If we see a
1526 // declaration specifier, just assume it was missing and continue parsing.
1527 // Otherwise things are very confused and we skip to recover.
1528 if (!isDeclarationSpecifier()) {
1529 SkipUntil(tok::r_brace, true, true);
1530 if (Tok.is(tok::semi))
1531 ConsumeToken();
1532 }
John McCalld8ac0572009-11-03 19:26:08 +00001533 }
1534
Douglas Gregor23c94db2010-07-02 17:43:08 +00001535 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
John McCalld8ac0572009-11-03 19:26:08 +00001536 DeclsInGroup.data(),
1537 DeclsInGroup.size());
Reid Spencer5f016e22007-07-11 17:01:13 +00001538}
1539
Richard Smithad762fc2011-04-14 22:09:26 +00001540/// Parse an optional simple-asm-expr and attributes, and attach them to a
1541/// declarator. Returns true on an error.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001542bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
Richard Smithad762fc2011-04-14 22:09:26 +00001543 // If a simple-asm-expr is present, parse it.
1544 if (Tok.is(tok::kw_asm)) {
1545 SourceLocation Loc;
1546 ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1547 if (AsmLabel.isInvalid()) {
1548 SkipUntil(tok::semi, true, true);
1549 return true;
1550 }
1551
1552 D.setAsmLabel(AsmLabel.release());
1553 D.SetRangeEnd(Loc);
1554 }
1555
1556 MaybeParseGNUAttributes(D);
1557 return false;
1558}
1559
Douglas Gregor1426e532009-05-12 21:31:51 +00001560/// \brief Parse 'declaration' after parsing 'declaration-specifiers
1561/// declarator'. This method parses the remainder of the declaration
1562/// (including any attributes or initializer, among other things) and
1563/// finalizes the declaration.
Reid Spencer5f016e22007-07-11 17:01:13 +00001564///
Reid Spencer5f016e22007-07-11 17:01:13 +00001565/// init-declarator: [C99 6.7]
1566/// declarator
1567/// declarator '=' initializer
1568/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
1569/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00001570/// [C++] declarator initializer[opt]
1571///
1572/// [C++] initializer:
1573/// [C++] '=' initializer-clause
1574/// [C++] '(' expression-list ')'
Sebastian Redl50de12f2009-03-24 22:27:57 +00001575/// [C++0x] '=' 'default' [TODO]
1576/// [C++0x] '=' 'delete'
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001577/// [C++0x] braced-init-list
Sebastian Redl50de12f2009-03-24 22:27:57 +00001578///
1579/// According to the standard grammar, =default and =delete are function
1580/// definitions, but that definitely doesn't fit with the parser here.
Reid Spencer5f016e22007-07-11 17:01:13 +00001581///
John McCalld226f652010-08-21 09:40:31 +00001582Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
Douglas Gregore542c862009-06-23 23:11:28 +00001583 const ParsedTemplateInfo &TemplateInfo) {
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001584 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-04-14 22:09:26 +00001585 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001586
Richard Smithad762fc2011-04-14 22:09:26 +00001587 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1588}
Mike Stump1eb44332009-09-09 15:08:12 +00001589
Richard Smithad762fc2011-04-14 22:09:26 +00001590Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1591 const ParsedTemplateInfo &TemplateInfo) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001592 // Inform the current actions module that we just parsed this declarator.
John McCalld226f652010-08-21 09:40:31 +00001593 Decl *ThisDecl = 0;
Douglas Gregord5a423b2009-09-25 18:43:00 +00001594 switch (TemplateInfo.Kind) {
1595 case ParsedTemplateInfo::NonTemplate:
Douglas Gregor23c94db2010-07-02 17:43:08 +00001596 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
Douglas Gregord5a423b2009-09-25 18:43:00 +00001597 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00001598
Douglas Gregord5a423b2009-09-25 18:43:00 +00001599 case ParsedTemplateInfo::Template:
1600 case ParsedTemplateInfo::ExplicitSpecialization:
Douglas Gregor23c94db2010-07-02 17:43:08 +00001601 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
Benjamin Kramer5354e772012-08-23 23:38:35 +00001602 *TemplateInfo.TemplateParams,
Douglas Gregord5a423b2009-09-25 18:43:00 +00001603 D);
1604 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00001605
Douglas Gregord5a423b2009-09-25 18:43:00 +00001606 case ParsedTemplateInfo::ExplicitInstantiation: {
Chad Rosier8decdee2012-06-26 22:30:43 +00001607 DeclResult ThisRes
Douglas Gregor23c94db2010-07-02 17:43:08 +00001608 = Actions.ActOnExplicitInstantiation(getCurScope(),
Douglas Gregord5a423b2009-09-25 18:43:00 +00001609 TemplateInfo.ExternLoc,
1610 TemplateInfo.TemplateLoc,
1611 D);
1612 if (ThisRes.isInvalid()) {
1613 SkipUntil(tok::semi, true, true);
John McCalld226f652010-08-21 09:40:31 +00001614 return 0;
Douglas Gregord5a423b2009-09-25 18:43:00 +00001615 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001616
Douglas Gregord5a423b2009-09-25 18:43:00 +00001617 ThisDecl = ThisRes.get();
1618 break;
1619 }
1620 }
Mike Stump1eb44332009-09-09 15:08:12 +00001621
Richard Smith34b41d92011-02-20 03:19:35 +00001622 bool TypeContainsAuto =
1623 D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
1624
Douglas Gregor1426e532009-05-12 21:31:51 +00001625 // Parse declarator '=' initializer.
Richard Trieud6c7c672012-01-18 22:54:52 +00001626 // If a '==' or '+=' is found, suggest a fixit to '='.
Richard Trieufcaf27e2012-01-19 22:01:51 +00001627 if (isTokenEqualOrEqualTypo()) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001628 ConsumeToken();
Anders Carlsson37bf9d22010-09-24 21:25:25 +00001629 if (Tok.is(tok::kw_delete)) {
Sean Hunte4246a62011-05-12 06:15:49 +00001630 if (D.isFunctionDeclarator())
1631 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1632 << 1 /* delete */;
1633 else
1634 Diag(ConsumeToken(), diag::err_deleted_non_function);
Sean Huntfe2695e2011-05-06 01:42:00 +00001635 } else if (Tok.is(tok::kw_default)) {
Sean Hunte4246a62011-05-12 06:15:49 +00001636 if (D.isFunctionDeclarator())
Sebastian Redlecfcd562012-02-11 23:51:21 +00001637 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1638 << 0 /* default */;
Sean Hunte4246a62011-05-12 06:15:49 +00001639 else
1640 Diag(ConsumeToken(), diag::err_default_special_members);
Douglas Gregor1426e532009-05-12 21:31:51 +00001641 } else {
David Blaikie4e4d0842012-03-11 07:00:24 +00001642 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
John McCall731ad842009-12-19 09:28:58 +00001643 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001644 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001645 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001646
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001647 if (Tok.is(tok::code_completion)) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001648 Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
Peter Collingbourneec98f2f2012-07-27 12:56:09 +00001649 Actions.FinalizeDeclaration(ThisDecl);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00001650 cutOffParsing();
1651 return 0;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001652 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001653
John McCall60d7b3a2010-08-24 06:29:42 +00001654 ExprResult Init(ParseInitializer());
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001655
David Blaikie4e4d0842012-03-11 07:00:24 +00001656 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001657 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001658 ExitScope();
1659 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001660
Douglas Gregor1426e532009-05-12 21:31:51 +00001661 if (Init.isInvalid()) {
Douglas Gregor00225542010-03-01 18:27:54 +00001662 SkipUntil(tok::comma, true, true);
1663 Actions.ActOnInitializerError(ThisDecl);
1664 } else
Richard Smith34b41d92011-02-20 03:19:35 +00001665 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1666 /*DirectInit=*/false, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001667 }
1668 } else if (Tok.is(tok::l_paren)) {
1669 // Parse C++ direct initializer: '(' expression-list ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001670 BalancedDelimiterTracker T(*this, tok::l_paren);
1671 T.consumeOpen();
1672
Benjamin Kramer4e28d9e2012-08-23 22:51:59 +00001673 ExprVector Exprs;
Douglas Gregor1426e532009-05-12 21:31:51 +00001674 CommaLocsTy CommaLocs;
1675
David Blaikie4e4d0842012-03-11 07:00:24 +00001676 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregorb4debae2009-12-22 17:47:17 +00001677 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001678 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001679 }
1680
Douglas Gregor1426e532009-05-12 21:31:51 +00001681 if (ParseExpressionList(Exprs, CommaLocs)) {
1682 SkipUntil(tok::r_paren);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001683
David Blaikie4e4d0842012-03-11 07:00:24 +00001684 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001685 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001686 ExitScope();
1687 }
Douglas Gregor1426e532009-05-12 21:31:51 +00001688 } else {
1689 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001690 T.consumeClose();
Douglas Gregor1426e532009-05-12 21:31:51 +00001691
1692 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1693 "Unexpected number of commas!");
Douglas Gregorb4debae2009-12-22 17:47:17 +00001694
David Blaikie4e4d0842012-03-11 07:00:24 +00001695 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001696 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001697 ExitScope();
1698 }
1699
Sebastian Redl5b9cc5d2012-02-11 23:51:47 +00001700 ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
1701 T.getCloseLocation(),
Benjamin Kramer3fe198b2012-08-23 21:35:17 +00001702 Exprs);
Sebastian Redl5b9cc5d2012-02-11 23:51:47 +00001703 Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
1704 /*DirectInit=*/true, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001705 }
Fariborz Jahanian3b5f9dc2012-07-03 22:54:28 +00001706 } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace) &&
Fariborz Jahanianb0ed95c2012-07-03 23:22:13 +00001707 (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001708 // Parse C++0x braced-init-list.
Richard Smith7fe62082011-10-15 05:09:34 +00001709 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1710
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001711 if (D.getCXXScopeSpec().isSet()) {
1712 EnterScope(0);
1713 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1714 }
1715
1716 ExprResult Init(ParseBraceInitializer());
1717
1718 if (D.getCXXScopeSpec().isSet()) {
1719 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1720 ExitScope();
1721 }
1722
1723 if (Init.isInvalid()) {
1724 Actions.ActOnInitializerError(ThisDecl);
1725 } else
1726 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1727 /*DirectInit=*/true, TypeContainsAuto);
1728
Douglas Gregor1426e532009-05-12 21:31:51 +00001729 } else {
Richard Smith34b41d92011-02-20 03:19:35 +00001730 Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001731 }
1732
Richard Smith483b9f32011-02-21 20:05:19 +00001733 Actions.FinalizeDeclaration(ThisDecl);
1734
Douglas Gregor1426e532009-05-12 21:31:51 +00001735 return ThisDecl;
1736}
1737
Reid Spencer5f016e22007-07-11 17:01:13 +00001738/// ParseSpecifierQualifierList
1739/// specifier-qualifier-list:
1740/// type-specifier specifier-qualifier-list[opt]
1741/// type-qualifier specifier-qualifier-list[opt]
1742/// [GNU] attributes specifier-qualifier-list[opt]
1743///
Richard Smith69730c12012-03-12 07:56:15 +00001744void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1745 DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001746 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
1747 /// parse declaration-specifiers and complain about extra stuff.
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001748 /// TODO: diagnose attribute-specifiers and alignment-specifiers.
Richard Smith69730c12012-03-12 07:56:15 +00001749 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
Mike Stump1eb44332009-09-09 15:08:12 +00001750
Reid Spencer5f016e22007-07-11 17:01:13 +00001751 // Validate declspec for type-name.
1752 unsigned Specs = DS.getParsedSpecifiers();
Richard Smitha971d242012-05-09 20:55:26 +00001753 if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1754 !DS.hasTypeSpecifier()) {
Richard Smith69730c12012-03-12 07:56:15 +00001755 Diag(Tok, diag::err_expected_type);
1756 DS.SetTypeSpecError();
1757 } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
1758 !DS.hasAttributes()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001759 Diag(Tok, diag::err_typename_requires_specqual);
Richard Smith69730c12012-03-12 07:56:15 +00001760 if (!DS.hasTypeSpecifier())
1761 DS.SetTypeSpecError();
1762 }
Mike Stump1eb44332009-09-09 15:08:12 +00001763
Reid Spencer5f016e22007-07-11 17:01:13 +00001764 // Issue diagnostic and remove storage class if present.
1765 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
1766 if (DS.getStorageClassSpecLoc().isValid())
1767 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1768 else
1769 Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
1770 DS.ClearStorageClassSpecs();
1771 }
Mike Stump1eb44332009-09-09 15:08:12 +00001772
Reid Spencer5f016e22007-07-11 17:01:13 +00001773 // Issue diagnostic and remove function specfier if present.
1774 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregorb48fe382008-10-31 09:07:45 +00001775 if (DS.isInlineSpecified())
1776 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
1777 if (DS.isVirtualSpecified())
1778 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
1779 if (DS.isExplicitSpecified())
1780 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
Reid Spencer5f016e22007-07-11 17:01:13 +00001781 DS.ClearFunctionSpecs();
1782 }
Richard Smith69730c12012-03-12 07:56:15 +00001783
1784 // Issue diagnostic and remove constexpr specfier if present.
1785 if (DS.isConstexprSpecified()) {
1786 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
1787 DS.ClearConstexprSpec();
1788 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001789}
1790
Chris Lattnerc199ab32009-04-12 20:42:31 +00001791/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
1792/// specified token is valid after the identifier in a declarator which
1793/// immediately follows the declspec. For example, these things are valid:
1794///
1795/// int x [ 4]; // direct-declarator
1796/// int x ( int y); // direct-declarator
1797/// int(int x ) // direct-declarator
1798/// int x ; // simple-declaration
1799/// int x = 17; // init-declarator-list
1800/// int x , y; // init-declarator-list
1801/// int x __asm__ ("foo"); // init-declarator-list
Chris Lattnerb6645dd2009-04-14 21:16:09 +00001802/// int x : 4; // struct-declarator
Chris Lattnerc83c27a2009-04-12 22:29:43 +00001803/// int x { 5}; // C++'0x unified initializers
Chris Lattnerc199ab32009-04-12 20:42:31 +00001804///
1805/// This is not, because 'x' does not immediately follow the declspec (though
1806/// ')' happens to be valid anyway).
1807/// int (x)
1808///
1809static bool isValidAfterIdentifierInDeclarator(const Token &T) {
1810 return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
1811 T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
Chris Lattnerb6645dd2009-04-14 21:16:09 +00001812 T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
Chris Lattnerc199ab32009-04-12 20:42:31 +00001813}
1814
Chris Lattnere40c2952009-04-14 21:34:55 +00001815
1816/// ParseImplicitInt - This method is called when we have an non-typename
1817/// identifier in a declspec (which normally terminates the decl spec) when
1818/// the declspec has no type specifier. In this case, the declspec is either
1819/// malformed or is "implicit int" (in K&R and C89).
1820///
1821/// This method handles diagnosing this prettily and returns false if the
1822/// declspec is done being processed. If it recovers and thinks there may be
1823/// other pieces of declspec after it, it returns true.
1824///
Chris Lattnerf4382f52009-04-14 22:17:06 +00001825bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00001826 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00001827 AccessSpecifier AS, DeclSpecContext DSC) {
Chris Lattnerf4382f52009-04-14 22:17:06 +00001828 assert(Tok.is(tok::identifier) && "should have identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00001829
Chris Lattnere40c2952009-04-14 21:34:55 +00001830 SourceLocation Loc = Tok.getLocation();
1831 // If we see an identifier that is not a type name, we normally would
1832 // parse it as the identifer being declared. However, when a typename
1833 // is typo'd or the definition is not included, this will incorrectly
1834 // parse the typename as the identifier name and fall over misparsing
1835 // later parts of the diagnostic.
1836 //
1837 // As such, we try to do some look-ahead in cases where this would
1838 // otherwise be an "implicit-int" case to see if this is invalid. For
1839 // example: "static foo_t x = 4;" In this case, if we parsed foo_t as
1840 // an identifier with implicit int, we'd get a parse error because the
1841 // next token is obviously invalid for a type. Parse these as a case
1842 // with an invalid type specifier.
1843 assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
Mike Stump1eb44332009-09-09 15:08:12 +00001844
Chris Lattnere40c2952009-04-14 21:34:55 +00001845 // Since we know that this either implicit int (which is rare) or an
Richard Smith827adaf2012-05-15 21:01:51 +00001846 // error, do lookahead to try to do better recovery. This never applies
1847 // within a type specifier. Outside of C++, we allow this even if the
1848 // language doesn't "officially" support implicit int -- we support
1849 // implicit int as an extension in C99 and C11. Allegedly, MS also
1850 // supports implicit int in C++ mode.
Richard Smitha971d242012-05-09 20:55:26 +00001851 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
Richard Smith827adaf2012-05-15 21:01:51 +00001852 (!getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt) &&
Richard Smith69730c12012-03-12 07:56:15 +00001853 isValidAfterIdentifierInDeclarator(NextToken())) {
Chris Lattnere40c2952009-04-14 21:34:55 +00001854 // If this token is valid for implicit int, e.g. "static x = 4", then
1855 // we just avoid eating the identifier, so it will be parsed as the
1856 // identifier in the declarator.
1857 return false;
1858 }
Mike Stump1eb44332009-09-09 15:08:12 +00001859
Richard Smith827adaf2012-05-15 21:01:51 +00001860 if (getLangOpts().CPlusPlus &&
1861 DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
1862 // Don't require a type specifier if we have the 'auto' storage class
1863 // specifier in C++98 -- we'll promote it to a type specifier.
1864 return false;
1865 }
1866
Chris Lattnere40c2952009-04-14 21:34:55 +00001867 // Otherwise, if we don't consume this token, we are going to emit an
1868 // error anyway. Try to recover from various common problems. Check
1869 // to see if this was a reference to a tag name without a tag specified.
1870 // This is a common problem in C (saying 'foo' instead of 'struct foo').
Chris Lattnerf4382f52009-04-14 22:17:06 +00001871 //
1872 // C++ doesn't need this, and isTagName doesn't take SS.
1873 if (SS == 0) {
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00001874 const char *TagName = 0, *FixitTagName = 0;
Chris Lattnerf4382f52009-04-14 22:17:06 +00001875 tok::TokenKind TagKind = tok::unknown;
Mike Stump1eb44332009-09-09 15:08:12 +00001876
Douglas Gregor23c94db2010-07-02 17:43:08 +00001877 switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
Chris Lattnere40c2952009-04-14 21:34:55 +00001878 default: break;
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00001879 case DeclSpec::TST_enum:
1880 TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break;
1881 case DeclSpec::TST_union:
1882 TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
1883 case DeclSpec::TST_struct:
1884 TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
Joao Matos6666ed42012-08-31 18:45:21 +00001885 case DeclSpec::TST_interface:
1886 TagName="__interface"; FixitTagName = "__interface ";
1887 TagKind=tok::kw___interface;break;
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00001888 case DeclSpec::TST_class:
1889 TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
Chris Lattnere40c2952009-04-14 21:34:55 +00001890 }
Mike Stump1eb44332009-09-09 15:08:12 +00001891
Chris Lattnerf4382f52009-04-14 22:17:06 +00001892 if (TagName) {
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001893 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
1894 LookupResult R(Actions, TokenName, SourceLocation(),
1895 Sema::LookupOrdinaryName);
1896
Chris Lattnerf4382f52009-04-14 22:17:06 +00001897 Diag(Loc, diag::err_use_of_tag_name_without_tag)
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001898 << TokenName << TagName << getLangOpts().CPlusPlus
1899 << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
1900
1901 if (Actions.LookupParsedName(R, getCurScope(), SS)) {
1902 for (LookupResult::iterator I = R.begin(), IEnd = R.end();
1903 I != IEnd; ++I)
Kaelyn Uhrain392b3f52012-04-27 18:26:49 +00001904 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00001905 << TokenName << TagName;
1906 }
Mike Stump1eb44332009-09-09 15:08:12 +00001907
Chris Lattnerf4382f52009-04-14 22:17:06 +00001908 // Parse this as a tag as if the missing tag were present.
1909 if (TagKind == tok::kw_enum)
Richard Smith69730c12012-03-12 07:56:15 +00001910 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
Chris Lattnerf4382f52009-04-14 22:17:06 +00001911 else
Richard Smith69730c12012-03-12 07:56:15 +00001912 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
1913 /*EnteringContext*/ false, DSC_normal);
Chris Lattnerf4382f52009-04-14 22:17:06 +00001914 return true;
1915 }
Chris Lattnere40c2952009-04-14 21:34:55 +00001916 }
Mike Stump1eb44332009-09-09 15:08:12 +00001917
Richard Smith8f0a7e72012-05-15 21:29:55 +00001918 // Determine whether this identifier could plausibly be the name of something
Richard Smith7514db22012-05-15 21:42:17 +00001919 // being declared (with a missing type).
Richard Smith8f0a7e72012-05-15 21:29:55 +00001920 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
1921 (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
Richard Smith827adaf2012-05-15 21:01:51 +00001922 // Look ahead to the next token to try to figure out what this declaration
1923 // was supposed to be.
1924 switch (NextToken().getKind()) {
1925 case tok::comma:
1926 case tok::equal:
1927 case tok::kw_asm:
1928 case tok::l_brace:
1929 case tok::l_square:
1930 case tok::semi:
1931 // This looks like a variable declaration. The type is probably missing.
1932 // We're done parsing decl-specifiers.
1933 return false;
1934
1935 case tok::l_paren: {
1936 // static x(4); // 'x' is not a type
1937 // x(int n); // 'x' is not a type
1938 // x (*p)[]; // 'x' is a type
1939 //
1940 // Since we're in an error case (or the rare 'implicit int in C++' MS
1941 // extension), we can afford to perform a tentative parse to determine
1942 // which case we're in.
1943 TentativeParsingAction PA(*this);
1944 ConsumeToken();
1945 TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
1946 PA.Revert();
1947 if (TPR == TPResult::False())
1948 return false;
1949 // The identifier is followed by a parenthesized declarator.
1950 // It's supposed to be a type.
1951 break;
1952 }
1953
1954 default:
1955 // This is probably supposed to be a type. This includes cases like:
1956 // int f(itn);
1957 // struct S { unsinged : 4; };
1958 break;
1959 }
1960 }
1961
Chad Rosier8decdee2012-06-26 22:30:43 +00001962 // This is almost certainly an invalid type name. Let the action emit a
Douglas Gregora786fdb2009-10-13 23:27:22 +00001963 // diagnostic and attempt to recover.
John McCallb3d87482010-08-24 05:47:05 +00001964 ParsedType T;
Kaelyn Uhrain50dc12a2012-06-15 23:45:58 +00001965 IdentifierInfo *II = Tok.getIdentifierInfo();
1966 if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
Douglas Gregora786fdb2009-10-13 23:27:22 +00001967 // The action emitted a diagnostic, so we don't have to.
1968 if (T) {
1969 // The action has suggested that the type T could be used. Set that as
1970 // the type in the declaration specifiers, consume the would-be type
1971 // name token, and we're done.
1972 const char *PrevSpec;
1973 unsigned DiagID;
John McCallb3d87482010-08-24 05:47:05 +00001974 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
Douglas Gregora786fdb2009-10-13 23:27:22 +00001975 DS.SetRangeEnd(Tok.getLocation());
1976 ConsumeToken();
Kaelyn Uhrain50dc12a2012-06-15 23:45:58 +00001977 // There may be other declaration specifiers after this.
1978 return true;
1979 } else if (II != Tok.getIdentifierInfo()) {
1980 // If no type was suggested, the correction is to a keyword
1981 Tok.setKind(II->getTokenID());
Douglas Gregora786fdb2009-10-13 23:27:22 +00001982 // There may be other declaration specifiers after this.
1983 return true;
1984 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001985
Douglas Gregora786fdb2009-10-13 23:27:22 +00001986 // Fall through; the action had no suggestion for us.
1987 } else {
1988 // The action did not emit a diagnostic, so emit one now.
1989 SourceRange R;
1990 if (SS) R = SS->getRange();
1991 Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
1992 }
Mike Stump1eb44332009-09-09 15:08:12 +00001993
Douglas Gregora786fdb2009-10-13 23:27:22 +00001994 // Mark this as an error.
Richard Smith69730c12012-03-12 07:56:15 +00001995 DS.SetTypeSpecError();
Chris Lattnere40c2952009-04-14 21:34:55 +00001996 DS.SetRangeEnd(Tok.getLocation());
1997 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00001998
Chris Lattnere40c2952009-04-14 21:34:55 +00001999 // TODO: Could inject an invalid typedef decl in an enclosing scope to
2000 // avoid rippling error messages on subsequent uses of the same type,
2001 // could be useful if #include was forgotten.
2002 return false;
2003}
2004
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002005/// \brief Determine the declaration specifier context from the declarator
2006/// context.
2007///
2008/// \param Context the declarator context, which is one of the
2009/// Declarator::TheContext enumerator values.
Chad Rosier8decdee2012-06-26 22:30:43 +00002010Parser::DeclSpecContext
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002011Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
2012 if (Context == Declarator::MemberContext)
2013 return DSC_class;
2014 if (Context == Declarator::FileContext)
2015 return DSC_top_level;
Richard Smith6d96d3a2012-03-15 01:02:11 +00002016 if (Context == Declarator::TrailingReturnContext)
2017 return DSC_trailing;
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002018 return DSC_normal;
2019}
2020
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002021/// ParseAlignArgument - Parse the argument to an alignment-specifier.
2022///
2023/// FIXME: Simply returns an alignof() expression if the argument is a
2024/// type. Ideally, the type should be propagated directly into Sema.
2025///
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002026/// [C11] type-id
2027/// [C11] constant-expression
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002028/// [C++0x] type-id ...[opt]
2029/// [C++0x] assignment-expression ...[opt]
2030ExprResult Parser::ParseAlignArgument(SourceLocation Start,
2031 SourceLocation &EllipsisLoc) {
2032 ExprResult ER;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002033 if (isTypeIdInParens()) {
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002034 SourceLocation TypeLoc = Tok.getLocation();
2035 ParsedType Ty = ParseTypeName().get();
2036 SourceRange TypeRange(Start, Tok.getLocation());
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002037 ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
2038 Ty.getAsOpaquePtr(), TypeRange);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002039 } else
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002040 ER = ParseConstantExpression();
2041
David Blaikie4e4d0842012-03-11 07:00:24 +00002042 if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis))
Peter Collingbournefe9b2a82011-10-24 17:56:00 +00002043 EllipsisLoc = ConsumeToken();
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002044
2045 return ER;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002046}
2047
2048/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
2049/// attribute to Attrs.
2050///
2051/// alignment-specifier:
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002052/// [C11] '_Alignas' '(' type-id ')'
2053/// [C11] '_Alignas' '(' constant-expression ')'
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002054/// [C++0x] 'alignas' '(' type-id ...[opt] ')'
2055/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')'
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002056void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
2057 SourceLocation *endLoc) {
2058 assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
2059 "Not an alignment-specifier!");
2060
2061 SourceLocation KWLoc = Tok.getLocation();
2062 ConsumeToken();
2063
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002064 BalancedDelimiterTracker T(*this, tok::l_paren);
2065 if (T.expectAndConsume(diag::err_expected_lparen))
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002066 return;
2067
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002068 SourceLocation EllipsisLoc;
2069 ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002070 if (ArgExpr.isInvalid()) {
2071 SkipUntil(tok::r_paren);
2072 return;
2073 }
2074
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002075 T.consumeClose();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002076 if (endLoc)
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002077 *endLoc = T.getCloseLocation();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002078
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002079 // FIXME: Handle pack-expansions here.
2080 if (EllipsisLoc.isValid()) {
2081 Diag(EllipsisLoc, diag::err_alignas_pack_exp_unsupported);
2082 return;
2083 }
2084
Benjamin Kramer4e28d9e2012-08-23 22:51:59 +00002085 ExprVector ArgExprs;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002086 ArgExprs.push_back(ArgExpr.release());
Sean Hunt8e083e72012-06-19 23:57:03 +00002087 // FIXME: This should not be GNU, but we since the attribute used is
2088 // based on the spelling, and there is no true spelling for
2089 // C++11 attributes, this isn't accepted.
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002090 Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
Benjamin Kramer4e28d9e2012-08-23 22:51:59 +00002091 0, T.getOpenLocation(), ArgExprs.data(), 1,
Sean Hunt8e083e72012-06-19 23:57:03 +00002092 AttributeList::AS_GNU);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002093}
2094
Reid Spencer5f016e22007-07-11 17:01:13 +00002095/// ParseDeclarationSpecifiers
2096/// declaration-specifiers: [C99 6.7]
2097/// storage-class-specifier declaration-specifiers[opt]
2098/// type-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002099/// [C99] function-specifier declaration-specifiers[opt]
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002100/// [C11] alignment-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002101/// [GNU] attributes declaration-specifiers[opt]
Douglas Gregor8d267c52011-09-09 02:06:17 +00002102/// [Clang] '__module_private__' declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002103///
2104/// storage-class-specifier: [C99 6.7.1]
2105/// 'typedef'
2106/// 'extern'
2107/// 'static'
2108/// 'auto'
2109/// 'register'
Sebastian Redl669d5d72008-11-14 23:42:31 +00002110/// [C++] 'mutable'
Reid Spencer5f016e22007-07-11 17:01:13 +00002111/// [GNU] '__thread'
Reid Spencer5f016e22007-07-11 17:01:13 +00002112/// function-specifier: [C99 6.7.4]
2113/// [C99] 'inline'
Douglas Gregorb48fe382008-10-31 09:07:45 +00002114/// [C++] 'virtual'
2115/// [C++] 'explicit'
Peter Collingbournef315fa82011-02-14 01:42:53 +00002116/// [OpenCL] '__kernel'
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002117/// 'friend': [C++ dcl.friend]
Sebastian Redl2ac67232009-11-05 15:47:02 +00002118/// 'constexpr': [C++0x dcl.constexpr]
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002119
Reid Spencer5f016e22007-07-11 17:01:13 +00002120///
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +00002121void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00002122 const ParsedTemplateInfo &TemplateInfo,
John McCall67d1a672009-08-06 02:15:43 +00002123 AccessSpecifier AS,
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002124 DeclSpecContext DSContext,
2125 LateParsedAttrList *LateAttrs) {
Douglas Gregor312eadb2011-04-24 05:37:28 +00002126 if (DS.getSourceRange().isInvalid()) {
2127 DS.SetRangeStart(Tok.getLocation());
2128 DS.SetRangeEnd(Tok.getLocation());
2129 }
Chad Rosier8decdee2012-06-26 22:30:43 +00002130
Douglas Gregorefaa93a2011-11-07 17:33:42 +00002131 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
Sean Hunt2edf0a22012-06-23 05:07:58 +00002132 bool AttrsLastTime = false;
2133 ParsedAttributesWithRange attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00002134 while (1) {
John McCallfec54012009-08-03 20:12:06 +00002135 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00002136 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00002137 unsigned DiagID = 0;
2138
Reid Spencer5f016e22007-07-11 17:01:13 +00002139 SourceLocation Loc = Tok.getLocation();
Douglas Gregor12e083c2008-11-07 15:42:26 +00002140
Reid Spencer5f016e22007-07-11 17:01:13 +00002141 switch (Tok.getKind()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002142 default:
Chris Lattnerbce61352008-07-26 00:20:22 +00002143 DoneWithDeclSpec:
Sean Hunt2edf0a22012-06-23 05:07:58 +00002144 if (!AttrsLastTime)
2145 ProhibitAttributes(attrs);
2146 else
2147 DS.takeAttributesFrom(attrs);
Peter Collingbournef1907682011-09-29 18:03:57 +00002148
Reid Spencer5f016e22007-07-11 17:01:13 +00002149 // If this is not a declaration specifier token, we're done reading decl
2150 // specifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00002151 DS.Finish(Diags, PP);
Reid Spencer5f016e22007-07-11 17:01:13 +00002152 return;
Mike Stump1eb44332009-09-09 15:08:12 +00002153
Sean Hunt2edf0a22012-06-23 05:07:58 +00002154 case tok::l_square:
2155 case tok::kw_alignas:
2156 if (!isCXX11AttributeSpecifier())
2157 goto DoneWithDeclSpec;
2158
2159 ProhibitAttributes(attrs);
2160 // FIXME: It would be good to recover by accepting the attributes,
2161 // but attempting to do that now would cause serious
2162 // madness in terms of diagnostics.
2163 attrs.clear();
2164 attrs.Range = SourceRange();
2165
2166 ParseCXX11Attributes(attrs);
2167 AttrsLastTime = true;
Chad Rosier8decdee2012-06-26 22:30:43 +00002168 continue;
Sean Hunt2edf0a22012-06-23 05:07:58 +00002169
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002170 case tok::code_completion: {
John McCallf312b1e2010-08-26 23:41:50 +00002171 Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002172 if (DS.hasTypeSpecifier()) {
2173 bool AllowNonIdentifiers
2174 = (getCurScope()->getFlags() & (Scope::ControlScope |
2175 Scope::BlockScope |
2176 Scope::TemplateParamScope |
2177 Scope::FunctionPrototypeScope |
2178 Scope::AtCatchScope)) == 0;
2179 bool AllowNestedNameSpecifiers
Chad Rosier8decdee2012-06-26 22:30:43 +00002180 = DSContext == DSC_top_level ||
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002181 (DSContext == DSC_class && DS.isFriendSpecified());
2182
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002183 Actions.CodeCompleteDeclSpec(getCurScope(), DS,
Chad Rosier8decdee2012-06-26 22:30:43 +00002184 AllowNonIdentifiers,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002185 AllowNestedNameSpecifiers);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002186 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00002187 }
2188
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00002189 if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2190 CCC = Sema::PCC_LocalDeclarationSpecifiers;
2191 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
Chad Rosier8decdee2012-06-26 22:30:43 +00002192 CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
John McCallf312b1e2010-08-26 23:41:50 +00002193 : Sema::PCC_Template;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002194 else if (DSContext == DSC_class)
John McCallf312b1e2010-08-26 23:41:50 +00002195 CCC = Sema::PCC_Class;
Argyrios Kyrtzidis849639d2012-02-07 16:50:53 +00002196 else if (CurParsedObjCImpl)
John McCallf312b1e2010-08-26 23:41:50 +00002197 CCC = Sema::PCC_ObjCImplementation;
Chad Rosier8decdee2012-06-26 22:30:43 +00002198
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002199 Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002200 return cutOffParsing();
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002201 }
2202
Chris Lattner5e02c472009-01-05 00:07:25 +00002203 case tok::coloncolon: // ::foo::bar
John McCall9ba61662010-02-26 08:45:28 +00002204 // C++ scope specifier. Annotate and loop, or bail out on error.
2205 if (TryAnnotateCXXScopeToken(true)) {
2206 if (!DS.hasTypeSpecifier())
2207 DS.SetTypeSpecError();
2208 goto DoneWithDeclSpec;
2209 }
John McCall2e0a7152010-03-01 18:20:46 +00002210 if (Tok.is(tok::coloncolon)) // ::new or ::delete
2211 goto DoneWithDeclSpec;
John McCall9ba61662010-02-26 08:45:28 +00002212 continue;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002213
2214 case tok::annot_cxxscope: {
Richard Smithf63eee72012-05-09 18:56:43 +00002215 if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002216 goto DoneWithDeclSpec;
2217
John McCallaa87d332009-12-12 11:40:51 +00002218 CXXScopeSpec SS;
Douglas Gregorc34348a2011-02-24 17:54:50 +00002219 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2220 Tok.getAnnotationRange(),
2221 SS);
John McCallaa87d332009-12-12 11:40:51 +00002222
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002223 // We are looking for a qualified typename.
Douglas Gregor9135c722009-03-25 15:40:00 +00002224 Token Next = NextToken();
Mike Stump1eb44332009-09-09 15:08:12 +00002225 if (Next.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002226 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
Douglas Gregorc45c2322009-03-31 00:43:58 +00002227 ->Kind == TNK_Type_template) {
Douglas Gregor9135c722009-03-25 15:40:00 +00002228 // We have a qualified template-id, e.g., N::A<int>
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002229
2230 // C++ [class.qual]p2:
2231 // In a lookup in which the constructor is an acceptable lookup
2232 // result and the nested-name-specifier nominates a class C:
2233 //
2234 // - if the name specified after the
2235 // nested-name-specifier, when looked up in C, is the
2236 // injected-class-name of C (Clause 9), or
2237 //
2238 // - if the name specified after the nested-name-specifier
2239 // is the same as the identifier or the
2240 // simple-template-id's template-name in the last
2241 // component of the nested-name-specifier,
2242 //
2243 // the name is instead considered to name the constructor of
2244 // class C.
Chad Rosier8decdee2012-06-26 22:30:43 +00002245 //
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002246 // Thus, if the template-name is actually the constructor
2247 // name, then the code is ill-formed; this interpretation is
Chad Rosier8decdee2012-06-26 22:30:43 +00002248 // reinforced by the NAD status of core issue 635.
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002249 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
John McCallba9d8532010-04-13 06:39:49 +00002250 if ((DSContext == DSC_top_level ||
2251 (DSContext == DSC_class && DS.isFriendSpecified())) &&
2252 TemplateId->Name &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002253 Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002254 if (isConstructorDeclarator()) {
2255 // The user meant this to be an out-of-line constructor
2256 // definition, but template arguments are not allowed
2257 // there. Just allow this as a constructor; we'll
2258 // complain about it later.
2259 goto DoneWithDeclSpec;
2260 }
2261
2262 // The user meant this to name a type, but it actually names
2263 // a constructor with some extraneous template
2264 // arguments. Complain, then parse it as a type as the user
2265 // intended.
2266 Diag(TemplateId->TemplateNameLoc,
2267 diag::err_out_of_line_template_id_names_constructor)
2268 << TemplateId->Name;
2269 }
2270
John McCallaa87d332009-12-12 11:40:51 +00002271 DS.getTypeSpecScope() = SS;
2272 ConsumeToken(); // The C++ scope.
Mike Stump1eb44332009-09-09 15:08:12 +00002273 assert(Tok.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002274 "ParseOptionalCXXScopeSpecifier not working");
Douglas Gregor059101f2011-03-02 00:47:37 +00002275 AnnotateTemplateIdTokenAsType();
Douglas Gregor9135c722009-03-25 15:40:00 +00002276 continue;
2277 }
2278
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002279 if (Next.is(tok::annot_typename)) {
John McCallaa87d332009-12-12 11:40:51 +00002280 DS.getTypeSpecScope() = SS;
2281 ConsumeToken(); // The C++ scope.
John McCallb3d87482010-08-24 05:47:05 +00002282 if (Tok.getAnnotationValue()) {
2283 ParsedType T = getTypeAnnotation(Tok);
Nico Weber253e80b2010-11-22 10:30:56 +00002284 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
Chad Rosier8decdee2012-06-26 22:30:43 +00002285 Tok.getAnnotationEndLoc(),
John McCallb3d87482010-08-24 05:47:05 +00002286 PrevSpec, DiagID, T);
Richard Smithb3cd3c02012-09-14 18:27:01 +00002287 if (isInvalid)
2288 break;
John McCallb3d87482010-08-24 05:47:05 +00002289 }
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002290 else
2291 DS.SetTypeSpecError();
2292 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2293 ConsumeToken(); // The typename
2294 }
2295
Douglas Gregor9135c722009-03-25 15:40:00 +00002296 if (Next.isNot(tok::identifier))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002297 goto DoneWithDeclSpec;
2298
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002299 // If we're in a context where the identifier could be a class name,
2300 // check whether this is a constructor declaration.
John McCallba9d8532010-04-13 06:39:49 +00002301 if ((DSContext == DSC_top_level ||
2302 (DSContext == DSC_class && DS.isFriendSpecified())) &&
Chad Rosier8decdee2012-06-26 22:30:43 +00002303 Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002304 &SS)) {
2305 if (isConstructorDeclarator())
2306 goto DoneWithDeclSpec;
2307
2308 // As noted in C++ [class.qual]p2 (cited above), when the name
2309 // of the class is qualified in a context where it could name
2310 // a constructor, its a constructor name. However, we've
2311 // looked at the declarator, and the user probably meant this
2312 // to be a type. Complain that it isn't supposed to be treated
2313 // as a type, then proceed to parse it as a type.
2314 Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
2315 << Next.getIdentifierInfo();
2316 }
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002317
John McCallb3d87482010-08-24 05:47:05 +00002318 ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2319 Next.getLocation(),
Douglas Gregor9e876872011-03-01 18:12:44 +00002320 getCurScope(), &SS,
2321 false, false, ParsedType(),
Abramo Bagnarafad03b72012-01-27 08:46:19 +00002322 /*IsCtorOrDtorName=*/false,
Douglas Gregor9e876872011-03-01 18:12:44 +00002323 /*NonTrivialSourceInfo=*/true);
Douglas Gregor55f6b142009-02-09 18:46:07 +00002324
Chris Lattnerf4382f52009-04-14 22:17:06 +00002325 // If the referenced identifier is not a type, then this declspec is
2326 // erroneous: We already checked about that it has no type specifier, and
2327 // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
Mike Stump1eb44332009-09-09 15:08:12 +00002328 // typename.
Chris Lattnerf4382f52009-04-14 22:17:06 +00002329 if (TypeRep == 0) {
2330 ConsumeToken(); // Eat the scope spec so the identifier is current.
Richard Smith69730c12012-03-12 07:56:15 +00002331 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002332 goto DoneWithDeclSpec;
Chris Lattnerf4382f52009-04-14 22:17:06 +00002333 }
Mike Stump1eb44332009-09-09 15:08:12 +00002334
John McCallaa87d332009-12-12 11:40:51 +00002335 DS.getTypeSpecScope() = SS;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002336 ConsumeToken(); // The C++ scope.
2337
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002338 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002339 DiagID, TypeRep);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002340 if (isInvalid)
2341 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002342
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002343 DS.SetRangeEnd(Tok.getLocation());
2344 ConsumeToken(); // The typename.
2345
2346 continue;
2347 }
Mike Stump1eb44332009-09-09 15:08:12 +00002348
Chris Lattner80d0c892009-01-21 19:48:37 +00002349 case tok::annot_typename: {
John McCallb3d87482010-08-24 05:47:05 +00002350 if (Tok.getAnnotationValue()) {
2351 ParsedType T = getTypeAnnotation(Tok);
Nico Weberc43271e2010-11-22 12:50:03 +00002352 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00002353 DiagID, T);
2354 } else
Douglas Gregor31a19b62009-04-01 21:51:26 +00002355 DS.SetTypeSpecError();
Chad Rosier8decdee2012-06-26 22:30:43 +00002356
Chris Lattner5c5db552010-04-05 18:18:31 +00002357 if (isInvalid)
2358 break;
2359
Chris Lattner80d0c892009-01-21 19:48:37 +00002360 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2361 ConsumeToken(); // The typename
Mike Stump1eb44332009-09-09 15:08:12 +00002362
Chris Lattner80d0c892009-01-21 19:48:37 +00002363 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2364 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosier8decdee2012-06-26 22:30:43 +00002365 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002366 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002367 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002368
Chris Lattner80d0c892009-01-21 19:48:37 +00002369 continue;
2370 }
Mike Stump1eb44332009-09-09 15:08:12 +00002371
Douglas Gregorbfad9152011-04-28 15:48:45 +00002372 case tok::kw___is_signed:
2373 // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
2374 // typically treats it as a trait. If we see __is_signed as it appears
2375 // in libstdc++, e.g.,
2376 //
2377 // static const bool __is_signed;
2378 //
2379 // then treat __is_signed as an identifier rather than as a keyword.
2380 if (DS.getTypeSpecType() == TST_bool &&
2381 DS.getTypeQualifiers() == DeclSpec::TQ_const &&
2382 DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2383 Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
2384 Tok.setKind(tok::identifier);
2385 }
2386
2387 // We're done with the declaration-specifiers.
2388 goto DoneWithDeclSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00002389
Chris Lattner3bd934a2008-07-26 01:18:38 +00002390 // typedef-name
David Blaikie42d6d0c2011-12-04 05:04:18 +00002391 case tok::kw_decltype:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002392 case tok::identifier: {
Chris Lattner5e02c472009-01-05 00:07:25 +00002393 // In C++, check to see if this is a scope specifier like foo::bar::, if
2394 // so handle it as such. This is important for ctor parsing.
David Blaikie4e4d0842012-03-11 07:00:24 +00002395 if (getLangOpts().CPlusPlus) {
John McCall9ba61662010-02-26 08:45:28 +00002396 if (TryAnnotateCXXScopeToken(true)) {
2397 if (!DS.hasTypeSpecifier())
2398 DS.SetTypeSpecError();
2399 goto DoneWithDeclSpec;
2400 }
2401 if (!Tok.is(tok::identifier))
2402 continue;
2403 }
Mike Stump1eb44332009-09-09 15:08:12 +00002404
Chris Lattner3bd934a2008-07-26 01:18:38 +00002405 // This identifier can only be a typedef name if we haven't already seen
2406 // a type-specifier. Without this check we misparse:
2407 // typedef int X; struct Y { short X; }; as 'short int'.
2408 if (DS.hasTypeSpecifier())
2409 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00002410
John Thompson82287d12010-02-05 00:12:22 +00002411 // Check for need to substitute AltiVec keyword tokens.
2412 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2413 break;
2414
Richard Smithf63eee72012-05-09 18:56:43 +00002415 // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2416 // allow the use of a typedef name as a type specifier.
2417 if (DS.isTypeAltiVecVector())
2418 goto DoneWithDeclSpec;
2419
John McCallb3d87482010-08-24 05:47:05 +00002420 ParsedType TypeRep =
2421 Actions.getTypeName(*Tok.getIdentifierInfo(),
2422 Tok.getLocation(), getCurScope());
Douglas Gregor55f6b142009-02-09 18:46:07 +00002423
Chris Lattnerc199ab32009-04-12 20:42:31 +00002424 // If this is not a typedef name, don't parse it as part of the declspec,
2425 // it must be an implicit int or an error.
John McCallb3d87482010-08-24 05:47:05 +00002426 if (!TypeRep) {
Richard Smith69730c12012-03-12 07:56:15 +00002427 if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +00002428 goto DoneWithDeclSpec;
Chris Lattnerc199ab32009-04-12 20:42:31 +00002429 }
Douglas Gregor55f6b142009-02-09 18:46:07 +00002430
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002431 // If we're in a context where the identifier could be a class name,
2432 // check whether this is a constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002433 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002434 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002435 isConstructorDeclarator())
Douglas Gregorb48fe382008-10-31 09:07:45 +00002436 goto DoneWithDeclSpec;
2437
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002438 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002439 DiagID, TypeRep);
Chris Lattner3bd934a2008-07-26 01:18:38 +00002440 if (isInvalid)
2441 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002442
Chris Lattner3bd934a2008-07-26 01:18:38 +00002443 DS.SetRangeEnd(Tok.getLocation());
2444 ConsumeToken(); // The identifier
2445
2446 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2447 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosier8decdee2012-06-26 22:30:43 +00002448 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002449 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002450 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002451
Steve Naroff4f9b9f12008-09-22 10:28:57 +00002452 // Need to support trailing type qualifiers (e.g. "id<p> const").
2453 // If a type specifier follows, it will be diagnosed elsewhere.
2454 continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +00002455 }
Douglas Gregor39a8de12009-02-25 19:37:18 +00002456
2457 // type-name
2458 case tok::annot_template_id: {
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002459 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
Douglas Gregorc45c2322009-03-31 00:43:58 +00002460 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor39a8de12009-02-25 19:37:18 +00002461 // This template-id does not refer to a type name, so we're
2462 // done with the type-specifiers.
2463 goto DoneWithDeclSpec;
2464 }
2465
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002466 // If we're in a context where the template-id could be a
2467 // constructor name or specialization, check whether this is a
2468 // constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002469 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002470 Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002471 isConstructorDeclarator())
2472 goto DoneWithDeclSpec;
2473
Douglas Gregor39a8de12009-02-25 19:37:18 +00002474 // Turn the template-id annotation token into a type annotation
2475 // token, then try again to parse it as a type-specifier.
Douglas Gregor31a19b62009-04-01 21:51:26 +00002476 AnnotateTemplateIdTokenAsType();
Douglas Gregor39a8de12009-02-25 19:37:18 +00002477 continue;
2478 }
2479
Reid Spencer5f016e22007-07-11 17:01:13 +00002480 // GNU attributes support.
2481 case tok::kw___attribute:
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002482 ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
Reid Spencer5f016e22007-07-11 17:01:13 +00002483 continue;
Steve Narofff59e17e2008-12-24 20:59:21 +00002484
2485 // Microsoft declspec support.
2486 case tok::kw___declspec:
John McCall7f040a92010-12-24 02:08:15 +00002487 ParseMicrosoftDeclSpec(DS.getAttributes());
Steve Narofff59e17e2008-12-24 20:59:21 +00002488 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00002489
Steve Naroff239f0732008-12-25 14:16:32 +00002490 // Microsoft single token adornments.
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002491 case tok::kw___forceinline: {
2492 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
2493 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
Richard Smithb3cd3c02012-09-14 18:27:01 +00002494 SourceLocation AttrNameLoc = Tok.getLocation();
Sean Hunt93f95f22012-06-18 16:13:52 +00002495 // FIXME: This does not work correctly if it is set to be a declspec
2496 // attribute, and a GNU attribute is simply incorrect.
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002497 DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
Sean Hunt93f95f22012-06-18 16:13:52 +00002498 SourceLocation(), 0, 0, AttributeList::AS_GNU);
Richard Smithb3cd3c02012-09-14 18:27:01 +00002499 break;
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002500 }
Eli Friedman290eeb02009-06-08 23:27:34 +00002501
2502 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00002503 case tok::kw___ptr32:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00002504 case tok::kw___w64:
Steve Naroff239f0732008-12-25 14:16:32 +00002505 case tok::kw___cdecl:
2506 case tok::kw___stdcall:
2507 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00002508 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00002509 case tok::kw___unaligned:
John McCall7f040a92010-12-24 02:08:15 +00002510 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00002511 continue;
2512
Dawn Perchik52fc3142010-09-03 01:29:35 +00002513 // Borland single token adornments.
2514 case tok::kw___pascal:
John McCall7f040a92010-12-24 02:08:15 +00002515 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00002516 continue;
2517
Peter Collingbournef315fa82011-02-14 01:42:53 +00002518 // OpenCL single token adornments.
2519 case tok::kw___kernel:
2520 ParseOpenCLAttributes(DS.getAttributes());
2521 continue;
2522
Reid Spencer5f016e22007-07-11 17:01:13 +00002523 // storage-class-specifier
2524 case tok::kw_typedef:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002525 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2526 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002527 break;
2528 case tok::kw_extern:
2529 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +00002530 Diag(Tok, diag::ext_thread_before) << "extern";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002531 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2532 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002533 break;
Steve Naroff8d54bf22007-12-18 00:16:02 +00002534 case tok::kw___private_extern__:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002535 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2536 Loc, PrevSpec, DiagID);
Steve Naroff8d54bf22007-12-18 00:16:02 +00002537 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002538 case tok::kw_static:
2539 if (DS.isThreadSpecified())
Chris Lattner1ab3b962008-11-18 07:48:38 +00002540 Diag(Tok, diag::ext_thread_before) << "static";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002541 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2542 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002543 break;
2544 case tok::kw_auto:
David Blaikie4e4d0842012-03-11 07:00:24 +00002545 if (getLangOpts().CPlusPlus0x) {
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002546 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002547 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2548 PrevSpec, DiagID);
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002549 if (!isInvalid)
Richard Smith8f4fb192011-09-04 19:54:14 +00002550 Diag(Tok, diag::ext_auto_storage_class)
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002551 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
Richard Smith8f4fb192011-09-04 19:54:14 +00002552 } else
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002553 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2554 DiagID);
Richard Smith8f4fb192011-09-04 19:54:14 +00002555 } else
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002556 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2557 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002558 break;
2559 case tok::kw_register:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002560 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2561 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002562 break;
Sebastian Redl669d5d72008-11-14 23:42:31 +00002563 case tok::kw_mutable:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002564 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2565 PrevSpec, DiagID);
Sebastian Redl669d5d72008-11-14 23:42:31 +00002566 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002567 case tok::kw___thread:
John McCallfec54012009-08-03 20:12:06 +00002568 isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002569 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002570
Reid Spencer5f016e22007-07-11 17:01:13 +00002571 // function-specifier
2572 case tok::kw_inline:
John McCallfec54012009-08-03 20:12:06 +00002573 isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002574 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002575 case tok::kw_virtual:
John McCallfec54012009-08-03 20:12:06 +00002576 isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002577 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002578 case tok::kw_explicit:
John McCallfec54012009-08-03 20:12:06 +00002579 isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002580 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002581
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002582 // alignment-specifier
2583 case tok::kw__Alignas:
David Blaikie4e4d0842012-03-11 07:00:24 +00002584 if (!getLangOpts().C11)
Jordan Rosef70a8862012-06-30 21:33:57 +00002585 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002586 ParseAlignmentSpecifier(DS.getAttributes());
2587 continue;
2588
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002589 // friend
2590 case tok::kw_friend:
John McCall67d1a672009-08-06 02:15:43 +00002591 if (DSContext == DSC_class)
2592 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2593 else {
2594 PrevSpec = ""; // not actually used by the diagnostic
2595 DiagID = diag::err_friend_invalid_in_context;
2596 isInvalid = true;
2597 }
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002598 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002599
Douglas Gregor8d267c52011-09-09 02:06:17 +00002600 // Modules
2601 case tok::kw___module_private__:
2602 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2603 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00002604
Sebastian Redl2ac67232009-11-05 15:47:02 +00002605 // constexpr
2606 case tok::kw_constexpr:
2607 isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2608 break;
2609
Chris Lattner80d0c892009-01-21 19:48:37 +00002610 // type-specifier
2611 case tok::kw_short:
John McCallfec54012009-08-03 20:12:06 +00002612 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2613 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002614 break;
2615 case tok::kw_long:
2616 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
John McCallfec54012009-08-03 20:12:06 +00002617 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2618 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002619 else
John McCallfec54012009-08-03 20:12:06 +00002620 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2621 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002622 break;
Francois Pichet338d7f72011-04-28 01:59:37 +00002623 case tok::kw___int64:
2624 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2625 DiagID);
2626 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002627 case tok::kw_signed:
John McCallfec54012009-08-03 20:12:06 +00002628 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2629 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002630 break;
2631 case tok::kw_unsigned:
John McCallfec54012009-08-03 20:12:06 +00002632 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
2633 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002634 break;
2635 case tok::kw__Complex:
John McCallfec54012009-08-03 20:12:06 +00002636 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
2637 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002638 break;
2639 case tok::kw__Imaginary:
John McCallfec54012009-08-03 20:12:06 +00002640 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
2641 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002642 break;
2643 case tok::kw_void:
John McCallfec54012009-08-03 20:12:06 +00002644 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
2645 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002646 break;
2647 case tok::kw_char:
John McCallfec54012009-08-03 20:12:06 +00002648 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
2649 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002650 break;
2651 case tok::kw_int:
John McCallfec54012009-08-03 20:12:06 +00002652 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
2653 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002654 break;
Richard Smith5a5a9712012-04-04 06:24:32 +00002655 case tok::kw___int128:
2656 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
2657 DiagID);
2658 break;
2659 case tok::kw_half:
2660 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
2661 DiagID);
2662 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002663 case tok::kw_float:
John McCallfec54012009-08-03 20:12:06 +00002664 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
2665 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002666 break;
2667 case tok::kw_double:
John McCallfec54012009-08-03 20:12:06 +00002668 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
2669 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002670 break;
2671 case tok::kw_wchar_t:
John McCallfec54012009-08-03 20:12:06 +00002672 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
2673 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002674 break;
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002675 case tok::kw_char16_t:
John McCallfec54012009-08-03 20:12:06 +00002676 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
2677 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002678 break;
2679 case tok::kw_char32_t:
John McCallfec54012009-08-03 20:12:06 +00002680 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
2681 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00002682 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002683 case tok::kw_bool:
2684 case tok::kw__Bool:
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00002685 if (Tok.is(tok::kw_bool) &&
2686 DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
2687 DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
2688 PrevSpec = ""; // Not used by the diagnostic.
2689 DiagID = diag::err_bool_redeclaration;
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00002690 // For better error recovery.
2691 Tok.setKind(tok::identifier);
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00002692 isInvalid = true;
2693 } else {
2694 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
2695 DiagID);
2696 }
Chris Lattner80d0c892009-01-21 19:48:37 +00002697 break;
2698 case tok::kw__Decimal32:
John McCallfec54012009-08-03 20:12:06 +00002699 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
2700 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002701 break;
2702 case tok::kw__Decimal64:
John McCallfec54012009-08-03 20:12:06 +00002703 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
2704 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002705 break;
2706 case tok::kw__Decimal128:
John McCallfec54012009-08-03 20:12:06 +00002707 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
2708 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002709 break;
John Thompson82287d12010-02-05 00:12:22 +00002710 case tok::kw___vector:
2711 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
2712 break;
2713 case tok::kw___pixel:
2714 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
2715 break;
John McCalla5fc4722011-04-09 22:50:59 +00002716 case tok::kw___unknown_anytype:
2717 isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
2718 PrevSpec, DiagID);
2719 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002720
2721 // class-specifier:
2722 case tok::kw_class:
2723 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00002724 case tok::kw___interface:
Chris Lattner4c97d762009-04-12 21:49:30 +00002725 case tok::kw_union: {
2726 tok::TokenKind Kind = Tok.getKind();
2727 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00002728 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
2729 EnteringContext, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00002730 continue;
Chris Lattner4c97d762009-04-12 21:49:30 +00002731 }
Chris Lattner80d0c892009-01-21 19:48:37 +00002732
2733 // enum-specifier:
2734 case tok::kw_enum:
Chris Lattner4c97d762009-04-12 21:49:30 +00002735 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00002736 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00002737 continue;
2738
2739 // cv-qualifier:
2740 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00002741 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00002742 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattner80d0c892009-01-21 19:48:37 +00002743 break;
2744 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00002745 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00002746 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattner80d0c892009-01-21 19:48:37 +00002747 break;
2748 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00002749 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00002750 getLangOpts(), /*IsTypeSpec*/true);
Chris Lattner80d0c892009-01-21 19:48:37 +00002751 break;
2752
Douglas Gregord57959a2009-03-27 23:10:48 +00002753 // C++ typename-specifier:
2754 case tok::kw_typename:
John McCall9ba61662010-02-26 08:45:28 +00002755 if (TryAnnotateTypeOrScopeToken()) {
2756 DS.SetTypeSpecError();
2757 goto DoneWithDeclSpec;
2758 }
2759 if (!Tok.is(tok::kw_typename))
Douglas Gregord57959a2009-03-27 23:10:48 +00002760 continue;
2761 break;
2762
Chris Lattner80d0c892009-01-21 19:48:37 +00002763 // GNU typeof support.
2764 case tok::kw_typeof:
2765 ParseTypeofSpecifier(DS);
2766 continue;
2767
David Blaikie42d6d0c2011-12-04 05:04:18 +00002768 case tok::annot_decltype:
Anders Carlsson6fd634f2009-06-24 17:47:40 +00002769 ParseDecltypeSpecifier(DS);
2770 continue;
2771
Sean Huntdb5d44b2011-05-19 05:37:45 +00002772 case tok::kw___underlying_type:
2773 ParseUnderlyingTypeSpecifier(DS);
Eli Friedmanb001de72011-10-06 23:00:33 +00002774 continue;
2775
2776 case tok::kw__Atomic:
2777 ParseAtomicSpecifier(DS);
2778 continue;
Sean Huntdb5d44b2011-05-19 05:37:45 +00002779
Peter Collingbourne207f4d82011-03-18 22:38:29 +00002780 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00002781 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00002782 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00002783 goto DoneWithDeclSpec;
2784 case tok::kw___private:
2785 case tok::kw___global:
2786 case tok::kw___local:
2787 case tok::kw___constant:
2788 case tok::kw___read_only:
2789 case tok::kw___write_only:
2790 case tok::kw___read_write:
2791 ParseOpenCLQualifiers(DS);
2792 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00002793
Steve Naroffd3ded1f2008-06-05 00:02:44 +00002794 case tok::less:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002795 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerbce61352008-07-26 00:20:22 +00002796 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
2797 // but we support it.
David Blaikie4e4d0842012-03-11 07:00:24 +00002798 if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
Chris Lattnerbce61352008-07-26 00:20:22 +00002799 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00002800
Douglas Gregor46f936e2010-11-19 17:10:50 +00002801 if (!ParseObjCProtocolQualifiers(DS))
2802 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
2803 << FixItHint::CreateInsertion(Loc, "id")
2804 << SourceRange(Loc, DS.getSourceRange().getEnd());
Chad Rosier8decdee2012-06-26 22:30:43 +00002805
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002806 // Need to support trailing type qualifiers (e.g. "id<p> const").
2807 // If a type specifier follows, it will be diagnosed elsewhere.
2808 continue;
Reid Spencer5f016e22007-07-11 17:01:13 +00002809 }
John McCallfec54012009-08-03 20:12:06 +00002810 // If the specifier wasn't legal, issue a diagnostic.
Reid Spencer5f016e22007-07-11 17:01:13 +00002811 if (isInvalid) {
2812 assert(PrevSpec && "Method did not return previous specifier!");
John McCallfec54012009-08-03 20:12:06 +00002813 assert(DiagID);
Chad Rosier8decdee2012-06-26 22:30:43 +00002814
Douglas Gregorae2fb142010-08-23 14:34:43 +00002815 if (DiagID == diag::ext_duplicate_declspec)
2816 Diag(Tok, DiagID)
2817 << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
2818 else
2819 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00002820 }
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002821
Chris Lattner81c018d2008-03-13 06:29:04 +00002822 DS.SetRangeEnd(Tok.getLocation());
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00002823 if (DiagID != diag::err_bool_redeclaration)
2824 ConsumeToken();
Sean Hunt2edf0a22012-06-23 05:07:58 +00002825
2826 AttrsLastTime = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00002827 }
2828}
Douglas Gregoradcac882008-12-01 23:54:00 +00002829
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002830/// ParseStructDeclaration - Parse a struct declaration without the terminating
2831/// semicolon.
2832///
Reid Spencer5f016e22007-07-11 17:01:13 +00002833/// struct-declaration:
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002834/// specifier-qualifier-list struct-declarator-list
Reid Spencer5f016e22007-07-11 17:01:13 +00002835/// [GNU] __extension__ struct-declaration
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002836/// [GNU] specifier-qualifier-list
Reid Spencer5f016e22007-07-11 17:01:13 +00002837/// struct-declarator-list:
2838/// struct-declarator
2839/// struct-declarator-list ',' struct-declarator
2840/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
2841/// struct-declarator:
2842/// declarator
2843/// [GNU] declarator attributes[opt]
2844/// declarator[opt] ':' constant-expression
2845/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
2846///
Chris Lattnere1359422008-04-10 06:46:29 +00002847void Parser::
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002848ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
Chad Rosier8decdee2012-06-26 22:30:43 +00002849
Chris Lattnerc46d1a12008-10-20 06:45:43 +00002850 if (Tok.is(tok::kw___extension__)) {
2851 // __extension__ silences extension warnings in the subexpression.
2852 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroff28a7ca82007-08-20 22:28:22 +00002853 ConsumeToken();
Chris Lattnerc46d1a12008-10-20 06:45:43 +00002854 return ParseStructDeclaration(DS, Fields);
2855 }
Mike Stump1eb44332009-09-09 15:08:12 +00002856
Steve Naroff28a7ca82007-08-20 22:28:22 +00002857 // Parse the common specifier-qualifiers-list piece.
Steve Naroff28a7ca82007-08-20 22:28:22 +00002858 ParseSpecifierQualifierList(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00002859
Douglas Gregor4920f1f2009-01-12 22:49:06 +00002860 // If there are no declarators, this is a free-standing declaration
2861 // specifier. Let the actions module cope with it.
Chris Lattner04d66662007-10-09 17:33:22 +00002862 if (Tok.is(tok::semi)) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002863 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
2864 DS);
2865 DS.complete(TheDecl);
Steve Naroff28a7ca82007-08-20 22:28:22 +00002866 return;
2867 }
2868
2869 // Read struct-declarators until we find the semicolon.
John McCallbdd563e2009-11-03 02:38:08 +00002870 bool FirstDeclarator = true;
Richard Smith7984de32012-01-12 23:53:29 +00002871 SourceLocation CommaLoc;
Steve Naroff28a7ca82007-08-20 22:28:22 +00002872 while (1) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002873 ParsingFieldDeclarator DeclaratorInfo(*this, DS);
Richard Smith7984de32012-01-12 23:53:29 +00002874 DeclaratorInfo.D.setCommaLoc(CommaLoc);
John McCallbdd563e2009-11-03 02:38:08 +00002875
2876 // Attributes are only allowed here on successive declarators.
John McCall7f040a92010-12-24 02:08:15 +00002877 if (!FirstDeclarator)
2878 MaybeParseGNUAttributes(DeclaratorInfo.D);
Mike Stump1eb44332009-09-09 15:08:12 +00002879
Steve Naroff28a7ca82007-08-20 22:28:22 +00002880 /// struct-declarator: declarator
2881 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattnera1efc8c2009-12-10 01:59:24 +00002882 if (Tok.isNot(tok::colon)) {
2883 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
2884 ColonProtectionRAIIObject X(*this);
Chris Lattnere1359422008-04-10 06:46:29 +00002885 ParseDeclarator(DeclaratorInfo.D);
Chris Lattnera1efc8c2009-12-10 01:59:24 +00002886 }
Mike Stump1eb44332009-09-09 15:08:12 +00002887
Chris Lattner04d66662007-10-09 17:33:22 +00002888 if (Tok.is(tok::colon)) {
Steve Naroff28a7ca82007-08-20 22:28:22 +00002889 ConsumeToken();
John McCall60d7b3a2010-08-24 06:29:42 +00002890 ExprResult Res(ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00002891 if (Res.isInvalid())
Steve Naroff28a7ca82007-08-20 22:28:22 +00002892 SkipUntil(tok::semi, true, true);
Chris Lattner60b1e3e2008-04-10 06:15:14 +00002893 else
Sebastian Redleffa8d12008-12-10 00:02:53 +00002894 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroff28a7ca82007-08-20 22:28:22 +00002895 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00002896
Steve Naroff28a7ca82007-08-20 22:28:22 +00002897 // If attributes exist after the declarator, parse them.
John McCall7f040a92010-12-24 02:08:15 +00002898 MaybeParseGNUAttributes(DeclaratorInfo.D);
Sebastian Redlab197ba2009-02-09 18:23:29 +00002899
John McCallbdd563e2009-11-03 02:38:08 +00002900 // We're done with this declarator; invoke the callback.
Eli Friedman817a8862012-08-08 23:35:12 +00002901 Fields.invoke(DeclaratorInfo);
John McCallbdd563e2009-11-03 02:38:08 +00002902
Steve Naroff28a7ca82007-08-20 22:28:22 +00002903 // If we don't have a comma, it is either the end of the list (a ';')
2904 // or an error, bail out.
Chris Lattner04d66662007-10-09 17:33:22 +00002905 if (Tok.isNot(tok::comma))
Chris Lattnercd4b83c2007-10-29 04:42:53 +00002906 return;
Sebastian Redlab197ba2009-02-09 18:23:29 +00002907
Steve Naroff28a7ca82007-08-20 22:28:22 +00002908 // Consume the comma.
Richard Smith7984de32012-01-12 23:53:29 +00002909 CommaLoc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00002910
John McCallbdd563e2009-11-03 02:38:08 +00002911 FirstDeclarator = false;
Steve Naroff28a7ca82007-08-20 22:28:22 +00002912 }
Steve Naroff28a7ca82007-08-20 22:28:22 +00002913}
2914
2915/// ParseStructUnionBody
2916/// struct-contents:
2917/// struct-declaration-list
2918/// [EXT] empty
2919/// [GNU] "struct-declaration-list" without terminatoring ';'
2920/// struct-declaration-list:
2921/// struct-declaration
2922/// struct-declaration-list struct-declaration
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002923/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroff28a7ca82007-08-20 22:28:22 +00002924///
Reid Spencer5f016e22007-07-11 17:01:13 +00002925void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
John McCalld226f652010-08-21 09:40:31 +00002926 unsigned TagType, Decl *TagDecl) {
John McCallf312b1e2010-08-26 23:41:50 +00002927 PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2928 "parsing struct/union body");
Mike Stump1eb44332009-09-09 15:08:12 +00002929
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002930 BalancedDelimiterTracker T(*this, tok::l_brace);
2931 if (T.consumeOpen())
2932 return;
Mike Stump1eb44332009-09-09 15:08:12 +00002933
Douglas Gregor3218c4b2009-01-09 22:42:13 +00002934 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00002935 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
Douglas Gregor72de6672009-01-08 20:45:30 +00002936
Reid Spencer5f016e22007-07-11 17:01:13 +00002937 // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
2938 // C++.
David Blaikie4e4d0842012-03-11 07:00:24 +00002939 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {
Richard Smithd7c56e12011-12-29 21:57:33 +00002940 Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union);
2941 Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union);
2942 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002943
Chris Lattner5f9e2722011-07-23 10:55:15 +00002944 SmallVector<Decl *, 32> FieldDecls;
Chris Lattnere1359422008-04-10 06:46:29 +00002945
Reid Spencer5f016e22007-07-11 17:01:13 +00002946 // While we still have something to read, read the declarations in the struct.
Chris Lattner04d66662007-10-09 17:33:22 +00002947 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00002948 // Each iteration of this loop reads one struct-declaration.
Mike Stump1eb44332009-09-09 15:08:12 +00002949
Reid Spencer5f016e22007-07-11 17:01:13 +00002950 // Check for extraneous top-level semicolon.
Chris Lattner04d66662007-10-09 17:33:22 +00002951 if (Tok.is(tok::semi)) {
Richard Smitheab9d6f2012-07-23 05:45:25 +00002952 ConsumeExtraSemi(InsideStruct, TagType);
Reid Spencer5f016e22007-07-11 17:01:13 +00002953 continue;
2954 }
Chris Lattnere1359422008-04-10 06:46:29 +00002955
John McCallbdd563e2009-11-03 02:38:08 +00002956 if (!Tok.is(tok::at)) {
2957 struct CFieldCallback : FieldCallback {
2958 Parser &P;
John McCalld226f652010-08-21 09:40:31 +00002959 Decl *TagDecl;
Chris Lattner5f9e2722011-07-23 10:55:15 +00002960 SmallVectorImpl<Decl *> &FieldDecls;
John McCallbdd563e2009-11-03 02:38:08 +00002961
John McCalld226f652010-08-21 09:40:31 +00002962 CFieldCallback(Parser &P, Decl *TagDecl,
Chris Lattner5f9e2722011-07-23 10:55:15 +00002963 SmallVectorImpl<Decl *> &FieldDecls) :
John McCallbdd563e2009-11-03 02:38:08 +00002964 P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
2965
Eli Friedmandcdff462012-08-08 23:53:27 +00002966 void invoke(ParsingFieldDeclarator &FD) {
John McCallbdd563e2009-11-03 02:38:08 +00002967 // Install the declarator into the current TagDecl.
John McCalld226f652010-08-21 09:40:31 +00002968 Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
John McCall4ba39712009-11-03 21:13:47 +00002969 FD.D.getDeclSpec().getSourceRange().getBegin(),
2970 FD.D, FD.BitfieldSize);
John McCallbdd563e2009-11-03 02:38:08 +00002971 FieldDecls.push_back(Field);
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002972 FD.complete(Field);
Douglas Gregor91a28862009-08-26 14:27:30 +00002973 }
John McCallbdd563e2009-11-03 02:38:08 +00002974 } Callback(*this, TagDecl, FieldDecls);
2975
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00002976 // Parse all the comma separated declarators.
2977 ParsingDeclSpec DS(*this);
John McCallbdd563e2009-11-03 02:38:08 +00002978 ParseStructDeclaration(DS, Callback);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002979 } else { // Handle @defs
2980 ConsumeToken();
2981 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
2982 Diag(Tok, diag::err_unexpected_at);
Chris Lattner3e156ad2010-02-02 00:37:27 +00002983 SkipUntil(tok::semi, true);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002984 continue;
2985 }
2986 ConsumeToken();
2987 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
2988 if (!Tok.is(tok::identifier)) {
2989 Diag(Tok, diag::err_expected_ident);
Chris Lattner3e156ad2010-02-02 00:37:27 +00002990 SkipUntil(tok::semi, true);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002991 continue;
2992 }
Chris Lattner5f9e2722011-07-23 10:55:15 +00002993 SmallVector<Decl *, 16> Fields;
Douglas Gregor23c94db2010-07-02 17:43:08 +00002994 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
Douglas Gregor44b43212008-12-11 16:49:14 +00002995 Tok.getIdentifierInfo(), Fields);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00002996 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
2997 ConsumeToken();
2998 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
Mike Stump1eb44332009-09-09 15:08:12 +00002999 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003000
Chris Lattner04d66662007-10-09 17:33:22 +00003001 if (Tok.is(tok::semi)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003002 ConsumeToken();
Chris Lattner04d66662007-10-09 17:33:22 +00003003 } else if (Tok.is(tok::r_brace)) {
Chris Lattner3e156ad2010-02-02 00:37:27 +00003004 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
Reid Spencer5f016e22007-07-11 17:01:13 +00003005 break;
3006 } else {
Chris Lattner3e156ad2010-02-02 00:37:27 +00003007 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
3008 // Skip to end of block or statement to avoid ext-warning on extra ';'.
Reid Spencer5f016e22007-07-11 17:01:13 +00003009 SkipUntil(tok::r_brace, true, true);
Chris Lattner3e156ad2010-02-02 00:37:27 +00003010 // If we stopped at a ';', eat it.
3011 if (Tok.is(tok::semi)) ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00003012 }
3013 }
Mike Stump1eb44332009-09-09 15:08:12 +00003014
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003015 T.consumeClose();
Mike Stump1eb44332009-09-09 15:08:12 +00003016
John McCall0b7e6782011-03-24 11:26:52 +00003017 ParsedAttributes attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00003018 // If attributes exist after struct contents, parse them.
John McCall7f040a92010-12-24 02:08:15 +00003019 MaybeParseGNUAttributes(attrs);
Daniel Dunbar1bfe1c22008-10-03 02:03:53 +00003020
Douglas Gregor23c94db2010-07-02 17:43:08 +00003021 Actions.ActOnFields(getCurScope(),
David Blaikie77b6de02011-09-22 02:58:26 +00003022 RecordLoc, TagDecl, FieldDecls,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003023 T.getOpenLocation(), T.getCloseLocation(),
John McCall7f040a92010-12-24 02:08:15 +00003024 attrs.getList());
Douglas Gregor72de6672009-01-08 20:45:30 +00003025 StructScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003026 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
3027 T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00003028}
3029
Reid Spencer5f016e22007-07-11 17:01:13 +00003030/// ParseEnumSpecifier
3031/// enum-specifier: [C99 6.7.2.2]
3032/// 'enum' identifier[opt] '{' enumerator-list '}'
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003033///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00003034/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
3035/// '}' attributes[opt]
Aaron Ballman6454a022012-03-01 04:09:28 +00003036/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
3037/// '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00003038/// 'enum' identifier
3039/// [GNU] 'enum' attributes[opt] identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003040///
Richard Smith1af83c42012-03-23 03:33:32 +00003041/// [C++11] enum-head '{' enumerator-list[opt] '}'
3042/// [C++11] enum-head '{' enumerator-list ',' '}'
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003043///
Richard Smith1af83c42012-03-23 03:33:32 +00003044/// enum-head: [C++11]
3045/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
3046/// enum-key attribute-specifier-seq[opt] nested-name-specifier
3047/// identifier enum-base[opt]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003048///
Richard Smith1af83c42012-03-23 03:33:32 +00003049/// enum-key: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003050/// 'enum'
3051/// 'enum' 'class'
3052/// 'enum' 'struct'
3053///
Richard Smith1af83c42012-03-23 03:33:32 +00003054/// enum-base: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003055/// ':' type-specifier-seq
3056///
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003057/// [C++] elaborated-type-specifier:
3058/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
3059///
Chris Lattner4c97d762009-04-12 21:49:30 +00003060void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Douglas Gregor9b9edd62010-03-02 17:53:14 +00003061 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00003062 AccessSpecifier AS, DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003063 // Parse the tag portion of this.
Douglas Gregor374929f2009-09-18 15:37:17 +00003064 if (Tok.is(tok::code_completion)) {
3065 // Code completion for an enum name.
Douglas Gregor23c94db2010-07-02 17:43:08 +00003066 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00003067 return cutOffParsing();
Douglas Gregor374929f2009-09-18 15:37:17 +00003068 }
John McCall57c13002011-07-06 05:58:41 +00003069
Sean Hunt2edf0a22012-06-23 05:07:58 +00003070 // If attributes exist after tag, parse them.
3071 ParsedAttributesWithRange attrs(AttrFactory);
3072 MaybeParseGNUAttributes(attrs);
3073 MaybeParseCXX0XAttributes(attrs);
3074
3075 // If declspecs exist after tag, parse them.
3076 while (Tok.is(tok::kw___declspec))
3077 ParseMicrosoftDeclSpec(attrs);
3078
Richard Smithbdad7a22012-01-10 01:33:14 +00003079 SourceLocation ScopedEnumKWLoc;
John McCall57c13002011-07-06 05:58:41 +00003080 bool IsScopedUsingClassTag = false;
3081
John McCall1e12b3d2012-06-23 22:30:04 +00003082 // In C++11, recognize 'enum class' and 'enum struct'.
David Blaikie4e4d0842012-03-11 07:00:24 +00003083 if (getLangOpts().CPlusPlus0x &&
John McCall57c13002011-07-06 05:58:41 +00003084 (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
Richard Smith7fe62082011-10-15 05:09:34 +00003085 Diag(Tok, diag::warn_cxx98_compat_scoped_enum);
John McCall57c13002011-07-06 05:58:41 +00003086 IsScopedUsingClassTag = Tok.is(tok::kw_class);
Richard Smithbdad7a22012-01-10 01:33:14 +00003087 ScopedEnumKWLoc = ConsumeToken();
Chad Rosier8decdee2012-06-26 22:30:43 +00003088
John McCall1e12b3d2012-06-23 22:30:04 +00003089 // Attributes are not allowed between these keywords. Diagnose,
3090 // but then just treat them like they appeared in the right place.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003091 ProhibitAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003092
3093 // They are allowed afterwards, though.
3094 MaybeParseGNUAttributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003095 MaybeParseCXX0XAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003096 while (Tok.is(tok::kw___declspec))
3097 ParseMicrosoftDeclSpec(attrs);
John McCall57c13002011-07-06 05:58:41 +00003098 }
Richard Smith1af83c42012-03-23 03:33:32 +00003099
John McCall13489672012-05-07 06:16:58 +00003100 // C++11 [temp.explicit]p12:
3101 // The usual access controls do not apply to names used to specify
3102 // explicit instantiations.
3103 // We extend this to also cover explicit specializations. Note that
3104 // we don't suppress if this turns out to be an elaborated type
3105 // specifier.
3106 bool shouldDelayDiagsInTag =
3107 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3108 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3109 SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
Richard Smith1af83c42012-03-23 03:33:32 +00003110
Richard Smith7796eb52012-03-12 08:56:40 +00003111 // Enum definitions should not be parsed in a trailing-return-type.
3112 bool AllowDeclaration = DSC != DSC_trailing;
3113
3114 bool AllowFixedUnderlyingType = AllowDeclaration &&
3115 (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt ||
3116 getLangOpts().ObjC2);
John McCall57c13002011-07-06 05:58:41 +00003117
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00003118 CXXScopeSpec &SS = DS.getTypeSpecScope();
David Blaikie4e4d0842012-03-11 07:00:24 +00003119 if (getLangOpts().CPlusPlus) {
John McCall57c13002011-07-06 05:58:41 +00003120 // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3121 // if a fixed underlying type is allowed.
3122 ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
Chad Rosier8decdee2012-06-26 22:30:43 +00003123
3124 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003125 /*EnteringContext=*/false))
John McCall9ba61662010-02-26 08:45:28 +00003126 return;
3127
3128 if (SS.isSet() && Tok.isNot(tok::identifier)) {
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003129 Diag(Tok, diag::err_expected_ident);
3130 if (Tok.isNot(tok::l_brace)) {
3131 // Has no name and is not a definition.
3132 // Skip the rest of this declarator, up until the comma or semicolon.
3133 SkipUntil(tok::comma, true);
3134 return;
3135 }
3136 }
3137 }
Mike Stump1eb44332009-09-09 15:08:12 +00003138
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003139 // Must have either 'enum name' or 'enum {...}'.
Douglas Gregorb9075602011-02-22 02:55:24 +00003140 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
Richard Smith7796eb52012-03-12 08:56:40 +00003141 !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003142 Diag(Tok, diag::err_expected_ident_lbrace);
Mike Stump1eb44332009-09-09 15:08:12 +00003143
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003144 // Skip the rest of this declarator, up until the comma or semicolon.
3145 SkipUntil(tok::comma, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00003146 return;
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003147 }
Mike Stump1eb44332009-09-09 15:08:12 +00003148
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003149 // If an identifier is present, consume and remember it.
3150 IdentifierInfo *Name = 0;
3151 SourceLocation NameLoc;
3152 if (Tok.is(tok::identifier)) {
3153 Name = Tok.getIdentifierInfo();
3154 NameLoc = ConsumeToken();
3155 }
Mike Stump1eb44332009-09-09 15:08:12 +00003156
Richard Smithbdad7a22012-01-10 01:33:14 +00003157 if (!Name && ScopedEnumKWLoc.isValid()) {
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003158 // C++0x 7.2p2: The optional identifier shall not be omitted in the
3159 // declaration of a scoped enumeration.
3160 Diag(Tok, diag::err_scoped_enum_missing_identifier);
Richard Smithbdad7a22012-01-10 01:33:14 +00003161 ScopedEnumKWLoc = SourceLocation();
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003162 IsScopedUsingClassTag = false;
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003163 }
3164
John McCall13489672012-05-07 06:16:58 +00003165 // Okay, end the suppression area. We'll decide whether to emit the
3166 // diagnostics in a second.
3167 if (shouldDelayDiagsInTag)
3168 diagsFromTag.done();
Richard Smith1af83c42012-03-23 03:33:32 +00003169
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003170 TypeResult BaseType;
3171
Douglas Gregora61b3e72010-12-01 17:42:47 +00003172 // Parse the fixed underlying type.
Richard Smith139be702012-07-02 19:14:01 +00003173 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
Douglas Gregorb9075602011-02-22 02:55:24 +00003174 if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003175 bool PossibleBitfield = false;
Richard Smith139be702012-07-02 19:14:01 +00003176 if (CanBeBitfield) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003177 // If we're in class scope, this can either be an enum declaration with
3178 // an underlying type, or a declaration of a bitfield member. We try to
3179 // use a simple disambiguation scheme first to catch the common cases
Chad Rosier8decdee2012-06-26 22:30:43 +00003180 // (integer literal, sizeof); if it's still ambiguous, we then consider
3181 // anything that's a simple-type-specifier followed by '(' as an
3182 // expression. This suffices because function types are not valid
Douglas Gregora61b3e72010-12-01 17:42:47 +00003183 // underlying types anyway.
Richard Smith05766812012-08-18 00:55:03 +00003184 EnterExpressionEvaluationContext Unevaluated(Actions,
3185 Sema::ConstantEvaluated);
Douglas Gregora61b3e72010-12-01 17:42:47 +00003186 TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
Chad Rosier8decdee2012-06-26 22:30:43 +00003187 // If the next token starts an expression, we know we're parsing a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003188 // bit-field. This is the common case.
3189 if (TPR == TPResult::True())
3190 PossibleBitfield = true;
3191 // If the next token starts a type-specifier-seq, it may be either a
3192 // a fixed underlying type or the start of a function-style cast in C++;
Chad Rosier8decdee2012-06-26 22:30:43 +00003193 // lookahead one more token to see if it's obvious that we have a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003194 // fixed underlying type.
Chad Rosier8decdee2012-06-26 22:30:43 +00003195 else if (TPR == TPResult::False() &&
Douglas Gregora61b3e72010-12-01 17:42:47 +00003196 GetLookAheadToken(2).getKind() == tok::semi) {
3197 // Consume the ':'.
3198 ConsumeToken();
3199 } else {
3200 // We have the start of a type-specifier-seq, so we have to perform
3201 // tentative parsing to determine whether we have an expression or a
3202 // type.
3203 TentativeParsingAction TPA(*this);
3204
3205 // Consume the ':'.
3206 ConsumeToken();
Richard Smithd81e9612012-02-23 01:36:12 +00003207
3208 // If we see a type specifier followed by an open-brace, we have an
3209 // ambiguity between an underlying type and a C++11 braced
3210 // function-style cast. Resolve this by always treating it as an
3211 // underlying type.
3212 // FIXME: The standard is not entirely clear on how to disambiguate in
3213 // this case.
David Blaikie4e4d0842012-03-11 07:00:24 +00003214 if ((getLangOpts().CPlusPlus &&
Richard Smithd81e9612012-02-23 01:36:12 +00003215 isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
David Blaikie4e4d0842012-03-11 07:00:24 +00003216 (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003217 // We'll parse this as a bitfield later.
3218 PossibleBitfield = true;
3219 TPA.Revert();
3220 } else {
3221 // We have a type-specifier-seq.
3222 TPA.Commit();
3223 }
3224 }
3225 } else {
3226 // Consume the ':'.
3227 ConsumeToken();
3228 }
3229
3230 if (!PossibleBitfield) {
3231 SourceRange Range;
3232 BaseType = ParseTypeName(&Range);
Chad Rosier8decdee2012-06-26 22:30:43 +00003233
David Blaikie4e4d0842012-03-11 07:00:24 +00003234 if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2)
Douglas Gregor86f208c2011-02-22 20:32:04 +00003235 Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
3236 << Range;
David Blaikie4e4d0842012-03-11 07:00:24 +00003237 if (getLangOpts().CPlusPlus0x)
Richard Smith7fe62082011-10-15 05:09:34 +00003238 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
Douglas Gregora61b3e72010-12-01 17:42:47 +00003239 }
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003240 }
3241
Richard Smithbdad7a22012-01-10 01:33:14 +00003242 // There are four options here. If we have 'friend enum foo;' then this is a
3243 // friend declaration, and cannot have an accompanying definition. If we have
3244 // 'enum foo;', then this is a forward declaration. If we have
3245 // 'enum foo {...' then this is a definition. Otherwise we have something
3246 // like 'enum foo xyz', a reference.
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003247 //
3248 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3249 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
3250 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
3251 //
John McCallf312b1e2010-08-26 23:41:50 +00003252 Sema::TagUseKind TUK;
John McCall13489672012-05-07 06:16:58 +00003253 if (!AllowDeclaration) {
Richard Smith7796eb52012-03-12 08:56:40 +00003254 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003255 } else if (Tok.is(tok::l_brace)) {
3256 if (DS.isFriendSpecified()) {
3257 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3258 << SourceRange(DS.getFriendSpecLoc());
3259 ConsumeBrace();
3260 SkipUntil(tok::r_brace);
3261 TUK = Sema::TUK_Friend;
3262 } else {
3263 TUK = Sema::TUK_Definition;
3264 }
Richard Smithc9f35172012-06-25 21:37:02 +00003265 } else if (DSC != DSC_type_specifier &&
3266 (Tok.is(tok::semi) ||
Richard Smith139be702012-07-02 19:14:01 +00003267 (Tok.isAtStartOfLine() &&
3268 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
Richard Smithc9f35172012-06-25 21:37:02 +00003269 TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3270 if (Tok.isNot(tok::semi)) {
3271 // A semicolon was missing after this declaration. Diagnose and recover.
3272 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3273 "enum");
3274 PP.EnterToken(Tok);
3275 Tok.setKind(tok::semi);
3276 }
John McCall13489672012-05-07 06:16:58 +00003277 } else {
John McCallf312b1e2010-08-26 23:41:50 +00003278 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003279 }
3280
3281 // If this is an elaborated type specifier, and we delayed
3282 // diagnostics before, just merge them into the current pool.
3283 if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3284 diagsFromTag.redelay();
3285 }
Richard Smith1af83c42012-03-23 03:33:32 +00003286
3287 MultiTemplateParamsArg TParams;
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003288 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
John McCallf312b1e2010-08-26 23:41:50 +00003289 TUK != Sema::TUK_Reference) {
Richard Smith1af83c42012-03-23 03:33:32 +00003290 if (!getLangOpts().CPlusPlus0x || !SS.isSet()) {
3291 // Skip the rest of this declarator, up until the comma or semicolon.
3292 Diag(Tok, diag::err_enum_template);
3293 SkipUntil(tok::comma, true);
3294 return;
3295 }
3296
3297 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3298 // Enumerations can't be explicitly instantiated.
3299 DS.SetTypeSpecError();
3300 Diag(StartLoc, diag::err_explicit_instantiation_enum);
3301 return;
3302 }
3303
3304 assert(TemplateInfo.TemplateParams && "no template parameters");
3305 TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3306 TemplateInfo.TemplateParams->size());
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003307 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003308
Sean Hunt2edf0a22012-06-23 05:07:58 +00003309 if (TUK == Sema::TUK_Reference)
3310 ProhibitAttributes(attrs);
Richard Smith1af83c42012-03-23 03:33:32 +00003311
Douglas Gregorb9075602011-02-22 02:55:24 +00003312 if (!Name && TUK != Sema::TUK_Definition) {
3313 Diag(Tok, diag::err_enumerator_unnamed_no_def);
Richard Smith1af83c42012-03-23 03:33:32 +00003314
Douglas Gregorb9075602011-02-22 02:55:24 +00003315 // Skip the rest of this declarator, up until the comma or semicolon.
3316 SkipUntil(tok::comma, true);
3317 return;
3318 }
Richard Smith1af83c42012-03-23 03:33:32 +00003319
Douglas Gregor402abb52009-05-28 23:31:59 +00003320 bool Owned = false;
John McCallc4e70192009-09-11 04:59:25 +00003321 bool IsDependent = false;
Douglas Gregor48c89f42010-04-24 16:38:41 +00003322 const char *PrevSpec = 0;
3323 unsigned DiagID;
John McCalld226f652010-08-21 09:40:31 +00003324 Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
John McCall7f040a92010-12-24 02:08:15 +00003325 StartLoc, SS, Name, NameLoc, attrs.getList(),
Richard Smith1af83c42012-03-23 03:33:32 +00003326 AS, DS.getModulePrivateSpecLoc(), TParams,
Richard Smithbdad7a22012-01-10 01:33:14 +00003327 Owned, IsDependent, ScopedEnumKWLoc,
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003328 IsScopedUsingClassTag, BaseType);
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003329
Douglas Gregor48c89f42010-04-24 16:38:41 +00003330 if (IsDependent) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003331 // This enum has a dependent nested-name-specifier. Handle it as a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003332 // dependent tag.
3333 if (!Name) {
3334 DS.SetTypeSpecError();
3335 Diag(Tok, diag::err_expected_type_name_after_typename);
3336 return;
3337 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003338
Douglas Gregor23c94db2010-07-02 17:43:08 +00003339 TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
Chad Rosier8decdee2012-06-26 22:30:43 +00003340 TUK, SS, Name, StartLoc,
Douglas Gregor48c89f42010-04-24 16:38:41 +00003341 NameLoc);
3342 if (Type.isInvalid()) {
3343 DS.SetTypeSpecError();
3344 return;
3345 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003346
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003347 if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3348 NameLoc.isValid() ? NameLoc : StartLoc,
3349 PrevSpec, DiagID, Type.get()))
Douglas Gregor48c89f42010-04-24 16:38:41 +00003350 Diag(StartLoc, DiagID) << PrevSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00003351
Douglas Gregor48c89f42010-04-24 16:38:41 +00003352 return;
3353 }
Mike Stump1eb44332009-09-09 15:08:12 +00003354
John McCalld226f652010-08-21 09:40:31 +00003355 if (!TagDecl) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003356 // The action failed to produce an enumeration tag. If this is a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003357 // definition, consume the entire definition.
Richard Smith7796eb52012-03-12 08:56:40 +00003358 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
Douglas Gregor48c89f42010-04-24 16:38:41 +00003359 ConsumeBrace();
3360 SkipUntil(tok::r_brace);
3361 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003362
Douglas Gregor48c89f42010-04-24 16:38:41 +00003363 DS.SetTypeSpecError();
3364 return;
3365 }
Richard Smithbdad7a22012-01-10 01:33:14 +00003366
Richard Smithc9f35172012-06-25 21:37:02 +00003367 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
John McCall13489672012-05-07 06:16:58 +00003368 ParseEnumBody(StartLoc, TagDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00003369
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003370 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3371 NameLoc.isValid() ? NameLoc : StartLoc,
3372 PrevSpec, DiagID, TagDecl, Owned))
John McCallfec54012009-08-03 20:12:06 +00003373 Diag(StartLoc, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003374}
3375
3376/// ParseEnumBody - Parse a {} enclosed enumerator-list.
3377/// enumerator-list:
3378/// enumerator
3379/// enumerator-list ',' enumerator
3380/// enumerator:
3381/// enumeration-constant
3382/// enumeration-constant '=' constant-expression
3383/// enumeration-constant:
3384/// identifier
3385///
John McCalld226f652010-08-21 09:40:31 +00003386void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Douglas Gregor074149e2009-01-05 19:45:36 +00003387 // Enter the scope of the enum body and start the definition.
3388 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003389 Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
Douglas Gregor074149e2009-01-05 19:45:36 +00003390
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003391 BalancedDelimiterTracker T(*this, tok::l_brace);
3392 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00003393
Chris Lattner7946dd32007-08-27 17:24:30 +00003394 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
David Blaikie4e4d0842012-03-11 07:00:24 +00003395 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
Fariborz Jahanian05115522010-05-28 22:23:22 +00003396 Diag(Tok, diag::error_empty_enum);
Mike Stump1eb44332009-09-09 15:08:12 +00003397
Chris Lattner5f9e2722011-07-23 10:55:15 +00003398 SmallVector<Decl *, 32> EnumConstantDecls;
Reid Spencer5f016e22007-07-11 17:01:13 +00003399
John McCalld226f652010-08-21 09:40:31 +00003400 Decl *LastEnumConstDecl = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00003401
Reid Spencer5f016e22007-07-11 17:01:13 +00003402 // Parse the enumerator-list.
Chris Lattner04d66662007-10-09 17:33:22 +00003403 while (Tok.is(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003404 IdentifierInfo *Ident = Tok.getIdentifierInfo();
3405 SourceLocation IdentLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003406
John McCall5b629aa2010-10-22 23:36:17 +00003407 // If attributes exist after the enumerator, parse them.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003408 ParsedAttributesWithRange attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003409 MaybeParseGNUAttributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003410 MaybeParseCXX0XAttributes(attrs);
3411 ProhibitAttributes(attrs);
John McCall5b629aa2010-10-22 23:36:17 +00003412
Reid Spencer5f016e22007-07-11 17:01:13 +00003413 SourceLocation EqualLoc;
John McCall60d7b3a2010-08-24 06:29:42 +00003414 ExprResult AssignedVal;
John McCall92576642012-05-07 06:16:41 +00003415 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
Chad Rosier8decdee2012-06-26 22:30:43 +00003416
Chris Lattner04d66662007-10-09 17:33:22 +00003417 if (Tok.is(tok::equal)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003418 EqualLoc = ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00003419 AssignedVal = ParseConstantExpression();
3420 if (AssignedVal.isInvalid())
Reid Spencer5f016e22007-07-11 17:01:13 +00003421 SkipUntil(tok::comma, tok::r_brace, true, true);
Reid Spencer5f016e22007-07-11 17:01:13 +00003422 }
Mike Stump1eb44332009-09-09 15:08:12 +00003423
Reid Spencer5f016e22007-07-11 17:01:13 +00003424 // Install the enumerator constant into EnumDecl.
John McCalld226f652010-08-21 09:40:31 +00003425 Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3426 LastEnumConstDecl,
3427 IdentLoc, Ident,
John McCall7f040a92010-12-24 02:08:15 +00003428 attrs.getList(), EqualLoc,
John McCalld226f652010-08-21 09:40:31 +00003429 AssignedVal.release());
Fariborz Jahanian5a477db2011-12-09 01:15:54 +00003430 PD.complete(EnumConstDecl);
Chad Rosier8decdee2012-06-26 22:30:43 +00003431
Reid Spencer5f016e22007-07-11 17:01:13 +00003432 EnumConstantDecls.push_back(EnumConstDecl);
3433 LastEnumConstDecl = EnumConstDecl;
Mike Stump1eb44332009-09-09 15:08:12 +00003434
Douglas Gregor751f6922010-09-07 14:51:08 +00003435 if (Tok.is(tok::identifier)) {
3436 // We're missing a comma between enumerators.
3437 SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
Chad Rosier8decdee2012-06-26 22:30:43 +00003438 Diag(Loc, diag::err_enumerator_list_missing_comma)
Douglas Gregor751f6922010-09-07 14:51:08 +00003439 << FixItHint::CreateInsertion(Loc, ", ");
3440 continue;
3441 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003442
Chris Lattner04d66662007-10-09 17:33:22 +00003443 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +00003444 break;
3445 SourceLocation CommaLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003446
Richard Smith7fe62082011-10-15 05:09:34 +00003447 if (Tok.isNot(tok::identifier)) {
David Blaikie4e4d0842012-03-11 07:00:24 +00003448 if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x)
Richard Smitheab9d6f2012-07-23 05:45:25 +00003449 Diag(CommaLoc, getLangOpts().CPlusPlus ?
3450 diag::ext_enumerator_list_comma_cxx :
3451 diag::ext_enumerator_list_comma_c)
Richard Smith7fe62082011-10-15 05:09:34 +00003452 << FixItHint::CreateRemoval(CommaLoc);
David Blaikie4e4d0842012-03-11 07:00:24 +00003453 else if (getLangOpts().CPlusPlus0x)
Richard Smith7fe62082011-10-15 05:09:34 +00003454 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3455 << FixItHint::CreateRemoval(CommaLoc);
3456 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003457 }
Mike Stump1eb44332009-09-09 15:08:12 +00003458
Reid Spencer5f016e22007-07-11 17:01:13 +00003459 // Eat the }.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003460 T.consumeClose();
Reid Spencer5f016e22007-07-11 17:01:13 +00003461
Reid Spencer5f016e22007-07-11 17:01:13 +00003462 // If attributes exist after the identifier list, parse them.
John McCall0b7e6782011-03-24 11:26:52 +00003463 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003464 MaybeParseGNUAttributes(attrs);
Douglas Gregor72de6672009-01-08 20:45:30 +00003465
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003466 Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
3467 EnumDecl, EnumConstantDecls.data(),
3468 EnumConstantDecls.size(), getCurScope(),
3469 attrs.getList());
Mike Stump1eb44332009-09-09 15:08:12 +00003470
Douglas Gregor72de6672009-01-08 20:45:30 +00003471 EnumScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003472 Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3473 T.getCloseLocation());
Richard Smithc9f35172012-06-25 21:37:02 +00003474
3475 // The next token must be valid after an enum definition. If not, a ';'
3476 // was probably forgotten.
Richard Smith139be702012-07-02 19:14:01 +00003477 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3478 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
Richard Smithc9f35172012-06-25 21:37:02 +00003479 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3480 // Push this token back into the preprocessor and change our current token
3481 // to ';' so that the rest of the code recovers as though there were an
3482 // ';' after the definition.
3483 PP.EnterToken(Tok);
3484 Tok.setKind(tok::semi);
3485 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003486}
3487
3488/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff5f8aa692008-02-11 23:15:56 +00003489/// start of a type-qualifier-list.
3490bool Parser::isTypeQualifier() const {
3491 switch (Tok.getKind()) {
3492 default: return false;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003493
3494 // type-qualifier only in OpenCL
3495 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003496 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003497
Steve Naroff5f8aa692008-02-11 23:15:56 +00003498 // type-qualifier
3499 case tok::kw_const:
3500 case tok::kw_volatile:
3501 case tok::kw_restrict:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003502 case tok::kw___private:
3503 case tok::kw___local:
3504 case tok::kw___global:
3505 case tok::kw___constant:
3506 case tok::kw___read_only:
3507 case tok::kw___read_write:
3508 case tok::kw___write_only:
Steve Naroff5f8aa692008-02-11 23:15:56 +00003509 return true;
3510 }
3511}
3512
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003513/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3514/// is definitely a type-specifier. Return false if it isn't part of a type
3515/// specifier or if we're not sure.
3516bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3517 switch (Tok.getKind()) {
3518 default: return false;
3519 // type-specifiers
3520 case tok::kw_short:
3521 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003522 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003523 case tok::kw___int128:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003524 case tok::kw_signed:
3525 case tok::kw_unsigned:
3526 case tok::kw__Complex:
3527 case tok::kw__Imaginary:
3528 case tok::kw_void:
3529 case tok::kw_char:
3530 case tok::kw_wchar_t:
3531 case tok::kw_char16_t:
3532 case tok::kw_char32_t:
3533 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003534 case tok::kw_half:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003535 case tok::kw_float:
3536 case tok::kw_double:
3537 case tok::kw_bool:
3538 case tok::kw__Bool:
3539 case tok::kw__Decimal32:
3540 case tok::kw__Decimal64:
3541 case tok::kw__Decimal128:
3542 case tok::kw___vector:
Chad Rosier8decdee2012-06-26 22:30:43 +00003543
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003544 // struct-or-union-specifier (C99) or class-specifier (C++)
3545 case tok::kw_class:
3546 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00003547 case tok::kw___interface:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003548 case tok::kw_union:
3549 // enum-specifier
3550 case tok::kw_enum:
Chad Rosier8decdee2012-06-26 22:30:43 +00003551
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003552 // typedef-name
3553 case tok::annot_typename:
3554 return true;
3555 }
3556}
3557
Steve Naroff5f8aa692008-02-11 23:15:56 +00003558/// isTypeSpecifierQualifier - Return true if the current token could be the
Reid Spencer5f016e22007-07-11 17:01:13 +00003559/// start of a specifier-qualifier-list.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003560bool Parser::isTypeSpecifierQualifier() {
Reid Spencer5f016e22007-07-11 17:01:13 +00003561 switch (Tok.getKind()) {
3562 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003563
Chris Lattner166a8fc2009-01-04 23:41:41 +00003564 case tok::identifier: // foo::bar
John Thompson82287d12010-02-05 00:12:22 +00003565 if (TryAltiVecVectorToken())
3566 return true;
3567 // Fall through.
Douglas Gregord57959a2009-03-27 23:10:48 +00003568 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00003569 // Annotate typenames and C++ scope specifiers. If we get one, just
3570 // recurse to handle whatever we get.
3571 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003572 return true;
3573 if (Tok.is(tok::identifier))
3574 return false;
3575 return isTypeSpecifierQualifier();
Douglas Gregord57959a2009-03-27 23:10:48 +00003576
Chris Lattner166a8fc2009-01-04 23:41:41 +00003577 case tok::coloncolon: // ::foo::bar
3578 if (NextToken().is(tok::kw_new) || // ::new
3579 NextToken().is(tok::kw_delete)) // ::delete
3580 return false;
3581
Chris Lattner166a8fc2009-01-04 23:41:41 +00003582 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003583 return true;
3584 return isTypeSpecifierQualifier();
Mike Stump1eb44332009-09-09 15:08:12 +00003585
Reid Spencer5f016e22007-07-11 17:01:13 +00003586 // GNU attributes support.
3587 case tok::kw___attribute:
Steve Naroffd1861fd2007-07-31 12:34:36 +00003588 // GNU typeof support.
3589 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00003590
Reid Spencer5f016e22007-07-11 17:01:13 +00003591 // type-specifiers
3592 case tok::kw_short:
3593 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003594 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003595 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00003596 case tok::kw_signed:
3597 case tok::kw_unsigned:
3598 case tok::kw__Complex:
3599 case tok::kw__Imaginary:
3600 case tok::kw_void:
3601 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00003602 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003603 case tok::kw_char16_t:
3604 case tok::kw_char32_t:
Reid Spencer5f016e22007-07-11 17:01:13 +00003605 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003606 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00003607 case tok::kw_float:
3608 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00003609 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00003610 case tok::kw__Bool:
3611 case tok::kw__Decimal32:
3612 case tok::kw__Decimal64:
3613 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00003614 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00003615
Chris Lattner99dc9142008-04-13 18:59:07 +00003616 // struct-or-union-specifier (C99) or class-specifier (C++)
3617 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00003618 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00003619 case tok::kw___interface:
Reid Spencer5f016e22007-07-11 17:01:13 +00003620 case tok::kw_union:
3621 // enum-specifier
3622 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00003623
Reid Spencer5f016e22007-07-11 17:01:13 +00003624 // type-qualifier
3625 case tok::kw_const:
3626 case tok::kw_volatile:
3627 case tok::kw_restrict:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003628
3629 // typedef-name
Chris Lattnerb31757b2009-01-06 05:06:21 +00003630 case tok::annot_typename:
Reid Spencer5f016e22007-07-11 17:01:13 +00003631 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00003632
Chris Lattner7c186be2008-10-20 00:25:30 +00003633 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3634 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00003635 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00003636
Steve Naroff239f0732008-12-25 14:16:32 +00003637 case tok::kw___cdecl:
3638 case tok::kw___stdcall:
3639 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003640 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00003641 case tok::kw___w64:
3642 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003643 case tok::kw___ptr32:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003644 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003645 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003646
3647 case tok::kw___private:
3648 case tok::kw___local:
3649 case tok::kw___global:
3650 case tok::kw___constant:
3651 case tok::kw___read_only:
3652 case tok::kw___read_write:
3653 case tok::kw___write_only:
3654
Eli Friedman290eeb02009-06-08 23:27:34 +00003655 return true;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003656
3657 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003658 return getLangOpts().OpenCL;
Eli Friedmanb001de72011-10-06 23:00:33 +00003659
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00003660 // C11 _Atomic()
Eli Friedmanb001de72011-10-06 23:00:33 +00003661 case tok::kw__Atomic:
3662 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00003663 }
3664}
3665
3666/// isDeclarationSpecifier() - Return true if the current token is part of a
3667/// declaration specifier.
Douglas Gregor9497a732010-09-16 01:51:54 +00003668///
3669/// \param DisambiguatingWithExpression True to indicate that the purpose of
3670/// this check is to disambiguate between an expression and a declaration.
3671bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003672 switch (Tok.getKind()) {
3673 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003674
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003675 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003676 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003677
Chris Lattner166a8fc2009-01-04 23:41:41 +00003678 case tok::identifier: // foo::bar
Steve Naroff61f72cb2009-03-09 21:12:44 +00003679 // Unfortunate hack to support "Class.factoryMethod" notation.
David Blaikie4e4d0842012-03-11 07:00:24 +00003680 if (getLangOpts().ObjC1 && NextToken().is(tok::period))
Steve Naroff61f72cb2009-03-09 21:12:44 +00003681 return false;
John Thompson82287d12010-02-05 00:12:22 +00003682 if (TryAltiVecVectorToken())
3683 return true;
3684 // Fall through.
David Blaikie42d6d0c2011-12-04 05:04:18 +00003685 case tok::kw_decltype: // decltype(T())::type
Douglas Gregord57959a2009-03-27 23:10:48 +00003686 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00003687 // Annotate typenames and C++ scope specifiers. If we get one, just
3688 // recurse to handle whatever we get.
3689 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003690 return true;
3691 if (Tok.is(tok::identifier))
3692 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00003693
Douglas Gregor9497a732010-09-16 01:51:54 +00003694 // If we're in Objective-C and we have an Objective-C class type followed
Chad Rosier8decdee2012-06-26 22:30:43 +00003695 // by an identifier and then either ':' or ']', in a place where an
Douglas Gregor9497a732010-09-16 01:51:54 +00003696 // expression is permitted, then this is probably a class message send
3697 // missing the initial '['. In this case, we won't consider this to be
3698 // the start of a declaration.
Chad Rosier8decdee2012-06-26 22:30:43 +00003699 if (DisambiguatingWithExpression &&
Douglas Gregor9497a732010-09-16 01:51:54 +00003700 isStartOfObjCClassMessageMissingOpenBracket())
3701 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00003702
John McCall9ba61662010-02-26 08:45:28 +00003703 return isDeclarationSpecifier();
3704
Chris Lattner166a8fc2009-01-04 23:41:41 +00003705 case tok::coloncolon: // ::foo::bar
3706 if (NextToken().is(tok::kw_new) || // ::new
3707 NextToken().is(tok::kw_delete)) // ::delete
3708 return false;
Mike Stump1eb44332009-09-09 15:08:12 +00003709
Chris Lattner166a8fc2009-01-04 23:41:41 +00003710 // Annotate typenames and C++ scope specifiers. If we get one, just
3711 // recurse to handle whatever we get.
3712 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00003713 return true;
3714 return isDeclarationSpecifier();
Mike Stump1eb44332009-09-09 15:08:12 +00003715
Reid Spencer5f016e22007-07-11 17:01:13 +00003716 // storage-class-specifier
3717 case tok::kw_typedef:
3718 case tok::kw_extern:
Steve Naroff8d54bf22007-12-18 00:16:02 +00003719 case tok::kw___private_extern__:
Reid Spencer5f016e22007-07-11 17:01:13 +00003720 case tok::kw_static:
3721 case tok::kw_auto:
3722 case tok::kw_register:
3723 case tok::kw___thread:
Mike Stump1eb44332009-09-09 15:08:12 +00003724
Douglas Gregor8d267c52011-09-09 02:06:17 +00003725 // Modules
3726 case tok::kw___module_private__:
Chad Rosier8decdee2012-06-26 22:30:43 +00003727
Reid Spencer5f016e22007-07-11 17:01:13 +00003728 // type-specifiers
3729 case tok::kw_short:
3730 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003731 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003732 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00003733 case tok::kw_signed:
3734 case tok::kw_unsigned:
3735 case tok::kw__Complex:
3736 case tok::kw__Imaginary:
3737 case tok::kw_void:
3738 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00003739 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003740 case tok::kw_char16_t:
3741 case tok::kw_char32_t:
3742
Reid Spencer5f016e22007-07-11 17:01:13 +00003743 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003744 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00003745 case tok::kw_float:
3746 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00003747 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00003748 case tok::kw__Bool:
3749 case tok::kw__Decimal32:
3750 case tok::kw__Decimal64:
3751 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00003752 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00003753
Chris Lattner99dc9142008-04-13 18:59:07 +00003754 // struct-or-union-specifier (C99) or class-specifier (C++)
3755 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00003756 case tok::kw_struct:
3757 case tok::kw_union:
Joao Matos6666ed42012-08-31 18:45:21 +00003758 case tok::kw___interface:
Reid Spencer5f016e22007-07-11 17:01:13 +00003759 // enum-specifier
3760 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00003761
Reid Spencer5f016e22007-07-11 17:01:13 +00003762 // type-qualifier
3763 case tok::kw_const:
3764 case tok::kw_volatile:
3765 case tok::kw_restrict:
Steve Naroffd1861fd2007-07-31 12:34:36 +00003766
Reid Spencer5f016e22007-07-11 17:01:13 +00003767 // function-specifier
3768 case tok::kw_inline:
Douglas Gregorb48fe382008-10-31 09:07:45 +00003769 case tok::kw_virtual:
3770 case tok::kw_explicit:
Chris Lattnerd6c7c182007-08-09 16:40:21 +00003771
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00003772 // static_assert-declaration
3773 case tok::kw__Static_assert:
3774
Chris Lattner1ef08762007-08-09 17:01:07 +00003775 // GNU typeof support.
3776 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00003777
Chris Lattner1ef08762007-08-09 17:01:07 +00003778 // GNU attributes.
Chris Lattnerd6c7c182007-08-09 16:40:21 +00003779 case tok::kw___attribute:
Reid Spencer5f016e22007-07-11 17:01:13 +00003780 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00003781
Francois Pichete3d49b42011-06-19 08:02:06 +00003782 // C++0x decltype.
David Blaikie42d6d0c2011-12-04 05:04:18 +00003783 case tok::annot_decltype:
Francois Pichete3d49b42011-06-19 08:02:06 +00003784 return true;
3785
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00003786 // C11 _Atomic()
Eli Friedmanb001de72011-10-06 23:00:33 +00003787 case tok::kw__Atomic:
3788 return true;
3789
Chris Lattnerf3948c42008-07-26 03:38:44 +00003790 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3791 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00003792 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00003793
Douglas Gregord9d75e52011-04-27 05:41:15 +00003794 // typedef-name
3795 case tok::annot_typename:
3796 return !DisambiguatingWithExpression ||
3797 !isStartOfObjCClassMessageMissingOpenBracket();
Chad Rosier8decdee2012-06-26 22:30:43 +00003798
Steve Naroff47f52092009-01-06 19:34:12 +00003799 case tok::kw___declspec:
Steve Naroff239f0732008-12-25 14:16:32 +00003800 case tok::kw___cdecl:
3801 case tok::kw___stdcall:
3802 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003803 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00003804 case tok::kw___w64:
3805 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003806 case tok::kw___ptr32:
Eli Friedman290eeb02009-06-08 23:27:34 +00003807 case tok::kw___forceinline:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003808 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003809 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003810
3811 case tok::kw___private:
3812 case tok::kw___local:
3813 case tok::kw___global:
3814 case tok::kw___constant:
3815 case tok::kw___read_only:
3816 case tok::kw___read_write:
3817 case tok::kw___write_only:
3818
Eli Friedman290eeb02009-06-08 23:27:34 +00003819 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00003820 }
3821}
3822
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003823bool Parser::isConstructorDeclarator() {
3824 TentativeParsingAction TPA(*this);
3825
3826 // Parse the C++ scope specifier.
3827 CXXScopeSpec SS;
Chad Rosier8decdee2012-06-26 22:30:43 +00003828 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00003829 /*EnteringContext=*/true)) {
John McCall9ba61662010-02-26 08:45:28 +00003830 TPA.Revert();
3831 return false;
3832 }
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003833
3834 // Parse the constructor name.
3835 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
3836 // We already know that we have a constructor name; just consume
3837 // the token.
3838 ConsumeToken();
3839 } else {
3840 TPA.Revert();
3841 return false;
3842 }
3843
Richard Smith22592862012-03-27 23:05:05 +00003844 // Current class name must be followed by a left parenthesis.
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003845 if (Tok.isNot(tok::l_paren)) {
3846 TPA.Revert();
3847 return false;
3848 }
3849 ConsumeParen();
3850
Richard Smith22592862012-03-27 23:05:05 +00003851 // A right parenthesis, or ellipsis followed by a right parenthesis signals
3852 // that we have a constructor.
3853 if (Tok.is(tok::r_paren) ||
3854 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003855 TPA.Revert();
3856 return true;
3857 }
3858
3859 // If we need to, enter the specified scope.
3860 DeclaratorScopeObj DeclScopeObj(*this, SS);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003861 if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003862 DeclScopeObj.EnterDeclaratorScope();
3863
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00003864 // Optionally skip Microsoft attributes.
John McCall0b7e6782011-03-24 11:26:52 +00003865 ParsedAttributes Attrs(AttrFactory);
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00003866 MaybeParseMicrosoftAttributes(Attrs);
3867
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003868 // Check whether the next token(s) are part of a declaration
3869 // specifier, in which case we have the start of a parameter and,
3870 // therefore, we know that this is a constructor.
Richard Smith412e0cc2012-03-27 00:56:56 +00003871 bool IsConstructor = false;
3872 if (isDeclarationSpecifier())
3873 IsConstructor = true;
3874 else if (Tok.is(tok::identifier) ||
3875 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
3876 // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
3877 // This might be a parenthesized member name, but is more likely to
3878 // be a constructor declaration with an invalid argument type. Keep
3879 // looking.
3880 if (Tok.is(tok::annot_cxxscope))
3881 ConsumeToken();
3882 ConsumeToken();
3883
3884 // If this is not a constructor, we must be parsing a declarator,
Richard Smith5d8388c2012-03-27 01:42:32 +00003885 // which must have one of the following syntactic forms (see the
3886 // grammar extract at the start of ParseDirectDeclarator):
Richard Smith412e0cc2012-03-27 00:56:56 +00003887 switch (Tok.getKind()) {
3888 case tok::l_paren:
3889 // C(X ( int));
3890 case tok::l_square:
3891 // C(X [ 5]);
3892 // C(X [ [attribute]]);
3893 case tok::coloncolon:
3894 // C(X :: Y);
3895 // C(X :: *p);
3896 case tok::r_paren:
3897 // C(X )
3898 // Assume this isn't a constructor, rather than assuming it's a
3899 // constructor with an unnamed parameter of an ill-formed type.
3900 break;
3901
3902 default:
3903 IsConstructor = true;
3904 break;
3905 }
3906 }
3907
Douglas Gregor0efc2c12010-01-13 17:31:36 +00003908 TPA.Revert();
3909 return IsConstructor;
3910}
Reid Spencer5f016e22007-07-11 17:01:13 +00003911
3912/// ParseTypeQualifierListOpt
Dawn Perchik52fc3142010-09-03 01:29:35 +00003913/// type-qualifier-list: [C99 6.7.5]
3914/// type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00003915/// [vendor] attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00003916/// [ only if VendorAttributesAllowed=true ]
3917/// type-qualifier-list type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00003918/// [vendor] type-qualifier-list attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00003919/// [ only if VendorAttributesAllowed=true ]
3920/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
3921/// [ only if CXX0XAttributesAllowed=true ]
3922/// Note: vendor can be GNU, MS, etc.
Reid Spencer5f016e22007-07-11 17:01:13 +00003923///
Dawn Perchik52fc3142010-09-03 01:29:35 +00003924void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
3925 bool VendorAttributesAllowed,
Richard Smithc56298d2012-04-10 03:25:07 +00003926 bool CXX11AttributesAllowed) {
3927 if (getLangOpts().CPlusPlus0x && CXX11AttributesAllowed &&
Richard Smith6ee326a2012-04-10 01:32:12 +00003928 isCXX11AttributeSpecifier()) {
John McCall0b7e6782011-03-24 11:26:52 +00003929 ParsedAttributesWithRange attrs(AttrFactory);
Richard Smithc56298d2012-04-10 03:25:07 +00003930 ParseCXX11Attributes(attrs);
Richard Smith6ee326a2012-04-10 01:32:12 +00003931 DS.takeAttributesFrom(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00003932 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00003933
3934 SourceLocation EndLoc;
3935
Reid Spencer5f016e22007-07-11 17:01:13 +00003936 while (1) {
John McCallfec54012009-08-03 20:12:06 +00003937 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00003938 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00003939 unsigned DiagID = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +00003940 SourceLocation Loc = Tok.getLocation();
3941
3942 switch (Tok.getKind()) {
Douglas Gregor1a480c42010-08-27 17:35:51 +00003943 case tok::code_completion:
3944 Actions.CodeCompleteTypeQualifiers(DS);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00003945 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00003946
Reid Spencer5f016e22007-07-11 17:01:13 +00003947 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00003948 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00003949 getLangOpts(), /*IsTypeSpec*/false);
Reid Spencer5f016e22007-07-11 17:01:13 +00003950 break;
3951 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00003952 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00003953 getLangOpts(), /*IsTypeSpec*/false);
Reid Spencer5f016e22007-07-11 17:01:13 +00003954 break;
3955 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00003956 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smith42926a02012-07-24 20:24:58 +00003957 getLangOpts(), /*IsTypeSpec*/false);
Reid Spencer5f016e22007-07-11 17:01:13 +00003958 break;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003959
3960 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00003961 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003962 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003963 goto DoneWithTypeQuals;
3964 case tok::kw___private:
3965 case tok::kw___global:
3966 case tok::kw___local:
3967 case tok::kw___constant:
3968 case tok::kw___read_only:
3969 case tok::kw___write_only:
3970 case tok::kw___read_write:
3971 ParseOpenCLQualifiers(DS);
3972 break;
3973
Eli Friedman290eeb02009-06-08 23:27:34 +00003974 case tok::kw___w64:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00003975 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00003976 case tok::kw___ptr32:
Steve Naroff239f0732008-12-25 14:16:32 +00003977 case tok::kw___cdecl:
3978 case tok::kw___stdcall:
3979 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00003980 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00003981 case tok::kw___unaligned:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003982 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003983 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00003984 continue;
3985 }
3986 goto DoneWithTypeQuals;
Dawn Perchik52fc3142010-09-03 01:29:35 +00003987 case tok::kw___pascal:
3988 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003989 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00003990 continue;
3991 }
3992 goto DoneWithTypeQuals;
Reid Spencer5f016e22007-07-11 17:01:13 +00003993 case tok::kw___attribute:
Dawn Perchik52fc3142010-09-03 01:29:35 +00003994 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00003995 ParseGNUAttributes(DS.getAttributes());
Chris Lattner5a69d1c2008-12-18 07:02:59 +00003996 continue; // do *not* consume the next token!
3997 }
3998 // otherwise, FALL THROUGH!
3999 default:
Steve Naroff239f0732008-12-25 14:16:32 +00004000 DoneWithTypeQuals:
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004001 // If this is not a type-qualifier token, we're done reading type
4002 // qualifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00004003 DS.Finish(Diags, PP);
Abramo Bagnara796aa442011-03-12 11:17:06 +00004004 if (EndLoc.isValid())
4005 DS.SetRangeEnd(EndLoc);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004006 return;
Reid Spencer5f016e22007-07-11 17:01:13 +00004007 }
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004008
Reid Spencer5f016e22007-07-11 17:01:13 +00004009 // If the specifier combination wasn't legal, issue a diagnostic.
4010 if (isInvalid) {
4011 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +00004012 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00004013 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00004014 EndLoc = ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00004015 }
4016}
4017
4018
4019/// ParseDeclarator - Parse and verify a newly-initialized declarator.
4020///
4021void Parser::ParseDeclarator(Declarator &D) {
4022 /// This implements the 'declarator' production in the C grammar, then checks
4023 /// for well-formedness and issues diagnostics.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004024 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Reid Spencer5f016e22007-07-11 17:01:13 +00004025}
4026
Richard Smith9988f282012-03-29 01:16:42 +00004027static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
4028 if (Kind == tok::star || Kind == tok::caret)
4029 return true;
4030
4031 // We parse rvalue refs in C++03, because otherwise the errors are scary.
4032 if (!Lang.CPlusPlus)
4033 return false;
4034
4035 return Kind == tok::amp || Kind == tok::ampamp;
4036}
4037
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004038/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
4039/// is parsed by the function passed to it. Pass null, and the direct-declarator
4040/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004041/// ptr-operator production.
4042///
Richard Smith0706df42011-10-19 21:33:05 +00004043/// If the grammar of this construct is extended, matching changes must also be
Richard Smith5d8388c2012-03-27 01:42:32 +00004044/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
4045/// isConstructorDeclarator.
Richard Smith0706df42011-10-19 21:33:05 +00004046///
Sebastian Redlf30208a2009-01-24 21:16:55 +00004047/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
4048/// [C] pointer[opt] direct-declarator
4049/// [C++] direct-declarator
4050/// [C++] ptr-operator declarator
Reid Spencer5f016e22007-07-11 17:01:13 +00004051///
4052/// pointer: [C99 6.7.5]
4053/// '*' type-qualifier-list[opt]
4054/// '*' type-qualifier-list[opt] pointer
4055///
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004056/// ptr-operator:
4057/// '*' cv-qualifier-seq[opt]
4058/// '&'
Sebastian Redl05532f22009-03-15 22:02:01 +00004059/// [C++0x] '&&'
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004060/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redl05532f22009-03-15 22:02:01 +00004061/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redlf30208a2009-01-24 21:16:55 +00004062/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004063void Parser::ParseDeclaratorInternal(Declarator &D,
4064 DirectDeclParseFunction DirectDeclParser) {
Douglas Gregor91a28862009-08-26 14:27:30 +00004065 if (Diags.hasAllExtensionsSilenced())
4066 D.setExtension();
Chad Rosier8decdee2012-06-26 22:30:43 +00004067
Sebastian Redlf30208a2009-01-24 21:16:55 +00004068 // C++ member pointers start with a '::' or a nested-name.
4069 // Member pointers get special handling, since there's no place for the
4070 // scope spec in the generic path below.
David Blaikie4e4d0842012-03-11 07:00:24 +00004071 if (getLangOpts().CPlusPlus &&
Chris Lattnerf919bfe2009-03-24 17:04:48 +00004072 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
4073 Tok.is(tok::annot_cxxscope))) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004074 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4075 D.getContext() == Declarator::MemberContext;
Sebastian Redlf30208a2009-01-24 21:16:55 +00004076 CXXScopeSpec SS;
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004077 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004078
Jeffrey Yasskinedc28772010-04-07 23:29:58 +00004079 if (SS.isNotEmpty()) {
Mike Stump1eb44332009-09-09 15:08:12 +00004080 if (Tok.isNot(tok::star)) {
Sebastian Redlf30208a2009-01-24 21:16:55 +00004081 // The scope spec really belongs to the direct-declarator.
4082 D.getCXXScopeSpec() = SS;
4083 if (DirectDeclParser)
4084 (this->*DirectDeclParser)(D);
4085 return;
4086 }
4087
4088 SourceLocation Loc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00004089 D.SetRangeEnd(Loc);
John McCall0b7e6782011-03-24 11:26:52 +00004090 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004091 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004092 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004093
4094 // Recurse to parse whatever is left.
4095 ParseDeclaratorInternal(D, DirectDeclParser);
4096
4097 // Sema will have to catch (syntactically invalid) pointers into global
4098 // scope. It has to catch pointers into namespace scope anyway.
4099 D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004100 Loc),
4101 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004102 /* Don't replace range end. */SourceLocation());
Sebastian Redlf30208a2009-01-24 21:16:55 +00004103 return;
4104 }
4105 }
4106
4107 tok::TokenKind Kind = Tok.getKind();
Steve Naroff5618bd42008-08-27 16:04:49 +00004108 // Not a pointer, C++ reference, or block.
Richard Smith9988f282012-03-29 01:16:42 +00004109 if (!isPtrOperatorToken(Kind, getLangOpts())) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004110 if (DirectDeclParser)
4111 (this->*DirectDeclParser)(D);
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004112 return;
4113 }
Sebastian Redlf30208a2009-01-24 21:16:55 +00004114
Sebastian Redl05532f22009-03-15 22:02:01 +00004115 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4116 // '&&' -> rvalue reference
Sebastian Redl743de1f2009-03-23 00:00:23 +00004117 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redlab197ba2009-02-09 18:23:29 +00004118 D.SetRangeEnd(Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +00004119
Chris Lattner9af55002009-03-27 04:18:06 +00004120 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner76549142008-02-21 01:32:26 +00004121 // Is a pointer.
John McCall0b7e6782011-03-24 11:26:52 +00004122 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004123
Richard Smith6ee326a2012-04-10 01:32:12 +00004124 // FIXME: GNU attributes are not allowed here in a new-type-id.
Reid Spencer5f016e22007-07-11 17:01:13 +00004125 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004126 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004127
Reid Spencer5f016e22007-07-11 17:01:13 +00004128 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004129 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff5618bd42008-08-27 16:04:49 +00004130 if (Kind == tok::star)
4131 // Remember that we parsed a pointer type, and remember the type-quals.
4132 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
Chandler Carruthd067c072011-02-23 18:51:59 +00004133 DS.getConstSpecLoc(),
4134 DS.getVolatileSpecLoc(),
John McCall0b7e6782011-03-24 11:26:52 +00004135 DS.getRestrictSpecLoc()),
4136 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004137 SourceLocation());
Steve Naroff5618bd42008-08-27 16:04:49 +00004138 else
4139 // Remember that we parsed a Block type, and remember the type-quals.
Mike Stump1eb44332009-09-09 15:08:12 +00004140 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004141 Loc),
4142 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004143 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004144 } else {
4145 // Is a reference
John McCall0b7e6782011-03-24 11:26:52 +00004146 DeclSpec DS(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00004147
Sebastian Redl743de1f2009-03-23 00:00:23 +00004148 // Complain about rvalue references in C++03, but then go on and build
4149 // the declarator.
Richard Smith7fe62082011-10-15 05:09:34 +00004150 if (Kind == tok::ampamp)
David Blaikie4e4d0842012-03-11 07:00:24 +00004151 Diag(Loc, getLangOpts().CPlusPlus0x ?
Richard Smith7fe62082011-10-15 05:09:34 +00004152 diag::warn_cxx98_compat_rvalue_reference :
4153 diag::ext_rvalue_reference);
Sebastian Redl743de1f2009-03-23 00:00:23 +00004154
Richard Smith6ee326a2012-04-10 01:32:12 +00004155 // GNU-style and C++11 attributes are allowed here, as is restrict.
4156 ParseTypeQualifierListOpt(DS);
4157 D.ExtendWithDeclSpec(DS);
4158
Reid Spencer5f016e22007-07-11 17:01:13 +00004159 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4160 // cv-qualifiers are introduced through the use of a typedef or of a
4161 // template type argument, in which case the cv-qualifiers are ignored.
Reid Spencer5f016e22007-07-11 17:01:13 +00004162 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4163 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4164 Diag(DS.getConstSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004165 diag::err_invalid_reference_qualifier_application) << "const";
Reid Spencer5f016e22007-07-11 17:01:13 +00004166 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4167 Diag(DS.getVolatileSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004168 diag::err_invalid_reference_qualifier_application) << "volatile";
Reid Spencer5f016e22007-07-11 17:01:13 +00004169 }
4170
4171 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004172 ParseDeclaratorInternal(D, DirectDeclParser);
Reid Spencer5f016e22007-07-11 17:01:13 +00004173
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004174 if (D.getNumTypeObjects() > 0) {
4175 // C++ [dcl.ref]p4: There shall be no references to references.
4176 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4177 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattnerda83bac2008-11-19 07:37:42 +00004178 if (const IdentifierInfo *II = D.getIdentifier())
4179 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4180 << II;
4181 else
4182 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4183 << "type name";
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004184
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004185 // Once we've complained about the reference-to-reference, we
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004186 // can go ahead and build the (technically ill-formed)
4187 // declarator: reference collapsing will take care of it.
4188 }
4189 }
4190
Reid Spencer5f016e22007-07-11 17:01:13 +00004191 // Remember that we parsed a reference type. It doesn't have type-quals.
Chris Lattner76549142008-02-21 01:32:26 +00004192 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redl05532f22009-03-15 22:02:01 +00004193 Kind == tok::amp),
John McCall0b7e6782011-03-24 11:26:52 +00004194 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004195 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004196 }
4197}
4198
Richard Smith9988f282012-03-29 01:16:42 +00004199static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4200 SourceLocation EllipsisLoc) {
4201 if (EllipsisLoc.isValid()) {
4202 FixItHint Insertion;
4203 if (!D.getEllipsisLoc().isValid()) {
4204 Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4205 D.setEllipsisLoc(EllipsisLoc);
4206 }
4207 P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4208 << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4209 }
4210}
4211
Reid Spencer5f016e22007-07-11 17:01:13 +00004212/// ParseDirectDeclarator
4213/// direct-declarator: [C99 6.7.5]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004214/// [C99] identifier
Reid Spencer5f016e22007-07-11 17:01:13 +00004215/// '(' declarator ')'
4216/// [GNU] '(' attributes declarator ')'
4217/// [C90] direct-declarator '[' constant-expression[opt] ']'
4218/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4219/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4220/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4221/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00004222/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4223/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00004224/// direct-declarator '(' parameter-type-list ')'
4225/// direct-declarator '(' identifier-list[opt] ')'
4226/// [GNU] direct-declarator '(' parameter-forward-declarations
4227/// parameter-type-list[opt] ')'
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00004228/// [C++] direct-declarator '(' parameter-declaration-clause ')'
4229/// cv-qualifier-seq[opt] exception-specification[opt]
Richard Smith6ee326a2012-04-10 01:32:12 +00004230/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4231/// attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4232/// ref-qualifier[opt] exception-specification[opt]
Douglas Gregorb48fe382008-10-31 09:07:45 +00004233/// [C++] declarator-id
Richard Smith6ee326a2012-04-10 01:32:12 +00004234/// [C++11] declarator-id attribute-specifier-seq[opt]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004235///
4236/// declarator-id: [C++ 8]
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004237/// '...'[opt] id-expression
Douglas Gregor42a552f2008-11-05 20:51:48 +00004238/// '::'[opt] nested-name-specifier[opt] type-name
4239///
4240/// id-expression: [C++ 5.1]
4241/// unqualified-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004242/// qualified-id
Douglas Gregor42a552f2008-11-05 20:51:48 +00004243///
4244/// unqualified-id: [C++ 5.1]
Mike Stump1eb44332009-09-09 15:08:12 +00004245/// identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004246/// operator-function-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004247/// conversion-function-id
Mike Stump1eb44332009-09-09 15:08:12 +00004248/// '~' class-name
Douglas Gregor39a8de12009-02-25 19:37:18 +00004249/// template-id
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +00004250///
Richard Smith5d8388c2012-03-27 01:42:32 +00004251/// Note, any additional constructs added here may need corresponding changes
4252/// in isConstructorDeclarator.
Reid Spencer5f016e22007-07-11 17:01:13 +00004253void Parser::ParseDirectDeclarator(Declarator &D) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004254 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004255
David Blaikie4e4d0842012-03-11 07:00:24 +00004256 if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004257 // ParseDeclaratorInternal might already have parsed the scope.
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004258 if (D.getCXXScopeSpec().isEmpty()) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004259 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4260 D.getContext() == Declarator::MemberContext;
Chad Rosier8decdee2012-06-26 22:30:43 +00004261 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004262 EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004263 }
4264
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004265 if (D.getCXXScopeSpec().isValid()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00004266 if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
John McCalle7e278b2009-12-11 20:04:54 +00004267 // Change the declaration context for name lookup, until this function
4268 // is exited (and the declarator has been parsed).
4269 DeclScopeObj.EnterDeclaratorScope();
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004270 }
4271
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004272 // C++0x [dcl.fct]p14:
4273 // There is a syntactic ambiguity when an ellipsis occurs at the end
Chad Rosier8decdee2012-06-26 22:30:43 +00004274 // of a parameter-declaration-clause without a preceding comma. In
4275 // this case, the ellipsis is parsed as part of the
4276 // abstract-declarator if the type of the parameter names a template
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004277 // parameter pack that has not been expanded; otherwise, it is parsed
4278 // as part of the parameter-declaration-clause.
Richard Smith9988f282012-03-29 01:16:42 +00004279 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004280 !((D.getContext() == Declarator::PrototypeContext ||
4281 D.getContext() == Declarator::BlockLiteralContext) &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004282 NextToken().is(tok::r_paren) &&
Richard Smith9988f282012-03-29 01:16:42 +00004283 !Actions.containsUnexpandedParameterPacks(D))) {
4284 SourceLocation EllipsisLoc = ConsumeToken();
4285 if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4286 // The ellipsis was put in the wrong place. Recover, and explain to
4287 // the user what they should have done.
4288 ParseDeclarator(D);
4289 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4290 return;
4291 } else
4292 D.setEllipsisLoc(EllipsisLoc);
4293
4294 // The ellipsis can't be followed by a parenthesized declarator. We
4295 // check for that in ParseParenDeclarator, after we have disambiguated
4296 // the l_paren token.
4297 }
4298
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004299 if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4300 Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4301 // We found something that indicates the start of an unqualified-id.
4302 // Parse that unqualified-id.
John McCallba9d8532010-04-13 06:39:49 +00004303 bool AllowConstructorName;
4304 if (D.getDeclSpec().hasTypeSpecifier())
4305 AllowConstructorName = false;
4306 else if (D.getCXXScopeSpec().isSet())
4307 AllowConstructorName =
4308 (D.getContext() == Declarator::FileContext ||
4309 (D.getContext() == Declarator::MemberContext &&
4310 D.getDeclSpec().isFriendSpecified()));
4311 else
4312 AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4313
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004314 SourceLocation TemplateKWLoc;
Chad Rosier8decdee2012-06-26 22:30:43 +00004315 if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4316 /*EnteringContext=*/true,
4317 /*AllowDestructorName=*/true,
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004318 AllowConstructorName,
John McCallb3d87482010-08-24 05:47:05 +00004319 ParsedType(),
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004320 TemplateKWLoc,
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004321 D.getName()) ||
4322 // Once we're past the identifier, if the scope was bad, mark the
4323 // whole declarator bad.
4324 D.getCXXScopeSpec().isInvalid()) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004325 D.SetIdentifier(0, Tok.getLocation());
4326 D.setInvalidType(true);
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004327 } else {
4328 // Parsed the unqualified-id; update range information and move along.
4329 if (D.getSourceRange().getBegin().isInvalid())
4330 D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4331 D.SetRangeEnd(D.getName().getSourceRange().getEnd());
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004332 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004333 goto PastIdentifier;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00004334 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004335 } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004336 assert(!getLangOpts().CPlusPlus &&
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004337 "There's a C++-specific check for tok::identifier above");
4338 assert(Tok.getIdentifierInfo() && "Not an identifier?");
4339 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4340 ConsumeToken();
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004341 goto PastIdentifier;
4342 }
Richard Smith9988f282012-03-29 01:16:42 +00004343
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004344 if (Tok.is(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004345 // direct-declarator: '(' declarator ')'
4346 // direct-declarator: '(' attributes declarator ')'
4347 // Example: 'char (*X)' or 'int (*XX)(void)'
4348 ParseParenDeclarator(D);
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004349
4350 // If the declarator was parenthesized, we entered the declarator
4351 // scope when parsing the parenthesized declarator, then exited
4352 // the scope already. Re-enter the scope, if we need to.
4353 if (D.getCXXScopeSpec().isSet()) {
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004354 // If there was an error parsing parenthesized declarator, declarator
Richard Smith9988f282012-03-29 01:16:42 +00004355 // scope may have been entered before. Don't do it again.
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004356 if (!D.isInvalidType() &&
4357 Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004358 // Change the declaration context for name lookup, until this function
4359 // is exited (and the declarator has been parsed).
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004360 DeclScopeObj.EnterDeclaratorScope();
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004361 }
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004362 } else if (D.mayOmitIdentifier()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004363 // This could be something simple like "int" (in which case the declarator
4364 // portion is empty), if an abstract-declarator is allowed.
4365 D.SetIdentifier(0, Tok.getLocation());
4366 } else {
David Blaikiee75d9cf2012-06-29 22:03:56 +00004367 if (Tok.getKind() == tok::annot_pragma_parser_crash)
David Blaikie377da4c2012-08-21 18:56:49 +00004368 LLVM_BUILTIN_TRAP;
Douglas Gregore950d4b2009-03-06 23:28:18 +00004369 if (D.getContext() == Declarator::MemberContext)
4370 Diag(Tok, diag::err_expected_member_name_or_semi)
4371 << D.getDeclSpec().getSourceRange();
David Blaikie4e4d0842012-03-11 07:00:24 +00004372 else if (getLangOpts().CPlusPlus)
4373 Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004374 else
Chris Lattner1ab3b962008-11-18 07:48:38 +00004375 Diag(Tok, diag::err_expected_ident_lparen);
Reid Spencer5f016e22007-07-11 17:01:13 +00004376 D.SetIdentifier(0, Tok.getLocation());
Chris Lattner1f6f54b2008-11-11 06:13:16 +00004377 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00004378 }
Mike Stump1eb44332009-09-09 15:08:12 +00004379
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004380 PastIdentifier:
Reid Spencer5f016e22007-07-11 17:01:13 +00004381 assert(D.isPastIdentifier() &&
4382 "Haven't past the location of the identifier yet?");
Mike Stump1eb44332009-09-09 15:08:12 +00004383
Richard Smith6ee326a2012-04-10 01:32:12 +00004384 // Don't parse attributes unless we have parsed an unparenthesized name.
4385 if (D.hasName() && !D.getNumTypeObjects())
John McCall7f040a92010-12-24 02:08:15 +00004386 MaybeParseCXX0XAttributes(D);
Sean Huntbbd37c62009-11-21 08:43:09 +00004387
Reid Spencer5f016e22007-07-11 17:01:13 +00004388 while (1) {
Chris Lattner04d66662007-10-09 17:33:22 +00004389 if (Tok.is(tok::l_paren)) {
David Blaikie42d6d0c2011-12-04 05:04:18 +00004390 // Enter function-declaration scope, limiting any declarators to the
4391 // function prototype scope, including parameter declarators.
4392 ParseScope PrototypeScope(this,
4393 Scope::FunctionPrototypeScope|Scope::DeclScope);
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00004394 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4395 // In such a case, check if we actually have a function declarator; if it
4396 // is not, the declarator has been fully parsed.
Richard Smithb9c62612012-07-30 21:30:52 +00004397 bool IsAmbiguous = false;
Richard Smith05766812012-08-18 00:55:03 +00004398 if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
4399 // The name of the declarator, if any, is tentatively declared within
4400 // a possible direct initializer.
4401 TentativelyDeclaredIdentifiers.push_back(D.getIdentifier());
4402 bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
4403 TentativelyDeclaredIdentifiers.pop_back();
4404 if (!IsFunctionDecl)
4405 break;
4406 }
John McCall0b7e6782011-03-24 11:26:52 +00004407 ParsedAttributes attrs(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004408 BalancedDelimiterTracker T(*this, tok::l_paren);
4409 T.consumeOpen();
Richard Smithb9c62612012-07-30 21:30:52 +00004410 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004411 PrototypeScope.Exit();
Chris Lattner04d66662007-10-09 17:33:22 +00004412 } else if (Tok.is(tok::l_square)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004413 ParseBracketDeclarator(D);
4414 } else {
4415 break;
4416 }
4417 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004418}
Reid Spencer5f016e22007-07-11 17:01:13 +00004419
Chris Lattneref4715c2008-04-06 05:45:57 +00004420/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
4421/// only called before the identifier, so these are most likely just grouping
Mike Stump1eb44332009-09-09 15:08:12 +00004422/// parens for precedence. If we find that these are actually function
Chris Lattneref4715c2008-04-06 05:45:57 +00004423/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4424///
4425/// direct-declarator:
4426/// '(' declarator ')'
4427/// [GNU] '(' attributes declarator ')'
Chris Lattner7399ee02008-10-20 02:05:46 +00004428/// direct-declarator '(' parameter-type-list ')'
4429/// direct-declarator '(' identifier-list[opt] ')'
4430/// [GNU] direct-declarator '(' parameter-forward-declarations
4431/// parameter-type-list[opt] ')'
Chris Lattneref4715c2008-04-06 05:45:57 +00004432///
4433void Parser::ParseParenDeclarator(Declarator &D) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004434 BalancedDelimiterTracker T(*this, tok::l_paren);
4435 T.consumeOpen();
4436
Chris Lattneref4715c2008-04-06 05:45:57 +00004437 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00004438
Chris Lattner7399ee02008-10-20 02:05:46 +00004439 // Eat any attributes before we look at whether this is a grouping or function
4440 // declarator paren. If this is a grouping paren, the attribute applies to
4441 // the type being built up, for example:
4442 // int (__attribute__(()) *x)(long y)
4443 // If this ends up not being a grouping paren, the attribute applies to the
4444 // first argument, for example:
4445 // int (__attribute__(()) int x)
4446 // In either case, we need to eat any attributes to be able to determine what
4447 // sort of paren this is.
4448 //
John McCall0b7e6782011-03-24 11:26:52 +00004449 ParsedAttributes attrs(AttrFactory);
Chris Lattner7399ee02008-10-20 02:05:46 +00004450 bool RequiresArg = false;
4451 if (Tok.is(tok::kw___attribute)) {
John McCall7f040a92010-12-24 02:08:15 +00004452 ParseGNUAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004453
Chris Lattner7399ee02008-10-20 02:05:46 +00004454 // We require that the argument list (if this is a non-grouping paren) be
4455 // present even if the attribute list was empty.
4456 RequiresArg = true;
4457 }
Steve Naroff239f0732008-12-25 14:16:32 +00004458 // Eat any Microsoft extensions.
Eli Friedman290eeb02009-06-08 23:27:34 +00004459 if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004460 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004461 Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64) ||
Francois Pichet58fd97a2011-08-25 00:36:46 +00004462 Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) {
John McCall7f040a92010-12-24 02:08:15 +00004463 ParseMicrosoftTypeAttributes(attrs);
Eli Friedman290eeb02009-06-08 23:27:34 +00004464 }
Dawn Perchik52fc3142010-09-03 01:29:35 +00004465 // Eat any Borland extensions.
Ted Kremenek8113ecf2010-11-10 05:59:39 +00004466 if (Tok.is(tok::kw___pascal))
John McCall7f040a92010-12-24 02:08:15 +00004467 ParseBorlandTypeAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004468
Chris Lattneref4715c2008-04-06 05:45:57 +00004469 // If we haven't past the identifier yet (or where the identifier would be
4470 // stored, if this is an abstract declarator), then this is probably just
4471 // grouping parens. However, if this could be an abstract-declarator, then
4472 // this could also be the start of function arguments (consider 'void()').
4473 bool isGrouping;
Mike Stump1eb44332009-09-09 15:08:12 +00004474
Chris Lattneref4715c2008-04-06 05:45:57 +00004475 if (!D.mayOmitIdentifier()) {
4476 // If this can't be an abstract-declarator, this *must* be a grouping
4477 // paren, because we haven't seen the identifier yet.
4478 isGrouping = true;
4479 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Richard Smith22592862012-03-27 23:05:05 +00004480 (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
4481 NextToken().is(tok::r_paren)) || // C++ int(...)
Richard Smith6ce48a72012-04-11 04:01:28 +00004482 isDeclarationSpecifier() || // 'int(int)' is a function.
4483 isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function.
Chris Lattneref4715c2008-04-06 05:45:57 +00004484 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
4485 // considered to be a type, not a K&R identifier-list.
4486 isGrouping = false;
4487 } else {
4488 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
4489 isGrouping = true;
4490 }
Mike Stump1eb44332009-09-09 15:08:12 +00004491
Chris Lattneref4715c2008-04-06 05:45:57 +00004492 // If this is a grouping paren, handle:
4493 // direct-declarator: '(' declarator ')'
4494 // direct-declarator: '(' attributes declarator ')'
4495 if (isGrouping) {
Richard Smith9988f282012-03-29 01:16:42 +00004496 SourceLocation EllipsisLoc = D.getEllipsisLoc();
4497 D.setEllipsisLoc(SourceLocation());
4498
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00004499 bool hadGroupingParens = D.hasGroupingParens();
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00004500 D.setGroupingParens(true);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004501 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattneref4715c2008-04-06 05:45:57 +00004502 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004503 T.consumeClose();
Chad Rosier8decdee2012-06-26 22:30:43 +00004504 D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004505 T.getCloseLocation()),
4506 attrs, T.getCloseLocation());
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00004507
4508 D.setGroupingParens(hadGroupingParens);
Richard Smith9988f282012-03-29 01:16:42 +00004509
4510 // An ellipsis cannot be placed outside parentheses.
4511 if (EllipsisLoc.isValid())
4512 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4513
Chris Lattneref4715c2008-04-06 05:45:57 +00004514 return;
4515 }
Mike Stump1eb44332009-09-09 15:08:12 +00004516
Chris Lattneref4715c2008-04-06 05:45:57 +00004517 // Okay, if this wasn't a grouping paren, it must be the start of a function
4518 // argument list. Recognize that this declarator will never have an
Chris Lattner7399ee02008-10-20 02:05:46 +00004519 // identifier (and remember where it would have been), then call into
4520 // ParseFunctionDeclarator to handle of argument list.
Chris Lattneref4715c2008-04-06 05:45:57 +00004521 D.SetIdentifier(0, Tok.getLocation());
4522
David Blaikie42d6d0c2011-12-04 05:04:18 +00004523 // Enter function-declaration scope, limiting any declarators to the
4524 // function prototype scope, including parameter declarators.
4525 ParseScope PrototypeScope(this,
4526 Scope::FunctionPrototypeScope|Scope::DeclScope);
Richard Smithb9c62612012-07-30 21:30:52 +00004527 ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004528 PrototypeScope.Exit();
Chris Lattneref4715c2008-04-06 05:45:57 +00004529}
4530
4531/// ParseFunctionDeclarator - We are after the identifier and have parsed the
4532/// declarator D up to a paren, which indicates that we are parsing function
4533/// arguments.
Reid Spencer5f016e22007-07-11 17:01:13 +00004534///
Richard Smith6ee326a2012-04-10 01:32:12 +00004535/// If FirstArgAttrs is non-null, then the caller parsed those arguments
4536/// immediately after the open paren - they should be considered to be the
4537/// first argument of a parameter.
Chris Lattner7399ee02008-10-20 02:05:46 +00004538///
Richard Smith6ee326a2012-04-10 01:32:12 +00004539/// If RequiresArg is true, then the first argument of the function is required
4540/// to be present and required to not be an identifier list.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004541///
Richard Smith6ee326a2012-04-10 01:32:12 +00004542/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
4543/// (C++11) ref-qualifier[opt], exception-specification[opt],
4544/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
4545///
4546/// [C++11] exception-specification:
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004547/// dynamic-exception-specification
4548/// noexcept-specification
4549///
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004550void Parser::ParseFunctionDeclarator(Declarator &D,
Richard Smith6ee326a2012-04-10 01:32:12 +00004551 ParsedAttributes &FirstArgAttrs,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004552 BalancedDelimiterTracker &Tracker,
Richard Smithb9c62612012-07-30 21:30:52 +00004553 bool IsAmbiguous,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004554 bool RequiresArg) {
Chad Rosier8decdee2012-06-26 22:30:43 +00004555 assert(getCurScope()->isFunctionPrototypeScope() &&
David Blaikie42d6d0c2011-12-04 05:04:18 +00004556 "Should call from a Function scope");
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004557 // lparen is already consumed!
4558 assert(D.isPastIdentifier() && "Should not call before identifier!");
4559
4560 // This should be true when the function has typed arguments.
4561 // Otherwise, it is treated as a K&R-style function.
4562 bool HasProto = false;
4563 // Build up an array of information about the parsed arguments.
Chris Lattner5f9e2722011-07-23 10:55:15 +00004564 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004565 // Remember where we see an ellipsis, if any.
4566 SourceLocation EllipsisLoc;
4567
4568 DeclSpec DS(AttrFactory);
4569 bool RefQualifierIsLValueRef = true;
4570 SourceLocation RefQualifierLoc;
Douglas Gregor43f51032011-10-19 06:04:55 +00004571 SourceLocation ConstQualifierLoc;
4572 SourceLocation VolatileQualifierLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004573 ExceptionSpecificationType ESpecType = EST_None;
4574 SourceRange ESpecRange;
Chris Lattner5f9e2722011-07-23 10:55:15 +00004575 SmallVector<ParsedType, 2> DynamicExceptions;
4576 SmallVector<SourceRange, 2> DynamicExceptionRanges;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004577 ExprResult NoexceptExpr;
Richard Smith6ee326a2012-04-10 01:32:12 +00004578 ParsedAttributes FnAttrs(AttrFactory);
Richard Smith54655be2012-06-12 01:51:59 +00004579 TypeResult TrailingReturnType;
Richard Smith6ee326a2012-04-10 01:32:12 +00004580
James Molloy16f1f712012-02-29 10:24:19 +00004581 Actions.ActOnStartFunctionDeclarator();
4582
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004583 SourceLocation EndLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004584 if (isFunctionDeclaratorIdentifierList()) {
4585 if (RequiresArg)
4586 Diag(Tok, diag::err_argument_required_after_attribute);
4587
4588 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
4589
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004590 Tracker.consumeClose();
4591 EndLoc = Tracker.getCloseLocation();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004592 } else {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004593 if (Tok.isNot(tok::r_paren))
Richard Smith6ee326a2012-04-10 01:32:12 +00004594 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004595 else if (RequiresArg)
4596 Diag(Tok, diag::err_argument_required_after_attribute);
4597
David Blaikie4e4d0842012-03-11 07:00:24 +00004598 HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004599
4600 // If we have the closing ')', eat it.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004601 Tracker.consumeClose();
4602 EndLoc = Tracker.getCloseLocation();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004603
David Blaikie4e4d0842012-03-11 07:00:24 +00004604 if (getLangOpts().CPlusPlus) {
Richard Smith6ee326a2012-04-10 01:32:12 +00004605 // FIXME: Accept these components in any order, and produce fixits to
4606 // correct the order if the user gets it wrong. Ideally we should deal
4607 // with the virt-specifier-seq and pure-specifier in the same way.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004608
4609 // Parse cv-qualifier-seq[opt].
Richard Smith6ee326a2012-04-10 01:32:12 +00004610 ParseTypeQualifierListOpt(DS, false /*no attributes*/, false);
4611 if (!DS.getSourceRange().getEnd().isInvalid()) {
4612 EndLoc = DS.getSourceRange().getEnd();
4613 ConstQualifierLoc = DS.getConstSpecLoc();
4614 VolatileQualifierLoc = DS.getVolatileSpecLoc();
4615 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004616
4617 // Parse ref-qualifier[opt].
4618 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004619 Diag(Tok, getLangOpts().CPlusPlus0x ?
Richard Smith7fe62082011-10-15 05:09:34 +00004620 diag::warn_cxx98_compat_ref_qualifier :
4621 diag::ext_ref_qualifier);
Richard Smith6ee326a2012-04-10 01:32:12 +00004622
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004623 RefQualifierIsLValueRef = Tok.is(tok::amp);
4624 RefQualifierLoc = ConsumeToken();
4625 EndLoc = RefQualifierLoc;
4626 }
4627
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004628 // C++11 [expr.prim.general]p3:
Chad Rosier8decdee2012-06-26 22:30:43 +00004629 // If a declaration declares a member function or member function
4630 // template of a class X, the expression this is a prvalue of type
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004631 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
Chad Rosier8decdee2012-06-26 22:30:43 +00004632 // and the end of the function-definition, member-declarator, or
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004633 // declarator.
Chad Rosier8decdee2012-06-26 22:30:43 +00004634 bool IsCXX11MemberFunction =
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004635 getLangOpts().CPlusPlus0x &&
4636 (D.getContext() == Declarator::MemberContext ||
4637 (D.getContext() == Declarator::FileContext &&
Chad Rosier8decdee2012-06-26 22:30:43 +00004638 D.getCXXScopeSpec().isValid() &&
Douglas Gregorcefc3af2012-04-16 07:05:22 +00004639 Actions.CurContext->isRecord()));
4640 Sema::CXXThisScopeRAII ThisScope(Actions,
4641 dyn_cast<CXXRecordDecl>(Actions.CurContext),
4642 DS.getTypeQualifiers(),
4643 IsCXX11MemberFunction);
Richard Smitha058fd42012-05-02 22:22:32 +00004644
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004645 // Parse exception-specification[opt].
Richard Smitha058fd42012-05-02 22:22:32 +00004646 ESpecType = tryParseExceptionSpecification(ESpecRange,
Douglas Gregor74e2fc32012-04-16 18:27:27 +00004647 DynamicExceptions,
4648 DynamicExceptionRanges,
Richard Smitha058fd42012-05-02 22:22:32 +00004649 NoexceptExpr);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004650 if (ESpecType != EST_None)
4651 EndLoc = ESpecRange.getEnd();
4652
Richard Smith6ee326a2012-04-10 01:32:12 +00004653 // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
4654 // after the exception-specification.
4655 MaybeParseCXX0XAttributes(FnAttrs);
4656
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004657 // Parse trailing-return-type[opt].
David Blaikie4e4d0842012-03-11 07:00:24 +00004658 if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) {
Richard Smith7fe62082011-10-15 05:09:34 +00004659 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
Douglas Gregorae7902c2011-08-04 15:30:47 +00004660 SourceRange Range;
Richard Smith54655be2012-06-12 01:51:59 +00004661 TrailingReturnType = ParseTrailingReturnType(Range);
Douglas Gregorae7902c2011-08-04 15:30:47 +00004662 if (Range.getEnd().isValid())
4663 EndLoc = Range.getEnd();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004664 }
4665 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004666 }
4667
4668 // Remember that we parsed a function type, and remember the attributes.
4669 D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
4670 /*isVariadic=*/EllipsisLoc.isValid(),
Richard Smithb9c62612012-07-30 21:30:52 +00004671 IsAmbiguous, EllipsisLoc,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004672 ParamInfo.data(), ParamInfo.size(),
4673 DS.getTypeQualifiers(),
4674 RefQualifierIsLValueRef,
Douglas Gregor43f51032011-10-19 06:04:55 +00004675 RefQualifierLoc, ConstQualifierLoc,
4676 VolatileQualifierLoc,
Douglas Gregor90ebed02011-07-13 21:47:47 +00004677 /*MutableLoc=*/SourceLocation(),
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004678 ESpecType, ESpecRange.getBegin(),
4679 DynamicExceptions.data(),
4680 DynamicExceptionRanges.data(),
4681 DynamicExceptions.size(),
4682 NoexceptExpr.isUsable() ?
4683 NoexceptExpr.get() : 0,
Chad Rosier8decdee2012-06-26 22:30:43 +00004684 Tracker.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004685 EndLoc, D,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004686 TrailingReturnType),
Richard Smith6ee326a2012-04-10 01:32:12 +00004687 FnAttrs, EndLoc);
James Molloy16f1f712012-02-29 10:24:19 +00004688
4689 Actions.ActOnEndFunctionDeclarator();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004690}
4691
4692/// isFunctionDeclaratorIdentifierList - This parameter list may have an
4693/// identifier list form for a K&R-style function: void foo(a,b,c)
4694///
4695/// Note that identifier-lists are only allowed for normal declarators, not for
4696/// abstract-declarators.
4697bool Parser::isFunctionDeclaratorIdentifierList() {
David Blaikie4e4d0842012-03-11 07:00:24 +00004698 return !getLangOpts().CPlusPlus
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004699 && Tok.is(tok::identifier)
4700 && !TryAltiVecVectorToken()
4701 // K&R identifier lists can't have typedefs as identifiers, per C99
4702 // 6.7.5.3p11.
4703 && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
4704 // Identifier lists follow a really simple grammar: the identifiers can
4705 // be followed *only* by a ", identifier" or ")". However, K&R
4706 // identifier lists are really rare in the brave new modern world, and
4707 // it is very common for someone to typo a type in a non-K&R style
4708 // list. If we are presented with something like: "void foo(intptr x,
4709 // float y)", we don't want to start parsing the function declarator as
4710 // though it is a K&R style declarator just because intptr is an
4711 // invalid type.
4712 //
4713 // To handle this, we check to see if the token after the first
4714 // identifier is a "," or ")". Only then do we parse it as an
4715 // identifier list.
4716 && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
4717}
4718
4719/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
4720/// we found a K&R-style identifier list instead of a typed parameter list.
4721///
4722/// After returning, ParamInfo will hold the parsed parameters.
4723///
4724/// identifier-list: [C99 6.7.5]
4725/// identifier
4726/// identifier-list ',' identifier
4727///
4728void Parser::ParseFunctionDeclaratorIdentifierList(
4729 Declarator &D,
Chris Lattner5f9e2722011-07-23 10:55:15 +00004730 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004731 // If there was no identifier specified for the declarator, either we are in
4732 // an abstract-declarator, or we are in a parameter declarator which was found
4733 // to be abstract. In abstract-declarators, identifier lists are not valid:
4734 // diagnose this.
4735 if (!D.getIdentifier())
4736 Diag(Tok, diag::ext_ident_list_in_param);
4737
4738 // Maintain an efficient lookup of params we have seen so far.
4739 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
4740
4741 while (1) {
4742 // If this isn't an identifier, report the error and skip until ')'.
4743 if (Tok.isNot(tok::identifier)) {
4744 Diag(Tok, diag::err_expected_ident);
4745 SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true);
4746 // Forget we parsed anything.
4747 ParamInfo.clear();
4748 return;
4749 }
4750
4751 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
4752
4753 // Reject 'typedef int y; int test(x, y)', but continue parsing.
4754 if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
4755 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
4756
4757 // Verify that the argument identifier has not already been mentioned.
4758 if (!ParamsSoFar.insert(ParmII)) {
4759 Diag(Tok, diag::err_param_redefinition) << ParmII;
4760 } else {
4761 // Remember this identifier in ParamInfo.
4762 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4763 Tok.getLocation(),
4764 0));
4765 }
4766
4767 // Eat the identifier.
4768 ConsumeToken();
4769
4770 // The list continues if we see a comma.
4771 if (Tok.isNot(tok::comma))
4772 break;
4773 ConsumeToken();
4774 }
4775}
4776
4777/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
4778/// after the opening parenthesis. This function will not parse a K&R-style
4779/// identifier list.
4780///
Richard Smith6ce48a72012-04-11 04:01:28 +00004781/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the
4782/// caller parsed those arguments immediately after the open paren - they should
4783/// be considered to be part of the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004784///
4785/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
4786/// be the location of the ellipsis, if any was parsed.
4787///
Reid Spencer5f016e22007-07-11 17:01:13 +00004788/// parameter-type-list: [C99 6.7.5]
4789/// parameter-list
4790/// parameter-list ',' '...'
Douglas Gregored5d6512009-09-22 21:41:40 +00004791/// [C++] parameter-list '...'
Reid Spencer5f016e22007-07-11 17:01:13 +00004792///
4793/// parameter-list: [C99 6.7.5]
4794/// parameter-declaration
4795/// parameter-list ',' parameter-declaration
4796///
4797/// parameter-declaration: [C99 6.7.5]
4798/// declaration-specifiers declarator
Chris Lattner04421082008-04-08 04:40:51 +00004799/// [C++] declaration-specifiers declarator '=' assignment-expression
Sebastian Redl84407ba2012-03-14 15:54:00 +00004800/// [C++11] initializer-clause
Reid Spencer5f016e22007-07-11 17:01:13 +00004801/// [GNU] declaration-specifiers declarator attributes
Sebastian Redl50de12f2009-03-24 22:27:57 +00004802/// declaration-specifiers abstract-declarator[opt]
4803/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner8123a952008-04-10 02:22:51 +00004804/// '=' assignment-expression
Reid Spencer5f016e22007-07-11 17:01:13 +00004805/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
Richard Smith6ce48a72012-04-11 04:01:28 +00004806/// [C++11] attribute-specifier-seq parameter-declaration
Reid Spencer5f016e22007-07-11 17:01:13 +00004807///
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004808void Parser::ParseParameterDeclarationClause(
4809 Declarator &D,
Richard Smith6ce48a72012-04-11 04:01:28 +00004810 ParsedAttributes &FirstArgAttrs,
Chris Lattner5f9e2722011-07-23 10:55:15 +00004811 SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004812 SourceLocation &EllipsisLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00004813
Chris Lattnerf97409f2008-04-06 06:57:35 +00004814 while (1) {
4815 if (Tok.is(tok::ellipsis)) {
Richard Smith6ce48a72012-04-11 04:01:28 +00004816 // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
4817 // before deciding this was a parameter-declaration-clause.
Douglas Gregor965acbb2009-02-18 07:07:28 +00004818 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattnerf97409f2008-04-06 06:57:35 +00004819 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00004820 }
Mike Stump1eb44332009-09-09 15:08:12 +00004821
Chris Lattnerf97409f2008-04-06 06:57:35 +00004822 // Parse the declaration-specifiers.
John McCall54abf7d2009-11-04 02:18:39 +00004823 // Just use the ParsingDeclaration "scope" of the declarator.
John McCall0b7e6782011-03-24 11:26:52 +00004824 DeclSpec DS(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004825
Richard Smith6ce48a72012-04-11 04:01:28 +00004826 // Parse any C++11 attributes.
4827 MaybeParseCXX0XAttributes(DS.getAttributes());
4828
John McCall7f040a92010-12-24 02:08:15 +00004829 // Skip any Microsoft attributes before a param.
David Blaikie4e4d0842012-03-11 07:00:24 +00004830 if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
John McCall7f040a92010-12-24 02:08:15 +00004831 ParseMicrosoftAttributes(DS.getAttributes());
4832
4833 SourceLocation DSStart = Tok.getLocation();
Chris Lattner7399ee02008-10-20 02:05:46 +00004834
4835 // If the caller parsed attributes for the first argument, add them now.
John McCall7f040a92010-12-24 02:08:15 +00004836 // Take them so that we only apply the attributes to the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00004837 // FIXME: If we can leave the attributes in the token stream somehow, we can
Richard Smith6ce48a72012-04-11 04:01:28 +00004838 // get rid of a parameter (FirstArgAttrs) and this statement. It might be
4839 // too much hassle.
4840 DS.takeAttributesFrom(FirstArgAttrs);
John McCall7f040a92010-12-24 02:08:15 +00004841
Chris Lattnere64c5492009-02-27 18:38:20 +00004842 ParseDeclarationSpecifiers(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00004843
Chris Lattnerf97409f2008-04-06 06:57:35 +00004844 // Parse the declarator. This is "PrototypeContext", because we must
4845 // accept either 'declarator' or 'abstract-declarator' here.
4846 Declarator ParmDecl(DS, Declarator::PrototypeContext);
4847 ParseDeclarator(ParmDecl);
4848
4849 // Parse GNU attributes, if present.
John McCall7f040a92010-12-24 02:08:15 +00004850 MaybeParseGNUAttributes(ParmDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00004851
Chris Lattnerf97409f2008-04-06 06:57:35 +00004852 // Remember this parsed parameter in ParamInfo.
4853 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
Mike Stump1eb44332009-09-09 15:08:12 +00004854
Douglas Gregor72b505b2008-12-16 21:30:33 +00004855 // DefArgToks is used when the parsing of default arguments needs
4856 // to be delayed.
4857 CachedTokens *DefArgToks = 0;
4858
Chris Lattnerf97409f2008-04-06 06:57:35 +00004859 // If no parameter was specified, verify that *something* was specified,
4860 // otherwise we have a missing type and identifier.
Chris Lattnere64c5492009-02-27 18:38:20 +00004861 if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
4862 ParmDecl.getNumTypeObjects() == 0) {
Chris Lattnerf97409f2008-04-06 06:57:35 +00004863 // Completely missing, emit error.
4864 Diag(DSStart, diag::err_missing_param);
4865 } else {
4866 // Otherwise, we have something. Add it and let semantic analysis try
4867 // to grok it and add the result to the ParamInfo we are building.
Mike Stump1eb44332009-09-09 15:08:12 +00004868
Chris Lattnerf97409f2008-04-06 06:57:35 +00004869 // Inform the actions module about the parameter declarator, so it gets
4870 // added to the current scope.
John McCalld226f652010-08-21 09:40:31 +00004871 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
Chris Lattner04421082008-04-08 04:40:51 +00004872
4873 // Parse the default argument, if any. We parse the default
4874 // arguments in all dialects; the semantic analysis in
4875 // ActOnParamDefaultArgument will reject the default argument in
4876 // C.
4877 if (Tok.is(tok::equal)) {
Douglas Gregor61366e92008-12-24 00:01:03 +00004878 SourceLocation EqualLoc = Tok.getLocation();
4879
Chris Lattner04421082008-04-08 04:40:51 +00004880 // Parse the default argument
Douglas Gregor72b505b2008-12-16 21:30:33 +00004881 if (D.getContext() == Declarator::MemberContext) {
4882 // If we're inside a class definition, cache the tokens
4883 // corresponding to the default argument. We'll actually parse
4884 // them when we see the end of the class definition.
Douglas Gregor72b505b2008-12-16 21:30:33 +00004885 // FIXME: Can we use a smart pointer for Toks?
4886 DefArgToks = new CachedTokens;
4887
Mike Stump1eb44332009-09-09 15:08:12 +00004888 if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
Argyrios Kyrtzidis14b91622010-04-23 21:20:12 +00004889 /*StopAtSemi=*/true,
4890 /*ConsumeFinalToken=*/false)) {
Douglas Gregor72b505b2008-12-16 21:30:33 +00004891 delete DefArgToks;
4892 DefArgToks = 0;
Douglas Gregor61366e92008-12-24 00:01:03 +00004893 Actions.ActOnParamDefaultArgumentError(Param);
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00004894 } else {
4895 // Mark the end of the default argument so that we know when to
4896 // stop when we parse it later on.
4897 Token DefArgEnd;
4898 DefArgEnd.startToken();
4899 DefArgEnd.setKind(tok::cxx_defaultarg_end);
4900 DefArgEnd.setLocation(Tok.getLocation());
4901 DefArgToks->push_back(DefArgEnd);
Mike Stump1eb44332009-09-09 15:08:12 +00004902 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
Anders Carlsson5e300d12009-06-12 16:51:40 +00004903 (*DefArgToks)[1].getLocation());
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00004904 }
Chris Lattner04421082008-04-08 04:40:51 +00004905 } else {
Douglas Gregor72b505b2008-12-16 21:30:33 +00004906 // Consume the '='.
Douglas Gregor61366e92008-12-24 00:01:03 +00004907 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00004908
Chad Rosier8decdee2012-06-26 22:30:43 +00004909 // The argument isn't actually potentially evaluated unless it is
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00004910 // used.
4911 EnterExpressionEvaluationContext Eval(Actions,
Douglas Gregorccc1b5e2012-02-21 00:37:24 +00004912 Sema::PotentiallyEvaluatedIfUsed,
4913 Param);
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00004914
Sebastian Redl84407ba2012-03-14 15:54:00 +00004915 ExprResult DefArgResult;
Sebastian Redl3e280b52012-03-18 22:25:45 +00004916 if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
4917 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Sebastian Redl84407ba2012-03-14 15:54:00 +00004918 DefArgResult = ParseBraceInitializer();
Sebastian Redl3e280b52012-03-18 22:25:45 +00004919 } else
Sebastian Redl84407ba2012-03-14 15:54:00 +00004920 DefArgResult = ParseAssignmentExpression();
Douglas Gregor72b505b2008-12-16 21:30:33 +00004921 if (DefArgResult.isInvalid()) {
4922 Actions.ActOnParamDefaultArgumentError(Param);
4923 SkipUntil(tok::comma, tok::r_paren, true, true);
4924 } else {
4925 // Inform the actions module about the default argument
4926 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
John McCall9ae2f072010-08-23 23:25:46 +00004927 DefArgResult.take());
Douglas Gregor72b505b2008-12-16 21:30:33 +00004928 }
Chris Lattner04421082008-04-08 04:40:51 +00004929 }
4930 }
Mike Stump1eb44332009-09-09 15:08:12 +00004931
4932 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4933 ParmDecl.getIdentifierLoc(), Param,
Douglas Gregor72b505b2008-12-16 21:30:33 +00004934 DefArgToks));
Chris Lattnerf97409f2008-04-06 06:57:35 +00004935 }
4936
4937 // If the next token is a comma, consume it and keep reading arguments.
Douglas Gregored5d6512009-09-22 21:41:40 +00004938 if (Tok.isNot(tok::comma)) {
4939 if (Tok.is(tok::ellipsis)) {
Douglas Gregored5d6512009-09-22 21:41:40 +00004940 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chad Rosier8decdee2012-06-26 22:30:43 +00004941
David Blaikie4e4d0842012-03-11 07:00:24 +00004942 if (!getLangOpts().CPlusPlus) {
Douglas Gregored5d6512009-09-22 21:41:40 +00004943 // We have ellipsis without a preceding ',', which is ill-formed
4944 // in C. Complain and provide the fix.
4945 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
Douglas Gregor849b2432010-03-31 17:46:05 +00004946 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
Douglas Gregored5d6512009-09-22 21:41:40 +00004947 }
4948 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004949
Douglas Gregored5d6512009-09-22 21:41:40 +00004950 break;
4951 }
Mike Stump1eb44332009-09-09 15:08:12 +00004952
Chris Lattnerf97409f2008-04-06 06:57:35 +00004953 // Consume the comma.
4954 ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00004955 }
Mike Stump1eb44332009-09-09 15:08:12 +00004956
Chris Lattner66d28652008-04-06 06:34:08 +00004957}
Chris Lattneref4715c2008-04-06 05:45:57 +00004958
Reid Spencer5f016e22007-07-11 17:01:13 +00004959/// [C90] direct-declarator '[' constant-expression[opt] ']'
4960/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4961/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4962/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4963/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00004964/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4965/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00004966void Parser::ParseBracketDeclarator(Declarator &D) {
Richard Smith6ee326a2012-04-10 01:32:12 +00004967 if (CheckProhibitedCXX11Attribute())
4968 return;
4969
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004970 BalancedDelimiterTracker T(*this, tok::l_square);
4971 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00004972
Chris Lattner378c7e42008-12-18 07:27:21 +00004973 // C array syntax has many features, but by-far the most common is [] and [4].
4974 // This code does a fast path to handle some of the most obvious cases.
4975 if (Tok.getKind() == tok::r_square) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004976 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00004977 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004978 MaybeParseCXX0XAttributes(attrs);
Chad Rosier8decdee2012-06-26 22:30:43 +00004979
Chris Lattner378c7e42008-12-18 07:27:21 +00004980 // Remember that we parsed the empty array type.
John McCall60d7b3a2010-08-24 06:29:42 +00004981 ExprResult NumElements;
John McCall0b7e6782011-03-24 11:26:52 +00004982 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004983 T.getOpenLocation(),
4984 T.getCloseLocation()),
4985 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00004986 return;
4987 } else if (Tok.getKind() == tok::numeric_constant &&
4988 GetLookAheadToken(1).is(tok::r_square)) {
4989 // [4] is very common. Parse the numeric constant expression.
Richard Smith36f5cfe2012-03-09 08:00:36 +00004990 ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
Chris Lattner378c7e42008-12-18 07:27:21 +00004991 ConsumeToken();
4992
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004993 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00004994 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00004995 MaybeParseCXX0XAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004996
Chris Lattner378c7e42008-12-18 07:27:21 +00004997 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00004998 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
John McCall7f040a92010-12-24 02:08:15 +00004999 ExprRes.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005000 T.getOpenLocation(),
5001 T.getCloseLocation()),
5002 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00005003 return;
5004 }
Mike Stump1eb44332009-09-09 15:08:12 +00005005
Reid Spencer5f016e22007-07-11 17:01:13 +00005006 // If valid, this location is the position where we read the 'static' keyword.
5007 SourceLocation StaticLoc;
Chris Lattner04d66662007-10-09 17:33:22 +00005008 if (Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00005009 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005010
Reid Spencer5f016e22007-07-11 17:01:13 +00005011 // If there is a type-qualifier-list, read it now.
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005012 // Type qualifiers in an array subscript are a C99 feature.
John McCall0b7e6782011-03-24 11:26:52 +00005013 DeclSpec DS(AttrFactory);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00005014 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Mike Stump1eb44332009-09-09 15:08:12 +00005015
Reid Spencer5f016e22007-07-11 17:01:13 +00005016 // If we haven't already read 'static', check to see if there is one after the
5017 // type-qualifier-list.
Chris Lattner04d66662007-10-09 17:33:22 +00005018 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00005019 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005020
Reid Spencer5f016e22007-07-11 17:01:13 +00005021 // Handle "direct-declarator [ type-qual-list[opt] * ]".
5022 bool isStar = false;
John McCall60d7b3a2010-08-24 06:29:42 +00005023 ExprResult NumElements;
Mike Stump1eb44332009-09-09 15:08:12 +00005024
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005025 // Handle the case where we have '[*]' as the array size. However, a leading
5026 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
Sylvestre Ledrubed28ac2012-07-23 08:59:39 +00005027 // the token after the star is a ']'. Since stars in arrays are
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005028 // infrequent, use of lookahead is not costly here.
5029 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattnera711dd02008-04-06 05:27:21 +00005030 ConsumeToken(); // Eat the '*'.
Reid Spencer5f016e22007-07-11 17:01:13 +00005031
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005032 if (StaticLoc.isValid()) {
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005033 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005034 StaticLoc = SourceLocation(); // Drop the static.
5035 }
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005036 isStar = true;
Chris Lattner04d66662007-10-09 17:33:22 +00005037 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner378c7e42008-12-18 07:27:21 +00005038 // Note, in C89, this production uses the constant-expr production instead
5039 // of assignment-expr. The only difference is that assignment-expr allows
5040 // things like '=' and '*='. Sema rejects these in C89 mode because they
5041 // are not i-c-e's, so we don't need to distinguish between the two here.
Mike Stump1eb44332009-09-09 15:08:12 +00005042
Douglas Gregore0762c92009-06-19 23:52:42 +00005043 // Parse the constant-expression or assignment-expression now (depending
5044 // on dialect).
David Blaikie4e4d0842012-03-11 07:00:24 +00005045 if (getLangOpts().CPlusPlus) {
Douglas Gregore0762c92009-06-19 23:52:42 +00005046 NumElements = ParseConstantExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00005047 } else {
5048 EnterExpressionEvaluationContext Unevaluated(Actions,
5049 Sema::ConstantEvaluated);
Douglas Gregore0762c92009-06-19 23:52:42 +00005050 NumElements = ParseAssignmentExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00005051 }
Reid Spencer5f016e22007-07-11 17:01:13 +00005052 }
Mike Stump1eb44332009-09-09 15:08:12 +00005053
Reid Spencer5f016e22007-07-11 17:01:13 +00005054 // If there was an error parsing the assignment-expression, recover.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00005055 if (NumElements.isInvalid()) {
Chris Lattner5cb10d32009-04-24 22:30:50 +00005056 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00005057 // If the expression was invalid, skip it.
5058 SkipUntil(tok::r_square);
5059 return;
5060 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00005061
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005062 T.consumeClose();
Sebastian Redlab197ba2009-02-09 18:23:29 +00005063
John McCall0b7e6782011-03-24 11:26:52 +00005064 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00005065 MaybeParseCXX0XAttributes(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00005066
Chris Lattner378c7e42008-12-18 07:27:21 +00005067 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00005068 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
Reid Spencer5f016e22007-07-11 17:01:13 +00005069 StaticLoc.isValid(), isStar,
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00005070 NumElements.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005071 T.getOpenLocation(),
5072 T.getCloseLocation()),
5073 attrs, T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00005074}
5075
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005076/// [GNU] typeof-specifier:
5077/// typeof ( expressions )
5078/// typeof ( type-name )
5079/// [GNU/C++] typeof unary-expression
Steve Naroffd1861fd2007-07-31 12:34:36 +00005080///
5081void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner04d66662007-10-09 17:33:22 +00005082 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005083 Token OpTok = Tok;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005084 SourceLocation StartLoc = ConsumeToken();
5085
John McCallcfb708c2010-01-13 20:03:27 +00005086 const bool hasParens = Tok.is(tok::l_paren);
5087
Eli Friedman80bfa3d2012-09-26 04:34:21 +00005088 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
5089 Sema::ReuseLambdaContextDecl);
Eli Friedman71b8fb52012-01-21 01:01:51 +00005090
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005091 bool isCastExpr;
John McCallb3d87482010-08-24 05:47:05 +00005092 ParsedType CastTy;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005093 SourceRange CastRange;
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00005094 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
5095 CastTy, CastRange);
John McCallcfb708c2010-01-13 20:03:27 +00005096 if (hasParens)
5097 DS.setTypeofParensRange(CastRange);
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005098
5099 if (CastRange.getEnd().isInvalid())
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005100 // FIXME: Not accurate, the range gets one token more than it should.
5101 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005102 else
5103 DS.SetRangeEnd(CastRange.getEnd());
Mike Stump1eb44332009-09-09 15:08:12 +00005104
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005105 if (isCastExpr) {
5106 if (!CastTy) {
5107 DS.SetTypeSpecError();
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005108 return;
Douglas Gregor809070a2009-02-18 17:45:20 +00005109 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005110
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005111 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005112 unsigned DiagID;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005113 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5114 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00005115 DiagID, CastTy))
5116 Diag(StartLoc, DiagID) << PrevSpec;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005117 return;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005118 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005119
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005120 // If we get here, the operand to the typeof was an expresion.
5121 if (Operand.isInvalid()) {
5122 DS.SetTypeSpecError();
Steve Naroff9dfa7b42007-08-02 02:53:48 +00005123 return;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005124 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005125
Eli Friedman71b8fb52012-01-21 01:01:51 +00005126 // We might need to transform the operand if it is potentially evaluated.
5127 Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5128 if (Operand.isInvalid()) {
5129 DS.SetTypeSpecError();
5130 return;
5131 }
5132
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005133 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005134 unsigned DiagID;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005135 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5136 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00005137 DiagID, Operand.get()))
John McCallfec54012009-08-03 20:12:06 +00005138 Diag(StartLoc, DiagID) << PrevSpec;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005139}
Chris Lattner1b492422010-02-28 18:33:55 +00005140
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00005141/// [C11] atomic-specifier:
Eli Friedmanb001de72011-10-06 23:00:33 +00005142/// _Atomic ( type-name )
5143///
5144void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
5145 assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier");
5146
5147 SourceLocation StartLoc = ConsumeToken();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005148 BalancedDelimiterTracker T(*this, tok::l_paren);
5149 if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) {
Eli Friedmanb001de72011-10-06 23:00:33 +00005150 SkipUntil(tok::r_paren);
5151 return;
5152 }
5153
5154 TypeResult Result = ParseTypeName();
5155 if (Result.isInvalid()) {
5156 SkipUntil(tok::r_paren);
5157 return;
5158 }
5159
5160 // Match the ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005161 T.consumeClose();
Eli Friedmanb001de72011-10-06 23:00:33 +00005162
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005163 if (T.getCloseLocation().isInvalid())
Eli Friedmanb001de72011-10-06 23:00:33 +00005164 return;
5165
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005166 DS.setTypeofParensRange(T.getRange());
5167 DS.SetRangeEnd(T.getCloseLocation());
Eli Friedmanb001de72011-10-06 23:00:33 +00005168
5169 const char *PrevSpec = 0;
5170 unsigned DiagID;
5171 if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5172 DiagID, Result.release()))
5173 Diag(StartLoc, DiagID) << PrevSpec;
5174}
5175
Chris Lattner1b492422010-02-28 18:33:55 +00005176
5177/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5178/// from TryAltiVecVectorToken.
5179bool Parser::TryAltiVecVectorTokenOutOfLine() {
5180 Token Next = NextToken();
5181 switch (Next.getKind()) {
5182 default: return false;
5183 case tok::kw_short:
5184 case tok::kw_long:
5185 case tok::kw_signed:
5186 case tok::kw_unsigned:
5187 case tok::kw_void:
5188 case tok::kw_char:
5189 case tok::kw_int:
5190 case tok::kw_float:
5191 case tok::kw_double:
5192 case tok::kw_bool:
5193 case tok::kw___pixel:
5194 Tok.setKind(tok::kw___vector);
5195 return true;
5196 case tok::identifier:
5197 if (Next.getIdentifierInfo() == Ident_pixel) {
5198 Tok.setKind(tok::kw___vector);
5199 return true;
5200 }
5201 return false;
5202 }
5203}
5204
5205bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5206 const char *&PrevSpec, unsigned &DiagID,
5207 bool &isInvalid) {
5208 if (Tok.getIdentifierInfo() == Ident_vector) {
5209 Token Next = NextToken();
5210 switch (Next.getKind()) {
5211 case tok::kw_short:
5212 case tok::kw_long:
5213 case tok::kw_signed:
5214 case tok::kw_unsigned:
5215 case tok::kw_void:
5216 case tok::kw_char:
5217 case tok::kw_int:
5218 case tok::kw_float:
5219 case tok::kw_double:
5220 case tok::kw_bool:
5221 case tok::kw___pixel:
5222 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5223 return true;
5224 case tok::identifier:
5225 if (Next.getIdentifierInfo() == Ident_pixel) {
5226 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5227 return true;
5228 }
5229 break;
5230 default:
5231 break;
5232 }
Douglas Gregora8f031f2010-06-16 15:28:57 +00005233 } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
Chris Lattner1b492422010-02-28 18:33:55 +00005234 DS.isTypeAltiVecVector()) {
5235 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5236 return true;
5237 }
5238 return false;
5239}