blob: 7b8093408bfd761d9b2ea8cc1b8f402b46a0a6ef [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"
Chandler Carruth55fc8732012-12-04 09:13:33 +000015#include "RAIIObjectsForParser.h"
Larisse Voufo7c64ef02013-06-21 00:08:46 +000016#include "clang/AST/DeclTemplate.h"
Benjamin Kramer9852f582012-12-01 16:35:25 +000017#include "clang/Basic/AddressSpaces.h"
Jordan Rose3f6f51e2013-02-08 22:30:41 +000018#include "clang/Basic/CharInfo.h"
Peter Collingbourne207f4d82011-03-18 22:38:29 +000019#include "clang/Basic/OpenCL.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000020#include "clang/Parse/ParseDiagnostic.h"
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +000021#include "clang/Sema/Lookup.h"
John McCall19510852010-08-20 18:27:03 +000022#include "clang/Sema/ParsedTemplate.h"
John McCallf312b1e2010-08-26 23:41:50 +000023#include "clang/Sema/PrettyDeclStackTrace.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000024#include "clang/Sema/Scope.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000025#include "llvm/ADT/SmallSet.h"
Benjamin Kramer8fe83e12012-02-04 13:45:25 +000026#include "llvm/ADT/SmallString.h"
Caitlin Sadowskib51e0312011-08-09 17:59:31 +000027#include "llvm/ADT/StringSwitch.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000028using namespace clang;
29
30//===----------------------------------------------------------------------===//
31// C99 6.7: Declarations.
32//===----------------------------------------------------------------------===//
33
34/// ParseTypeName
35/// type-name: [C99 6.7.6]
36/// specifier-qualifier-list abstract-declarator[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +000037///
38/// Called type-id in C++.
Douglas Gregor683a81f2011-01-31 16:09:46 +000039TypeResult Parser::ParseTypeName(SourceRange *Range,
John McCallf85e1932011-06-15 23:02:42 +000040 Declarator::TheContext Context,
Richard Smithc89edf52011-07-01 19:46:12 +000041 AccessSpecifier AS,
Richard Smith6b3d3e52013-02-20 19:22:51 +000042 Decl **OwnedType,
43 ParsedAttributes *Attrs) {
Richard Smith6d96d3a2012-03-15 01:02:11 +000044 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
Richard Smitha971d242012-05-09 20:55:26 +000045 if (DSC == DSC_normal)
46 DSC = DSC_type_specifier;
Richard Smith7796eb52012-03-12 08:56:40 +000047
Reid Spencer5f016e22007-07-11 17:01:13 +000048 // Parse the common declaration-specifiers piece.
John McCall0b7e6782011-03-24 11:26:52 +000049 DeclSpec DS(AttrFactory);
Richard Smith6b3d3e52013-02-20 19:22:51 +000050 if (Attrs)
51 DS.addAttributes(Attrs->getList());
Richard Smith7796eb52012-03-12 08:56:40 +000052 ParseSpecifierQualifierList(DS, AS, DSC);
Richard Smithc89edf52011-07-01 19:46:12 +000053 if (OwnedType)
54 *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
Sebastian Redlef65f062009-05-29 18:02:33 +000055
Reid Spencer5f016e22007-07-11 17:01:13 +000056 // Parse the abstract-declarator, if present.
Douglas Gregor683a81f2011-01-31 16:09:46 +000057 Declarator DeclaratorInfo(DS, Context);
Reid Spencer5f016e22007-07-11 17:01:13 +000058 ParseDeclarator(DeclaratorInfo);
Sebastian Redlef65f062009-05-29 18:02:33 +000059 if (Range)
60 *Range = DeclaratorInfo.getSourceRange();
61
Chris Lattnereaaebc72009-04-25 08:06:05 +000062 if (DeclaratorInfo.isInvalidType())
Douglas Gregor809070a2009-02-18 17:45:20 +000063 return true;
64
Douglas Gregor23c94db2010-07-02 17:43:08 +000065 return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
Reid Spencer5f016e22007-07-11 17:01:13 +000066}
67
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +000068
69/// isAttributeLateParsed - Return true if the attribute has arguments that
70/// require late parsing.
71static bool isAttributeLateParsed(const IdentifierInfo &II) {
72 return llvm::StringSwitch<bool>(II.getName())
73#include "clang/Parse/AttrLateParsed.inc"
74 .Default(false);
75}
76
Sean Huntbbd37c62009-11-21 08:43:09 +000077/// ParseGNUAttributes - Parse a non-empty attributes list.
Reid Spencer5f016e22007-07-11 17:01:13 +000078///
79/// [GNU] attributes:
80/// attribute
81/// attributes attribute
82///
83/// [GNU] attribute:
84/// '__attribute__' '(' '(' attribute-list ')' ')'
85///
86/// [GNU] attribute-list:
87/// attrib
88/// attribute_list ',' attrib
89///
90/// [GNU] attrib:
91/// empty
92/// attrib-name
93/// attrib-name '(' identifier ')'
94/// attrib-name '(' identifier ',' nonempty-expr-list ')'
95/// attrib-name '(' argument-expression-list [C99 6.5.2] ')'
96///
97/// [GNU] attrib-name:
98/// identifier
99/// typespec
100/// typequal
101/// storageclass
Mike Stump1eb44332009-09-09 15:08:12 +0000102///
Richard Smith4c6c4112013-09-03 18:57:36 +0000103/// Whether an attribute takes an 'identifier' is determined by the
104/// attrib-name. GCC's behavior here is not worth imitating:
Reid Spencer5f016e22007-07-11 17:01:13 +0000105///
Richard Smith4c6c4112013-09-03 18:57:36 +0000106/// * In C mode, if the attribute argument list starts with an identifier
107/// followed by a ',' or an ')', and the identifier doesn't resolve to
108/// a type, it is parsed as an identifier. If the attribute actually
109/// wanted an expression, it's out of luck (but it turns out that no
110/// attributes work that way, because C constant expressions are very
111/// limited).
112/// * In C++ mode, if the attribute argument list starts with an identifier,
113/// and the attribute *wants* an identifier, it is parsed as an identifier.
114/// At block scope, any additional tokens between the identifier and the
115/// ',' or ')' are ignored, otherwise they produce a parse error.
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000116///
Richard Smith4c6c4112013-09-03 18:57:36 +0000117/// We follow the C++ model, but don't allow junk after the identifier.
John McCall7f040a92010-12-24 02:08:15 +0000118void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000119 SourceLocation *endLoc,
120 LateParsedAttrList *LateAttrs) {
Sean Huntbbd37c62009-11-21 08:43:09 +0000121 assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
Mike Stump1eb44332009-09-09 15:08:12 +0000122
Chris Lattner04d66662007-10-09 17:33:22 +0000123 while (Tok.is(tok::kw___attribute)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000124 ConsumeToken();
125 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
126 "attribute")) {
Alexey Bataev8fe24752013-11-18 08:17:37 +0000127 SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
John McCall7f040a92010-12-24 02:08:15 +0000128 return;
Reid Spencer5f016e22007-07-11 17:01:13 +0000129 }
130 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
Alexey Bataev8fe24752013-11-18 08:17:37 +0000131 SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
John McCall7f040a92010-12-24 02:08:15 +0000132 return;
Reid Spencer5f016e22007-07-11 17:01:13 +0000133 }
134 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
Chris Lattner04d66662007-10-09 17:33:22 +0000135 while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
136 Tok.is(tok::comma)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000137 if (Tok.is(tok::comma)) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000138 // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
139 ConsumeToken();
140 continue;
141 }
142 // we have an identifier or declaration specifier (const, int, etc.)
143 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
144 SourceLocation AttrNameLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +0000145
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000146 if (Tok.is(tok::l_paren)) {
147 // handle "parameterized" attributes
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000148 if (LateAttrs && isAttributeLateParsed(*AttrName)) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000149 LateParsedAttribute *LA =
150 new LateParsedAttribute(this, *AttrName, AttrNameLoc);
151 LateAttrs->push_back(LA);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000152
Bill Wendlingad017fa2012-12-20 19:22:21 +0000153 // Attributes in a class are parsed at the end of the class, along
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000154 // with other late-parsed declarations.
DeLesley Hutchins161db022012-11-02 21:44:32 +0000155 if (!ClassStack.empty() && !LateAttrs->parseSoon())
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000156 getCurrentClass().LateParsedDeclarations.push_back(LA);
Mike Stump1eb44332009-09-09 15:08:12 +0000157
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000158 // consume everything up to and including the matching right parens
159 ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
Mike Stump1eb44332009-09-09 15:08:12 +0000160
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000161 Token Eof;
162 Eof.startToken();
163 Eof.setLocation(Tok.getLocation());
164 LA->Toks.push_back(Eof);
165 } else {
Michael Han6880f492012-10-03 01:56:22 +0000166 ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
Michael Han45bed132012-10-04 16:42:52 +0000167 0, SourceLocation(), AttributeList::AS_GNU);
Reid Spencer5f016e22007-07-11 17:01:13 +0000168 }
169 } else {
Aaron Ballman624421f2013-08-31 01:11:41 +0000170 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
171 AttributeList::AS_GNU);
Reid Spencer5f016e22007-07-11 17:01:13 +0000172 }
173 }
174 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
Alexey Bataev8fe24752013-11-18 08:17:37 +0000175 SkipUntil(tok::r_paren, StopAtSemi);
Sean Huntbbd37c62009-11-21 08:43:09 +0000176 SourceLocation Loc = Tok.getLocation();
Richard Smithd92aa2d2013-10-24 01:07:54 +0000177 if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
Alexey Bataev8fe24752013-11-18 08:17:37 +0000178 SkipUntil(tok::r_paren, StopAtSemi);
John McCall7f040a92010-12-24 02:08:15 +0000179 if (endLoc)
180 *endLoc = Loc;
Reid Spencer5f016e22007-07-11 17:01:13 +0000181 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000182}
183
Aaron Ballman9feedb82013-11-04 12:55:56 +0000184/// \brief Normalizes an attribute name by dropping prefixed and suffixed __.
185static StringRef normalizeAttrName(StringRef Name) {
Richard Smithd92aa2d2013-10-24 01:07:54 +0000186 if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
187 Name = Name.drop_front(2).drop_back(2);
Aaron Ballman9feedb82013-11-04 12:55:56 +0000188 return Name;
189}
190
191/// \brief Determine whether the given attribute has an identifier argument.
192static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
193 return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
Richard Smithd92aa2d2013-10-24 01:07:54 +0000194#include "clang/Parse/AttrIdentifierArg.inc"
Douglas Gregor92eb7d82013-05-02 23:25:32 +0000195 .Default(false);
196}
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000197
Aaron Ballman9feedb82013-11-04 12:55:56 +0000198/// \brief Determine whether the given attribute parses a type argument.
199static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
200 return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
201#include "clang/Parse/AttrTypeArg.inc"
202 .Default(false);
203}
204
Richard Smith8edabd92013-09-03 18:01:40 +0000205IdentifierLoc *Parser::ParseIdentifierLoc() {
206 assert(Tok.is(tok::identifier) && "expected an identifier");
207 IdentifierLoc *IL = IdentifierLoc::create(Actions.Context,
208 Tok.getLocation(),
209 Tok.getIdentifierInfo());
210 ConsumeToken();
211 return IL;
212}
213
Richard Smithd386fef2013-10-31 01:56:18 +0000214void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
215 SourceLocation AttrNameLoc,
216 ParsedAttributes &Attrs,
217 SourceLocation *EndLoc) {
218 BalancedDelimiterTracker Parens(*this, tok::l_paren);
219 Parens.consumeOpen();
220
221 TypeResult T;
222 if (Tok.isNot(tok::r_paren))
223 T = ParseTypeName();
224
225 if (Parens.consumeClose())
226 return;
227
228 if (T.isInvalid())
229 return;
230
231 if (T.isUsable())
232 Attrs.addNewTypeAttr(&AttrName,
233 SourceRange(AttrNameLoc, Parens.getCloseLocation()), 0,
234 AttrNameLoc, T.get(), AttributeList::AS_GNU);
235 else
236 Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),
237 0, AttrNameLoc, 0, 0, AttributeList::AS_GNU);
238}
239
Michael Han6880f492012-10-03 01:56:22 +0000240/// Parse the arguments to a parameterized GNU attribute or
241/// a C++11 attribute in "gnu" namespace.
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000242void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
243 SourceLocation AttrNameLoc,
244 ParsedAttributes &Attrs,
Michael Han6880f492012-10-03 01:56:22 +0000245 SourceLocation *EndLoc,
246 IdentifierInfo *ScopeName,
247 SourceLocation ScopeLoc,
248 AttributeList::Syntax Syntax) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000249
250 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
251
Richard Smithd92aa2d2013-10-24 01:07:54 +0000252 AttributeList::Kind AttrKind =
Richard Smithd386fef2013-10-31 01:56:18 +0000253 AttributeList::getKind(AttrName, ScopeName, Syntax);
Richard Smithd92aa2d2013-10-24 01:07:54 +0000254
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000255 // Availability attributes have their own grammar.
Richard Smithd386fef2013-10-31 01:56:18 +0000256 // FIXME: All these cases fail to pass in the syntax and scope, and might be
257 // written as C++11 gnu:: attributes.
Richard Smithd92aa2d2013-10-24 01:07:54 +0000258 if (AttrKind == AttributeList::AT_Availability) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000259 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
260 return;
261 }
Richard Smithd386fef2013-10-31 01:56:18 +0000262 // Thread safety attributes are parsed in an unevaluated context.
263 // FIXME: Share the bulk of the parsing code here and just pull out
264 // the unevaluated context.
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000265 if (IsThreadSafetyAttribute(AttrName->getName())) {
266 ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
267 return;
268 }
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +0000269 // Type safety attributes have their own grammar.
Richard Smithd92aa2d2013-10-24 01:07:54 +0000270 if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +0000271 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
272 return;
273 }
Aaron Ballman9feedb82013-11-04 12:55:56 +0000274 // Some attributes expect solely a type parameter.
275 if (attributeIsTypeArgAttr(*AttrName)) {
Richard Smithd386fef2013-10-31 01:56:18 +0000276 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc);
277 return;
278 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000279
Richard Smithd92aa2d2013-10-24 01:07:54 +0000280 // Ignore the left paren location for now.
281 ConsumeParen();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000282
Aaron Ballman624421f2013-08-31 01:11:41 +0000283 ArgsVector ArgExprs;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000284
Richard Smithd386fef2013-10-31 01:56:18 +0000285 if (Tok.is(tok::identifier)) {
Richard Smithd92aa2d2013-10-24 01:07:54 +0000286 // If this attribute wants an 'identifier' argument, make it so.
Richard Smithd386fef2013-10-31 01:56:18 +0000287 bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName);
Richard Smithd92aa2d2013-10-24 01:07:54 +0000288
289 // If we don't know how to parse this attribute, but this is the only
290 // token in this argument, assume it's meant to be an identifier.
Bill Wendling307c92e2013-12-05 18:35:37 +0000291 if (AttrKind == AttributeList::UnknownAttribute ||
292 AttrKind == AttributeList::IgnoredAttribute) {
Richard Smithd92aa2d2013-10-24 01:07:54 +0000293 const Token &Next = NextToken();
Richard Smithd386fef2013-10-31 01:56:18 +0000294 IsIdentifierArg = Next.is(tok::r_paren) || Next.is(tok::comma);
Richard Smithd92aa2d2013-10-24 01:07:54 +0000295 }
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000296
Richard Smithd386fef2013-10-31 01:56:18 +0000297 if (IsIdentifierArg)
298 ArgExprs.push_back(ParseIdentifierLoc());
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000299 }
300
Richard Smithd386fef2013-10-31 01:56:18 +0000301 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000302 // Eat the comma.
Aaron Ballman624421f2013-08-31 01:11:41 +0000303 if (!ArgExprs.empty())
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000304 ConsumeToken();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000305
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000306 // Parse the non-empty comma-separated list of expressions.
307 while (1) {
308 ExprResult ArgExpr(ParseAssignmentExpression());
309 if (ArgExpr.isInvalid()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +0000310 SkipUntil(tok::r_paren, StopAtSemi);
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000311 return;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000312 }
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000313 ArgExprs.push_back(ArgExpr.release());
314 if (Tok.isNot(tok::comma))
315 break;
316 ConsumeToken(); // Eat the comma, move to the next argument
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000317 }
Fariborz Jahanian7a81e412011-10-18 17:11:10 +0000318 }
Richard Smithfe0a0fb2011-10-17 21:20:17 +0000319
320 SourceLocation RParen = Tok.getLocation();
Richard Smithd386fef2013-10-31 01:56:18 +0000321 if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
Michael Han45bed132012-10-04 16:42:52 +0000322 SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
Richard Smithd386fef2013-10-31 01:56:18 +0000323 Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
324 ArgExprs.data(), ArgExprs.size(), Syntax);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000325 }
326}
327
Chad Rosier8decdee2012-06-26 22:30:43 +0000328/// \brief Parses a single argument for a declspec, including the
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000329/// surrounding parens.
Chad Rosier8decdee2012-06-26 22:30:43 +0000330void Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000331 SourceLocation AttrNameLoc,
332 ParsedAttributes &Attrs)
333{
334 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosier8decdee2012-06-26 22:30:43 +0000335 if (T.expectAndConsume(diag::err_expected_lparen_after,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000336 AttrName->getNameStart(), tok::r_paren))
337 return;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000338
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000339 ExprResult ArgExpr(ParseConstantExpression());
340 if (ArgExpr.isInvalid()) {
341 T.skipToEnd();
342 return;
343 }
Aaron Ballman624421f2013-08-31 01:11:41 +0000344 ArgsUnion ExprList = ArgExpr.take();
345 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, &ExprList, 1,
346 AttributeList::AS_Declspec);
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000347
348 T.consumeClose();
349}
350
Chad Rosier8decdee2012-06-26 22:30:43 +0000351/// \brief Determines whether a declspec is a "simple" one requiring no
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000352/// arguments.
353bool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) {
354 return llvm::StringSwitch<bool>(Ident->getName())
355 .Case("dllimport", true)
356 .Case("dllexport", true)
357 .Case("noreturn", true)
358 .Case("nothrow", true)
359 .Case("noinline", true)
360 .Case("naked", true)
361 .Case("appdomain", true)
362 .Case("process", true)
363 .Case("jitintrinsic", true)
364 .Case("noalias", true)
365 .Case("restrict", true)
366 .Case("novtable", true)
367 .Case("selectany", true)
368 .Case("thread", true)
Aaron Ballman3ce0de62013-05-04 16:58:37 +0000369 .Case("safebuffers", true )
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000370 .Default(false);
371}
372
Chad Rosier8decdee2012-06-26 22:30:43 +0000373/// \brief Attempts to parse a declspec which is not simple (one that takes
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000374/// parameters). Will return false if we properly handled the declspec, or
375/// true if it is an unknown declspec.
Chad Rosier8decdee2012-06-26 22:30:43 +0000376void Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000377 SourceLocation Loc,
378 ParsedAttributes &Attrs) {
379 // Try to handle the easy case first -- these declspecs all take a single
380 // parameter as their argument.
381 if (llvm::StringSwitch<bool>(Ident->getName())
382 .Case("uuid", true)
383 .Case("align", true)
384 .Case("allocate", true)
385 .Default(false)) {
386 ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
387 } else if (Ident->getName() == "deprecated") {
Chad Rosier8decdee2012-06-26 22:30:43 +0000388 // The deprecated declspec has an optional single argument, so we will
389 // check for a l-paren to decide whether we should parse an argument or
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000390 // not.
391 if (Tok.getKind() == tok::l_paren)
392 ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
393 else
Aaron Ballman624421f2013-08-31 01:11:41 +0000394 Attrs.addNew(Ident, Loc, 0, Loc, 0, 0, AttributeList::AS_Declspec);
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000395 } else if (Ident->getName() == "property") {
396 // The property declspec is more complex in that it can take one or two
Chad Rosier8decdee2012-06-26 22:30:43 +0000397 // assignment expressions as a parameter, but the lhs of the assignment
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000398 // must be named get or put.
John McCall76da55d2013-04-16 07:28:30 +0000399 if (Tok.isNot(tok::l_paren)) {
400 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
401 << Ident->getNameStart();
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000402 return;
John McCall76da55d2013-04-16 07:28:30 +0000403 }
404 BalancedDelimiterTracker T(*this, tok::l_paren);
405 T.expectAndConsume(diag::err_expected_lparen_after,
406 Ident->getNameStart(), tok::r_paren);
407
408 enum AccessorKind {
409 AK_Invalid = -1,
410 AK_Put = 0, AK_Get = 1 // indices into AccessorNames
411 };
412 IdentifierInfo *AccessorNames[] = { 0, 0 };
413 bool HasInvalidAccessor = false;
414
415 // Parse the accessor specifications.
416 while (true) {
417 // Stop if this doesn't look like an accessor spec.
418 if (!Tok.is(tok::identifier)) {
419 // If the user wrote a completely empty list, use a special diagnostic.
420 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
421 AccessorNames[AK_Put] == 0 && AccessorNames[AK_Get] == 0) {
422 Diag(Loc, diag::err_ms_property_no_getter_or_putter);
423 break;
424 }
425
426 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
427 break;
428 }
429
430 AccessorKind Kind;
431 SourceLocation KindLoc = Tok.getLocation();
432 StringRef KindStr = Tok.getIdentifierInfo()->getName();
433 if (KindStr == "get") {
434 Kind = AK_Get;
435 } else if (KindStr == "put") {
436 Kind = AK_Put;
437
438 // Recover from the common mistake of using 'set' instead of 'put'.
439 } else if (KindStr == "set") {
440 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
441 << FixItHint::CreateReplacement(KindLoc, "put");
442 Kind = AK_Put;
443
444 // Handle the mistake of forgetting the accessor kind by skipping
445 // this accessor.
446 } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) {
447 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
448 ConsumeToken();
449 HasInvalidAccessor = true;
450 goto next_property_accessor;
451
452 // Otherwise, complain about the unknown accessor kind.
453 } else {
454 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
455 HasInvalidAccessor = true;
456 Kind = AK_Invalid;
457
458 // Try to keep parsing unless it doesn't look like an accessor spec.
459 if (!NextToken().is(tok::equal)) break;
460 }
461
462 // Consume the identifier.
463 ConsumeToken();
464
465 // Consume the '='.
466 if (Tok.is(tok::equal)) {
467 ConsumeToken();
468 } else {
469 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
470 << KindStr;
471 break;
472 }
473
474 // Expect the method name.
475 if (!Tok.is(tok::identifier)) {
476 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
477 break;
478 }
479
480 if (Kind == AK_Invalid) {
481 // Just drop invalid accessors.
482 } else if (AccessorNames[Kind] != NULL) {
483 // Complain about the repeated accessor, ignore it, and keep parsing.
484 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
485 } else {
486 AccessorNames[Kind] = Tok.getIdentifierInfo();
487 }
488 ConsumeToken();
489
490 next_property_accessor:
491 // Keep processing accessors until we run out.
492 if (Tok.is(tok::comma)) {
493 ConsumeAnyToken();
494 continue;
495
496 // If we run into the ')', stop without consuming it.
497 } else if (Tok.is(tok::r_paren)) {
498 break;
499 } else {
500 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
501 break;
502 }
503 }
504
505 // Only add the property attribute if it was well-formed.
506 if (!HasInvalidAccessor) {
Aaron Ballman624421f2013-08-31 01:11:41 +0000507 Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(),
John McCall76da55d2013-04-16 07:28:30 +0000508 AccessorNames[AK_Get], AccessorNames[AK_Put],
509 AttributeList::AS_Declspec);
510 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000511 T.skipToEnd();
512 } else {
513 // We don't recognize this as a valid declspec, but instead of creating the
514 // attribute and allowing sema to warn about it, we will warn here instead.
515 // This is because some attributes have multiple spellings, but we need to
516 // disallow that for declspecs (such as align vs aligned). If we made the
Chad Rosier8decdee2012-06-26 22:30:43 +0000517 // attribute, we'd have to split the valid declspec spelling logic into
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000518 // both locations.
519 Diag(Loc, diag::warn_ms_declspec_unknown) << Ident;
520
521 // If there's an open paren, we should eat the open and close parens under
522 // the assumption that this unknown declspec has parameters.
523 BalancedDelimiterTracker T(*this, tok::l_paren);
524 if (!T.consumeOpen())
525 T.skipToEnd();
526 }
527}
528
Eli Friedmana23b4852009-06-08 07:21:15 +0000529/// [MS] decl-specifier:
530/// __declspec ( extended-decl-modifier-seq )
531///
532/// [MS] extended-decl-modifier-seq:
533/// extended-decl-modifier[opt]
534/// extended-decl-modifier extended-decl-modifier-seq
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000535void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
Steve Narofff59e17e2008-12-24 20:59:21 +0000536 assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
Eli Friedmana23b4852009-06-08 07:21:15 +0000537
Steve Narofff59e17e2008-12-24 20:59:21 +0000538 ConsumeToken();
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000539 BalancedDelimiterTracker T(*this, tok::l_paren);
Chad Rosier8decdee2012-06-26 22:30:43 +0000540 if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000541 tok::r_paren))
John McCall7f040a92010-12-24 02:08:15 +0000542 return;
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000543
Chad Rosier8decdee2012-06-26 22:30:43 +0000544 // An empty declspec is perfectly legal and should not warn. Additionally,
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000545 // you can specify multiple attributes per declspec.
546 while (Tok.getKind() != tok::r_paren) {
547 // We expect either a well-known identifier or a generic string. Anything
548 // else is a malformed declspec.
549 bool IsString = Tok.getKind() == tok::string_literal ? true : false;
Chad Rosier8decdee2012-06-26 22:30:43 +0000550 if (!IsString && Tok.getKind() != tok::identifier &&
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000551 Tok.getKind() != tok::kw_restrict) {
552 Diag(Tok, diag::err_ms_declspec_type);
553 T.skipToEnd();
554 return;
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000555 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000556
557 IdentifierInfo *AttrName;
558 SourceLocation AttrNameLoc;
559 if (IsString) {
560 SmallString<8> StrBuffer;
561 bool Invalid = false;
562 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
563 if (Invalid) {
564 T.skipToEnd();
565 return;
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000566 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000567 AttrName = PP.getIdentifierInfo(Str);
568 AttrNameLoc = ConsumeStringToken();
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000569 } else {
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000570 AttrName = Tok.getIdentifierInfo();
571 AttrNameLoc = ConsumeToken();
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000572 }
Chad Rosier8decdee2012-06-26 22:30:43 +0000573
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000574 if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
Chad Rosier8decdee2012-06-26 22:30:43 +0000575 // If we have a generic string, we will allow it because there is no
576 // documented list of allowable string declspecs, but we know they exist
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000577 // (for instance, SAL declspecs in older versions of MSVC).
578 //
Chad Rosier8decdee2012-06-26 22:30:43 +0000579 // Alternatively, if the identifier is a simple one, then it requires no
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000580 // arguments and can be turned into an attribute directly.
Aaron Ballman624421f2013-08-31 01:11:41 +0000581 Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
582 AttributeList::AS_Declspec);
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000583 else
584 ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
Jakob Stoklund Olesen35329362012-06-19 21:48:43 +0000585 }
Aaron Ballmanfc685ac2012-06-19 22:09:27 +0000586 T.consumeClose();
Eli Friedman290eeb02009-06-08 23:27:34 +0000587}
588
John McCall7f040a92010-12-24 02:08:15 +0000589void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
Eli Friedman290eeb02009-06-08 23:27:34 +0000590 // Treat these like attributes
Eli Friedman290eeb02009-06-08 23:27:34 +0000591 while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
Douglas Gregorf813a2c2010-05-18 16:57:00 +0000592 Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl) ||
Francois Pichet3bd9aa42011-08-18 09:59:55 +0000593 Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
Aaron Ballmanaa9df092013-05-22 23:25:32 +0000594 Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned) ||
595 Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) {
Eli Friedman290eeb02009-06-08 23:27:34 +0000596 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
597 SourceLocation AttrNameLoc = ConsumeToken();
Aaron Ballman624421f2013-08-31 01:11:41 +0000598 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
599 AttributeList::AS_Keyword);
Eli Friedman290eeb02009-06-08 23:27:34 +0000600 }
Steve Narofff59e17e2008-12-24 20:59:21 +0000601}
602
John McCall7f040a92010-12-24 02:08:15 +0000603void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
Dawn Perchik52fc3142010-09-03 01:29:35 +0000604 // Treat these like attributes
605 while (Tok.is(tok::kw___pascal)) {
606 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
607 SourceLocation AttrNameLoc = ConsumeToken();
Aaron Ballman624421f2013-08-31 01:11:41 +0000608 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
609 AttributeList::AS_Keyword);
Dawn Perchik52fc3142010-09-03 01:29:35 +0000610 }
John McCall7f040a92010-12-24 02:08:15 +0000611}
612
Peter Collingbournef315fa82011-02-14 01:42:53 +0000613void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
614 // Treat these like attributes
615 while (Tok.is(tok::kw___kernel)) {
Richard Smith5cd532c2013-01-29 01:24:26 +0000616 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
Peter Collingbournef315fa82011-02-14 01:42:53 +0000617 SourceLocation AttrNameLoc = ConsumeToken();
Aaron Ballman624421f2013-08-31 01:11:41 +0000618 attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
619 AttributeList::AS_Keyword);
Peter Collingbournef315fa82011-02-14 01:42:53 +0000620 }
621}
622
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000623void Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
Richard Smith5cd532c2013-01-29 01:24:26 +0000624 // FIXME: The mapping from attribute spelling to semantics should be
625 // performed in Sema, not here.
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000626 SourceLocation Loc = Tok.getLocation();
627 switch(Tok.getKind()) {
628 // OpenCL qualifiers:
629 case tok::kw___private:
Chad Rosier8decdee2012-06-26 22:30:43 +0000630 case tok::kw_private:
John McCall0b7e6782011-03-24 11:26:52 +0000631 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000632 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000633 PP.getIdentifierInfo("address_space"), Loc, 0);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000634 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000635
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000636 case tok::kw___global:
John McCall0b7e6782011-03-24 11:26:52 +0000637 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000638 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000639 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000640 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000641
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000642 case tok::kw___local:
John McCall0b7e6782011-03-24 11:26:52 +0000643 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000644 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000645 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000646 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000647
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000648 case tok::kw___constant:
John McCall0b7e6782011-03-24 11:26:52 +0000649 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000650 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000651 PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000652 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000653
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000654 case tok::kw___read_only:
John McCall0b7e6782011-03-24 11:26:52 +0000655 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000656 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000657 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000658 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000659
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000660 case tok::kw___write_only:
John McCall0b7e6782011-03-24 11:26:52 +0000661 DS.getAttributes().addNewInteger(
Chad Rosier8decdee2012-06-26 22:30:43 +0000662 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000663 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000664 break;
Chad Rosier8decdee2012-06-26 22:30:43 +0000665
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000666 case tok::kw___read_write:
John McCall0b7e6782011-03-24 11:26:52 +0000667 DS.getAttributes().addNewInteger(
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000668 Actions.getASTContext(),
John McCall0b7e6782011-03-24 11:26:52 +0000669 PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
Peter Collingbourne207f4d82011-03-18 22:38:29 +0000670 break;
671 default: break;
672 }
673}
674
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000675/// \brief Parse a version number.
676///
677/// version:
678/// simple-integer
679/// simple-integer ',' simple-integer
680/// simple-integer ',' simple-integer ',' simple-integer
681VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
682 Range = Tok.getLocation();
683
684 if (!Tok.is(tok::numeric_constant)) {
685 Diag(Tok, diag::err_expected_version);
Alexey Bataev8fe24752013-11-18 08:17:37 +0000686 SkipUntil(tok::comma, tok::r_paren,
687 StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000688 return VersionTuple();
689 }
690
691 // Parse the major (and possibly minor and subminor) versions, which
692 // are stored in the numeric constant. We utilize a quirk of the
693 // lexer, which is that it handles something like 1.2.3 as a single
694 // numeric constant, rather than two separate tokens.
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000695 SmallString<512> Buffer;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000696 Buffer.resize(Tok.getLength()+1);
697 const char *ThisTokBegin = &Buffer[0];
698
699 // Get the spelling of the token, which eliminates trigraphs, etc.
700 bool Invalid = false;
701 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
702 if (Invalid)
703 return VersionTuple();
704
705 // Parse the major version.
706 unsigned AfterMajor = 0;
707 unsigned Major = 0;
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000708 while (AfterMajor < ActualLength && isDigit(ThisTokBegin[AfterMajor])) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000709 Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';
710 ++AfterMajor;
711 }
712
713 if (AfterMajor == 0) {
714 Diag(Tok, diag::err_expected_version);
Alexey Bataev8fe24752013-11-18 08:17:37 +0000715 SkipUntil(tok::comma, tok::r_paren,
716 StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000717 return VersionTuple();
718 }
719
720 if (AfterMajor == ActualLength) {
721 ConsumeToken();
722
723 // We only had a single version component.
724 if (Major == 0) {
725 Diag(Tok, diag::err_zero_version);
726 return VersionTuple();
727 }
728
729 return VersionTuple(Major);
730 }
731
732 if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) {
733 Diag(Tok, diag::err_expected_version);
Alexey Bataev8fe24752013-11-18 08:17:37 +0000734 SkipUntil(tok::comma, tok::r_paren,
735 StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000736 return VersionTuple();
737 }
738
739 // Parse the minor version.
740 unsigned AfterMinor = AfterMajor + 1;
741 unsigned Minor = 0;
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000742 while (AfterMinor < ActualLength && isDigit(ThisTokBegin[AfterMinor])) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000743 Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';
744 ++AfterMinor;
745 }
746
747 if (AfterMinor == ActualLength) {
748 ConsumeToken();
Chad Rosier8decdee2012-06-26 22:30:43 +0000749
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000750 // We had major.minor.
751 if (Major == 0 && Minor == 0) {
752 Diag(Tok, diag::err_zero_version);
753 return VersionTuple();
754 }
755
Chad Rosier8decdee2012-06-26 22:30:43 +0000756 return VersionTuple(Major, Minor);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000757 }
758
759 // If what follows is not a '.', we have a problem.
760 if (ThisTokBegin[AfterMinor] != '.') {
761 Diag(Tok, diag::err_expected_version);
Alexey Bataev8fe24752013-11-18 08:17:37 +0000762 SkipUntil(tok::comma, tok::r_paren,
763 StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
Chad Rosier8decdee2012-06-26 22:30:43 +0000764 return VersionTuple();
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000765 }
766
767 // Parse the subminor version.
768 unsigned AfterSubminor = AfterMinor + 1;
769 unsigned Subminor = 0;
Jordan Rose3f6f51e2013-02-08 22:30:41 +0000770 while (AfterSubminor < ActualLength && isDigit(ThisTokBegin[AfterSubminor])) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000771 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';
772 ++AfterSubminor;
773 }
774
775 if (AfterSubminor != ActualLength) {
776 Diag(Tok, diag::err_expected_version);
Alexey Bataev8fe24752013-11-18 08:17:37 +0000777 SkipUntil(tok::comma, tok::r_paren,
778 StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000779 return VersionTuple();
780 }
781 ConsumeToken();
782 return VersionTuple(Major, Minor, Subminor);
783}
784
785/// \brief Parse the contents of the "availability" attribute.
786///
787/// availability-attribute:
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000788/// 'availability' '(' platform ',' version-arg-list, opt-message')'
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000789///
790/// platform:
791/// identifier
792///
793/// version-arg-list:
794/// version-arg
795/// version-arg ',' version-arg-list
796///
797/// version-arg:
798/// 'introduced' '=' version
799/// 'deprecated' '=' version
Douglas Gregor93a70672012-03-11 04:53:21 +0000800/// 'obsoleted' = version
Douglas Gregorb53e4172011-03-26 03:35:55 +0000801/// 'unavailable'
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000802/// opt-message:
803/// 'message' '=' <string>
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000804void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
805 SourceLocation AvailabilityLoc,
806 ParsedAttributes &attrs,
807 SourceLocation *endLoc) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000808 enum { Introduced, Deprecated, Obsoleted, Unknown };
809 AvailabilityChange Changes[Unknown];
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000810 ExprResult MessageExpr;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000811
812 // Opening '('.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000813 BalancedDelimiterTracker T(*this, tok::l_paren);
814 if (T.consumeOpen()) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000815 Diag(Tok, diag::err_expected_lparen);
816 return;
817 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000818
819 // Parse the platform name,
820 if (Tok.isNot(tok::identifier)) {
821 Diag(Tok, diag::err_availability_expected_platform);
Alexey Bataev8fe24752013-11-18 08:17:37 +0000822 SkipUntil(tok::r_paren, StopAtSemi);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000823 return;
824 }
Richard Smith8edabd92013-09-03 18:01:40 +0000825 IdentifierLoc *Platform = ParseIdentifierLoc();
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000826
827 // Parse the ',' following the platform name.
828 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
829 return;
830
831 // If we haven't grabbed the pointers for the identifiers
832 // "introduced", "deprecated", and "obsoleted", do so now.
833 if (!Ident_introduced) {
834 Ident_introduced = PP.getIdentifierInfo("introduced");
835 Ident_deprecated = PP.getIdentifierInfo("deprecated");
836 Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
Douglas Gregorb53e4172011-03-26 03:35:55 +0000837 Ident_unavailable = PP.getIdentifierInfo("unavailable");
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000838 Ident_message = PP.getIdentifierInfo("message");
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000839 }
840
841 // Parse the set of introductions/deprecations/removals.
Douglas Gregorb53e4172011-03-26 03:35:55 +0000842 SourceLocation UnavailableLoc;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000843 do {
844 if (Tok.isNot(tok::identifier)) {
845 Diag(Tok, diag::err_availability_expected_change);
Alexey Bataev8fe24752013-11-18 08:17:37 +0000846 SkipUntil(tok::r_paren, StopAtSemi);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000847 return;
848 }
849 IdentifierInfo *Keyword = Tok.getIdentifierInfo();
850 SourceLocation KeywordLoc = ConsumeToken();
851
Douglas Gregorb53e4172011-03-26 03:35:55 +0000852 if (Keyword == Ident_unavailable) {
853 if (UnavailableLoc.isValid()) {
854 Diag(KeywordLoc, diag::err_availability_redundant)
855 << Keyword << SourceRange(UnavailableLoc);
Chad Rosier8decdee2012-06-26 22:30:43 +0000856 }
Douglas Gregorb53e4172011-03-26 03:35:55 +0000857 UnavailableLoc = KeywordLoc;
858
859 if (Tok.isNot(tok::comma))
860 break;
861
862 ConsumeToken();
863 continue;
Chad Rosier8decdee2012-06-26 22:30:43 +0000864 }
865
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000866 if (Tok.isNot(tok::equal)) {
867 Diag(Tok, diag::err_expected_equal_after)
868 << Keyword;
Alexey Bataev8fe24752013-11-18 08:17:37 +0000869 SkipUntil(tok::r_paren, StopAtSemi);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000870 return;
871 }
872 ConsumeToken();
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000873 if (Keyword == Ident_message) {
Benjamin Kramerc5617142013-09-13 17:31:48 +0000874 if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals.
Andy Gibbs97f84612012-11-17 19:16:52 +0000875 Diag(Tok, diag::err_expected_string_literal)
876 << /*Source='availability attribute'*/2;
Alexey Bataev8fe24752013-11-18 08:17:37 +0000877 SkipUntil(tok::r_paren, StopAtSemi);
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000878 return;
879 }
880 MessageExpr = ParseStringLiteralExpression();
881 break;
882 }
Chad Rosier8decdee2012-06-26 22:30:43 +0000883
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000884 SourceRange VersionRange;
885 VersionTuple Version = ParseVersionTuple(VersionRange);
Chad Rosier8decdee2012-06-26 22:30:43 +0000886
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000887 if (Version.empty()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +0000888 SkipUntil(tok::r_paren, StopAtSemi);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000889 return;
890 }
891
892 unsigned Index;
893 if (Keyword == Ident_introduced)
894 Index = Introduced;
895 else if (Keyword == Ident_deprecated)
896 Index = Deprecated;
897 else if (Keyword == Ident_obsoleted)
898 Index = Obsoleted;
Chad Rosier8decdee2012-06-26 22:30:43 +0000899 else
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000900 Index = Unknown;
901
902 if (Index < Unknown) {
903 if (!Changes[Index].KeywordLoc.isInvalid()) {
904 Diag(KeywordLoc, diag::err_availability_redundant)
Chad Rosier8decdee2012-06-26 22:30:43 +0000905 << Keyword
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000906 << SourceRange(Changes[Index].KeywordLoc,
907 Changes[Index].VersionRange.getEnd());
908 }
909
910 Changes[Index].KeywordLoc = KeywordLoc;
911 Changes[Index].Version = Version;
912 Changes[Index].VersionRange = VersionRange;
913 } else {
914 Diag(KeywordLoc, diag::err_availability_unknown_change)
915 << Keyword << VersionRange;
916 }
917
918 if (Tok.isNot(tok::comma))
919 break;
920
921 ConsumeToken();
922 } while (true);
923
924 // Closing ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000925 if (T.consumeClose())
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000926 return;
927
928 if (endLoc)
Douglas Gregor4a8dfb52011-10-12 16:37:45 +0000929 *endLoc = T.getCloseLocation();
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000930
Douglas Gregorb53e4172011-03-26 03:35:55 +0000931 // The 'unavailable' availability cannot be combined with any other
932 // availability changes. Make sure that hasn't happened.
933 if (UnavailableLoc.isValid()) {
934 bool Complained = false;
935 for (unsigned Index = Introduced; Index != Unknown; ++Index) {
936 if (Changes[Index].KeywordLoc.isValid()) {
937 if (!Complained) {
938 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
939 << SourceRange(Changes[Index].KeywordLoc,
940 Changes[Index].VersionRange.getEnd());
941 Complained = true;
942 }
943
944 // Clear out the availability.
945 Changes[Index] = AvailabilityChange();
946 }
947 }
948 }
949
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000950 // Record this attribute
Chad Rosier8decdee2012-06-26 22:30:43 +0000951 attrs.addNew(&Availability,
952 SourceRange(AvailabilityLoc, T.getCloseLocation()),
Fariborz Jahanianf96708d2012-01-23 23:38:32 +0000953 0, AvailabilityLoc,
Aaron Ballman624421f2013-08-31 01:11:41 +0000954 Platform,
John McCall0b7e6782011-03-24 11:26:52 +0000955 Changes[Introduced],
956 Changes[Deprecated],
Chad Rosier8decdee2012-06-26 22:30:43 +0000957 Changes[Obsoleted],
Fariborz Jahanian006e42f2011-12-10 00:28:41 +0000958 UnavailableLoc, MessageExpr.take(),
Sean Hunt93f95f22012-06-18 16:13:52 +0000959 AttributeList::AS_GNU);
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000960}
961
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000962
Bill Wendlingad017fa2012-12-20 19:22:21 +0000963// Late Parsed Attributes:
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000964// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
965
966void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
967
968void Parser::LateParsedClass::ParseLexedAttributes() {
969 Self->ParseLexedAttributes(*Class);
970}
971
972void Parser::LateParsedAttribute::ParseLexedAttributes() {
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +0000973 Self->ParseLexedAttribute(*this, true, false);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000974}
975
976/// Wrapper class which calls ParseLexedAttribute, after setting up the
977/// scope appropriately.
978void Parser::ParseLexedAttributes(ParsingClass &Class) {
979 // Deal with templates
980 // FIXME: Test cases to make sure this does the right thing for templates.
981 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
982 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
983 HasTemplateScope);
984 if (HasTemplateScope)
985 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
986
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000987 // Set or update the scope flags.
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000988 bool AlreadyHasClassScope = Class.TopLevelClass;
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000989 unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +0000990 ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
991 ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
992
DeLesley Hutchinscf2fa2f2012-04-06 15:10:17 +0000993 // Enter the scope of nested classes
994 if (!AlreadyHasClassScope)
995 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
996 Class.TagOrTemplate);
Benjamin Kramer268efba2012-05-17 12:01:52 +0000997 if (!Class.LateParsedDeclarations.empty()) {
Douglas Gregorcefc3af2012-04-16 07:05:22 +0000998 for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
999 Class.LateParsedDeclarations[i]->ParseLexedAttributes();
1000 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001001 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001002
DeLesley Hutchinscf2fa2f2012-04-06 15:10:17 +00001003 if (!AlreadyHasClassScope)
1004 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
1005 Class.TagOrTemplate);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001006}
1007
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001008
1009/// \brief Parse all attributes in LAs, and attach them to Decl D.
1010void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
1011 bool EnterScope, bool OnDefinition) {
DeLesley Hutchins161db022012-11-02 21:44:32 +00001012 assert(LAs.parseSoon() &&
1013 "Attribute list should be marked for immediate parsing.");
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001014 for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
DeLesley Hutchins95526a42012-08-15 22:41:04 +00001015 if (D)
1016 LAs[i]->addDecl(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001017 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
Benjamin Kramerd306cf72012-04-14 12:44:47 +00001018 delete LAs[i];
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001019 }
1020 LAs.clear();
1021}
1022
1023
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001024/// \brief Finish parsing an attribute for which parsing was delayed.
1025/// This will be called at the end of parsing a class declaration
1026/// for each LateParsedAttribute. We consume the saved tokens and
Chad Rosier8decdee2012-06-26 22:30:43 +00001027/// create an attribute with the arguments filled in. We add this
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001028/// to the Attribute list for the decl.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001029void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
1030 bool EnterScope, bool OnDefinition) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001031 // Save the current token position.
1032 SourceLocation OrigLoc = Tok.getLocation();
1033
1034 // Append the current token at the end of the new token stream so that it
1035 // doesn't get lost.
1036 LA.Toks.push_back(Tok);
1037 PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
1038 // Consume the previously pushed token.
Argyrios Kyrtzidisab2d09b2013-03-27 23:58:17 +00001039 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001040
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001041 if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
Richard Smithcd8ab512013-01-17 01:30:42 +00001042 // FIXME: Do not warn on C++11 attributes, once we start supporting
1043 // them here.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001044 Diag(Tok, diag::warn_attribute_on_function_definition)
1045 << LA.AttrName.getName();
1046 }
1047
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001048 ParsedAttributes Attrs(AttrFactory);
1049 SourceLocation endLoc;
1050
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +00001051 if (LA.Decls.size() > 0) {
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00001052 Decl *D = LA.Decls[0];
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +00001053 NamedDecl *ND = dyn_cast<NamedDecl>(D);
1054 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +00001055
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +00001056 // Allow 'this' within late-parsed attributes.
Richard Smithcafeb942013-06-07 02:33:37 +00001057 Sema::CXXThisScopeRAII ThisScope(Actions, RD, /*TypeQuals=*/0,
1058 ND && ND->isCXXInstanceMember());
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001059
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +00001060 if (LA.Decls.size() == 1) {
1061 // If the Decl is templatized, add template parameters to scope.
1062 bool HasTemplateScope = EnterScope && D->isTemplateDecl();
1063 ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
1064 if (HasTemplateScope)
1065 Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00001066
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +00001067 // If the Decl is on a function, add function parameters to the scope.
1068 bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
1069 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope);
1070 if (HasFunScope)
1071 Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00001072
Michael Han6880f492012-10-03 01:56:22 +00001073 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
Michael Han45bed132012-10-04 16:42:52 +00001074 0, SourceLocation(), AttributeList::AS_GNU);
DeLesley Hutchinsd30fb9e2012-08-20 21:32:18 +00001075
1076 if (HasFunScope) {
1077 Actions.ActOnExitFunctionContext();
1078 FnScope.Exit(); // Pop scope, and remove Decls from IdResolver
1079 }
1080 if (HasTemplateScope) {
1081 TempScope.Exit();
1082 }
1083 } else {
1084 // If there are multiple decls, then the decl cannot be within the
1085 // function scope.
Michael Han6880f492012-10-03 01:56:22 +00001086 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
Michael Han45bed132012-10-04 16:42:52 +00001087 0, SourceLocation(), AttributeList::AS_GNU);
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00001088 }
DeLesley Hutchins7ec419a2012-03-02 22:29:50 +00001089 } else {
1090 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
Caitlin Sadowskied9d84a2011-09-08 17:42:31 +00001091 }
1092
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00001093 for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
1094 Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
1095 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001096
1097 if (Tok.getLocation() != OrigLoc) {
1098 // Due to a parsing error, we either went over the cached tokens or
1099 // there are still cached tokens left, so we skip the leftover tokens.
1100 // Since this is an uncommon situation that should be avoided, use the
1101 // expensive isBeforeInTranslationUnit call.
1102 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
1103 OrigLoc))
1104 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
Douglas Gregord78ef5b2012-03-08 01:00:17 +00001105 ConsumeAnyToken();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001106 }
1107}
1108
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001109/// \brief Wrapper around a case statement checking if AttrName is
1110/// one of the thread safety attributes
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001111bool Parser::IsThreadSafetyAttribute(StringRef AttrName) {
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001112 return llvm::StringSwitch<bool>(AttrName)
1113 .Case("guarded_by", true)
1114 .Case("guarded_var", true)
1115 .Case("pt_guarded_by", true)
1116 .Case("pt_guarded_var", true)
1117 .Case("lockable", true)
1118 .Case("scoped_lockable", true)
1119 .Case("no_thread_safety_analysis", true)
1120 .Case("acquired_after", true)
1121 .Case("acquired_before", true)
1122 .Case("exclusive_lock_function", true)
1123 .Case("shared_lock_function", true)
1124 .Case("exclusive_trylock_function", true)
1125 .Case("shared_trylock_function", true)
1126 .Case("unlock_function", true)
1127 .Case("lock_returned", true)
1128 .Case("locks_excluded", true)
1129 .Case("exclusive_locks_required", true)
1130 .Case("shared_locks_required", true)
1131 .Default(false);
1132}
1133
1134/// \brief Parse the contents of thread safety attributes. These
1135/// should always be parsed as an expression list.
1136///
1137/// We need to special case the parsing due to the fact that if the first token
1138/// of the first argument is an identifier, the main parse loop will store
1139/// that token as a "parameter" and the rest of
1140/// the arguments will be added to a list of "arguments". However,
1141/// subsequent tokens in the first argument are lost. We instead parse each
1142/// argument as an expression and add all arguments to the list of "arguments".
1143/// In future, we will take advantage of this special case to also
1144/// deal with some argument scoping issues here (for example, referring to a
1145/// function parameter in the attribute on that function).
1146void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
1147 SourceLocation AttrNameLoc,
1148 ParsedAttributes &Attrs,
1149 SourceLocation *EndLoc) {
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001150 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001151
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001152 BalancedDelimiterTracker T(*this, tok::l_paren);
1153 T.consumeOpen();
Chad Rosier8decdee2012-06-26 22:30:43 +00001154
Aaron Ballman624421f2013-08-31 01:11:41 +00001155 ArgsVector ArgExprs;
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001156 bool ArgExprsOk = true;
Chad Rosier8decdee2012-06-26 22:30:43 +00001157
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001158 // now parse the list of expressions
DeLesley Hutchins4805f152011-12-14 19:36:06 +00001159 while (Tok.isNot(tok::r_paren)) {
DeLesley Hutchinsed4330b2013-02-07 19:01:07 +00001160 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001161 ExprResult ArgExpr(ParseAssignmentExpression());
1162 if (ArgExpr.isInvalid()) {
1163 ArgExprsOk = false;
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001164 T.consumeClose();
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001165 break;
1166 } else {
1167 ArgExprs.push_back(ArgExpr.release());
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001168 }
Caitlin Sadowskieff98fc2011-09-08 17:42:22 +00001169 if (Tok.isNot(tok::comma))
1170 break;
1171 ConsumeToken(); // Eat the comma, move to the next argument
1172 }
1173 // Match the ')'.
DeLesley Hutchins23323e02012-01-20 22:50:54 +00001174 if (ArgExprsOk && !T.consumeClose()) {
Aaron Ballman624421f2013-08-31 01:11:41 +00001175 Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(),
1176 ArgExprs.size(), AttributeList::AS_GNU);
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001177 }
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001178 if (EndLoc)
1179 *EndLoc = T.getCloseLocation();
Caitlin Sadowskib51e0312011-08-09 17:59:31 +00001180}
1181
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00001182void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
1183 SourceLocation AttrNameLoc,
1184 ParsedAttributes &Attrs,
1185 SourceLocation *EndLoc) {
1186 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1187
1188 BalancedDelimiterTracker T(*this, tok::l_paren);
1189 T.consumeOpen();
1190
1191 if (Tok.isNot(tok::identifier)) {
1192 Diag(Tok, diag::err_expected_ident);
1193 T.skipToEnd();
1194 return;
1195 }
Richard Smith8edabd92013-09-03 18:01:40 +00001196 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00001197
1198 if (Tok.isNot(tok::comma)) {
1199 Diag(Tok, diag::err_expected_comma);
1200 T.skipToEnd();
1201 return;
1202 }
1203 ConsumeToken();
1204
1205 SourceRange MatchingCTypeRange;
1206 TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);
1207 if (MatchingCType.isInvalid()) {
1208 T.skipToEnd();
1209 return;
1210 }
1211
1212 bool LayoutCompatible = false;
1213 bool MustBeNull = false;
1214 while (Tok.is(tok::comma)) {
1215 ConsumeToken();
1216 if (Tok.isNot(tok::identifier)) {
1217 Diag(Tok, diag::err_expected_ident);
1218 T.skipToEnd();
1219 return;
1220 }
1221 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1222 if (Flag->isStr("layout_compatible"))
1223 LayoutCompatible = true;
1224 else if (Flag->isStr("must_be_null"))
1225 MustBeNull = true;
1226 else {
1227 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1228 T.skipToEnd();
1229 return;
1230 }
1231 ConsumeToken(); // consume flag
1232 }
1233
1234 if (!T.consumeClose()) {
1235 Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
Aaron Ballman624421f2013-08-31 01:11:41 +00001236 ArgumentKind, MatchingCType.release(),
1237 LayoutCompatible, MustBeNull,
1238 AttributeList::AS_GNU);
Dmitri Gribenko0d5a0692012-08-17 00:08:38 +00001239 }
1240
1241 if (EndLoc)
1242 *EndLoc = T.getCloseLocation();
1243}
1244
Richard Smith6ee326a2012-04-10 01:32:12 +00001245/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
1246/// of a C++11 attribute-specifier in a location where an attribute is not
1247/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
1248/// situation.
1249///
1250/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
1251/// this doesn't appear to actually be an attribute-specifier, and the caller
1252/// should try to parse it.
1253bool Parser::DiagnoseProhibitedCXX11Attribute() {
1254 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1255
1256 switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1257 case CAK_NotAttributeSpecifier:
1258 // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1259 return false;
1260
1261 case CAK_InvalidAttributeSpecifier:
1262 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1263 return false;
1264
1265 case CAK_AttributeSpecifier:
1266 // Parse and discard the attributes.
1267 SourceLocation BeginLoc = ConsumeBracket();
1268 ConsumeBracket();
Alexey Bataev8fe24752013-11-18 08:17:37 +00001269 SkipUntil(tok::r_square);
Richard Smith6ee326a2012-04-10 01:32:12 +00001270 assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1271 SourceLocation EndLoc = ConsumeBracket();
1272 Diag(BeginLoc, diag::err_attributes_not_allowed)
1273 << SourceRange(BeginLoc, EndLoc);
1274 return true;
1275 }
Chandler Carruth2c6dbd72012-04-10 16:03:08 +00001276 llvm_unreachable("All cases handled above.");
Richard Smith6ee326a2012-04-10 01:32:12 +00001277}
1278
Richard Smith975d52c2013-02-20 01:17:14 +00001279/// \brief We have found the opening square brackets of a C++11
1280/// attribute-specifier in a location where an attribute is not permitted, but
1281/// we know where the attributes ought to be written. Parse them anyway, and
1282/// provide a fixit moving them to the right place.
Richard Smith05321402013-02-19 23:47:15 +00001283void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
1284 SourceLocation CorrectLocation) {
1285 assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||
1286 Tok.is(tok::kw_alignas));
1287
1288 // Consume the attributes.
1289 SourceLocation Loc = Tok.getLocation();
1290 ParseCXX11Attributes(Attrs);
1291 CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true);
1292
1293 Diag(Loc, diag::err_attributes_not_allowed)
1294 << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
1295 << FixItHint::CreateRemoval(AttrRange);
1296}
1297
John McCall7f040a92010-12-24 02:08:15 +00001298void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1299 Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1300 << attrs.Range;
Dawn Perchik52fc3142010-09-03 01:29:35 +00001301}
1302
Michael Hanf64231e2012-11-06 19:34:54 +00001303void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) {
1304 AttributeList *AttrList = attrs.getList();
1305 while (AttrList) {
Richard Smith4e24f0f2013-01-02 12:01:23 +00001306 if (AttrList->isCXX11Attribute()) {
Richard Smithd03de6a2013-01-29 10:02:16 +00001307 Diag(AttrList->getLoc(), diag::err_attribute_not_type_attr)
Michael Hanf64231e2012-11-06 19:34:54 +00001308 << AttrList->getName();
1309 AttrList->setInvalid();
1310 }
1311 AttrList = AttrList->getNext();
1312 }
1313}
1314
Reid Spencer5f016e22007-07-11 17:01:13 +00001315/// ParseDeclaration - Parse a full 'declaration', which consists of
1316/// declaration-specifiers, some number of declarators, and a semicolon.
Chris Lattner97144fc2009-04-02 04:16:50 +00001317/// 'Context' should be a Declarator::TheContext value. This returns the
1318/// location of the semicolon in DeclEnd.
Chris Lattner8f08cb72007-08-25 06:57:03 +00001319///
1320/// declaration: [C99 6.7]
1321/// block-declaration ->
1322/// simple-declaration
1323/// others [FIXME]
Douglas Gregoradcac882008-12-01 23:54:00 +00001324/// [C++] template-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001325/// [C++] namespace-definition
Douglas Gregorf780abc2008-12-30 03:27:21 +00001326/// [C++] using-directive
Douglas Gregord7f37bf2009-06-22 23:06:13 +00001327/// [C++] using-declaration
Richard Smith534986f2012-04-14 00:33:13 +00001328/// [C++11/C11] static_assert-declaration
Chris Lattner8f08cb72007-08-25 06:57:03 +00001329/// others... [FIXME]
1330///
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001331Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1332 unsigned Context,
Sean Huntbbd37c62009-11-21 08:43:09 +00001333 SourceLocation &DeclEnd,
John McCall7f040a92010-12-24 02:08:15 +00001334 ParsedAttributesWithRange &attrs) {
Argyrios Kyrtzidis36d36802010-06-17 10:52:18 +00001335 ParenBraceBracketBalancer BalancerRAIIObj(*this);
Fariborz Jahaniane8cff362011-08-30 17:10:52 +00001336 // Must temporarily exit the objective-c container scope for
1337 // parsing c none objective-c decls.
1338 ObjCDeclContextSwitch ObjCDC(*this);
Chad Rosier8decdee2012-06-26 22:30:43 +00001339
John McCalld226f652010-08-21 09:40:31 +00001340 Decl *SingleDecl = 0;
Richard Smithc89edf52011-07-01 19:46:12 +00001341 Decl *OwnedType = 0;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001342 switch (Tok.getKind()) {
Douglas Gregoradcac882008-12-01 23:54:00 +00001343 case tok::kw_template:
Douglas Gregor1426e532009-05-12 21:31:51 +00001344 case tok::kw_export:
John McCall7f040a92010-12-24 02:08:15 +00001345 ProhibitAttributes(attrs);
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00001346 SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001347 break;
Sebastian Redld078e642010-08-27 23:12:46 +00001348 case tok::kw_inline:
Sebastian Redl88e64ca2010-08-31 00:36:45 +00001349 // Could be the start of an inline namespace. Allowed as an ext in C++03.
David Blaikie4e4d0842012-03-11 07:00:24 +00001350 if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
John McCall7f040a92010-12-24 02:08:15 +00001351 ProhibitAttributes(attrs);
Sebastian Redld078e642010-08-27 23:12:46 +00001352 SourceLocation InlineLoc = ConsumeToken();
1353 SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1354 break;
1355 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001356 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
Fariborz Jahanianc5be7b02010-09-28 20:42:35 +00001357 true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001358 case tok::kw_namespace:
John McCall7f040a92010-12-24 02:08:15 +00001359 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001360 SingleDecl = ParseNamespace(Context, DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001361 break;
Douglas Gregorf780abc2008-12-30 03:27:21 +00001362 case tok::kw_using:
John McCall78b81052010-11-10 02:40:36 +00001363 SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
Richard Smithc89edf52011-07-01 19:46:12 +00001364 DeclEnd, attrs, &OwnedType);
Chris Lattner682bf922009-03-29 16:50:03 +00001365 break;
Anders Carlsson511d7ab2009-03-11 16:27:10 +00001366 case tok::kw_static_assert:
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00001367 case tok::kw__Static_assert:
John McCall7f040a92010-12-24 02:08:15 +00001368 ProhibitAttributes(attrs);
Chris Lattner97144fc2009-04-02 04:16:50 +00001369 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
Chris Lattner682bf922009-03-29 16:50:03 +00001370 break;
Chris Lattner8f08cb72007-08-25 06:57:03 +00001371 default:
John McCall7f040a92010-12-24 02:08:15 +00001372 return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001373 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001374
Chris Lattner682bf922009-03-29 16:50:03 +00001375 // This routine returns a DeclGroup, if the thing we parsed only contains a
Richard Smithc89edf52011-07-01 19:46:12 +00001376 // single decl, convert it now. Alias declarations can also declare a type;
1377 // include that too if it is present.
1378 return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
Chris Lattner8f08cb72007-08-25 06:57:03 +00001379}
1380
1381/// simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
1382/// declaration-specifiers init-declarator-list[opt] ';'
Sean Hunt2edf0a22012-06-23 05:07:58 +00001383/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1384/// init-declarator-list ';'
Chris Lattner8f08cb72007-08-25 06:57:03 +00001385///[C90/C++]init-declarator-list ';' [TODO]
1386/// [OMP] threadprivate-directive [TODO]
Chris Lattnercd147752009-03-29 17:27:48 +00001387///
Sean Hunt2edf0a22012-06-23 05:07:58 +00001388/// for-range-declaration: [C++11 6.5p1: stmt.ranged]
Richard Smithad762fc2011-04-14 22:09:26 +00001389/// attribute-specifier-seq[opt] type-specifier-seq declarator
1390///
Chris Lattnercd147752009-03-29 17:27:48 +00001391/// If RequireSemi is false, this does not check for a ';' at the end of the
Chris Lattner5c5db552010-04-05 18:18:31 +00001392/// declaration. If it is true, it checks for and eats it.
Richard Smithad762fc2011-04-14 22:09:26 +00001393///
1394/// If FRI is non-null, we might be parsing a for-range-declaration instead
1395/// of a simple-declaration. If we find that we are, we also parse the
1396/// for-range-initializer, and place it here.
Sean Hunt2edf0a22012-06-23 05:07:58 +00001397Parser::DeclGroupPtrTy
1398Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1399 SourceLocation &DeclEnd,
Richard Smith68ea3ae2013-02-22 09:06:26 +00001400 ParsedAttributesWithRange &Attrs,
Sean Hunt2edf0a22012-06-23 05:07:58 +00001401 bool RequireSemi, ForRangeInit *FRI) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001402 // Parse the common declaration-specifiers piece.
John McCall54abf7d2009-11-04 02:18:39 +00001403 ParsingDeclSpec DS(*this);
Douglas Gregor312eadb2011-04-24 05:37:28 +00001404
Bill Wendlingf0cc19f2013-11-19 22:56:43 +00001405 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1406 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext);
1407
1408 // If we had a free-standing type definition with a missing semicolon, we
1409 // may get this far before the problem becomes obvious.
1410 if (DS.hasTagDefinition() &&
1411 DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext))
1412 return DeclGroupPtrTy();
Abramo Bagnara06284c12012-01-07 10:52:36 +00001413
Reid Spencer5f016e22007-07-11 17:01:13 +00001414 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1415 // declaration-specifiers init-declarator-list[opt] ';'
Chris Lattner04d66662007-10-09 17:33:22 +00001416 if (Tok.is(tok::semi)) {
Richard Smith68ea3ae2013-02-22 09:06:26 +00001417 ProhibitAttributes(Attrs);
Argyrios Kyrtzidis5641b0d2012-05-16 23:49:15 +00001418 DeclEnd = Tok.getLocation();
Chris Lattner5c5db552010-04-05 18:18:31 +00001419 if (RequireSemi) ConsumeToken();
John McCalld226f652010-08-21 09:40:31 +00001420 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
Douglas Gregor312eadb2011-04-24 05:37:28 +00001421 DS);
John McCall54abf7d2009-11-04 02:18:39 +00001422 DS.complete(TheDecl);
Chris Lattner682bf922009-03-29 16:50:03 +00001423 return Actions.ConvertDeclToDeclGroup(TheDecl);
Reid Spencer5f016e22007-07-11 17:01:13 +00001424 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001425
Richard Smith68ea3ae2013-02-22 09:06:26 +00001426 DS.takeAttributesFrom(Attrs);
Chad Rosier8decdee2012-06-26 22:30:43 +00001427 return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
John McCalld8ac0572009-11-03 19:26:08 +00001428}
Mike Stump1eb44332009-09-09 15:08:12 +00001429
Richard Smith0706df42011-10-19 21:33:05 +00001430/// Returns true if this might be the start of a declarator, or a common typo
1431/// for a declarator.
1432bool Parser::MightBeDeclarator(unsigned Context) {
1433 switch (Tok.getKind()) {
1434 case tok::annot_cxxscope:
1435 case tok::annot_template_id:
1436 case tok::caret:
1437 case tok::code_completion:
1438 case tok::coloncolon:
1439 case tok::ellipsis:
1440 case tok::kw___attribute:
1441 case tok::kw_operator:
1442 case tok::l_paren:
1443 case tok::star:
1444 return true;
1445
1446 case tok::amp:
1447 case tok::ampamp:
David Blaikie4e4d0842012-03-11 07:00:24 +00001448 return getLangOpts().CPlusPlus;
Richard Smith0706df42011-10-19 21:33:05 +00001449
Richard Smith1c94c162012-01-09 22:31:44 +00001450 case tok::l_square: // Might be an attribute on an unnamed bit-field.
Richard Smith80ad52f2013-01-02 11:42:31 +00001451 return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 &&
Richard Smith1c94c162012-01-09 22:31:44 +00001452 NextToken().is(tok::l_square);
1453
1454 case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
David Blaikie4e4d0842012-03-11 07:00:24 +00001455 return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
Richard Smith1c94c162012-01-09 22:31:44 +00001456
Richard Smith0706df42011-10-19 21:33:05 +00001457 case tok::identifier:
1458 switch (NextToken().getKind()) {
1459 case tok::code_completion:
1460 case tok::coloncolon:
1461 case tok::comma:
1462 case tok::equal:
1463 case tok::equalequal: // Might be a typo for '='.
1464 case tok::kw_alignas:
1465 case tok::kw_asm:
1466 case tok::kw___attribute:
1467 case tok::l_brace:
1468 case tok::l_paren:
1469 case tok::l_square:
1470 case tok::less:
1471 case tok::r_brace:
1472 case tok::r_paren:
1473 case tok::r_square:
1474 case tok::semi:
1475 return true;
1476
1477 case tok::colon:
1478 // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
Richard Smith1c94c162012-01-09 22:31:44 +00001479 // and in block scope it's probably a label. Inside a class definition,
1480 // this is a bit-field.
1481 return Context == Declarator::MemberContext ||
David Blaikie4e4d0842012-03-11 07:00:24 +00001482 (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
Richard Smith1c94c162012-01-09 22:31:44 +00001483
1484 case tok::identifier: // Possible virt-specifier.
Richard Smith4e24f0f2013-01-02 12:01:23 +00001485 return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken());
Richard Smith0706df42011-10-19 21:33:05 +00001486
1487 default:
1488 return false;
1489 }
1490
1491 default:
1492 return false;
1493 }
1494}
1495
Richard Smith994d73f2012-04-11 20:59:20 +00001496/// Skip until we reach something which seems like a sensible place to pick
1497/// up parsing after a malformed declaration. This will sometimes stop sooner
1498/// than SkipUntil(tok::r_brace) would, but will never stop later.
1499void Parser::SkipMalformedDecl() {
1500 while (true) {
1501 switch (Tok.getKind()) {
1502 case tok::l_brace:
1503 // Skip until matching }, then stop. We've probably skipped over
1504 // a malformed class or function definition or similar.
1505 ConsumeBrace();
Alexey Bataev8fe24752013-11-18 08:17:37 +00001506 SkipUntil(tok::r_brace);
Richard Smith994d73f2012-04-11 20:59:20 +00001507 if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
1508 // This declaration isn't over yet. Keep skipping.
1509 continue;
1510 }
1511 if (Tok.is(tok::semi))
1512 ConsumeToken();
1513 return;
1514
1515 case tok::l_square:
1516 ConsumeBracket();
Alexey Bataev8fe24752013-11-18 08:17:37 +00001517 SkipUntil(tok::r_square);
Richard Smith994d73f2012-04-11 20:59:20 +00001518 continue;
1519
1520 case tok::l_paren:
1521 ConsumeParen();
Alexey Bataev8fe24752013-11-18 08:17:37 +00001522 SkipUntil(tok::r_paren);
Richard Smith994d73f2012-04-11 20:59:20 +00001523 continue;
1524
1525 case tok::r_brace:
1526 return;
1527
1528 case tok::semi:
1529 ConsumeToken();
1530 return;
1531
1532 case tok::kw_inline:
1533 // 'inline namespace' at the start of a line is almost certainly
Jordan Rose94f29f42012-07-09 16:54:53 +00001534 // a good place to pick back up parsing, except in an Objective-C
1535 // @interface context.
1536 if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&
1537 (!ParsingInObjCContainer || CurParsedObjCImpl))
Richard Smith994d73f2012-04-11 20:59:20 +00001538 return;
1539 break;
1540
1541 case tok::kw_namespace:
1542 // 'namespace' at the start of a line is almost certainly a good
Jordan Rose94f29f42012-07-09 16:54:53 +00001543 // place to pick back up parsing, except in an Objective-C
1544 // @interface context.
1545 if (Tok.isAtStartOfLine() &&
1546 (!ParsingInObjCContainer || CurParsedObjCImpl))
1547 return;
1548 break;
1549
1550 case tok::at:
1551 // @end is very much like } in Objective-C contexts.
1552 if (NextToken().isObjCAtKeyword(tok::objc_end) &&
1553 ParsingInObjCContainer)
1554 return;
1555 break;
1556
1557 case tok::minus:
1558 case tok::plus:
1559 // - and + probably start new method declarations in Objective-C contexts.
1560 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
Richard Smith994d73f2012-04-11 20:59:20 +00001561 return;
1562 break;
1563
1564 case tok::eof:
1565 return;
1566
1567 default:
1568 break;
1569 }
1570
1571 ConsumeAnyToken();
1572 }
1573}
1574
John McCalld8ac0572009-11-03 19:26:08 +00001575/// ParseDeclGroup - Having concluded that this is either a function
1576/// definition or a group of object declarations, actually parse the
1577/// result.
John McCall54abf7d2009-11-04 02:18:39 +00001578Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1579 unsigned Context,
John McCalld8ac0572009-11-03 19:26:08 +00001580 bool AllowFunctionDefinitions,
Richard Smithad762fc2011-04-14 22:09:26 +00001581 SourceLocation *DeclEnd,
1582 ForRangeInit *FRI) {
John McCalld8ac0572009-11-03 19:26:08 +00001583 // Parse the first declarator.
John McCall54abf7d2009-11-04 02:18:39 +00001584 ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
John McCalld8ac0572009-11-03 19:26:08 +00001585 ParseDeclarator(D);
Chris Lattnercd147752009-03-29 17:27:48 +00001586
John McCalld8ac0572009-11-03 19:26:08 +00001587 // Bail out if the first declarator didn't seem well-formed.
1588 if (!D.hasName() && !D.mayOmitIdentifier()) {
Richard Smith994d73f2012-04-11 20:59:20 +00001589 SkipMalformedDecl();
John McCalld8ac0572009-11-03 19:26:08 +00001590 return DeclGroupPtrTy();
Chris Lattner23c4b182009-03-29 17:18:04 +00001591 }
Mike Stump1eb44332009-09-09 15:08:12 +00001592
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001593 // Save late-parsed attributes for now; they need to be parsed in the
1594 // appropriate function scope after the function Decl has been constructed.
DeLesley Hutchins161db022012-11-02 21:44:32 +00001595 // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList.
1596 LateParsedAttrList LateParsedAttrs(true);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001597 if (D.isFunctionDeclarator())
1598 MaybeParseGNUAttributes(D, &LateParsedAttrs);
1599
Chris Lattnerc82daef2010-07-11 22:24:20 +00001600 // Check to see if we have a function *definition* which must have a body.
Douglas Gregorb004a8e2013-04-16 16:01:32 +00001601 if (D.isFunctionDeclarator() &&
Chris Lattnerc82daef2010-07-11 22:24:20 +00001602 // Look at the next token to make sure that this isn't a function
1603 // declaration. We have to check this because __attribute__ might be the
1604 // start of a function definition in GCC-extended K&R C.
Fariborz Jahanianbe1d4ec2012-08-10 15:54:40 +00001605 !isDeclarationAfterDeclarator()) {
Chad Rosier8decdee2012-06-26 22:30:43 +00001606
Douglas Gregorb004a8e2013-04-16 16:01:32 +00001607 if (AllowFunctionDefinitions) {
1608 if (isStartOfFunctionDefinition(D)) {
1609 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
1610 Diag(Tok, diag::err_function_declared_typedef);
John McCalld8ac0572009-11-03 19:26:08 +00001611
Douglas Gregorb004a8e2013-04-16 16:01:32 +00001612 // Recover by treating the 'typedef' as spurious.
1613 DS.ClearStorageClassSpecs();
1614 }
1615
1616 Decl *TheDecl =
1617 ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
1618 return Actions.ConvertDeclToDeclGroup(TheDecl);
John McCalld8ac0572009-11-03 19:26:08 +00001619 }
1620
Douglas Gregorb004a8e2013-04-16 16:01:32 +00001621 if (isDeclarationSpecifier()) {
1622 // If there is an invalid declaration specifier right after the function
1623 // prototype, then we must be in a missing semicolon case where this isn't
1624 // actually a body. Just fall through into the code that handles it as a
1625 // prototype, and let the top-level code handle the erroneous declspec
1626 // where it would otherwise expect a comma or semicolon.
1627 } else {
1628 Diag(Tok, diag::err_expected_fn_body);
1629 SkipUntil(tok::semi);
1630 return DeclGroupPtrTy();
1631 }
John McCalld8ac0572009-11-03 19:26:08 +00001632 } else {
Douglas Gregorb004a8e2013-04-16 16:01:32 +00001633 if (Tok.is(tok::l_brace)) {
1634 Diag(Tok, diag::err_function_definition_not_allowed);
Alexey Bataev8fe24752013-11-18 08:17:37 +00001635 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
Douglas Gregorb004a8e2013-04-16 16:01:32 +00001636 }
John McCalld8ac0572009-11-03 19:26:08 +00001637 }
1638 }
1639
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001640 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-04-14 22:09:26 +00001641 return DeclGroupPtrTy();
1642
1643 // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
1644 // must parse and analyze the for-range-initializer before the declaration is
1645 // analyzed.
Douglas Gregor12849d02013-04-08 20:52:24 +00001646 //
1647 // Handle the Objective-C for-in loop variable similarly, although we
1648 // don't need to parse the container in advance.
1649 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
1650 bool IsForRangeLoop = false;
1651 if (Tok.is(tok::colon)) {
1652 IsForRangeLoop = true;
1653 FRI->ColonLoc = ConsumeToken();
1654 if (Tok.is(tok::l_brace))
1655 FRI->RangeExpr = ParseBraceInitializer();
1656 else
1657 FRI->RangeExpr = ParseExpression();
1658 }
1659
Richard Smithad762fc2011-04-14 22:09:26 +00001660 Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
Douglas Gregor12849d02013-04-08 20:52:24 +00001661 if (IsForRangeLoop)
1662 Actions.ActOnCXXForRangeDecl(ThisDecl);
Richard Smithad762fc2011-04-14 22:09:26 +00001663 Actions.FinalizeDeclaration(ThisDecl);
John McCall6895a642012-01-27 01:29:43 +00001664 D.complete(ThisDecl);
Rafael Espindola4549d7f2013-07-09 12:05:01 +00001665 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl);
Richard Smithad762fc2011-04-14 22:09:26 +00001666 }
1667
Chris Lattner5f9e2722011-07-23 10:55:15 +00001668 SmallVector<Decl *, 8> DeclsInGroup;
Richard Smithad762fc2011-04-14 22:09:26 +00001669 Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001670 if (LateParsedAttrs.size() > 0)
1671 ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
John McCall54abf7d2009-11-04 02:18:39 +00001672 D.complete(FirstDecl);
John McCalld226f652010-08-21 09:40:31 +00001673 if (FirstDecl)
John McCalld8ac0572009-11-03 19:26:08 +00001674 DeclsInGroup.push_back(FirstDecl);
1675
Richard Smith0706df42011-10-19 21:33:05 +00001676 bool ExpectSemi = Context != Declarator::ForContext;
Fariborz Jahanian6c89eaf2012-07-02 23:37:09 +00001677
John McCalld8ac0572009-11-03 19:26:08 +00001678 // If we don't have a comma, it is either the end of the list (a ';') or an
1679 // error, bail out.
1680 while (Tok.is(tok::comma)) {
Richard Smith0706df42011-10-19 21:33:05 +00001681 SourceLocation CommaLoc = ConsumeToken();
1682
1683 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1684 // This comma was followed by a line-break and something which can't be
1685 // the start of a declarator. The comma was probably a typo for a
1686 // semicolon.
1687 Diag(CommaLoc, diag::err_expected_semi_declaration)
1688 << FixItHint::CreateReplacement(CommaLoc, ";");
1689 ExpectSemi = false;
1690 break;
1691 }
John McCalld8ac0572009-11-03 19:26:08 +00001692
1693 // Parse the next declarator.
1694 D.clear();
Richard Smith7984de32012-01-12 23:53:29 +00001695 D.setCommaLoc(CommaLoc);
John McCalld8ac0572009-11-03 19:26:08 +00001696
1697 // Accept attributes in an init-declarator. In the first declarator in a
1698 // declaration, these would be part of the declspec. In subsequent
1699 // declarators, they become part of the declarator itself, so that they
1700 // don't apply to declarators after *this* one. Examples:
1701 // short __attribute__((common)) var; -> declspec
1702 // short var __attribute__((common)); -> declarator
1703 // short x, __attribute__((common)) var; -> declarator
John McCall7f040a92010-12-24 02:08:15 +00001704 MaybeParseGNUAttributes(D);
John McCalld8ac0572009-11-03 19:26:08 +00001705
1706 ParseDeclarator(D);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001707 if (!D.isInvalidType()) {
1708 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1709 D.complete(ThisDecl);
1710 if (ThisDecl)
Chad Rosier8decdee2012-06-26 22:30:43 +00001711 DeclsInGroup.push_back(ThisDecl);
Fariborz Jahanian9baf39d2012-01-13 00:14:12 +00001712 }
John McCalld8ac0572009-11-03 19:26:08 +00001713 }
1714
1715 if (DeclEnd)
1716 *DeclEnd = Tok.getLocation();
1717
Richard Smith0706df42011-10-19 21:33:05 +00001718 if (ExpectSemi &&
Chris Lattner8bb21d32012-04-28 16:12:17 +00001719 ExpectAndConsumeSemi(Context == Declarator::FileContext
1720 ? diag::err_invalid_token_after_toplevel_declarator
1721 : diag::err_expected_semi_declaration)) {
Chris Lattner004659a2010-07-11 22:42:07 +00001722 // Okay, there was no semicolon and one was expected. If we see a
1723 // declaration specifier, just assume it was missing and continue parsing.
1724 // Otherwise things are very confused and we skip to recover.
1725 if (!isDeclarationSpecifier()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +00001726 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
Chris Lattner004659a2010-07-11 22:42:07 +00001727 if (Tok.is(tok::semi))
1728 ConsumeToken();
1729 }
John McCalld8ac0572009-11-03 19:26:08 +00001730 }
1731
Rafael Espindola4549d7f2013-07-09 12:05:01 +00001732 return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
Reid Spencer5f016e22007-07-11 17:01:13 +00001733}
1734
Richard Smithad762fc2011-04-14 22:09:26 +00001735/// Parse an optional simple-asm-expr and attributes, and attach them to a
1736/// declarator. Returns true on an error.
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001737bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
Richard Smithad762fc2011-04-14 22:09:26 +00001738 // If a simple-asm-expr is present, parse it.
1739 if (Tok.is(tok::kw_asm)) {
1740 SourceLocation Loc;
1741 ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1742 if (AsmLabel.isInvalid()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +00001743 SkipUntil(tok::semi, StopBeforeMatch);
Richard Smithad762fc2011-04-14 22:09:26 +00001744 return true;
1745 }
1746
1747 D.setAsmLabel(AsmLabel.release());
1748 D.SetRangeEnd(Loc);
1749 }
1750
1751 MaybeParseGNUAttributes(D);
1752 return false;
1753}
1754
Douglas Gregor1426e532009-05-12 21:31:51 +00001755/// \brief Parse 'declaration' after parsing 'declaration-specifiers
1756/// declarator'. This method parses the remainder of the declaration
1757/// (including any attributes or initializer, among other things) and
1758/// finalizes the declaration.
Reid Spencer5f016e22007-07-11 17:01:13 +00001759///
Reid Spencer5f016e22007-07-11 17:01:13 +00001760/// init-declarator: [C99 6.7]
1761/// declarator
1762/// declarator '=' initializer
1763/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
1764/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00001765/// [C++] declarator initializer[opt]
1766///
1767/// [C++] initializer:
1768/// [C++] '=' initializer-clause
1769/// [C++] '(' expression-list ')'
Sebastian Redl50de12f2009-03-24 22:27:57 +00001770/// [C++0x] '=' 'default' [TODO]
1771/// [C++0x] '=' 'delete'
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001772/// [C++0x] braced-init-list
Sebastian Redl50de12f2009-03-24 22:27:57 +00001773///
1774/// According to the standard grammar, =default and =delete are function
1775/// definitions, but that definitely doesn't fit with the parser here.
Reid Spencer5f016e22007-07-11 17:01:13 +00001776///
John McCalld226f652010-08-21 09:40:31 +00001777Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
Douglas Gregore542c862009-06-23 23:11:28 +00001778 const ParsedTemplateInfo &TemplateInfo) {
DeLesley Hutchinsc24a2332012-02-16 16:50:43 +00001779 if (ParseAsmAttributesAfterDeclarator(D))
Richard Smithad762fc2011-04-14 22:09:26 +00001780 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001781
Richard Smithad762fc2011-04-14 22:09:26 +00001782 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1783}
Mike Stump1eb44332009-09-09 15:08:12 +00001784
Richard Smithad762fc2011-04-14 22:09:26 +00001785Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1786 const ParsedTemplateInfo &TemplateInfo) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001787 // Inform the current actions module that we just parsed this declarator.
John McCalld226f652010-08-21 09:40:31 +00001788 Decl *ThisDecl = 0;
Douglas Gregord5a423b2009-09-25 18:43:00 +00001789 switch (TemplateInfo.Kind) {
1790 case ParsedTemplateInfo::NonTemplate:
Douglas Gregor23c94db2010-07-02 17:43:08 +00001791 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
Douglas Gregord5a423b2009-09-25 18:43:00 +00001792 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00001793
Douglas Gregord5a423b2009-09-25 18:43:00 +00001794 case ParsedTemplateInfo::Template:
Larisse Voufoef4579c2013-08-06 01:03:05 +00001795 case ParsedTemplateInfo::ExplicitSpecialization: {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001796 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
Benjamin Kramer5354e772012-08-23 23:38:35 +00001797 *TemplateInfo.TemplateParams,
Douglas Gregord5a423b2009-09-25 18:43:00 +00001798 D);
Larisse Voufo25218132013-08-06 07:33:00 +00001799 if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl))
Larisse Voufoef4579c2013-08-06 01:03:05 +00001800 // Re-direct this decl to refer to the templated decl so that we can
1801 // initialize it.
1802 ThisDecl = VT->getTemplatedDecl();
1803 break;
1804 }
1805 case ParsedTemplateInfo::ExplicitInstantiation: {
1806 if (Tok.is(tok::semi)) {
1807 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
1808 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
1809 if (ThisRes.isInvalid()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +00001810 SkipUntil(tok::semi, StopBeforeMatch);
Larisse Voufoef4579c2013-08-06 01:03:05 +00001811 return 0;
1812 }
1813 ThisDecl = ThisRes.get();
1814 } else {
1815 // FIXME: This check should be for a variable template instantiation only.
1816
1817 // Check that this is a valid instantiation
1818 if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
1819 // If the declarator-id is not a template-id, issue a diagnostic and
1820 // recover by ignoring the 'template' keyword.
1821 Diag(Tok, diag::err_template_defn_explicit_instantiation)
1822 << 2 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
1823 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1824 } else {
1825 SourceLocation LAngleLoc =
1826 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
1827 Diag(D.getIdentifierLoc(),
1828 diag::err_explicit_instantiation_with_definition)
1829 << SourceRange(TemplateInfo.TemplateLoc)
1830 << FixItHint::CreateInsertion(LAngleLoc, "<>");
1831
1832 // Recover as if it were an explicit specialization.
1833 TemplateParameterLists FakedParamLists;
1834 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
1835 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0,
1836 LAngleLoc));
1837
1838 ThisDecl =
1839 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
1840 }
1841 }
Douglas Gregord5a423b2009-09-25 18:43:00 +00001842 break;
1843 }
1844 }
Mike Stump1eb44332009-09-09 15:08:12 +00001845
Richard Smitha2c36462013-04-26 16:15:35 +00001846 bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
Richard Smith34b41d92011-02-20 03:19:35 +00001847
Douglas Gregor1426e532009-05-12 21:31:51 +00001848 // Parse declarator '=' initializer.
Richard Trieud6c7c672012-01-18 22:54:52 +00001849 // If a '==' or '+=' is found, suggest a fixit to '='.
Richard Trieufcaf27e2012-01-19 22:01:51 +00001850 if (isTokenEqualOrEqualTypo()) {
Douglas Gregor1426e532009-05-12 21:31:51 +00001851 ConsumeToken();
Larisse Voufoef4579c2013-08-06 01:03:05 +00001852
Anders Carlsson37bf9d22010-09-24 21:25:25 +00001853 if (Tok.is(tok::kw_delete)) {
Sean Hunte4246a62011-05-12 06:15:49 +00001854 if (D.isFunctionDeclarator())
1855 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1856 << 1 /* delete */;
1857 else
1858 Diag(ConsumeToken(), diag::err_deleted_non_function);
Sean Huntfe2695e2011-05-06 01:42:00 +00001859 } else if (Tok.is(tok::kw_default)) {
Sean Hunte4246a62011-05-12 06:15:49 +00001860 if (D.isFunctionDeclarator())
Sebastian Redlecfcd562012-02-11 23:51:21 +00001861 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1862 << 0 /* default */;
Sean Hunte4246a62011-05-12 06:15:49 +00001863 else
1864 Diag(ConsumeToken(), diag::err_default_special_members);
Douglas Gregor1426e532009-05-12 21:31:51 +00001865 } else {
David Blaikie4e4d0842012-03-11 07:00:24 +00001866 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
John McCall731ad842009-12-19 09:28:58 +00001867 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001868 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001869 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001870
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001871 if (Tok.is(tok::code_completion)) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001872 Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
Peter Collingbourneec98f2f2012-07-27 12:56:09 +00001873 Actions.FinalizeDeclaration(ThisDecl);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00001874 cutOffParsing();
1875 return 0;
Douglas Gregor5ac3bdb2010-05-30 01:49:25 +00001876 }
Chad Rosier8decdee2012-06-26 22:30:43 +00001877
John McCall60d7b3a2010-08-24 06:29:42 +00001878 ExprResult Init(ParseInitializer());
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001879
David Blaikie4e4d0842012-03-11 07:00:24 +00001880 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001881 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
John McCall731ad842009-12-19 09:28:58 +00001882 ExitScope();
1883 }
Argyrios Kyrtzidis0ffd9ff2009-06-17 22:50:06 +00001884
Douglas Gregor1426e532009-05-12 21:31:51 +00001885 if (Init.isInvalid()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +00001886 SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
Douglas Gregor00225542010-03-01 18:27:54 +00001887 Actions.ActOnInitializerError(ThisDecl);
1888 } else
Richard Smith34b41d92011-02-20 03:19:35 +00001889 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1890 /*DirectInit=*/false, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001891 }
1892 } else if (Tok.is(tok::l_paren)) {
1893 // Parse C++ direct initializer: '(' expression-list ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001894 BalancedDelimiterTracker T(*this, tok::l_paren);
1895 T.consumeOpen();
1896
Benjamin Kramer4e28d9e2012-08-23 22:51:59 +00001897 ExprVector Exprs;
Douglas Gregor1426e532009-05-12 21:31:51 +00001898 CommaLocsTy CommaLocs;
1899
David Blaikie4e4d0842012-03-11 07:00:24 +00001900 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregorb4debae2009-12-22 17:47:17 +00001901 EnterScope(0);
Douglas Gregor23c94db2010-07-02 17:43:08 +00001902 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001903 }
1904
Douglas Gregor1426e532009-05-12 21:31:51 +00001905 if (ParseExpressionList(Exprs, CommaLocs)) {
David Blaikie3ea19c82012-10-10 23:15:05 +00001906 Actions.ActOnInitializerError(ThisDecl);
Alexey Bataev8fe24752013-11-18 08:17:37 +00001907 SkipUntil(tok::r_paren, StopAtSemi);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001908
David Blaikie4e4d0842012-03-11 07:00:24 +00001909 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001910 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001911 ExitScope();
1912 }
Douglas Gregor1426e532009-05-12 21:31:51 +00001913 } else {
1914 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00001915 T.consumeClose();
Douglas Gregor1426e532009-05-12 21:31:51 +00001916
1917 assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1918 "Unexpected number of commas!");
Douglas Gregorb4debae2009-12-22 17:47:17 +00001919
David Blaikie4e4d0842012-03-11 07:00:24 +00001920 if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00001921 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
Douglas Gregorb4debae2009-12-22 17:47:17 +00001922 ExitScope();
1923 }
1924
Sebastian Redl5b9cc5d2012-02-11 23:51:47 +00001925 ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
1926 T.getCloseLocation(),
Benjamin Kramer3fe198b2012-08-23 21:35:17 +00001927 Exprs);
Sebastian Redl5b9cc5d2012-02-11 23:51:47 +00001928 Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
1929 /*DirectInit=*/true, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001930 }
Richard Smith80ad52f2013-01-02 11:42:31 +00001931 } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
Fariborz Jahanianb0ed95c2012-07-03 23:22:13 +00001932 (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001933 // Parse C++0x braced-init-list.
Richard Smith7fe62082011-10-15 05:09:34 +00001934 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1935
Sebastian Redldbef1bb2011-06-05 12:23:16 +00001936 if (D.getCXXScopeSpec().isSet()) {
1937 EnterScope(0);
1938 Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1939 }
1940
1941 ExprResult Init(ParseBraceInitializer());
1942
1943 if (D.getCXXScopeSpec().isSet()) {
1944 Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1945 ExitScope();
1946 }
1947
1948 if (Init.isInvalid()) {
1949 Actions.ActOnInitializerError(ThisDecl);
1950 } else
1951 Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1952 /*DirectInit=*/true, TypeContainsAuto);
1953
Douglas Gregor1426e532009-05-12 21:31:51 +00001954 } else {
Richard Smith34b41d92011-02-20 03:19:35 +00001955 Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
Douglas Gregor1426e532009-05-12 21:31:51 +00001956 }
1957
Richard Smith483b9f32011-02-21 20:05:19 +00001958 Actions.FinalizeDeclaration(ThisDecl);
1959
Douglas Gregor1426e532009-05-12 21:31:51 +00001960 return ThisDecl;
1961}
1962
Reid Spencer5f016e22007-07-11 17:01:13 +00001963/// ParseSpecifierQualifierList
1964/// specifier-qualifier-list:
1965/// type-specifier specifier-qualifier-list[opt]
1966/// type-qualifier specifier-qualifier-list[opt]
1967/// [GNU] attributes specifier-qualifier-list[opt]
1968///
Richard Smith69730c12012-03-12 07:56:15 +00001969void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1970 DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001971 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
1972 /// parse declaration-specifiers and complain about extra stuff.
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00001973 /// TODO: diagnose attribute-specifiers and alignment-specifiers.
Richard Smith69730c12012-03-12 07:56:15 +00001974 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
Mike Stump1eb44332009-09-09 15:08:12 +00001975
Reid Spencer5f016e22007-07-11 17:01:13 +00001976 // Validate declspec for type-name.
1977 unsigned Specs = DS.getParsedSpecifiers();
Richard Smitha971d242012-05-09 20:55:26 +00001978 if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1979 !DS.hasTypeSpecifier()) {
Richard Smith69730c12012-03-12 07:56:15 +00001980 Diag(Tok, diag::err_expected_type);
1981 DS.SetTypeSpecError();
1982 } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
1983 !DS.hasAttributes()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00001984 Diag(Tok, diag::err_typename_requires_specqual);
Richard Smith69730c12012-03-12 07:56:15 +00001985 if (!DS.hasTypeSpecifier())
1986 DS.SetTypeSpecError();
1987 }
Mike Stump1eb44332009-09-09 15:08:12 +00001988
Reid Spencer5f016e22007-07-11 17:01:13 +00001989 // Issue diagnostic and remove storage class if present.
1990 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
1991 if (DS.getStorageClassSpecLoc().isValid())
1992 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1993 else
Richard Smithec642442013-04-12 22:46:28 +00001994 Diag(DS.getThreadStorageClassSpecLoc(),
1995 diag::err_typename_invalid_storageclass);
Reid Spencer5f016e22007-07-11 17:01:13 +00001996 DS.ClearStorageClassSpecs();
1997 }
Mike Stump1eb44332009-09-09 15:08:12 +00001998
Reid Spencer5f016e22007-07-11 17:01:13 +00001999 // Issue diagnostic and remove function specfier if present.
2000 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
Douglas Gregorb48fe382008-10-31 09:07:45 +00002001 if (DS.isInlineSpecified())
2002 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
2003 if (DS.isVirtualSpecified())
2004 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
2005 if (DS.isExplicitSpecified())
2006 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
Reid Spencer5f016e22007-07-11 17:01:13 +00002007 DS.ClearFunctionSpecs();
2008 }
Richard Smith69730c12012-03-12 07:56:15 +00002009
2010 // Issue diagnostic and remove constexpr specfier if present.
2011 if (DS.isConstexprSpecified()) {
2012 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
2013 DS.ClearConstexprSpec();
2014 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002015}
2016
Chris Lattnerc199ab32009-04-12 20:42:31 +00002017/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
2018/// specified token is valid after the identifier in a declarator which
2019/// immediately follows the declspec. For example, these things are valid:
2020///
2021/// int x [ 4]; // direct-declarator
2022/// int x ( int y); // direct-declarator
2023/// int(int x ) // direct-declarator
2024/// int x ; // simple-declaration
2025/// int x = 17; // init-declarator-list
2026/// int x , y; // init-declarator-list
2027/// int x __asm__ ("foo"); // init-declarator-list
Chris Lattnerb6645dd2009-04-14 21:16:09 +00002028/// int x : 4; // struct-declarator
Chris Lattnerc83c27a2009-04-12 22:29:43 +00002029/// int x { 5}; // C++'0x unified initializers
Chris Lattnerc199ab32009-04-12 20:42:31 +00002030///
2031/// This is not, because 'x' does not immediately follow the declspec (though
2032/// ')' happens to be valid anyway).
2033/// int (x)
2034///
2035static bool isValidAfterIdentifierInDeclarator(const Token &T) {
2036 return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
2037 T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
Chris Lattnerb6645dd2009-04-14 21:16:09 +00002038 T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
Chris Lattnerc199ab32009-04-12 20:42:31 +00002039}
2040
Chris Lattnere40c2952009-04-14 21:34:55 +00002041
2042/// ParseImplicitInt - This method is called when we have an non-typename
2043/// identifier in a declspec (which normally terminates the decl spec) when
2044/// the declspec has no type specifier. In this case, the declspec is either
2045/// malformed or is "implicit int" (in K&R and C89).
2046///
2047/// This method handles diagnosing this prettily and returns false if the
2048/// declspec is done being processed. If it recovers and thinks there may be
2049/// other pieces of declspec after it, it returns true.
2050///
Chris Lattnerf4382f52009-04-14 22:17:06 +00002051bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00002052 const ParsedTemplateInfo &TemplateInfo,
Michael Han2e397132012-11-26 22:54:45 +00002053 AccessSpecifier AS, DeclSpecContext DSC,
2054 ParsedAttributesWithRange &Attrs) {
Chris Lattnerf4382f52009-04-14 22:17:06 +00002055 assert(Tok.is(tok::identifier) && "should have identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00002056
Chris Lattnere40c2952009-04-14 21:34:55 +00002057 SourceLocation Loc = Tok.getLocation();
2058 // If we see an identifier that is not a type name, we normally would
2059 // parse it as the identifer being declared. However, when a typename
2060 // is typo'd or the definition is not included, this will incorrectly
2061 // parse the typename as the identifier name and fall over misparsing
2062 // later parts of the diagnostic.
2063 //
2064 // As such, we try to do some look-ahead in cases where this would
2065 // otherwise be an "implicit-int" case to see if this is invalid. For
2066 // example: "static foo_t x = 4;" In this case, if we parsed foo_t as
2067 // an identifier with implicit int, we'd get a parse error because the
2068 // next token is obviously invalid for a type. Parse these as a case
2069 // with an invalid type specifier.
2070 assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
Mike Stump1eb44332009-09-09 15:08:12 +00002071
Chris Lattnere40c2952009-04-14 21:34:55 +00002072 // Since we know that this either implicit int (which is rare) or an
Richard Smith827adaf2012-05-15 21:01:51 +00002073 // error, do lookahead to try to do better recovery. This never applies
2074 // within a type specifier. Outside of C++, we allow this even if the
2075 // language doesn't "officially" support implicit int -- we support
Richard Smith58eb3702013-04-30 22:43:51 +00002076 // implicit int as an extension in C99 and C11.
Richard Smitha971d242012-05-09 20:55:26 +00002077 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
Richard Smith58eb3702013-04-30 22:43:51 +00002078 !getLangOpts().CPlusPlus &&
Richard Smith69730c12012-03-12 07:56:15 +00002079 isValidAfterIdentifierInDeclarator(NextToken())) {
Chris Lattnere40c2952009-04-14 21:34:55 +00002080 // If this token is valid for implicit int, e.g. "static x = 4", then
2081 // we just avoid eating the identifier, so it will be parsed as the
2082 // identifier in the declarator.
2083 return false;
2084 }
Mike Stump1eb44332009-09-09 15:08:12 +00002085
Richard Smith827adaf2012-05-15 21:01:51 +00002086 if (getLangOpts().CPlusPlus &&
2087 DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
2088 // Don't require a type specifier if we have the 'auto' storage class
2089 // specifier in C++98 -- we'll promote it to a type specifier.
Richard Smithb79b17b2013-10-15 00:00:26 +00002090 if (SS)
2091 AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);
Richard Smith827adaf2012-05-15 21:01:51 +00002092 return false;
2093 }
2094
Chris Lattnere40c2952009-04-14 21:34:55 +00002095 // Otherwise, if we don't consume this token, we are going to emit an
2096 // error anyway. Try to recover from various common problems. Check
2097 // to see if this was a reference to a tag name without a tag specified.
2098 // This is a common problem in C (saying 'foo' instead of 'struct foo').
Chris Lattnerf4382f52009-04-14 22:17:06 +00002099 //
2100 // C++ doesn't need this, and isTagName doesn't take SS.
2101 if (SS == 0) {
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00002102 const char *TagName = 0, *FixitTagName = 0;
Chris Lattnerf4382f52009-04-14 22:17:06 +00002103 tok::TokenKind TagKind = tok::unknown;
Mike Stump1eb44332009-09-09 15:08:12 +00002104
Douglas Gregor23c94db2010-07-02 17:43:08 +00002105 switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
Chris Lattnere40c2952009-04-14 21:34:55 +00002106 default: break;
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00002107 case DeclSpec::TST_enum:
2108 TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break;
2109 case DeclSpec::TST_union:
2110 TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
2111 case DeclSpec::TST_struct:
2112 TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
Joao Matos6666ed42012-08-31 18:45:21 +00002113 case DeclSpec::TST_interface:
2114 TagName="__interface"; FixitTagName = "__interface ";
2115 TagKind=tok::kw___interface;break;
Argyrios Kyrtzidisb8a9d3b2011-04-21 17:29:47 +00002116 case DeclSpec::TST_class:
2117 TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
Chris Lattnere40c2952009-04-14 21:34:55 +00002118 }
Mike Stump1eb44332009-09-09 15:08:12 +00002119
Chris Lattnerf4382f52009-04-14 22:17:06 +00002120 if (TagName) {
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00002121 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2122 LookupResult R(Actions, TokenName, SourceLocation(),
2123 Sema::LookupOrdinaryName);
2124
Chris Lattnerf4382f52009-04-14 22:17:06 +00002125 Diag(Loc, diag::err_use_of_tag_name_without_tag)
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00002126 << TokenName << TagName << getLangOpts().CPlusPlus
2127 << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
2128
2129 if (Actions.LookupParsedName(R, getCurScope(), SS)) {
2130 for (LookupResult::iterator I = R.begin(), IEnd = R.end();
2131 I != IEnd; ++I)
Kaelyn Uhrain392b3f52012-04-27 18:26:49 +00002132 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
Kaelyn Uhrainaec2ac62012-04-26 23:36:17 +00002133 << TokenName << TagName;
2134 }
Mike Stump1eb44332009-09-09 15:08:12 +00002135
Chris Lattnerf4382f52009-04-14 22:17:06 +00002136 // Parse this as a tag as if the missing tag were present.
2137 if (TagKind == tok::kw_enum)
Richard Smith69730c12012-03-12 07:56:15 +00002138 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
Chris Lattnerf4382f52009-04-14 22:17:06 +00002139 else
Richard Smith69730c12012-03-12 07:56:15 +00002140 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
Michael Han2e397132012-11-26 22:54:45 +00002141 /*EnteringContext*/ false, DSC_normal, Attrs);
Chris Lattnerf4382f52009-04-14 22:17:06 +00002142 return true;
2143 }
Chris Lattnere40c2952009-04-14 21:34:55 +00002144 }
Mike Stump1eb44332009-09-09 15:08:12 +00002145
Richard Smith8f0a7e72012-05-15 21:29:55 +00002146 // Determine whether this identifier could plausibly be the name of something
Richard Smith7514db22012-05-15 21:42:17 +00002147 // being declared (with a missing type).
Richard Smith8f0a7e72012-05-15 21:29:55 +00002148 if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
2149 (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
Richard Smith827adaf2012-05-15 21:01:51 +00002150 // Look ahead to the next token to try to figure out what this declaration
2151 // was supposed to be.
2152 switch (NextToken().getKind()) {
Richard Smith827adaf2012-05-15 21:01:51 +00002153 case tok::l_paren: {
2154 // static x(4); // 'x' is not a type
2155 // x(int n); // 'x' is not a type
2156 // x (*p)[]; // 'x' is a type
2157 //
2158 // Since we're in an error case (or the rare 'implicit int in C++' MS
2159 // extension), we can afford to perform a tentative parse to determine
2160 // which case we're in.
2161 TentativeParsingAction PA(*this);
2162 ConsumeToken();
2163 TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
2164 PA.Revert();
Richard Smithb79b17b2013-10-15 00:00:26 +00002165
2166 if (TPR != TPResult::False()) {
2167 // The identifier is followed by a parenthesized declarator.
2168 // It's supposed to be a type.
2169 break;
2170 }
2171
2172 // If we're in a context where we could be declaring a constructor,
2173 // check whether this is a constructor declaration with a bogus name.
2174 if (DSC == DSC_class || (DSC == DSC_top_level && SS)) {
2175 IdentifierInfo *II = Tok.getIdentifierInfo();
2176 if (Actions.isCurrentClassNameTypo(II, SS)) {
2177 Diag(Loc, diag::err_constructor_bad_name)
2178 << Tok.getIdentifierInfo() << II
2179 << FixItHint::CreateReplacement(Tok.getLocation(), II->getName());
2180 Tok.setIdentifierInfo(II);
2181 }
2182 }
2183 // Fall through.
Richard Smith827adaf2012-05-15 21:01:51 +00002184 }
Richard Smithb79b17b2013-10-15 00:00:26 +00002185 case tok::comma:
2186 case tok::equal:
2187 case tok::kw_asm:
2188 case tok::l_brace:
2189 case tok::l_square:
2190 case tok::semi:
2191 // This looks like a variable or function declaration. The type is
2192 // probably missing. We're done parsing decl-specifiers.
2193 if (SS)
2194 AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);
2195 return false;
Richard Smith827adaf2012-05-15 21:01:51 +00002196
2197 default:
2198 // This is probably supposed to be a type. This includes cases like:
2199 // int f(itn);
2200 // struct S { unsinged : 4; };
2201 break;
2202 }
2203 }
2204
Chad Rosier8decdee2012-06-26 22:30:43 +00002205 // This is almost certainly an invalid type name. Let the action emit a
Douglas Gregora786fdb2009-10-13 23:27:22 +00002206 // diagnostic and attempt to recover.
John McCallb3d87482010-08-24 05:47:05 +00002207 ParsedType T;
Kaelyn Uhrain50dc12a2012-06-15 23:45:58 +00002208 IdentifierInfo *II = Tok.getIdentifierInfo();
2209 if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
Douglas Gregora786fdb2009-10-13 23:27:22 +00002210 // The action emitted a diagnostic, so we don't have to.
2211 if (T) {
2212 // The action has suggested that the type T could be used. Set that as
2213 // the type in the declaration specifiers, consume the would-be type
2214 // name token, and we're done.
2215 const char *PrevSpec;
2216 unsigned DiagID;
John McCallb3d87482010-08-24 05:47:05 +00002217 DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
Douglas Gregora786fdb2009-10-13 23:27:22 +00002218 DS.SetRangeEnd(Tok.getLocation());
2219 ConsumeToken();
Kaelyn Uhrain50dc12a2012-06-15 23:45:58 +00002220 // There may be other declaration specifiers after this.
2221 return true;
2222 } else if (II != Tok.getIdentifierInfo()) {
2223 // If no type was suggested, the correction is to a keyword
2224 Tok.setKind(II->getTokenID());
Douglas Gregora786fdb2009-10-13 23:27:22 +00002225 // There may be other declaration specifiers after this.
2226 return true;
2227 }
Chad Rosier8decdee2012-06-26 22:30:43 +00002228
Douglas Gregora786fdb2009-10-13 23:27:22 +00002229 // Fall through; the action had no suggestion for us.
2230 } else {
2231 // The action did not emit a diagnostic, so emit one now.
2232 SourceRange R;
2233 if (SS) R = SS->getRange();
2234 Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
2235 }
Mike Stump1eb44332009-09-09 15:08:12 +00002236
Douglas Gregora786fdb2009-10-13 23:27:22 +00002237 // Mark this as an error.
Richard Smith69730c12012-03-12 07:56:15 +00002238 DS.SetTypeSpecError();
Chris Lattnere40c2952009-04-14 21:34:55 +00002239 DS.SetRangeEnd(Tok.getLocation());
2240 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00002241
Chris Lattnere40c2952009-04-14 21:34:55 +00002242 // TODO: Could inject an invalid typedef decl in an enclosing scope to
2243 // avoid rippling error messages on subsequent uses of the same type,
2244 // could be useful if #include was forgotten.
2245 return false;
2246}
2247
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002248/// \brief Determine the declaration specifier context from the declarator
2249/// context.
2250///
2251/// \param Context the declarator context, which is one of the
2252/// Declarator::TheContext enumerator values.
Chad Rosier8decdee2012-06-26 22:30:43 +00002253Parser::DeclSpecContext
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002254Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
2255 if (Context == Declarator::MemberContext)
2256 return DSC_class;
2257 if (Context == Declarator::FileContext)
2258 return DSC_top_level;
Richard Smith6d96d3a2012-03-15 01:02:11 +00002259 if (Context == Declarator::TrailingReturnContext)
2260 return DSC_trailing;
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002261 return DSC_normal;
2262}
2263
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002264/// ParseAlignArgument - Parse the argument to an alignment-specifier.
2265///
2266/// FIXME: Simply returns an alignof() expression if the argument is a
2267/// type. Ideally, the type should be propagated directly into Sema.
2268///
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002269/// [C11] type-id
2270/// [C11] constant-expression
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002271/// [C++0x] type-id ...[opt]
2272/// [C++0x] assignment-expression ...[opt]
2273ExprResult Parser::ParseAlignArgument(SourceLocation Start,
2274 SourceLocation &EllipsisLoc) {
2275 ExprResult ER;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002276 if (isTypeIdInParens()) {
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002277 SourceLocation TypeLoc = Tok.getLocation();
2278 ParsedType Ty = ParseTypeName().get();
2279 SourceRange TypeRange(Start, Tok.getLocation());
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002280 ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
2281 Ty.getAsOpaquePtr(), TypeRange);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002282 } else
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002283 ER = ParseConstantExpression();
2284
Richard Smith80ad52f2013-01-02 11:42:31 +00002285 if (getLangOpts().CPlusPlus11 && Tok.is(tok::ellipsis))
Peter Collingbournefe9b2a82011-10-24 17:56:00 +00002286 EllipsisLoc = ConsumeToken();
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002287
2288 return ER;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002289}
2290
2291/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
2292/// attribute to Attrs.
2293///
2294/// alignment-specifier:
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002295/// [C11] '_Alignas' '(' type-id ')'
2296/// [C11] '_Alignas' '(' constant-expression ')'
Richard Smith33f04a22013-01-29 01:48:07 +00002297/// [C++11] 'alignas' '(' type-id ...[opt] ')'
2298/// [C++11] 'alignas' '(' assignment-expression ...[opt] ')'
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002299void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
Richard Smithf6565a92013-02-22 08:32:16 +00002300 SourceLocation *EndLoc) {
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002301 assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
2302 "Not an alignment-specifier!");
2303
Richard Smith33f04a22013-01-29 01:48:07 +00002304 IdentifierInfo *KWName = Tok.getIdentifierInfo();
2305 SourceLocation KWLoc = ConsumeToken();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002306
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002307 BalancedDelimiterTracker T(*this, tok::l_paren);
2308 if (T.expectAndConsume(diag::err_expected_lparen))
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002309 return;
2310
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002311 SourceLocation EllipsisLoc;
2312 ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002313 if (ArgExpr.isInvalid()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +00002314 T.skipToEnd();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002315 return;
2316 }
2317
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00002318 T.consumeClose();
Richard Smithf6565a92013-02-22 08:32:16 +00002319 if (EndLoc)
2320 *EndLoc = T.getCloseLocation();
Peter Collingbourne0b64ba92011-10-23 20:07:52 +00002321
Aaron Ballman624421f2013-08-31 01:11:41 +00002322 ArgsVector ArgExprs;
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002323 ArgExprs.push_back(ArgExpr.release());
Aaron Ballman624421f2013-08-31 01:11:41 +00002324 Attrs.addNew(KWName, KWLoc, 0, KWLoc, ArgExprs.data(), 1,
2325 AttributeList::AS_Keyword, EllipsisLoc);
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002326}
2327
Bill Wendlingf0cc19f2013-11-19 22:56:43 +00002328/// Determine whether we're looking at something that might be a declarator
2329/// in a simple-declaration. If it can't possibly be a declarator, maybe
2330/// diagnose a missing semicolon after a prior tag definition in the decl
2331/// specifier.
2332///
2333/// \return \c true if an error occurred and this can't be any kind of
2334/// declaration.
2335bool
2336Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
2337 DeclSpecContext DSContext,
2338 LateParsedAttrList *LateAttrs) {
2339 assert(DS.hasTagDefinition() && "shouldn't call this");
2340
2341 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2342 bool HasMissingSemi = false;
2343
2344 if (getLangOpts().CPlusPlus &&
2345 (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
2346 Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) &&
2347 TryAnnotateCXXScopeToken(EnteringContext)) {
2348 SkipMalformedDecl();
2349 return true;
2350 }
2351
2352 // Determine whether the following tokens could possibly be a
2353 // declarator.
2354 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
2355 const Token &Next = NextToken();
2356 // These tokens cannot come after the declarator-id in a
2357 // simple-declaration, and are likely to come after a type-specifier.
2358 HasMissingSemi = Next.is(tok::star) || Next.is(tok::amp) ||
2359 Next.is(tok::ampamp) || Next.is(tok::identifier) ||
2360 Next.is(tok::annot_cxxscope) ||
2361 Next.is(tok::coloncolon);
2362 } else if (Tok.is(tok::annot_cxxscope) &&
2363 NextToken().is(tok::identifier) &&
2364 DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
2365 // We almost certainly have a missing semicolon. Look up the name and
2366 // check; if it names a type, we're missing a semicolon.
2367 CXXScopeSpec SS;
2368 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2369 Tok.getAnnotationRange(), SS);
2370 const Token &Next = NextToken();
2371 IdentifierInfo *Name = Next.getIdentifierInfo();
2372 Sema::NameClassification Classification =
2373 Actions.ClassifyName(getCurScope(), SS, Name, Next.getLocation(),
2374 NextToken(), /*IsAddressOfOperand*/false);
2375 switch (Classification.getKind()) {
2376 case Sema::NC_Error:
2377 SkipMalformedDecl();
2378 return true;
2379
2380 case Sema::NC_Keyword:
2381 case Sema::NC_NestedNameSpecifier:
2382 llvm_unreachable("typo correction and nested name specifiers not "
2383 "possible here");
2384
2385 case Sema::NC_Type:
2386 case Sema::NC_TypeTemplate:
2387 // Not a previously-declared non-type entity.
2388 HasMissingSemi = true;
2389 break;
2390
2391 case Sema::NC_Unknown:
2392 case Sema::NC_Expression:
2393 case Sema::NC_VarTemplate:
2394 case Sema::NC_FunctionTemplate:
2395 // Might be a redeclaration of a prior entity.
2396 HasMissingSemi = false;
2397 break;
2398 }
2399 } else if (Tok.is(tok::kw_typename) || Tok.is(tok::annot_typename)) {
2400 HasMissingSemi = true;
2401 }
2402
2403 if (!HasMissingSemi)
2404 return false;
2405
2406 Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getLocEnd()),
2407 diag::err_expected_semi_after_tagdecl)
2408 << DeclSpec::getSpecifierName(DS.getTypeSpecType());
2409
2410 // Try to recover from the typo, by dropping the tag definition and parsing
2411 // the problematic tokens as a type.
2412 //
2413 // FIXME: Split the DeclSpec into pieces for the standalone
2414 // declaration and pieces for the following declaration, instead
2415 // of assuming that all the other pieces attach to new declaration,
2416 // and call ParsedFreeStandingDeclSpec as appropriate.
2417 DS.ClearTypeSpecType();
2418 ParsedTemplateInfo NotATemplate;
2419 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
2420 return false;
2421}
2422
Reid Spencer5f016e22007-07-11 17:01:13 +00002423/// ParseDeclarationSpecifiers
2424/// declaration-specifiers: [C99 6.7]
2425/// storage-class-specifier declaration-specifiers[opt]
2426/// type-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002427/// [C99] function-specifier declaration-specifiers[opt]
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00002428/// [C11] alignment-specifier declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002429/// [GNU] attributes declaration-specifiers[opt]
Douglas Gregor8d267c52011-09-09 02:06:17 +00002430/// [Clang] '__module_private__' declaration-specifiers[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00002431///
2432/// storage-class-specifier: [C99 6.7.1]
2433/// 'typedef'
2434/// 'extern'
2435/// 'static'
2436/// 'auto'
2437/// 'register'
Sebastian Redl669d5d72008-11-14 23:42:31 +00002438/// [C++] 'mutable'
Richard Smithec642442013-04-12 22:46:28 +00002439/// [C++11] 'thread_local'
2440/// [C11] '_Thread_local'
Reid Spencer5f016e22007-07-11 17:01:13 +00002441/// [GNU] '__thread'
Reid Spencer5f016e22007-07-11 17:01:13 +00002442/// function-specifier: [C99 6.7.4]
2443/// [C99] 'inline'
Douglas Gregorb48fe382008-10-31 09:07:45 +00002444/// [C++] 'virtual'
2445/// [C++] 'explicit'
Peter Collingbournef315fa82011-02-14 01:42:53 +00002446/// [OpenCL] '__kernel'
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002447/// 'friend': [C++ dcl.friend]
Sebastian Redl2ac67232009-11-05 15:47:02 +00002448/// 'constexpr': [C++0x dcl.constexpr]
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002449
Reid Spencer5f016e22007-07-11 17:01:13 +00002450///
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +00002451void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Douglas Gregor4d9a16f2009-05-12 23:25:50 +00002452 const ParsedTemplateInfo &TemplateInfo,
John McCall67d1a672009-08-06 02:15:43 +00002453 AccessSpecifier AS,
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002454 DeclSpecContext DSContext,
2455 LateParsedAttrList *LateAttrs) {
Douglas Gregor312eadb2011-04-24 05:37:28 +00002456 if (DS.getSourceRange().isInvalid()) {
2457 DS.SetRangeStart(Tok.getLocation());
2458 DS.SetRangeEnd(Tok.getLocation());
2459 }
Chad Rosier8decdee2012-06-26 22:30:43 +00002460
Douglas Gregorefaa93a2011-11-07 17:33:42 +00002461 bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
Sean Hunt2edf0a22012-06-23 05:07:58 +00002462 bool AttrsLastTime = false;
2463 ParsedAttributesWithRange attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00002464 while (1) {
John McCallfec54012009-08-03 20:12:06 +00002465 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00002466 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00002467 unsigned DiagID = 0;
2468
Reid Spencer5f016e22007-07-11 17:01:13 +00002469 SourceLocation Loc = Tok.getLocation();
Douglas Gregor12e083c2008-11-07 15:42:26 +00002470
Reid Spencer5f016e22007-07-11 17:01:13 +00002471 switch (Tok.getKind()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002472 default:
Chris Lattnerbce61352008-07-26 00:20:22 +00002473 DoneWithDeclSpec:
Sean Hunt2edf0a22012-06-23 05:07:58 +00002474 if (!AttrsLastTime)
2475 ProhibitAttributes(attrs);
Michael Hanf64231e2012-11-06 19:34:54 +00002476 else {
2477 // Reject C++11 attributes that appertain to decl specifiers as
2478 // we don't support any C++11 attributes that appertain to decl
2479 // specifiers. This also conforms to what g++ 4.8 is doing.
2480 ProhibitCXX11Attributes(attrs);
2481
Sean Hunt2edf0a22012-06-23 05:07:58 +00002482 DS.takeAttributesFrom(attrs);
Michael Hanf64231e2012-11-06 19:34:54 +00002483 }
Peter Collingbournef1907682011-09-29 18:03:57 +00002484
Reid Spencer5f016e22007-07-11 17:01:13 +00002485 // If this is not a declaration specifier token, we're done reading decl
2486 // specifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00002487 DS.Finish(Diags, PP);
Reid Spencer5f016e22007-07-11 17:01:13 +00002488 return;
Mike Stump1eb44332009-09-09 15:08:12 +00002489
Sean Hunt2edf0a22012-06-23 05:07:58 +00002490 case tok::l_square:
2491 case tok::kw_alignas:
Richard Smith672edb02013-02-22 09:15:49 +00002492 if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier())
Sean Hunt2edf0a22012-06-23 05:07:58 +00002493 goto DoneWithDeclSpec;
2494
2495 ProhibitAttributes(attrs);
2496 // FIXME: It would be good to recover by accepting the attributes,
2497 // but attempting to do that now would cause serious
2498 // madness in terms of diagnostics.
2499 attrs.clear();
2500 attrs.Range = SourceRange();
2501
2502 ParseCXX11Attributes(attrs);
2503 AttrsLastTime = true;
Chad Rosier8decdee2012-06-26 22:30:43 +00002504 continue;
Sean Hunt2edf0a22012-06-23 05:07:58 +00002505
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002506 case tok::code_completion: {
John McCallf312b1e2010-08-26 23:41:50 +00002507 Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002508 if (DS.hasTypeSpecifier()) {
2509 bool AllowNonIdentifiers
2510 = (getCurScope()->getFlags() & (Scope::ControlScope |
2511 Scope::BlockScope |
2512 Scope::TemplateParamScope |
2513 Scope::FunctionPrototypeScope |
2514 Scope::AtCatchScope)) == 0;
2515 bool AllowNestedNameSpecifiers
Chad Rosier8decdee2012-06-26 22:30:43 +00002516 = DSContext == DSC_top_level ||
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002517 (DSContext == DSC_class && DS.isFriendSpecified());
2518
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002519 Actions.CodeCompleteDeclSpec(getCurScope(), DS,
Chad Rosier8decdee2012-06-26 22:30:43 +00002520 AllowNonIdentifiers,
Douglas Gregorc7b6d882010-09-16 15:14:18 +00002521 AllowNestedNameSpecifiers);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002522 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00002523 }
2524
Douglas Gregor68e3c2e2011-02-15 20:33:25 +00002525 if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2526 CCC = Sema::PCC_LocalDeclarationSpecifiers;
2527 else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
Chad Rosier8decdee2012-06-26 22:30:43 +00002528 CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
John McCallf312b1e2010-08-26 23:41:50 +00002529 : Sema::PCC_Template;
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002530 else if (DSContext == DSC_class)
John McCallf312b1e2010-08-26 23:41:50 +00002531 CCC = Sema::PCC_Class;
Argyrios Kyrtzidis849639d2012-02-07 16:50:53 +00002532 else if (CurParsedObjCImpl)
John McCallf312b1e2010-08-26 23:41:50 +00002533 CCC = Sema::PCC_ObjCImplementation;
Chad Rosier8decdee2012-06-26 22:30:43 +00002534
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002535 Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00002536 return cutOffParsing();
Douglas Gregor2ccccb32010-08-23 18:23:48 +00002537 }
2538
Chris Lattner5e02c472009-01-05 00:07:25 +00002539 case tok::coloncolon: // ::foo::bar
John McCall9ba61662010-02-26 08:45:28 +00002540 // C++ scope specifier. Annotate and loop, or bail out on error.
Eli Friedman5a428202013-08-15 23:59:20 +00002541 if (TryAnnotateCXXScopeToken(EnteringContext)) {
John McCall9ba61662010-02-26 08:45:28 +00002542 if (!DS.hasTypeSpecifier())
2543 DS.SetTypeSpecError();
2544 goto DoneWithDeclSpec;
2545 }
John McCall2e0a7152010-03-01 18:20:46 +00002546 if (Tok.is(tok::coloncolon)) // ::new or ::delete
2547 goto DoneWithDeclSpec;
John McCall9ba61662010-02-26 08:45:28 +00002548 continue;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002549
2550 case tok::annot_cxxscope: {
Richard Smithf63eee72012-05-09 18:56:43 +00002551 if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002552 goto DoneWithDeclSpec;
2553
John McCallaa87d332009-12-12 11:40:51 +00002554 CXXScopeSpec SS;
Douglas Gregorc34348a2011-02-24 17:54:50 +00002555 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2556 Tok.getAnnotationRange(),
2557 SS);
John McCallaa87d332009-12-12 11:40:51 +00002558
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002559 // We are looking for a qualified typename.
Douglas Gregor9135c722009-03-25 15:40:00 +00002560 Token Next = NextToken();
Mike Stump1eb44332009-09-09 15:08:12 +00002561 if (Next.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002562 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
Douglas Gregorc45c2322009-03-31 00:43:58 +00002563 ->Kind == TNK_Type_template) {
Douglas Gregor9135c722009-03-25 15:40:00 +00002564 // We have a qualified template-id, e.g., N::A<int>
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002565
2566 // C++ [class.qual]p2:
2567 // In a lookup in which the constructor is an acceptable lookup
2568 // result and the nested-name-specifier nominates a class C:
2569 //
2570 // - if the name specified after the
2571 // nested-name-specifier, when looked up in C, is the
2572 // injected-class-name of C (Clause 9), or
2573 //
2574 // - if the name specified after the nested-name-specifier
2575 // is the same as the identifier or the
2576 // simple-template-id's template-name in the last
2577 // component of the nested-name-specifier,
2578 //
2579 // the name is instead considered to name the constructor of
2580 // class C.
Chad Rosier8decdee2012-06-26 22:30:43 +00002581 //
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002582 // Thus, if the template-name is actually the constructor
2583 // name, then the code is ill-formed; this interpretation is
Chad Rosier8decdee2012-06-26 22:30:43 +00002584 // reinforced by the NAD status of core issue 635.
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002585 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
Dmitri Gribenko1b9e8f72013-02-12 17:27:41 +00002586 if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
John McCallba9d8532010-04-13 06:39:49 +00002587 TemplateId->Name &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002588 Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002589 if (isConstructorDeclarator()) {
2590 // The user meant this to be an out-of-line constructor
2591 // definition, but template arguments are not allowed
2592 // there. Just allow this as a constructor; we'll
2593 // complain about it later.
2594 goto DoneWithDeclSpec;
2595 }
2596
2597 // The user meant this to name a type, but it actually names
2598 // a constructor with some extraneous template
2599 // arguments. Complain, then parse it as a type as the user
2600 // intended.
2601 Diag(TemplateId->TemplateNameLoc,
2602 diag::err_out_of_line_template_id_names_constructor)
2603 << TemplateId->Name;
2604 }
2605
John McCallaa87d332009-12-12 11:40:51 +00002606 DS.getTypeSpecScope() = SS;
2607 ConsumeToken(); // The C++ scope.
Mike Stump1eb44332009-09-09 15:08:12 +00002608 assert(Tok.is(tok::annot_template_id) &&
Douglas Gregor9135c722009-03-25 15:40:00 +00002609 "ParseOptionalCXXScopeSpecifier not working");
Douglas Gregor059101f2011-03-02 00:47:37 +00002610 AnnotateTemplateIdTokenAsType();
Douglas Gregor9135c722009-03-25 15:40:00 +00002611 continue;
2612 }
2613
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002614 if (Next.is(tok::annot_typename)) {
John McCallaa87d332009-12-12 11:40:51 +00002615 DS.getTypeSpecScope() = SS;
2616 ConsumeToken(); // The C++ scope.
John McCallb3d87482010-08-24 05:47:05 +00002617 if (Tok.getAnnotationValue()) {
2618 ParsedType T = getTypeAnnotation(Tok);
Nico Weber253e80b2010-11-22 10:30:56 +00002619 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
Chad Rosier8decdee2012-06-26 22:30:43 +00002620 Tok.getAnnotationEndLoc(),
John McCallb3d87482010-08-24 05:47:05 +00002621 PrevSpec, DiagID, T);
Richard Smithb3cd3c02012-09-14 18:27:01 +00002622 if (isInvalid)
2623 break;
John McCallb3d87482010-08-24 05:47:05 +00002624 }
Douglas Gregor9d7b3532009-09-28 07:26:33 +00002625 else
2626 DS.SetTypeSpecError();
2627 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2628 ConsumeToken(); // The typename
2629 }
2630
Douglas Gregor9135c722009-03-25 15:40:00 +00002631 if (Next.isNot(tok::identifier))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002632 goto DoneWithDeclSpec;
2633
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002634 // If we're in a context where the identifier could be a class name,
2635 // check whether this is a constructor declaration.
Dmitri Gribenko1b9e8f72013-02-12 17:27:41 +00002636 if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
Chad Rosier8decdee2012-06-26 22:30:43 +00002637 Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002638 &SS)) {
2639 if (isConstructorDeclarator())
2640 goto DoneWithDeclSpec;
2641
2642 // As noted in C++ [class.qual]p2 (cited above), when the name
2643 // of the class is qualified in a context where it could name
2644 // a constructor, its a constructor name. However, we've
2645 // looked at the declarator, and the user probably meant this
2646 // to be a type. Complain that it isn't supposed to be treated
2647 // as a type, then proceed to parse it as a type.
2648 Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
2649 << Next.getIdentifierInfo();
2650 }
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002651
John McCallb3d87482010-08-24 05:47:05 +00002652 ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2653 Next.getLocation(),
Douglas Gregor9e876872011-03-01 18:12:44 +00002654 getCurScope(), &SS,
2655 false, false, ParsedType(),
Abramo Bagnarafad03b72012-01-27 08:46:19 +00002656 /*IsCtorOrDtorName=*/false,
Douglas Gregor9e876872011-03-01 18:12:44 +00002657 /*NonTrivialSourceInfo=*/true);
Douglas Gregor55f6b142009-02-09 18:46:07 +00002658
Chris Lattnerf4382f52009-04-14 22:17:06 +00002659 // If the referenced identifier is not a type, then this declspec is
2660 // erroneous: We already checked about that it has no type specifier, and
2661 // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
Mike Stump1eb44332009-09-09 15:08:12 +00002662 // typename.
David Blaikie7247c882013-05-15 07:37:26 +00002663 if (!TypeRep) {
Chris Lattnerf4382f52009-04-14 22:17:06 +00002664 ConsumeToken(); // Eat the scope spec so the identifier is current.
Michael Han2e397132012-11-26 22:54:45 +00002665 ParsedAttributesWithRange Attrs(AttrFactory);
2666 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
2667 if (!Attrs.empty()) {
2668 AttrsLastTime = true;
2669 attrs.takeAllFrom(Attrs);
2670 }
2671 continue;
2672 }
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002673 goto DoneWithDeclSpec;
Chris Lattnerf4382f52009-04-14 22:17:06 +00002674 }
Mike Stump1eb44332009-09-09 15:08:12 +00002675
John McCallaa87d332009-12-12 11:40:51 +00002676 DS.getTypeSpecScope() = SS;
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002677 ConsumeToken(); // The C++ scope.
2678
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002679 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002680 DiagID, TypeRep);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002681 if (isInvalid)
2682 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002683
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00002684 DS.SetRangeEnd(Tok.getLocation());
2685 ConsumeToken(); // The typename.
2686
2687 continue;
2688 }
Mike Stump1eb44332009-09-09 15:08:12 +00002689
Chris Lattner80d0c892009-01-21 19:48:37 +00002690 case tok::annot_typename: {
Bill Wendlingf0cc19f2013-11-19 22:56:43 +00002691 // If we've previously seen a tag definition, we were almost surely
2692 // missing a semicolon after it.
2693 if (DS.hasTypeSpecifier() && DS.hasTagDefinition())
2694 goto DoneWithDeclSpec;
2695
John McCallb3d87482010-08-24 05:47:05 +00002696 if (Tok.getAnnotationValue()) {
2697 ParsedType T = getTypeAnnotation(Tok);
Nico Weberc43271e2010-11-22 12:50:03 +00002698 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00002699 DiagID, T);
2700 } else
Douglas Gregor31a19b62009-04-01 21:51:26 +00002701 DS.SetTypeSpecError();
Chad Rosier8decdee2012-06-26 22:30:43 +00002702
Chris Lattner5c5db552010-04-05 18:18:31 +00002703 if (isInvalid)
2704 break;
2705
Chris Lattner80d0c892009-01-21 19:48:37 +00002706 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2707 ConsumeToken(); // The typename
Mike Stump1eb44332009-09-09 15:08:12 +00002708
Chris Lattner80d0c892009-01-21 19:48:37 +00002709 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2710 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosier8decdee2012-06-26 22:30:43 +00002711 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002712 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002713 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002714
Chris Lattner80d0c892009-01-21 19:48:37 +00002715 continue;
2716 }
Mike Stump1eb44332009-09-09 15:08:12 +00002717
Douglas Gregorbfad9152011-04-28 15:48:45 +00002718 case tok::kw___is_signed:
2719 // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
2720 // typically treats it as a trait. If we see __is_signed as it appears
2721 // in libstdc++, e.g.,
2722 //
2723 // static const bool __is_signed;
2724 //
2725 // then treat __is_signed as an identifier rather than as a keyword.
2726 if (DS.getTypeSpecType() == TST_bool &&
2727 DS.getTypeQualifiers() == DeclSpec::TQ_const &&
Bill Wendling03e463e2013-12-16 02:32:55 +00002728 DS.getStorageClassSpec() == DeclSpec::SCS_static)
2729 TryKeywordIdentFallback(true);
Douglas Gregorbfad9152011-04-28 15:48:45 +00002730
2731 // We're done with the declaration-specifiers.
2732 goto DoneWithDeclSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00002733
Chris Lattner3bd934a2008-07-26 01:18:38 +00002734 // typedef-name
David Blaikie42d6d0c2011-12-04 05:04:18 +00002735 case tok::kw_decltype:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002736 case tok::identifier: {
Chris Lattner5e02c472009-01-05 00:07:25 +00002737 // In C++, check to see if this is a scope specifier like foo::bar::, if
2738 // so handle it as such. This is important for ctor parsing.
David Blaikie4e4d0842012-03-11 07:00:24 +00002739 if (getLangOpts().CPlusPlus) {
Eli Friedman5a428202013-08-15 23:59:20 +00002740 if (TryAnnotateCXXScopeToken(EnteringContext)) {
John McCall9ba61662010-02-26 08:45:28 +00002741 if (!DS.hasTypeSpecifier())
2742 DS.SetTypeSpecError();
2743 goto DoneWithDeclSpec;
2744 }
2745 if (!Tok.is(tok::identifier))
2746 continue;
2747 }
Mike Stump1eb44332009-09-09 15:08:12 +00002748
Chris Lattner3bd934a2008-07-26 01:18:38 +00002749 // This identifier can only be a typedef name if we haven't already seen
2750 // a type-specifier. Without this check we misparse:
2751 // typedef int X; struct Y { short X; }; as 'short int'.
2752 if (DS.hasTypeSpecifier())
2753 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00002754
John Thompson82287d12010-02-05 00:12:22 +00002755 // Check for need to substitute AltiVec keyword tokens.
2756 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2757 break;
2758
Richard Smithf63eee72012-05-09 18:56:43 +00002759 // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2760 // allow the use of a typedef name as a type specifier.
2761 if (DS.isTypeAltiVecVector())
2762 goto DoneWithDeclSpec;
2763
John McCallb3d87482010-08-24 05:47:05 +00002764 ParsedType TypeRep =
2765 Actions.getTypeName(*Tok.getIdentifierInfo(),
2766 Tok.getLocation(), getCurScope());
Douglas Gregor55f6b142009-02-09 18:46:07 +00002767
Chris Lattnerc199ab32009-04-12 20:42:31 +00002768 // If this is not a typedef name, don't parse it as part of the declspec,
2769 // it must be an implicit int or an error.
John McCallb3d87482010-08-24 05:47:05 +00002770 if (!TypeRep) {
Michael Han2e397132012-11-26 22:54:45 +00002771 ParsedAttributesWithRange Attrs(AttrFactory);
2772 if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) {
2773 if (!Attrs.empty()) {
2774 AttrsLastTime = true;
2775 attrs.takeAllFrom(Attrs);
2776 }
2777 continue;
2778 }
Chris Lattner3bd934a2008-07-26 01:18:38 +00002779 goto DoneWithDeclSpec;
Chris Lattnerc199ab32009-04-12 20:42:31 +00002780 }
Douglas Gregor55f6b142009-02-09 18:46:07 +00002781
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002782 // If we're in a context where the identifier could be a class name,
2783 // check whether this is a constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002784 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002785 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002786 isConstructorDeclarator())
Douglas Gregorb48fe382008-10-31 09:07:45 +00002787 goto DoneWithDeclSpec;
2788
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002789 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002790 DiagID, TypeRep);
Chris Lattner3bd934a2008-07-26 01:18:38 +00002791 if (isInvalid)
2792 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002793
Chris Lattner3bd934a2008-07-26 01:18:38 +00002794 DS.SetRangeEnd(Tok.getLocation());
2795 ConsumeToken(); // The identifier
2796
2797 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2798 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosier8decdee2012-06-26 22:30:43 +00002799 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002800 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002801 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002802
Steve Naroff4f9b9f12008-09-22 10:28:57 +00002803 // Need to support trailing type qualifiers (e.g. "id<p> const").
2804 // If a type specifier follows, it will be diagnosed elsewhere.
2805 continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +00002806 }
Douglas Gregor39a8de12009-02-25 19:37:18 +00002807
2808 // type-name
2809 case tok::annot_template_id: {
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002810 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
Douglas Gregorc45c2322009-03-31 00:43:58 +00002811 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor39a8de12009-02-25 19:37:18 +00002812 // This template-id does not refer to a type name, so we're
2813 // done with the type-specifiers.
2814 goto DoneWithDeclSpec;
2815 }
2816
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002817 // If we're in a context where the template-id could be a
2818 // constructor name or specialization, check whether this is a
2819 // constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002820 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002821 Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002822 isConstructorDeclarator())
2823 goto DoneWithDeclSpec;
2824
Douglas Gregor39a8de12009-02-25 19:37:18 +00002825 // Turn the template-id annotation token into a type annotation
2826 // token, then try again to parse it as a type-specifier.
Douglas Gregor31a19b62009-04-01 21:51:26 +00002827 AnnotateTemplateIdTokenAsType();
Douglas Gregor39a8de12009-02-25 19:37:18 +00002828 continue;
2829 }
2830
Reid Spencer5f016e22007-07-11 17:01:13 +00002831 // GNU attributes support.
2832 case tok::kw___attribute:
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002833 ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
Reid Spencer5f016e22007-07-11 17:01:13 +00002834 continue;
Steve Narofff59e17e2008-12-24 20:59:21 +00002835
2836 // Microsoft declspec support.
2837 case tok::kw___declspec:
John McCall7f040a92010-12-24 02:08:15 +00002838 ParseMicrosoftDeclSpec(DS.getAttributes());
Steve Narofff59e17e2008-12-24 20:59:21 +00002839 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00002840
Steve Naroff239f0732008-12-25 14:16:32 +00002841 // Microsoft single token adornments.
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002842 case tok::kw___forceinline: {
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002843 isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID);
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002844 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
Richard Smithb3cd3c02012-09-14 18:27:01 +00002845 SourceLocation AttrNameLoc = Tok.getLocation();
Sean Hunt93f95f22012-06-18 16:13:52 +00002846 // FIXME: This does not work correctly if it is set to be a declspec
2847 // attribute, and a GNU attribute is simply incorrect.
Aaron Ballman624421f2013-08-31 01:11:41 +00002848 DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
2849 AttributeList::AS_GNU);
Richard Smithb3cd3c02012-09-14 18:27:01 +00002850 break;
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002851 }
Eli Friedman290eeb02009-06-08 23:27:34 +00002852
Aaron Ballmanaa9df092013-05-22 23:25:32 +00002853 case tok::kw___sptr:
2854 case tok::kw___uptr:
Eli Friedman290eeb02009-06-08 23:27:34 +00002855 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00002856 case tok::kw___ptr32:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00002857 case tok::kw___w64:
Steve Naroff239f0732008-12-25 14:16:32 +00002858 case tok::kw___cdecl:
2859 case tok::kw___stdcall:
2860 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00002861 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00002862 case tok::kw___unaligned:
John McCall7f040a92010-12-24 02:08:15 +00002863 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00002864 continue;
2865
Dawn Perchik52fc3142010-09-03 01:29:35 +00002866 // Borland single token adornments.
2867 case tok::kw___pascal:
John McCall7f040a92010-12-24 02:08:15 +00002868 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00002869 continue;
2870
Peter Collingbournef315fa82011-02-14 01:42:53 +00002871 // OpenCL single token adornments.
2872 case tok::kw___kernel:
2873 ParseOpenCLAttributes(DS.getAttributes());
2874 continue;
2875
Reid Spencer5f016e22007-07-11 17:01:13 +00002876 // storage-class-specifier
2877 case tok::kw_typedef:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002878 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2879 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002880 break;
2881 case tok::kw_extern:
Richard Smithec642442013-04-12 22:46:28 +00002882 if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
Chris Lattner1ab3b962008-11-18 07:48:38 +00002883 Diag(Tok, diag::ext_thread_before) << "extern";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002884 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2885 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002886 break;
Steve Naroff8d54bf22007-12-18 00:16:02 +00002887 case tok::kw___private_extern__:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002888 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2889 Loc, PrevSpec, DiagID);
Steve Naroff8d54bf22007-12-18 00:16:02 +00002890 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002891 case tok::kw_static:
Richard Smithec642442013-04-12 22:46:28 +00002892 if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
Chris Lattner1ab3b962008-11-18 07:48:38 +00002893 Diag(Tok, diag::ext_thread_before) << "static";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002894 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2895 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002896 break;
2897 case tok::kw_auto:
Richard Smith80ad52f2013-01-02 11:42:31 +00002898 if (getLangOpts().CPlusPlus11) {
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002899 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002900 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2901 PrevSpec, DiagID);
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002902 if (!isInvalid)
Richard Smith8f4fb192011-09-04 19:54:14 +00002903 Diag(Tok, diag::ext_auto_storage_class)
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002904 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
Richard Smith8f4fb192011-09-04 19:54:14 +00002905 } else
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002906 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2907 DiagID);
Richard Smith8f4fb192011-09-04 19:54:14 +00002908 } else
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002909 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2910 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002911 break;
2912 case tok::kw_register:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002913 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2914 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002915 break;
Sebastian Redl669d5d72008-11-14 23:42:31 +00002916 case tok::kw_mutable:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002917 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2918 PrevSpec, DiagID);
Sebastian Redl669d5d72008-11-14 23:42:31 +00002919 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002920 case tok::kw___thread:
Richard Smithec642442013-04-12 22:46:28 +00002921 isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,
2922 PrevSpec, DiagID);
2923 break;
2924 case tok::kw_thread_local:
2925 isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc,
2926 PrevSpec, DiagID);
2927 break;
2928 case tok::kw__Thread_local:
2929 isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
2930 Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002931 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002932
Reid Spencer5f016e22007-07-11 17:01:13 +00002933 // function-specifier
2934 case tok::kw_inline:
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002935 isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002936 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002937 case tok::kw_virtual:
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002938 isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002939 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002940 case tok::kw_explicit:
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002941 isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002942 break;
Richard Smithde03c152013-01-17 22:16:11 +00002943 case tok::kw__Noreturn:
2944 if (!getLangOpts().C11)
2945 Diag(Loc, diag::ext_c11_noreturn);
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002946 isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);
Richard Smithde03c152013-01-17 22:16:11 +00002947 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002948
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002949 // alignment-specifier
2950 case tok::kw__Alignas:
David Blaikie4e4d0842012-03-11 07:00:24 +00002951 if (!getLangOpts().C11)
Jordan Rosef70a8862012-06-30 21:33:57 +00002952 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002953 ParseAlignmentSpecifier(DS.getAttributes());
2954 continue;
2955
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002956 // friend
2957 case tok::kw_friend:
John McCall67d1a672009-08-06 02:15:43 +00002958 if (DSContext == DSC_class)
2959 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2960 else {
2961 PrevSpec = ""; // not actually used by the diagnostic
2962 DiagID = diag::err_friend_invalid_in_context;
2963 isInvalid = true;
2964 }
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002965 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002966
Douglas Gregor8d267c52011-09-09 02:06:17 +00002967 // Modules
2968 case tok::kw___module_private__:
2969 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2970 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00002971
Sebastian Redl2ac67232009-11-05 15:47:02 +00002972 // constexpr
2973 case tok::kw_constexpr:
2974 isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2975 break;
2976
Chris Lattner80d0c892009-01-21 19:48:37 +00002977 // type-specifier
2978 case tok::kw_short:
John McCallfec54012009-08-03 20:12:06 +00002979 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2980 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002981 break;
2982 case tok::kw_long:
2983 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
John McCallfec54012009-08-03 20:12:06 +00002984 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2985 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002986 else
John McCallfec54012009-08-03 20:12:06 +00002987 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2988 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002989 break;
Francois Pichet338d7f72011-04-28 01:59:37 +00002990 case tok::kw___int64:
2991 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2992 DiagID);
2993 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002994 case tok::kw_signed:
John McCallfec54012009-08-03 20:12:06 +00002995 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2996 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002997 break;
2998 case tok::kw_unsigned:
John McCallfec54012009-08-03 20:12:06 +00002999 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
3000 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003001 break;
3002 case tok::kw__Complex:
John McCallfec54012009-08-03 20:12:06 +00003003 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
3004 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003005 break;
3006 case tok::kw__Imaginary:
John McCallfec54012009-08-03 20:12:06 +00003007 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
3008 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003009 break;
3010 case tok::kw_void:
John McCallfec54012009-08-03 20:12:06 +00003011 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
3012 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003013 break;
3014 case tok::kw_char:
John McCallfec54012009-08-03 20:12:06 +00003015 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
3016 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003017 break;
3018 case tok::kw_int:
John McCallfec54012009-08-03 20:12:06 +00003019 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
3020 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003021 break;
Richard Smith5a5a9712012-04-04 06:24:32 +00003022 case tok::kw___int128:
3023 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
3024 DiagID);
3025 break;
3026 case tok::kw_half:
3027 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
3028 DiagID);
3029 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00003030 case tok::kw_float:
John McCallfec54012009-08-03 20:12:06 +00003031 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
3032 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003033 break;
3034 case tok::kw_double:
John McCallfec54012009-08-03 20:12:06 +00003035 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
3036 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003037 break;
3038 case tok::kw_wchar_t:
John McCallfec54012009-08-03 20:12:06 +00003039 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
3040 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003041 break;
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003042 case tok::kw_char16_t:
John McCallfec54012009-08-03 20:12:06 +00003043 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
3044 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003045 break;
3046 case tok::kw_char32_t:
John McCallfec54012009-08-03 20:12:06 +00003047 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
3048 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003049 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00003050 case tok::kw_bool:
3051 case tok::kw__Bool:
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00003052 if (Tok.is(tok::kw_bool) &&
3053 DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
3054 DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
3055 PrevSpec = ""; // Not used by the diagnostic.
3056 DiagID = diag::err_bool_redeclaration;
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00003057 // For better error recovery.
3058 Tok.setKind(tok::identifier);
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00003059 isInvalid = true;
3060 } else {
3061 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
3062 DiagID);
3063 }
Chris Lattner80d0c892009-01-21 19:48:37 +00003064 break;
3065 case tok::kw__Decimal32:
John McCallfec54012009-08-03 20:12:06 +00003066 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
3067 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003068 break;
3069 case tok::kw__Decimal64:
John McCallfec54012009-08-03 20:12:06 +00003070 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
3071 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003072 break;
3073 case tok::kw__Decimal128:
John McCallfec54012009-08-03 20:12:06 +00003074 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
3075 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003076 break;
John Thompson82287d12010-02-05 00:12:22 +00003077 case tok::kw___vector:
3078 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
3079 break;
3080 case tok::kw___pixel:
3081 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
3082 break;
Guy Benyeib13621d2012-12-18 14:38:23 +00003083 case tok::kw_image1d_t:
3084 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc,
3085 PrevSpec, DiagID);
3086 break;
3087 case tok::kw_image1d_array_t:
3088 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc,
3089 PrevSpec, DiagID);
3090 break;
3091 case tok::kw_image1d_buffer_t:
3092 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc,
3093 PrevSpec, DiagID);
3094 break;
3095 case tok::kw_image2d_t:
3096 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc,
3097 PrevSpec, DiagID);
3098 break;
3099 case tok::kw_image2d_array_t:
3100 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc,
3101 PrevSpec, DiagID);
3102 break;
3103 case tok::kw_image3d_t:
3104 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc,
3105 PrevSpec, DiagID);
3106 break;
Guy Benyei21f18c42013-02-07 10:55:47 +00003107 case tok::kw_sampler_t:
3108 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc,
3109 PrevSpec, DiagID);
3110 break;
Guy Benyeie6b9d802013-01-20 12:31:11 +00003111 case tok::kw_event_t:
3112 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc,
3113 PrevSpec, DiagID);
3114 break;
John McCalla5fc4722011-04-09 22:50:59 +00003115 case tok::kw___unknown_anytype:
3116 isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
3117 PrevSpec, DiagID);
3118 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00003119
3120 // class-specifier:
3121 case tok::kw_class:
3122 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00003123 case tok::kw___interface:
Chris Lattner4c97d762009-04-12 21:49:30 +00003124 case tok::kw_union: {
3125 tok::TokenKind Kind = Tok.getKind();
3126 ConsumeToken();
Michael Han2e397132012-11-26 22:54:45 +00003127
3128 // These are attributes following class specifiers.
3129 // To produce better diagnostic, we parse them when
3130 // parsing class specifier.
Bill Wendlingad017fa2012-12-20 19:22:21 +00003131 ParsedAttributesWithRange Attributes(AttrFactory);
Richard Smith69730c12012-03-12 07:56:15 +00003132 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
Bill Wendlingad017fa2012-12-20 19:22:21 +00003133 EnteringContext, DSContext, Attributes);
Michael Han2e397132012-11-26 22:54:45 +00003134
3135 // If there are attributes following class specifier,
3136 // take them over and handle them here.
Bill Wendlingad017fa2012-12-20 19:22:21 +00003137 if (!Attributes.empty()) {
Michael Han2e397132012-11-26 22:54:45 +00003138 AttrsLastTime = true;
Bill Wendlingad017fa2012-12-20 19:22:21 +00003139 attrs.takeAllFrom(Attributes);
Michael Han2e397132012-11-26 22:54:45 +00003140 }
Chris Lattner80d0c892009-01-21 19:48:37 +00003141 continue;
Chris Lattner4c97d762009-04-12 21:49:30 +00003142 }
Chris Lattner80d0c892009-01-21 19:48:37 +00003143
3144 // enum-specifier:
3145 case tok::kw_enum:
Chris Lattner4c97d762009-04-12 21:49:30 +00003146 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00003147 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00003148 continue;
3149
3150 // cv-qualifier:
3151 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00003152 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00003153 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00003154 break;
3155 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00003156 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00003157 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00003158 break;
3159 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00003160 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00003161 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00003162 break;
3163
Douglas Gregord57959a2009-03-27 23:10:48 +00003164 // C++ typename-specifier:
3165 case tok::kw_typename:
John McCall9ba61662010-02-26 08:45:28 +00003166 if (TryAnnotateTypeOrScopeToken()) {
3167 DS.SetTypeSpecError();
3168 goto DoneWithDeclSpec;
3169 }
3170 if (!Tok.is(tok::kw_typename))
Douglas Gregord57959a2009-03-27 23:10:48 +00003171 continue;
3172 break;
3173
Chris Lattner80d0c892009-01-21 19:48:37 +00003174 // GNU typeof support.
3175 case tok::kw_typeof:
3176 ParseTypeofSpecifier(DS);
3177 continue;
3178
David Blaikie42d6d0c2011-12-04 05:04:18 +00003179 case tok::annot_decltype:
Anders Carlsson6fd634f2009-06-24 17:47:40 +00003180 ParseDecltypeSpecifier(DS);
3181 continue;
3182
Sean Huntdb5d44b2011-05-19 05:37:45 +00003183 case tok::kw___underlying_type:
3184 ParseUnderlyingTypeSpecifier(DS);
Eli Friedmanb001de72011-10-06 23:00:33 +00003185 continue;
3186
3187 case tok::kw__Atomic:
Richard Smith4cf4a5e2013-03-28 01:55:44 +00003188 // C11 6.7.2.4/4:
3189 // If the _Atomic keyword is immediately followed by a left parenthesis,
3190 // it is interpreted as a type specifier (with a type name), not as a
3191 // type qualifier.
3192 if (NextToken().is(tok::l_paren)) {
3193 ParseAtomicSpecifier(DS);
3194 continue;
3195 }
3196 isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
3197 getLangOpts());
3198 break;
Sean Huntdb5d44b2011-05-19 05:37:45 +00003199
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003200 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00003201 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003202 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003203 goto DoneWithDeclSpec;
3204 case tok::kw___private:
3205 case tok::kw___global:
3206 case tok::kw___local:
3207 case tok::kw___constant:
3208 case tok::kw___read_only:
3209 case tok::kw___write_only:
3210 case tok::kw___read_write:
3211 ParseOpenCLQualifiers(DS);
3212 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00003213
Steve Naroffd3ded1f2008-06-05 00:02:44 +00003214 case tok::less:
Chris Lattner3bd934a2008-07-26 01:18:38 +00003215 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerbce61352008-07-26 00:20:22 +00003216 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
3217 // but we support it.
David Blaikie4e4d0842012-03-11 07:00:24 +00003218 if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
Chris Lattnerbce61352008-07-26 00:20:22 +00003219 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00003220
Douglas Gregor46f936e2010-11-19 17:10:50 +00003221 if (!ParseObjCProtocolQualifiers(DS))
3222 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
3223 << FixItHint::CreateInsertion(Loc, "id")
3224 << SourceRange(Loc, DS.getSourceRange().getEnd());
Chad Rosier8decdee2012-06-26 22:30:43 +00003225
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00003226 // Need to support trailing type qualifiers (e.g. "id<p> const").
3227 // If a type specifier follows, it will be diagnosed elsewhere.
3228 continue;
Reid Spencer5f016e22007-07-11 17:01:13 +00003229 }
John McCallfec54012009-08-03 20:12:06 +00003230 // If the specifier wasn't legal, issue a diagnostic.
Reid Spencer5f016e22007-07-11 17:01:13 +00003231 if (isInvalid) {
3232 assert(PrevSpec && "Method did not return previous specifier!");
John McCallfec54012009-08-03 20:12:06 +00003233 assert(DiagID);
Chad Rosier8decdee2012-06-26 22:30:43 +00003234
Douglas Gregorae2fb142010-08-23 14:34:43 +00003235 if (DiagID == diag::ext_duplicate_declspec)
3236 Diag(Tok, DiagID)
3237 << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
3238 else
3239 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003240 }
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00003241
Chris Lattner81c018d2008-03-13 06:29:04 +00003242 DS.SetRangeEnd(Tok.getLocation());
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00003243 if (DiagID != diag::err_bool_redeclaration)
3244 ConsumeToken();
Sean Hunt2edf0a22012-06-23 05:07:58 +00003245
3246 AttrsLastTime = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00003247 }
3248}
Douglas Gregoradcac882008-12-01 23:54:00 +00003249
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003250/// ParseStructDeclaration - Parse a struct declaration without the terminating
3251/// semicolon.
3252///
Reid Spencer5f016e22007-07-11 17:01:13 +00003253/// struct-declaration:
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003254/// specifier-qualifier-list struct-declarator-list
Reid Spencer5f016e22007-07-11 17:01:13 +00003255/// [GNU] __extension__ struct-declaration
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003256/// [GNU] specifier-qualifier-list
Reid Spencer5f016e22007-07-11 17:01:13 +00003257/// struct-declarator-list:
3258/// struct-declarator
3259/// struct-declarator-list ',' struct-declarator
3260/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
3261/// struct-declarator:
3262/// declarator
3263/// [GNU] declarator attributes[opt]
3264/// declarator[opt] ':' constant-expression
3265/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
3266///
Chris Lattnere1359422008-04-10 06:46:29 +00003267void Parser::
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003268ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003269
Chris Lattnerc46d1a12008-10-20 06:45:43 +00003270 if (Tok.is(tok::kw___extension__)) {
3271 // __extension__ silences extension warnings in the subexpression.
3272 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroff28a7ca82007-08-20 22:28:22 +00003273 ConsumeToken();
Chris Lattnerc46d1a12008-10-20 06:45:43 +00003274 return ParseStructDeclaration(DS, Fields);
3275 }
Mike Stump1eb44332009-09-09 15:08:12 +00003276
Steve Naroff28a7ca82007-08-20 22:28:22 +00003277 // Parse the common specifier-qualifiers-list piece.
Steve Naroff28a7ca82007-08-20 22:28:22 +00003278 ParseSpecifierQualifierList(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00003279
Douglas Gregor4920f1f2009-01-12 22:49:06 +00003280 // If there are no declarators, this is a free-standing declaration
3281 // specifier. Let the actions module cope with it.
Chris Lattner04d66662007-10-09 17:33:22 +00003282 if (Tok.is(tok::semi)) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003283 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
3284 DS);
3285 DS.complete(TheDecl);
Steve Naroff28a7ca82007-08-20 22:28:22 +00003286 return;
3287 }
3288
3289 // Read struct-declarators until we find the semicolon.
John McCallbdd563e2009-11-03 02:38:08 +00003290 bool FirstDeclarator = true;
Richard Smith7984de32012-01-12 23:53:29 +00003291 SourceLocation CommaLoc;
Steve Naroff28a7ca82007-08-20 22:28:22 +00003292 while (1) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003293 ParsingFieldDeclarator DeclaratorInfo(*this, DS);
Richard Smith7984de32012-01-12 23:53:29 +00003294 DeclaratorInfo.D.setCommaLoc(CommaLoc);
John McCallbdd563e2009-11-03 02:38:08 +00003295
Bill Wendlingad017fa2012-12-20 19:22:21 +00003296 // Attributes are only allowed here on successive declarators.
John McCall7f040a92010-12-24 02:08:15 +00003297 if (!FirstDeclarator)
3298 MaybeParseGNUAttributes(DeclaratorInfo.D);
Mike Stump1eb44332009-09-09 15:08:12 +00003299
Steve Naroff28a7ca82007-08-20 22:28:22 +00003300 /// struct-declarator: declarator
3301 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattnera1efc8c2009-12-10 01:59:24 +00003302 if (Tok.isNot(tok::colon)) {
3303 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
3304 ColonProtectionRAIIObject X(*this);
Chris Lattnere1359422008-04-10 06:46:29 +00003305 ParseDeclarator(DeclaratorInfo.D);
Chris Lattnera1efc8c2009-12-10 01:59:24 +00003306 }
Mike Stump1eb44332009-09-09 15:08:12 +00003307
Chris Lattner04d66662007-10-09 17:33:22 +00003308 if (Tok.is(tok::colon)) {
Steve Naroff28a7ca82007-08-20 22:28:22 +00003309 ConsumeToken();
John McCall60d7b3a2010-08-24 06:29:42 +00003310 ExprResult Res(ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00003311 if (Res.isInvalid())
Alexey Bataev8fe24752013-11-18 08:17:37 +00003312 SkipUntil(tok::semi, StopBeforeMatch);
Chris Lattner60b1e3e2008-04-10 06:15:14 +00003313 else
Sebastian Redleffa8d12008-12-10 00:02:53 +00003314 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroff28a7ca82007-08-20 22:28:22 +00003315 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00003316
Steve Naroff28a7ca82007-08-20 22:28:22 +00003317 // If attributes exist after the declarator, parse them.
John McCall7f040a92010-12-24 02:08:15 +00003318 MaybeParseGNUAttributes(DeclaratorInfo.D);
Sebastian Redlab197ba2009-02-09 18:23:29 +00003319
John McCallbdd563e2009-11-03 02:38:08 +00003320 // We're done with this declarator; invoke the callback.
Eli Friedman817a8862012-08-08 23:35:12 +00003321 Fields.invoke(DeclaratorInfo);
John McCallbdd563e2009-11-03 02:38:08 +00003322
Steve Naroff28a7ca82007-08-20 22:28:22 +00003323 // If we don't have a comma, it is either the end of the list (a ';')
3324 // or an error, bail out.
Chris Lattner04d66662007-10-09 17:33:22 +00003325 if (Tok.isNot(tok::comma))
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003326 return;
Sebastian Redlab197ba2009-02-09 18:23:29 +00003327
Steve Naroff28a7ca82007-08-20 22:28:22 +00003328 // Consume the comma.
Richard Smith7984de32012-01-12 23:53:29 +00003329 CommaLoc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00003330
John McCallbdd563e2009-11-03 02:38:08 +00003331 FirstDeclarator = false;
Steve Naroff28a7ca82007-08-20 22:28:22 +00003332 }
Steve Naroff28a7ca82007-08-20 22:28:22 +00003333}
3334
3335/// ParseStructUnionBody
3336/// struct-contents:
3337/// struct-declaration-list
3338/// [EXT] empty
3339/// [GNU] "struct-declaration-list" without terminatoring ';'
3340/// struct-declaration-list:
3341/// struct-declaration
3342/// struct-declaration-list struct-declaration
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003343/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroff28a7ca82007-08-20 22:28:22 +00003344///
Reid Spencer5f016e22007-07-11 17:01:13 +00003345void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
John McCalld226f652010-08-21 09:40:31 +00003346 unsigned TagType, Decl *TagDecl) {
John McCallf312b1e2010-08-26 23:41:50 +00003347 PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
3348 "parsing struct/union body");
Andy Gibbsf50f3f72013-04-03 09:31:19 +00003349 assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");
Mike Stump1eb44332009-09-09 15:08:12 +00003350
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003351 BalancedDelimiterTracker T(*this, tok::l_brace);
3352 if (T.consumeOpen())
3353 return;
Mike Stump1eb44332009-09-09 15:08:12 +00003354
Douglas Gregor3218c4b2009-01-09 22:42:13 +00003355 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003356 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
Douglas Gregor72de6672009-01-08 20:45:30 +00003357
Chris Lattner5f9e2722011-07-23 10:55:15 +00003358 SmallVector<Decl *, 32> FieldDecls;
Chris Lattnere1359422008-04-10 06:46:29 +00003359
Reid Spencer5f016e22007-07-11 17:01:13 +00003360 // While we still have something to read, read the declarations in the struct.
Chris Lattner04d66662007-10-09 17:33:22 +00003361 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003362 // Each iteration of this loop reads one struct-declaration.
Mike Stump1eb44332009-09-09 15:08:12 +00003363
Reid Spencer5f016e22007-07-11 17:01:13 +00003364 // Check for extraneous top-level semicolon.
Chris Lattner04d66662007-10-09 17:33:22 +00003365 if (Tok.is(tok::semi)) {
Richard Smitheab9d6f2012-07-23 05:45:25 +00003366 ConsumeExtraSemi(InsideStruct, TagType);
Reid Spencer5f016e22007-07-11 17:01:13 +00003367 continue;
3368 }
Chris Lattnere1359422008-04-10 06:46:29 +00003369
Andy Gibbs74b9fa12013-04-03 09:46:04 +00003370 // Parse _Static_assert declaration.
3371 if (Tok.is(tok::kw__Static_assert)) {
3372 SourceLocation DeclEnd;
3373 ParseStaticAssertDeclaration(DeclEnd);
3374 continue;
3375 }
3376
Argyrios Kyrtzidisbd957452013-04-18 01:42:35 +00003377 if (Tok.is(tok::annot_pragma_pack)) {
3378 HandlePragmaPack();
3379 continue;
3380 }
3381
3382 if (Tok.is(tok::annot_pragma_align)) {
3383 HandlePragmaAlign();
3384 continue;
3385 }
3386
John McCallbdd563e2009-11-03 02:38:08 +00003387 if (!Tok.is(tok::at)) {
3388 struct CFieldCallback : FieldCallback {
3389 Parser &P;
John McCalld226f652010-08-21 09:40:31 +00003390 Decl *TagDecl;
Chris Lattner5f9e2722011-07-23 10:55:15 +00003391 SmallVectorImpl<Decl *> &FieldDecls;
John McCallbdd563e2009-11-03 02:38:08 +00003392
John McCalld226f652010-08-21 09:40:31 +00003393 CFieldCallback(Parser &P, Decl *TagDecl,
Chris Lattner5f9e2722011-07-23 10:55:15 +00003394 SmallVectorImpl<Decl *> &FieldDecls) :
John McCallbdd563e2009-11-03 02:38:08 +00003395 P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
3396
Eli Friedmandcdff462012-08-08 23:53:27 +00003397 void invoke(ParsingFieldDeclarator &FD) {
John McCallbdd563e2009-11-03 02:38:08 +00003398 // Install the declarator into the current TagDecl.
John McCalld226f652010-08-21 09:40:31 +00003399 Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
John McCall4ba39712009-11-03 21:13:47 +00003400 FD.D.getDeclSpec().getSourceRange().getBegin(),
3401 FD.D, FD.BitfieldSize);
John McCallbdd563e2009-11-03 02:38:08 +00003402 FieldDecls.push_back(Field);
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003403 FD.complete(Field);
Douglas Gregor91a28862009-08-26 14:27:30 +00003404 }
John McCallbdd563e2009-11-03 02:38:08 +00003405 } Callback(*this, TagDecl, FieldDecls);
3406
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003407 // Parse all the comma separated declarators.
3408 ParsingDeclSpec DS(*this);
John McCallbdd563e2009-11-03 02:38:08 +00003409 ParseStructDeclaration(DS, Callback);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003410 } else { // Handle @defs
3411 ConsumeToken();
3412 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
3413 Diag(Tok, diag::err_unexpected_at);
Alexey Bataev8fe24752013-11-18 08:17:37 +00003414 SkipUntil(tok::semi);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003415 continue;
3416 }
3417 ConsumeToken();
3418 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
3419 if (!Tok.is(tok::identifier)) {
3420 Diag(Tok, diag::err_expected_ident);
Alexey Bataev8fe24752013-11-18 08:17:37 +00003421 SkipUntil(tok::semi);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003422 continue;
3423 }
Chris Lattner5f9e2722011-07-23 10:55:15 +00003424 SmallVector<Decl *, 16> Fields;
Douglas Gregor23c94db2010-07-02 17:43:08 +00003425 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
Douglas Gregor44b43212008-12-11 16:49:14 +00003426 Tok.getIdentifierInfo(), Fields);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003427 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
3428 ConsumeToken();
3429 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
Mike Stump1eb44332009-09-09 15:08:12 +00003430 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003431
Chris Lattner04d66662007-10-09 17:33:22 +00003432 if (Tok.is(tok::semi)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003433 ConsumeToken();
Chris Lattner04d66662007-10-09 17:33:22 +00003434 } else if (Tok.is(tok::r_brace)) {
Chris Lattner3e156ad2010-02-02 00:37:27 +00003435 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
Reid Spencer5f016e22007-07-11 17:01:13 +00003436 break;
3437 } else {
Chris Lattner3e156ad2010-02-02 00:37:27 +00003438 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
3439 // Skip to end of block or statement to avoid ext-warning on extra ';'.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003440 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
Chris Lattner3e156ad2010-02-02 00:37:27 +00003441 // If we stopped at a ';', eat it.
3442 if (Tok.is(tok::semi)) ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00003443 }
3444 }
Mike Stump1eb44332009-09-09 15:08:12 +00003445
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003446 T.consumeClose();
Mike Stump1eb44332009-09-09 15:08:12 +00003447
John McCall0b7e6782011-03-24 11:26:52 +00003448 ParsedAttributes attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00003449 // If attributes exist after struct contents, parse them.
John McCall7f040a92010-12-24 02:08:15 +00003450 MaybeParseGNUAttributes(attrs);
Daniel Dunbar1bfe1c22008-10-03 02:03:53 +00003451
Douglas Gregor23c94db2010-07-02 17:43:08 +00003452 Actions.ActOnFields(getCurScope(),
David Blaikie77b6de02011-09-22 02:58:26 +00003453 RecordLoc, TagDecl, FieldDecls,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003454 T.getOpenLocation(), T.getCloseLocation(),
John McCall7f040a92010-12-24 02:08:15 +00003455 attrs.getList());
Douglas Gregor72de6672009-01-08 20:45:30 +00003456 StructScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003457 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
3458 T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00003459}
3460
Reid Spencer5f016e22007-07-11 17:01:13 +00003461/// ParseEnumSpecifier
3462/// enum-specifier: [C99 6.7.2.2]
3463/// 'enum' identifier[opt] '{' enumerator-list '}'
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003464///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00003465/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
3466/// '}' attributes[opt]
Aaron Ballman6454a022012-03-01 04:09:28 +00003467/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
3468/// '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00003469/// 'enum' identifier
3470/// [GNU] 'enum' attributes[opt] identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003471///
Richard Smith1af83c42012-03-23 03:33:32 +00003472/// [C++11] enum-head '{' enumerator-list[opt] '}'
3473/// [C++11] enum-head '{' enumerator-list ',' '}'
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003474///
Richard Smith1af83c42012-03-23 03:33:32 +00003475/// enum-head: [C++11]
3476/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
3477/// enum-key attribute-specifier-seq[opt] nested-name-specifier
3478/// identifier enum-base[opt]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003479///
Richard Smith1af83c42012-03-23 03:33:32 +00003480/// enum-key: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003481/// 'enum'
3482/// 'enum' 'class'
3483/// 'enum' 'struct'
3484///
Richard Smith1af83c42012-03-23 03:33:32 +00003485/// enum-base: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003486/// ':' type-specifier-seq
3487///
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003488/// [C++] elaborated-type-specifier:
3489/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
3490///
Chris Lattner4c97d762009-04-12 21:49:30 +00003491void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Douglas Gregor9b9edd62010-03-02 17:53:14 +00003492 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00003493 AccessSpecifier AS, DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003494 // Parse the tag portion of this.
Douglas Gregor374929f2009-09-18 15:37:17 +00003495 if (Tok.is(tok::code_completion)) {
3496 // Code completion for an enum name.
Douglas Gregor23c94db2010-07-02 17:43:08 +00003497 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00003498 return cutOffParsing();
Douglas Gregor374929f2009-09-18 15:37:17 +00003499 }
John McCall57c13002011-07-06 05:58:41 +00003500
Sean Hunt2edf0a22012-06-23 05:07:58 +00003501 // If attributes exist after tag, parse them.
3502 ParsedAttributesWithRange attrs(AttrFactory);
3503 MaybeParseGNUAttributes(attrs);
Richard Smith4e24f0f2013-01-02 12:01:23 +00003504 MaybeParseCXX11Attributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003505
3506 // If declspecs exist after tag, parse them.
3507 while (Tok.is(tok::kw___declspec))
3508 ParseMicrosoftDeclSpec(attrs);
3509
Richard Smithbdad7a22012-01-10 01:33:14 +00003510 SourceLocation ScopedEnumKWLoc;
John McCall57c13002011-07-06 05:58:41 +00003511 bool IsScopedUsingClassTag = false;
3512
John McCall1e12b3d2012-06-23 22:30:04 +00003513 // In C++11, recognize 'enum class' and 'enum struct'.
Richard Trieued5a2922013-04-23 02:47:36 +00003514 if (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct)) {
3515 Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum
3516 : diag::ext_scoped_enum);
John McCall57c13002011-07-06 05:58:41 +00003517 IsScopedUsingClassTag = Tok.is(tok::kw_class);
Richard Smithbdad7a22012-01-10 01:33:14 +00003518 ScopedEnumKWLoc = ConsumeToken();
Chad Rosier8decdee2012-06-26 22:30:43 +00003519
Bill Wendlingad017fa2012-12-20 19:22:21 +00003520 // Attributes are not allowed between these keywords. Diagnose,
John McCall1e12b3d2012-06-23 22:30:04 +00003521 // but then just treat them like they appeared in the right place.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003522 ProhibitAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003523
3524 // They are allowed afterwards, though.
3525 MaybeParseGNUAttributes(attrs);
Richard Smith4e24f0f2013-01-02 12:01:23 +00003526 MaybeParseCXX11Attributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003527 while (Tok.is(tok::kw___declspec))
3528 ParseMicrosoftDeclSpec(attrs);
John McCall57c13002011-07-06 05:58:41 +00003529 }
Richard Smith1af83c42012-03-23 03:33:32 +00003530
John McCall13489672012-05-07 06:16:58 +00003531 // C++11 [temp.explicit]p12:
3532 // The usual access controls do not apply to names used to specify
3533 // explicit instantiations.
3534 // We extend this to also cover explicit specializations. Note that
3535 // we don't suppress if this turns out to be an elaborated type
3536 // specifier.
3537 bool shouldDelayDiagsInTag =
3538 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3539 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3540 SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
Richard Smith1af83c42012-03-23 03:33:32 +00003541
Richard Smith7796eb52012-03-12 08:56:40 +00003542 // Enum definitions should not be parsed in a trailing-return-type.
3543 bool AllowDeclaration = DSC != DSC_trailing;
3544
3545 bool AllowFixedUnderlyingType = AllowDeclaration &&
Richard Smith80ad52f2013-01-02 11:42:31 +00003546 (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt ||
Richard Smith7796eb52012-03-12 08:56:40 +00003547 getLangOpts().ObjC2);
John McCall57c13002011-07-06 05:58:41 +00003548
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00003549 CXXScopeSpec &SS = DS.getTypeSpecScope();
David Blaikie4e4d0842012-03-11 07:00:24 +00003550 if (getLangOpts().CPlusPlus) {
John McCall57c13002011-07-06 05:58:41 +00003551 // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3552 // if a fixed underlying type is allowed.
3553 ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
Chad Rosier8decdee2012-06-26 22:30:43 +00003554
3555 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Richard Smith725fe0e2013-04-01 21:43:41 +00003556 /*EnteringContext=*/true))
John McCall9ba61662010-02-26 08:45:28 +00003557 return;
3558
3559 if (SS.isSet() && Tok.isNot(tok::identifier)) {
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003560 Diag(Tok, diag::err_expected_ident);
3561 if (Tok.isNot(tok::l_brace)) {
3562 // Has no name and is not a definition.
3563 // Skip the rest of this declarator, up until the comma or semicolon.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003564 SkipUntil(tok::comma, StopAtSemi);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003565 return;
3566 }
3567 }
3568 }
Mike Stump1eb44332009-09-09 15:08:12 +00003569
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003570 // Must have either 'enum name' or 'enum {...}'.
Douglas Gregorb9075602011-02-22 02:55:24 +00003571 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
Richard Smith7796eb52012-03-12 08:56:40 +00003572 !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003573 Diag(Tok, diag::err_expected_ident_lbrace);
Mike Stump1eb44332009-09-09 15:08:12 +00003574
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003575 // Skip the rest of this declarator, up until the comma or semicolon.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003576 SkipUntil(tok::comma, StopAtSemi);
Reid Spencer5f016e22007-07-11 17:01:13 +00003577 return;
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003578 }
Mike Stump1eb44332009-09-09 15:08:12 +00003579
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003580 // If an identifier is present, consume and remember it.
3581 IdentifierInfo *Name = 0;
3582 SourceLocation NameLoc;
3583 if (Tok.is(tok::identifier)) {
3584 Name = Tok.getIdentifierInfo();
3585 NameLoc = ConsumeToken();
3586 }
Mike Stump1eb44332009-09-09 15:08:12 +00003587
Richard Smithbdad7a22012-01-10 01:33:14 +00003588 if (!Name && ScopedEnumKWLoc.isValid()) {
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003589 // C++0x 7.2p2: The optional identifier shall not be omitted in the
3590 // declaration of a scoped enumeration.
3591 Diag(Tok, diag::err_scoped_enum_missing_identifier);
Richard Smithbdad7a22012-01-10 01:33:14 +00003592 ScopedEnumKWLoc = SourceLocation();
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003593 IsScopedUsingClassTag = false;
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003594 }
3595
John McCall13489672012-05-07 06:16:58 +00003596 // Okay, end the suppression area. We'll decide whether to emit the
3597 // diagnostics in a second.
3598 if (shouldDelayDiagsInTag)
3599 diagsFromTag.done();
Richard Smith1af83c42012-03-23 03:33:32 +00003600
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003601 TypeResult BaseType;
3602
Douglas Gregora61b3e72010-12-01 17:42:47 +00003603 // Parse the fixed underlying type.
Richard Smith139be702012-07-02 19:14:01 +00003604 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
Douglas Gregorb9075602011-02-22 02:55:24 +00003605 if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003606 bool PossibleBitfield = false;
Richard Smith139be702012-07-02 19:14:01 +00003607 if (CanBeBitfield) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003608 // If we're in class scope, this can either be an enum declaration with
3609 // an underlying type, or a declaration of a bitfield member. We try to
3610 // use a simple disambiguation scheme first to catch the common cases
Chad Rosier8decdee2012-06-26 22:30:43 +00003611 // (integer literal, sizeof); if it's still ambiguous, we then consider
3612 // anything that's a simple-type-specifier followed by '(' as an
3613 // expression. This suffices because function types are not valid
Douglas Gregora61b3e72010-12-01 17:42:47 +00003614 // underlying types anyway.
Richard Smith05766812012-08-18 00:55:03 +00003615 EnterExpressionEvaluationContext Unevaluated(Actions,
3616 Sema::ConstantEvaluated);
Douglas Gregora61b3e72010-12-01 17:42:47 +00003617 TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
Chad Rosier8decdee2012-06-26 22:30:43 +00003618 // If the next token starts an expression, we know we're parsing a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003619 // bit-field. This is the common case.
3620 if (TPR == TPResult::True())
3621 PossibleBitfield = true;
3622 // If the next token starts a type-specifier-seq, it may be either a
3623 // a fixed underlying type or the start of a function-style cast in C++;
Chad Rosier8decdee2012-06-26 22:30:43 +00003624 // lookahead one more token to see if it's obvious that we have a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003625 // fixed underlying type.
Chad Rosier8decdee2012-06-26 22:30:43 +00003626 else if (TPR == TPResult::False() &&
Douglas Gregora61b3e72010-12-01 17:42:47 +00003627 GetLookAheadToken(2).getKind() == tok::semi) {
3628 // Consume the ':'.
3629 ConsumeToken();
3630 } else {
3631 // We have the start of a type-specifier-seq, so we have to perform
3632 // tentative parsing to determine whether we have an expression or a
3633 // type.
3634 TentativeParsingAction TPA(*this);
3635
3636 // Consume the ':'.
3637 ConsumeToken();
Richard Smithd81e9612012-02-23 01:36:12 +00003638
3639 // If we see a type specifier followed by an open-brace, we have an
3640 // ambiguity between an underlying type and a C++11 braced
3641 // function-style cast. Resolve this by always treating it as an
3642 // underlying type.
3643 // FIXME: The standard is not entirely clear on how to disambiguate in
3644 // this case.
David Blaikie4e4d0842012-03-11 07:00:24 +00003645 if ((getLangOpts().CPlusPlus &&
Richard Smithd81e9612012-02-23 01:36:12 +00003646 isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
David Blaikie4e4d0842012-03-11 07:00:24 +00003647 (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003648 // We'll parse this as a bitfield later.
3649 PossibleBitfield = true;
3650 TPA.Revert();
3651 } else {
3652 // We have a type-specifier-seq.
3653 TPA.Commit();
3654 }
3655 }
3656 } else {
3657 // Consume the ':'.
3658 ConsumeToken();
3659 }
3660
3661 if (!PossibleBitfield) {
3662 SourceRange Range;
3663 BaseType = ParseTypeName(&Range);
Chad Rosier8decdee2012-06-26 22:30:43 +00003664
Richard Smith80ad52f2013-01-02 11:42:31 +00003665 if (getLangOpts().CPlusPlus11) {
Richard Smith7fe62082011-10-15 05:09:34 +00003666 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
Eli Friedmancef3a7b2012-11-02 01:34:28 +00003667 } else if (!getLangOpts().ObjC2) {
3668 if (getLangOpts().CPlusPlus)
3669 Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range;
3670 else
3671 Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range;
3672 }
Douglas Gregora61b3e72010-12-01 17:42:47 +00003673 }
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003674 }
3675
Richard Smithbdad7a22012-01-10 01:33:14 +00003676 // There are four options here. If we have 'friend enum foo;' then this is a
3677 // friend declaration, and cannot have an accompanying definition. If we have
3678 // 'enum foo;', then this is a forward declaration. If we have
3679 // 'enum foo {...' then this is a definition. Otherwise we have something
3680 // like 'enum foo xyz', a reference.
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003681 //
3682 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3683 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
3684 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
3685 //
John McCallf312b1e2010-08-26 23:41:50 +00003686 Sema::TagUseKind TUK;
John McCall13489672012-05-07 06:16:58 +00003687 if (!AllowDeclaration) {
Richard Smith7796eb52012-03-12 08:56:40 +00003688 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003689 } else if (Tok.is(tok::l_brace)) {
3690 if (DS.isFriendSpecified()) {
3691 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3692 << SourceRange(DS.getFriendSpecLoc());
3693 ConsumeBrace();
Alexey Bataev8fe24752013-11-18 08:17:37 +00003694 SkipUntil(tok::r_brace, StopAtSemi);
John McCall13489672012-05-07 06:16:58 +00003695 TUK = Sema::TUK_Friend;
3696 } else {
3697 TUK = Sema::TUK_Definition;
3698 }
Richard Smithc9f35172012-06-25 21:37:02 +00003699 } else if (DSC != DSC_type_specifier &&
3700 (Tok.is(tok::semi) ||
Richard Smith139be702012-07-02 19:14:01 +00003701 (Tok.isAtStartOfLine() &&
3702 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
Richard Smithc9f35172012-06-25 21:37:02 +00003703 TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3704 if (Tok.isNot(tok::semi)) {
3705 // A semicolon was missing after this declaration. Diagnose and recover.
3706 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3707 "enum");
3708 PP.EnterToken(Tok);
3709 Tok.setKind(tok::semi);
3710 }
John McCall13489672012-05-07 06:16:58 +00003711 } else {
John McCallf312b1e2010-08-26 23:41:50 +00003712 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003713 }
3714
3715 // If this is an elaborated type specifier, and we delayed
3716 // diagnostics before, just merge them into the current pool.
3717 if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3718 diagsFromTag.redelay();
3719 }
Richard Smith1af83c42012-03-23 03:33:32 +00003720
3721 MultiTemplateParamsArg TParams;
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003722 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
John McCallf312b1e2010-08-26 23:41:50 +00003723 TUK != Sema::TUK_Reference) {
Richard Smith80ad52f2013-01-02 11:42:31 +00003724 if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {
Richard Smith1af83c42012-03-23 03:33:32 +00003725 // Skip the rest of this declarator, up until the comma or semicolon.
3726 Diag(Tok, diag::err_enum_template);
Alexey Bataev8fe24752013-11-18 08:17:37 +00003727 SkipUntil(tok::comma, StopAtSemi);
Richard Smith1af83c42012-03-23 03:33:32 +00003728 return;
3729 }
3730
3731 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3732 // Enumerations can't be explicitly instantiated.
3733 DS.SetTypeSpecError();
3734 Diag(StartLoc, diag::err_explicit_instantiation_enum);
3735 return;
3736 }
3737
3738 assert(TemplateInfo.TemplateParams && "no template parameters");
3739 TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3740 TemplateInfo.TemplateParams->size());
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003741 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003742
Sean Hunt2edf0a22012-06-23 05:07:58 +00003743 if (TUK == Sema::TUK_Reference)
3744 ProhibitAttributes(attrs);
Richard Smith1af83c42012-03-23 03:33:32 +00003745
Douglas Gregorb9075602011-02-22 02:55:24 +00003746 if (!Name && TUK != Sema::TUK_Definition) {
3747 Diag(Tok, diag::err_enumerator_unnamed_no_def);
Richard Smith1af83c42012-03-23 03:33:32 +00003748
Douglas Gregorb9075602011-02-22 02:55:24 +00003749 // Skip the rest of this declarator, up until the comma or semicolon.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003750 SkipUntil(tok::comma, StopAtSemi);
Douglas Gregorb9075602011-02-22 02:55:24 +00003751 return;
3752 }
Richard Smith1af83c42012-03-23 03:33:32 +00003753
Douglas Gregor402abb52009-05-28 23:31:59 +00003754 bool Owned = false;
John McCallc4e70192009-09-11 04:59:25 +00003755 bool IsDependent = false;
Douglas Gregor48c89f42010-04-24 16:38:41 +00003756 const char *PrevSpec = 0;
3757 unsigned DiagID;
John McCalld226f652010-08-21 09:40:31 +00003758 Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
John McCall7f040a92010-12-24 02:08:15 +00003759 StartLoc, SS, Name, NameLoc, attrs.getList(),
Richard Smith1af83c42012-03-23 03:33:32 +00003760 AS, DS.getModulePrivateSpecLoc(), TParams,
Richard Smithbdad7a22012-01-10 01:33:14 +00003761 Owned, IsDependent, ScopedEnumKWLoc,
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003762 IsScopedUsingClassTag, BaseType);
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003763
Douglas Gregor48c89f42010-04-24 16:38:41 +00003764 if (IsDependent) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003765 // This enum has a dependent nested-name-specifier. Handle it as a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003766 // dependent tag.
3767 if (!Name) {
3768 DS.SetTypeSpecError();
3769 Diag(Tok, diag::err_expected_type_name_after_typename);
3770 return;
3771 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003772
Douglas Gregor23c94db2010-07-02 17:43:08 +00003773 TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
Chad Rosier8decdee2012-06-26 22:30:43 +00003774 TUK, SS, Name, StartLoc,
Douglas Gregor48c89f42010-04-24 16:38:41 +00003775 NameLoc);
3776 if (Type.isInvalid()) {
3777 DS.SetTypeSpecError();
3778 return;
3779 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003780
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003781 if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3782 NameLoc.isValid() ? NameLoc : StartLoc,
3783 PrevSpec, DiagID, Type.get()))
Douglas Gregor48c89f42010-04-24 16:38:41 +00003784 Diag(StartLoc, DiagID) << PrevSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00003785
Douglas Gregor48c89f42010-04-24 16:38:41 +00003786 return;
3787 }
Mike Stump1eb44332009-09-09 15:08:12 +00003788
John McCalld226f652010-08-21 09:40:31 +00003789 if (!TagDecl) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003790 // The action failed to produce an enumeration tag. If this is a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003791 // definition, consume the entire definition.
Richard Smith7796eb52012-03-12 08:56:40 +00003792 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
Douglas Gregor48c89f42010-04-24 16:38:41 +00003793 ConsumeBrace();
Alexey Bataev8fe24752013-11-18 08:17:37 +00003794 SkipUntil(tok::r_brace, StopAtSemi);
Douglas Gregor48c89f42010-04-24 16:38:41 +00003795 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003796
Douglas Gregor48c89f42010-04-24 16:38:41 +00003797 DS.SetTypeSpecError();
3798 return;
3799 }
Richard Smithbdad7a22012-01-10 01:33:14 +00003800
Richard Smithc9f35172012-06-25 21:37:02 +00003801 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
John McCall13489672012-05-07 06:16:58 +00003802 ParseEnumBody(StartLoc, TagDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00003803
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003804 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3805 NameLoc.isValid() ? NameLoc : StartLoc,
3806 PrevSpec, DiagID, TagDecl, Owned))
John McCallfec54012009-08-03 20:12:06 +00003807 Diag(StartLoc, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003808}
3809
3810/// ParseEnumBody - Parse a {} enclosed enumerator-list.
3811/// enumerator-list:
3812/// enumerator
3813/// enumerator-list ',' enumerator
3814/// enumerator:
3815/// enumeration-constant
3816/// enumeration-constant '=' constant-expression
3817/// enumeration-constant:
3818/// identifier
3819///
John McCalld226f652010-08-21 09:40:31 +00003820void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Douglas Gregor074149e2009-01-05 19:45:36 +00003821 // Enter the scope of the enum body and start the definition.
3822 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003823 Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
Douglas Gregor074149e2009-01-05 19:45:36 +00003824
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003825 BalancedDelimiterTracker T(*this, tok::l_brace);
3826 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00003827
Chris Lattner7946dd32007-08-27 17:24:30 +00003828 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
David Blaikie4e4d0842012-03-11 07:00:24 +00003829 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
Fariborz Jahanian05115522010-05-28 22:23:22 +00003830 Diag(Tok, diag::error_empty_enum);
Mike Stump1eb44332009-09-09 15:08:12 +00003831
Chris Lattner5f9e2722011-07-23 10:55:15 +00003832 SmallVector<Decl *, 32> EnumConstantDecls;
Reid Spencer5f016e22007-07-11 17:01:13 +00003833
John McCalld226f652010-08-21 09:40:31 +00003834 Decl *LastEnumConstDecl = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00003835
Reid Spencer5f016e22007-07-11 17:01:13 +00003836 // Parse the enumerator-list.
Chris Lattner04d66662007-10-09 17:33:22 +00003837 while (Tok.is(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003838 IdentifierInfo *Ident = Tok.getIdentifierInfo();
3839 SourceLocation IdentLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003840
John McCall5b629aa2010-10-22 23:36:17 +00003841 // If attributes exist after the enumerator, parse them.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003842 ParsedAttributesWithRange attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003843 MaybeParseGNUAttributes(attrs);
Richard Smith4e24f0f2013-01-02 12:01:23 +00003844 MaybeParseCXX11Attributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003845 ProhibitAttributes(attrs);
John McCall5b629aa2010-10-22 23:36:17 +00003846
Reid Spencer5f016e22007-07-11 17:01:13 +00003847 SourceLocation EqualLoc;
John McCall60d7b3a2010-08-24 06:29:42 +00003848 ExprResult AssignedVal;
John McCall92576642012-05-07 06:16:41 +00003849 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
Chad Rosier8decdee2012-06-26 22:30:43 +00003850
Chris Lattner04d66662007-10-09 17:33:22 +00003851 if (Tok.is(tok::equal)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003852 EqualLoc = ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00003853 AssignedVal = ParseConstantExpression();
3854 if (AssignedVal.isInvalid())
Alexey Bataev8fe24752013-11-18 08:17:37 +00003855 SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
Reid Spencer5f016e22007-07-11 17:01:13 +00003856 }
Mike Stump1eb44332009-09-09 15:08:12 +00003857
Reid Spencer5f016e22007-07-11 17:01:13 +00003858 // Install the enumerator constant into EnumDecl.
John McCalld226f652010-08-21 09:40:31 +00003859 Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3860 LastEnumConstDecl,
3861 IdentLoc, Ident,
John McCall7f040a92010-12-24 02:08:15 +00003862 attrs.getList(), EqualLoc,
John McCalld226f652010-08-21 09:40:31 +00003863 AssignedVal.release());
Fariborz Jahanian5a477db2011-12-09 01:15:54 +00003864 PD.complete(EnumConstDecl);
Chad Rosier8decdee2012-06-26 22:30:43 +00003865
Reid Spencer5f016e22007-07-11 17:01:13 +00003866 EnumConstantDecls.push_back(EnumConstDecl);
3867 LastEnumConstDecl = EnumConstDecl;
Mike Stump1eb44332009-09-09 15:08:12 +00003868
Douglas Gregor751f6922010-09-07 14:51:08 +00003869 if (Tok.is(tok::identifier)) {
3870 // We're missing a comma between enumerators.
3871 SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
Chad Rosier8decdee2012-06-26 22:30:43 +00003872 Diag(Loc, diag::err_enumerator_list_missing_comma)
Douglas Gregor751f6922010-09-07 14:51:08 +00003873 << FixItHint::CreateInsertion(Loc, ", ");
3874 continue;
3875 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003876
Chris Lattner04d66662007-10-09 17:33:22 +00003877 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +00003878 break;
3879 SourceLocation CommaLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003880
Richard Smith7fe62082011-10-15 05:09:34 +00003881 if (Tok.isNot(tok::identifier)) {
Richard Smith80ad52f2013-01-02 11:42:31 +00003882 if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)
Richard Smitheab9d6f2012-07-23 05:45:25 +00003883 Diag(CommaLoc, getLangOpts().CPlusPlus ?
3884 diag::ext_enumerator_list_comma_cxx :
3885 diag::ext_enumerator_list_comma_c)
Richard Smith7fe62082011-10-15 05:09:34 +00003886 << FixItHint::CreateRemoval(CommaLoc);
Richard Smith80ad52f2013-01-02 11:42:31 +00003887 else if (getLangOpts().CPlusPlus11)
Richard Smith7fe62082011-10-15 05:09:34 +00003888 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3889 << FixItHint::CreateRemoval(CommaLoc);
3890 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003891 }
Mike Stump1eb44332009-09-09 15:08:12 +00003892
Reid Spencer5f016e22007-07-11 17:01:13 +00003893 // Eat the }.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003894 T.consumeClose();
Reid Spencer5f016e22007-07-11 17:01:13 +00003895
Reid Spencer5f016e22007-07-11 17:01:13 +00003896 // If attributes exist after the identifier list, parse them.
John McCall0b7e6782011-03-24 11:26:52 +00003897 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003898 MaybeParseGNUAttributes(attrs);
Douglas Gregor72de6672009-01-08 20:45:30 +00003899
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003900 Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
Dmitri Gribenko9ff2b422013-04-27 20:23:52 +00003901 EnumDecl, EnumConstantDecls,
3902 getCurScope(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003903 attrs.getList());
Mike Stump1eb44332009-09-09 15:08:12 +00003904
Douglas Gregor72de6672009-01-08 20:45:30 +00003905 EnumScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003906 Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3907 T.getCloseLocation());
Richard Smithc9f35172012-06-25 21:37:02 +00003908
3909 // The next token must be valid after an enum definition. If not, a ';'
3910 // was probably forgotten.
Richard Smith139be702012-07-02 19:14:01 +00003911 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3912 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
Richard Smithc9f35172012-06-25 21:37:02 +00003913 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3914 // Push this token back into the preprocessor and change our current token
3915 // to ';' so that the rest of the code recovers as though there were an
3916 // ';' after the definition.
3917 PP.EnterToken(Tok);
3918 Tok.setKind(tok::semi);
3919 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003920}
3921
3922/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff5f8aa692008-02-11 23:15:56 +00003923/// start of a type-qualifier-list.
3924bool Parser::isTypeQualifier() const {
3925 switch (Tok.getKind()) {
3926 default: return false;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003927
3928 // type-qualifier only in OpenCL
3929 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003930 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003931
Steve Naroff5f8aa692008-02-11 23:15:56 +00003932 // type-qualifier
3933 case tok::kw_const:
3934 case tok::kw_volatile:
3935 case tok::kw_restrict:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003936 case tok::kw___private:
3937 case tok::kw___local:
3938 case tok::kw___global:
3939 case tok::kw___constant:
3940 case tok::kw___read_only:
3941 case tok::kw___read_write:
3942 case tok::kw___write_only:
Steve Naroff5f8aa692008-02-11 23:15:56 +00003943 return true;
3944 }
3945}
3946
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003947/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3948/// is definitely a type-specifier. Return false if it isn't part of a type
3949/// specifier or if we're not sure.
3950bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3951 switch (Tok.getKind()) {
3952 default: return false;
3953 // type-specifiers
3954 case tok::kw_short:
3955 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003956 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003957 case tok::kw___int128:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003958 case tok::kw_signed:
3959 case tok::kw_unsigned:
3960 case tok::kw__Complex:
3961 case tok::kw__Imaginary:
3962 case tok::kw_void:
3963 case tok::kw_char:
3964 case tok::kw_wchar_t:
3965 case tok::kw_char16_t:
3966 case tok::kw_char32_t:
3967 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003968 case tok::kw_half:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003969 case tok::kw_float:
3970 case tok::kw_double:
3971 case tok::kw_bool:
3972 case tok::kw__Bool:
3973 case tok::kw__Decimal32:
3974 case tok::kw__Decimal64:
3975 case tok::kw__Decimal128:
3976 case tok::kw___vector:
Chad Rosier8decdee2012-06-26 22:30:43 +00003977
Guy Benyeib13621d2012-12-18 14:38:23 +00003978 // OpenCL specific types:
3979 case tok::kw_image1d_t:
3980 case tok::kw_image1d_array_t:
3981 case tok::kw_image1d_buffer_t:
3982 case tok::kw_image2d_t:
3983 case tok::kw_image2d_array_t:
3984 case tok::kw_image3d_t:
Guy Benyei21f18c42013-02-07 10:55:47 +00003985 case tok::kw_sampler_t:
Guy Benyeie6b9d802013-01-20 12:31:11 +00003986 case tok::kw_event_t:
Guy Benyeib13621d2012-12-18 14:38:23 +00003987
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003988 // struct-or-union-specifier (C99) or class-specifier (C++)
3989 case tok::kw_class:
3990 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00003991 case tok::kw___interface:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003992 case tok::kw_union:
3993 // enum-specifier
3994 case tok::kw_enum:
Chad Rosier8decdee2012-06-26 22:30:43 +00003995
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003996 // typedef-name
3997 case tok::annot_typename:
3998 return true;
3999 }
4000}
4001
Steve Naroff5f8aa692008-02-11 23:15:56 +00004002/// isTypeSpecifierQualifier - Return true if the current token could be the
Reid Spencer5f016e22007-07-11 17:01:13 +00004003/// start of a specifier-qualifier-list.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004004bool Parser::isTypeSpecifierQualifier() {
Reid Spencer5f016e22007-07-11 17:01:13 +00004005 switch (Tok.getKind()) {
4006 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00004007
Chris Lattner166a8fc2009-01-04 23:41:41 +00004008 case tok::identifier: // foo::bar
John Thompson82287d12010-02-05 00:12:22 +00004009 if (TryAltiVecVectorToken())
4010 return true;
4011 // Fall through.
Douglas Gregord57959a2009-03-27 23:10:48 +00004012 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00004013 // Annotate typenames and C++ scope specifiers. If we get one, just
4014 // recurse to handle whatever we get.
4015 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004016 return true;
4017 if (Tok.is(tok::identifier))
4018 return false;
4019 return isTypeSpecifierQualifier();
Douglas Gregord57959a2009-03-27 23:10:48 +00004020
Chris Lattner166a8fc2009-01-04 23:41:41 +00004021 case tok::coloncolon: // ::foo::bar
4022 if (NextToken().is(tok::kw_new) || // ::new
4023 NextToken().is(tok::kw_delete)) // ::delete
4024 return false;
4025
Chris Lattner166a8fc2009-01-04 23:41:41 +00004026 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004027 return true;
4028 return isTypeSpecifierQualifier();
Mike Stump1eb44332009-09-09 15:08:12 +00004029
Reid Spencer5f016e22007-07-11 17:01:13 +00004030 // GNU attributes support.
4031 case tok::kw___attribute:
Steve Naroffd1861fd2007-07-31 12:34:36 +00004032 // GNU typeof support.
4033 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00004034
Reid Spencer5f016e22007-07-11 17:01:13 +00004035 // type-specifiers
4036 case tok::kw_short:
4037 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00004038 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00004039 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00004040 case tok::kw_signed:
4041 case tok::kw_unsigned:
4042 case tok::kw__Complex:
4043 case tok::kw__Imaginary:
4044 case tok::kw_void:
4045 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00004046 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00004047 case tok::kw_char16_t:
4048 case tok::kw_char32_t:
Reid Spencer5f016e22007-07-11 17:01:13 +00004049 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00004050 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00004051 case tok::kw_float:
4052 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00004053 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00004054 case tok::kw__Bool:
4055 case tok::kw__Decimal32:
4056 case tok::kw__Decimal64:
4057 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00004058 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00004059
Guy Benyeib13621d2012-12-18 14:38:23 +00004060 // OpenCL specific types:
4061 case tok::kw_image1d_t:
4062 case tok::kw_image1d_array_t:
4063 case tok::kw_image1d_buffer_t:
4064 case tok::kw_image2d_t:
4065 case tok::kw_image2d_array_t:
4066 case tok::kw_image3d_t:
Guy Benyei21f18c42013-02-07 10:55:47 +00004067 case tok::kw_sampler_t:
Guy Benyeie6b9d802013-01-20 12:31:11 +00004068 case tok::kw_event_t:
Guy Benyeib13621d2012-12-18 14:38:23 +00004069
Chris Lattner99dc9142008-04-13 18:59:07 +00004070 // struct-or-union-specifier (C99) or class-specifier (C++)
4071 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00004072 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00004073 case tok::kw___interface:
Reid Spencer5f016e22007-07-11 17:01:13 +00004074 case tok::kw_union:
4075 // enum-specifier
4076 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00004077
Reid Spencer5f016e22007-07-11 17:01:13 +00004078 // type-qualifier
4079 case tok::kw_const:
4080 case tok::kw_volatile:
4081 case tok::kw_restrict:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004082
John McCallb8a8de32012-11-14 00:49:39 +00004083 // Debugger support.
4084 case tok::kw___unknown_anytype:
4085
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004086 // typedef-name
Chris Lattnerb31757b2009-01-06 05:06:21 +00004087 case tok::annot_typename:
Reid Spencer5f016e22007-07-11 17:01:13 +00004088 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00004089
Chris Lattner7c186be2008-10-20 00:25:30 +00004090 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4091 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00004092 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00004093
Steve Naroff239f0732008-12-25 14:16:32 +00004094 case tok::kw___cdecl:
4095 case tok::kw___stdcall:
4096 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004097 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00004098 case tok::kw___w64:
4099 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00004100 case tok::kw___ptr32:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004101 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004102 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004103
4104 case tok::kw___private:
4105 case tok::kw___local:
4106 case tok::kw___global:
4107 case tok::kw___constant:
4108 case tok::kw___read_only:
4109 case tok::kw___read_write:
4110 case tok::kw___write_only:
4111
Eli Friedman290eeb02009-06-08 23:27:34 +00004112 return true;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004113
4114 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00004115 return getLangOpts().OpenCL;
Eli Friedmanb001de72011-10-06 23:00:33 +00004116
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004117 // C11 _Atomic
Eli Friedmanb001de72011-10-06 23:00:33 +00004118 case tok::kw__Atomic:
4119 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00004120 }
4121}
4122
4123/// isDeclarationSpecifier() - Return true if the current token is part of a
4124/// declaration specifier.
Douglas Gregor9497a732010-09-16 01:51:54 +00004125///
4126/// \param DisambiguatingWithExpression True to indicate that the purpose of
4127/// this check is to disambiguate between an expression and a declaration.
4128bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004129 switch (Tok.getKind()) {
4130 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00004131
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004132 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00004133 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004134
Chris Lattner166a8fc2009-01-04 23:41:41 +00004135 case tok::identifier: // foo::bar
Steve Naroff61f72cb2009-03-09 21:12:44 +00004136 // Unfortunate hack to support "Class.factoryMethod" notation.
David Blaikie4e4d0842012-03-11 07:00:24 +00004137 if (getLangOpts().ObjC1 && NextToken().is(tok::period))
Steve Naroff61f72cb2009-03-09 21:12:44 +00004138 return false;
John Thompson82287d12010-02-05 00:12:22 +00004139 if (TryAltiVecVectorToken())
4140 return true;
4141 // Fall through.
David Blaikie42d6d0c2011-12-04 05:04:18 +00004142 case tok::kw_decltype: // decltype(T())::type
Douglas Gregord57959a2009-03-27 23:10:48 +00004143 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00004144 // Annotate typenames and C++ scope specifiers. If we get one, just
4145 // recurse to handle whatever we get.
4146 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004147 return true;
4148 if (Tok.is(tok::identifier))
4149 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00004150
Douglas Gregor9497a732010-09-16 01:51:54 +00004151 // If we're in Objective-C and we have an Objective-C class type followed
Chad Rosier8decdee2012-06-26 22:30:43 +00004152 // by an identifier and then either ':' or ']', in a place where an
Douglas Gregor9497a732010-09-16 01:51:54 +00004153 // expression is permitted, then this is probably a class message send
4154 // missing the initial '['. In this case, we won't consider this to be
4155 // the start of a declaration.
Chad Rosier8decdee2012-06-26 22:30:43 +00004156 if (DisambiguatingWithExpression &&
Douglas Gregor9497a732010-09-16 01:51:54 +00004157 isStartOfObjCClassMessageMissingOpenBracket())
4158 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00004159
John McCall9ba61662010-02-26 08:45:28 +00004160 return isDeclarationSpecifier();
4161
Chris Lattner166a8fc2009-01-04 23:41:41 +00004162 case tok::coloncolon: // ::foo::bar
4163 if (NextToken().is(tok::kw_new) || // ::new
4164 NextToken().is(tok::kw_delete)) // ::delete
4165 return false;
Mike Stump1eb44332009-09-09 15:08:12 +00004166
Chris Lattner166a8fc2009-01-04 23:41:41 +00004167 // Annotate typenames and C++ scope specifiers. If we get one, just
4168 // recurse to handle whatever we get.
4169 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004170 return true;
4171 return isDeclarationSpecifier();
Mike Stump1eb44332009-09-09 15:08:12 +00004172
Reid Spencer5f016e22007-07-11 17:01:13 +00004173 // storage-class-specifier
4174 case tok::kw_typedef:
4175 case tok::kw_extern:
Steve Naroff8d54bf22007-12-18 00:16:02 +00004176 case tok::kw___private_extern__:
Reid Spencer5f016e22007-07-11 17:01:13 +00004177 case tok::kw_static:
4178 case tok::kw_auto:
4179 case tok::kw_register:
4180 case tok::kw___thread:
Richard Smithec642442013-04-12 22:46:28 +00004181 case tok::kw_thread_local:
4182 case tok::kw__Thread_local:
Mike Stump1eb44332009-09-09 15:08:12 +00004183
Douglas Gregor8d267c52011-09-09 02:06:17 +00004184 // Modules
4185 case tok::kw___module_private__:
Chad Rosier8decdee2012-06-26 22:30:43 +00004186
John McCallb8a8de32012-11-14 00:49:39 +00004187 // Debugger support
4188 case tok::kw___unknown_anytype:
4189
Reid Spencer5f016e22007-07-11 17:01:13 +00004190 // type-specifiers
4191 case tok::kw_short:
4192 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00004193 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00004194 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00004195 case tok::kw_signed:
4196 case tok::kw_unsigned:
4197 case tok::kw__Complex:
4198 case tok::kw__Imaginary:
4199 case tok::kw_void:
4200 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00004201 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00004202 case tok::kw_char16_t:
4203 case tok::kw_char32_t:
4204
Reid Spencer5f016e22007-07-11 17:01:13 +00004205 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00004206 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00004207 case tok::kw_float:
4208 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00004209 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00004210 case tok::kw__Bool:
4211 case tok::kw__Decimal32:
4212 case tok::kw__Decimal64:
4213 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00004214 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00004215
Guy Benyeib13621d2012-12-18 14:38:23 +00004216 // OpenCL specific types:
4217 case tok::kw_image1d_t:
4218 case tok::kw_image1d_array_t:
4219 case tok::kw_image1d_buffer_t:
4220 case tok::kw_image2d_t:
4221 case tok::kw_image2d_array_t:
4222 case tok::kw_image3d_t:
Guy Benyei21f18c42013-02-07 10:55:47 +00004223 case tok::kw_sampler_t:
Guy Benyeie6b9d802013-01-20 12:31:11 +00004224 case tok::kw_event_t:
Guy Benyeib13621d2012-12-18 14:38:23 +00004225
Chris Lattner99dc9142008-04-13 18:59:07 +00004226 // struct-or-union-specifier (C99) or class-specifier (C++)
4227 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00004228 case tok::kw_struct:
4229 case tok::kw_union:
Joao Matos6666ed42012-08-31 18:45:21 +00004230 case tok::kw___interface:
Reid Spencer5f016e22007-07-11 17:01:13 +00004231 // enum-specifier
4232 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00004233
Reid Spencer5f016e22007-07-11 17:01:13 +00004234 // type-qualifier
4235 case tok::kw_const:
4236 case tok::kw_volatile:
4237 case tok::kw_restrict:
Steve Naroffd1861fd2007-07-31 12:34:36 +00004238
Reid Spencer5f016e22007-07-11 17:01:13 +00004239 // function-specifier
4240 case tok::kw_inline:
Douglas Gregorb48fe382008-10-31 09:07:45 +00004241 case tok::kw_virtual:
4242 case tok::kw_explicit:
Richard Smithde03c152013-01-17 22:16:11 +00004243 case tok::kw__Noreturn:
Chris Lattnerd6c7c182007-08-09 16:40:21 +00004244
Richard Smith4cd81c52013-01-29 09:02:09 +00004245 // alignment-specifier
4246 case tok::kw__Alignas:
4247
Richard Smith53aec2a2012-10-25 00:00:53 +00004248 // friend keyword.
4249 case tok::kw_friend:
4250
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00004251 // static_assert-declaration
4252 case tok::kw__Static_assert:
4253
Chris Lattner1ef08762007-08-09 17:01:07 +00004254 // GNU typeof support.
4255 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00004256
Chris Lattner1ef08762007-08-09 17:01:07 +00004257 // GNU attributes.
Chris Lattnerd6c7c182007-08-09 16:40:21 +00004258 case tok::kw___attribute:
Mike Stump1eb44332009-09-09 15:08:12 +00004259
Richard Smith53aec2a2012-10-25 00:00:53 +00004260 // C++11 decltype and constexpr.
David Blaikie42d6d0c2011-12-04 05:04:18 +00004261 case tok::annot_decltype:
Richard Smith53aec2a2012-10-25 00:00:53 +00004262 case tok::kw_constexpr:
Francois Pichete3d49b42011-06-19 08:02:06 +00004263
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004264 // C11 _Atomic
Eli Friedmanb001de72011-10-06 23:00:33 +00004265 case tok::kw__Atomic:
4266 return true;
4267
Chris Lattnerf3948c42008-07-26 03:38:44 +00004268 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4269 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00004270 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00004271
Douglas Gregord9d75e52011-04-27 05:41:15 +00004272 // typedef-name
4273 case tok::annot_typename:
4274 return !DisambiguatingWithExpression ||
4275 !isStartOfObjCClassMessageMissingOpenBracket();
Chad Rosier8decdee2012-06-26 22:30:43 +00004276
Steve Naroff47f52092009-01-06 19:34:12 +00004277 case tok::kw___declspec:
Steve Naroff239f0732008-12-25 14:16:32 +00004278 case tok::kw___cdecl:
4279 case tok::kw___stdcall:
4280 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004281 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00004282 case tok::kw___w64:
Aaron Ballmanaa9df092013-05-22 23:25:32 +00004283 case tok::kw___sptr:
4284 case tok::kw___uptr:
Eli Friedman290eeb02009-06-08 23:27:34 +00004285 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00004286 case tok::kw___ptr32:
Eli Friedman290eeb02009-06-08 23:27:34 +00004287 case tok::kw___forceinline:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004288 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004289 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004290
4291 case tok::kw___private:
4292 case tok::kw___local:
4293 case tok::kw___global:
4294 case tok::kw___constant:
4295 case tok::kw___read_only:
4296 case tok::kw___read_write:
4297 case tok::kw___write_only:
4298
Eli Friedman290eeb02009-06-08 23:27:34 +00004299 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00004300 }
4301}
4302
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004303bool Parser::isConstructorDeclarator() {
4304 TentativeParsingAction TPA(*this);
4305
4306 // Parse the C++ scope specifier.
4307 CXXScopeSpec SS;
Chad Rosier8decdee2012-06-26 22:30:43 +00004308 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004309 /*EnteringContext=*/true)) {
John McCall9ba61662010-02-26 08:45:28 +00004310 TPA.Revert();
4311 return false;
4312 }
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004313
4314 // Parse the constructor name.
4315 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
4316 // We already know that we have a constructor name; just consume
4317 // the token.
4318 ConsumeToken();
4319 } else {
4320 TPA.Revert();
4321 return false;
4322 }
4323
Richard Smith22592862012-03-27 23:05:05 +00004324 // Current class name must be followed by a left parenthesis.
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004325 if (Tok.isNot(tok::l_paren)) {
4326 TPA.Revert();
4327 return false;
4328 }
4329 ConsumeParen();
4330
Richard Smith22592862012-03-27 23:05:05 +00004331 // A right parenthesis, or ellipsis followed by a right parenthesis signals
4332 // that we have a constructor.
4333 if (Tok.is(tok::r_paren) ||
4334 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004335 TPA.Revert();
4336 return true;
4337 }
4338
Richard Smith9ec28912013-09-06 00:12:20 +00004339 // A C++11 attribute here signals that we have a constructor, and is an
4340 // attribute on the first constructor parameter.
4341 if (getLangOpts().CPlusPlus11 &&
4342 isCXX11AttributeSpecifier(/*Disambiguate*/ false,
4343 /*OuterMightBeMessageSend*/ true)) {
4344 TPA.Revert();
4345 return true;
4346 }
4347
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004348 // If we need to, enter the specified scope.
4349 DeclaratorScopeObj DeclScopeObj(*this, SS);
Douglas Gregor23c94db2010-07-02 17:43:08 +00004350 if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004351 DeclScopeObj.EnterDeclaratorScope();
4352
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00004353 // Optionally skip Microsoft attributes.
John McCall0b7e6782011-03-24 11:26:52 +00004354 ParsedAttributes Attrs(AttrFactory);
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00004355 MaybeParseMicrosoftAttributes(Attrs);
4356
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004357 // Check whether the next token(s) are part of a declaration
4358 // specifier, in which case we have the start of a parameter and,
4359 // therefore, we know that this is a constructor.
Richard Smith412e0cc2012-03-27 00:56:56 +00004360 bool IsConstructor = false;
4361 if (isDeclarationSpecifier())
4362 IsConstructor = true;
4363 else if (Tok.is(tok::identifier) ||
4364 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
4365 // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
4366 // This might be a parenthesized member name, but is more likely to
4367 // be a constructor declaration with an invalid argument type. Keep
4368 // looking.
4369 if (Tok.is(tok::annot_cxxscope))
4370 ConsumeToken();
4371 ConsumeToken();
4372
4373 // If this is not a constructor, we must be parsing a declarator,
Richard Smith5d8388c2012-03-27 01:42:32 +00004374 // which must have one of the following syntactic forms (see the
4375 // grammar extract at the start of ParseDirectDeclarator):
Richard Smith412e0cc2012-03-27 00:56:56 +00004376 switch (Tok.getKind()) {
4377 case tok::l_paren:
4378 // C(X ( int));
4379 case tok::l_square:
4380 // C(X [ 5]);
4381 // C(X [ [attribute]]);
4382 case tok::coloncolon:
4383 // C(X :: Y);
4384 // C(X :: *p);
4385 case tok::r_paren:
4386 // C(X )
4387 // Assume this isn't a constructor, rather than assuming it's a
4388 // constructor with an unnamed parameter of an ill-formed type.
4389 break;
4390
4391 default:
4392 IsConstructor = true;
4393 break;
4394 }
4395 }
4396
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004397 TPA.Revert();
4398 return IsConstructor;
4399}
Reid Spencer5f016e22007-07-11 17:01:13 +00004400
4401/// ParseTypeQualifierListOpt
Dawn Perchik52fc3142010-09-03 01:29:35 +00004402/// type-qualifier-list: [C99 6.7.5]
4403/// type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00004404/// [vendor] attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00004405/// [ only if VendorAttributesAllowed=true ]
4406/// type-qualifier-list type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00004407/// [vendor] type-qualifier-list attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00004408/// [ only if VendorAttributesAllowed=true ]
4409/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
Richard Smith4e24f0f2013-01-02 12:01:23 +00004410/// [ only if CXX11AttributesAllowed=true ]
Dawn Perchik52fc3142010-09-03 01:29:35 +00004411/// Note: vendor can be GNU, MS, etc.
Reid Spencer5f016e22007-07-11 17:01:13 +00004412///
Dawn Perchik52fc3142010-09-03 01:29:35 +00004413void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
4414 bool VendorAttributesAllowed,
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004415 bool CXX11AttributesAllowed,
Bill Wendling7f3ec662013-11-26 04:10:07 +00004416 bool AtomicAllowed,
4417 bool IdentifierRequired) {
Richard Smith80ad52f2013-01-02 11:42:31 +00004418 if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed &&
Richard Smith6ee326a2012-04-10 01:32:12 +00004419 isCXX11AttributeSpecifier()) {
John McCall0b7e6782011-03-24 11:26:52 +00004420 ParsedAttributesWithRange attrs(AttrFactory);
Richard Smithc56298d2012-04-10 03:25:07 +00004421 ParseCXX11Attributes(attrs);
Richard Smith6ee326a2012-04-10 01:32:12 +00004422 DS.takeAttributesFrom(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00004423 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00004424
4425 SourceLocation EndLoc;
4426
Reid Spencer5f016e22007-07-11 17:01:13 +00004427 while (1) {
John McCallfec54012009-08-03 20:12:06 +00004428 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00004429 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00004430 unsigned DiagID = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +00004431 SourceLocation Loc = Tok.getLocation();
4432
4433 switch (Tok.getKind()) {
Douglas Gregor1a480c42010-08-27 17:35:51 +00004434 case tok::code_completion:
4435 Actions.CodeCompleteTypeQualifiers(DS);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00004436 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00004437
Reid Spencer5f016e22007-07-11 17:01:13 +00004438 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00004439 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00004440 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00004441 break;
4442 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00004443 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00004444 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00004445 break;
4446 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00004447 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00004448 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00004449 break;
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004450 case tok::kw__Atomic:
4451 if (!AtomicAllowed)
4452 goto DoneWithTypeQuals;
4453 isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
4454 getLangOpts());
4455 break;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004456
4457 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00004458 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00004459 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004460 goto DoneWithTypeQuals;
4461 case tok::kw___private:
4462 case tok::kw___global:
4463 case tok::kw___local:
4464 case tok::kw___constant:
4465 case tok::kw___read_only:
4466 case tok::kw___write_only:
4467 case tok::kw___read_write:
4468 ParseOpenCLQualifiers(DS);
4469 break;
4470
Aaron Ballmanaa9df092013-05-22 23:25:32 +00004471 case tok::kw___uptr:
Bill Wendling7f3ec662013-11-26 04:10:07 +00004472 // GNU libc headers in C mode use '__uptr' as an identifer which conflicts
4473 // with the MS modifier keyword.
4474 if (VendorAttributesAllowed && !getLangOpts().CPlusPlus &&
Bill Wendling03e463e2013-12-16 02:32:55 +00004475 IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) {
4476 if (TryKeywordIdentFallback(false))
4477 continue;
Bill Wendling7f3ec662013-11-26 04:10:07 +00004478 }
4479 case tok::kw___sptr:
Eli Friedman290eeb02009-06-08 23:27:34 +00004480 case tok::kw___w64:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00004481 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00004482 case tok::kw___ptr32:
Steve Naroff239f0732008-12-25 14:16:32 +00004483 case tok::kw___cdecl:
4484 case tok::kw___stdcall:
4485 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004486 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004487 case tok::kw___unaligned:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004488 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00004489 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00004490 continue;
4491 }
4492 goto DoneWithTypeQuals;
Dawn Perchik52fc3142010-09-03 01:29:35 +00004493 case tok::kw___pascal:
4494 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00004495 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00004496 continue;
4497 }
4498 goto DoneWithTypeQuals;
Reid Spencer5f016e22007-07-11 17:01:13 +00004499 case tok::kw___attribute:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004500 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00004501 ParseGNUAttributes(DS.getAttributes());
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004502 continue; // do *not* consume the next token!
4503 }
4504 // otherwise, FALL THROUGH!
4505 default:
Steve Naroff239f0732008-12-25 14:16:32 +00004506 DoneWithTypeQuals:
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004507 // If this is not a type-qualifier token, we're done reading type
4508 // qualifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00004509 DS.Finish(Diags, PP);
Abramo Bagnara796aa442011-03-12 11:17:06 +00004510 if (EndLoc.isValid())
4511 DS.SetRangeEnd(EndLoc);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004512 return;
Reid Spencer5f016e22007-07-11 17:01:13 +00004513 }
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004514
Reid Spencer5f016e22007-07-11 17:01:13 +00004515 // If the specifier combination wasn't legal, issue a diagnostic.
4516 if (isInvalid) {
4517 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +00004518 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00004519 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00004520 EndLoc = ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00004521 }
4522}
4523
4524
4525/// ParseDeclarator - Parse and verify a newly-initialized declarator.
4526///
4527void Parser::ParseDeclarator(Declarator &D) {
4528 /// This implements the 'declarator' production in the C grammar, then checks
4529 /// for well-formedness and issues diagnostics.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004530 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Reid Spencer5f016e22007-07-11 17:01:13 +00004531}
4532
Richard Smith9988f282012-03-29 01:16:42 +00004533static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
4534 if (Kind == tok::star || Kind == tok::caret)
4535 return true;
4536
4537 // We parse rvalue refs in C++03, because otherwise the errors are scary.
4538 if (!Lang.CPlusPlus)
4539 return false;
4540
4541 return Kind == tok::amp || Kind == tok::ampamp;
4542}
4543
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004544/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
4545/// is parsed by the function passed to it. Pass null, and the direct-declarator
4546/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004547/// ptr-operator production.
4548///
Richard Smith0706df42011-10-19 21:33:05 +00004549/// If the grammar of this construct is extended, matching changes must also be
Richard Smith5d8388c2012-03-27 01:42:32 +00004550/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
4551/// isConstructorDeclarator.
Richard Smith0706df42011-10-19 21:33:05 +00004552///
Sebastian Redlf30208a2009-01-24 21:16:55 +00004553/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
4554/// [C] pointer[opt] direct-declarator
4555/// [C++] direct-declarator
4556/// [C++] ptr-operator declarator
Reid Spencer5f016e22007-07-11 17:01:13 +00004557///
4558/// pointer: [C99 6.7.5]
4559/// '*' type-qualifier-list[opt]
4560/// '*' type-qualifier-list[opt] pointer
4561///
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004562/// ptr-operator:
4563/// '*' cv-qualifier-seq[opt]
4564/// '&'
Sebastian Redl05532f22009-03-15 22:02:01 +00004565/// [C++0x] '&&'
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004566/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redl05532f22009-03-15 22:02:01 +00004567/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redlf30208a2009-01-24 21:16:55 +00004568/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004569void Parser::ParseDeclaratorInternal(Declarator &D,
4570 DirectDeclParseFunction DirectDeclParser) {
Douglas Gregor91a28862009-08-26 14:27:30 +00004571 if (Diags.hasAllExtensionsSilenced())
4572 D.setExtension();
Chad Rosier8decdee2012-06-26 22:30:43 +00004573
Sebastian Redlf30208a2009-01-24 21:16:55 +00004574 // C++ member pointers start with a '::' or a nested-name.
4575 // Member pointers get special handling, since there's no place for the
4576 // scope spec in the generic path below.
David Blaikie4e4d0842012-03-11 07:00:24 +00004577 if (getLangOpts().CPlusPlus &&
Chris Lattnerf919bfe2009-03-24 17:04:48 +00004578 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
4579 Tok.is(tok::annot_cxxscope))) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004580 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4581 D.getContext() == Declarator::MemberContext;
Sebastian Redlf30208a2009-01-24 21:16:55 +00004582 CXXScopeSpec SS;
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004583 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004584
Jeffrey Yasskinedc28772010-04-07 23:29:58 +00004585 if (SS.isNotEmpty()) {
Mike Stump1eb44332009-09-09 15:08:12 +00004586 if (Tok.isNot(tok::star)) {
Sebastian Redlf30208a2009-01-24 21:16:55 +00004587 // The scope spec really belongs to the direct-declarator.
Richard Smith6a502c42013-01-08 22:43:49 +00004588 if (D.mayHaveIdentifier())
4589 D.getCXXScopeSpec() = SS;
4590 else
4591 AnnotateScopeToken(SS, true);
4592
Sebastian Redlf30208a2009-01-24 21:16:55 +00004593 if (DirectDeclParser)
4594 (this->*DirectDeclParser)(D);
4595 return;
4596 }
4597
4598 SourceLocation Loc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00004599 D.SetRangeEnd(Loc);
John McCall0b7e6782011-03-24 11:26:52 +00004600 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004601 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004602 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004603
4604 // Recurse to parse whatever is left.
4605 ParseDeclaratorInternal(D, DirectDeclParser);
4606
4607 // Sema will have to catch (syntactically invalid) pointers into global
4608 // scope. It has to catch pointers into namespace scope anyway.
4609 D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004610 Loc),
4611 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004612 /* Don't replace range end. */SourceLocation());
Sebastian Redlf30208a2009-01-24 21:16:55 +00004613 return;
4614 }
4615 }
4616
4617 tok::TokenKind Kind = Tok.getKind();
Steve Naroff5618bd42008-08-27 16:04:49 +00004618 // Not a pointer, C++ reference, or block.
Richard Smith9988f282012-03-29 01:16:42 +00004619 if (!isPtrOperatorToken(Kind, getLangOpts())) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004620 if (DirectDeclParser)
4621 (this->*DirectDeclParser)(D);
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004622 return;
4623 }
Sebastian Redlf30208a2009-01-24 21:16:55 +00004624
Sebastian Redl05532f22009-03-15 22:02:01 +00004625 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4626 // '&&' -> rvalue reference
Sebastian Redl743de1f2009-03-23 00:00:23 +00004627 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redlab197ba2009-02-09 18:23:29 +00004628 D.SetRangeEnd(Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +00004629
Chris Lattner9af55002009-03-27 04:18:06 +00004630 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner76549142008-02-21 01:32:26 +00004631 // Is a pointer.
John McCall0b7e6782011-03-24 11:26:52 +00004632 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004633
Richard Smith6ee326a2012-04-10 01:32:12 +00004634 // FIXME: GNU attributes are not allowed here in a new-type-id.
Bill Wendling7f3ec662013-11-26 04:10:07 +00004635 ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier());
Sebastian Redlab197ba2009-02-09 18:23:29 +00004636 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004637
Reid Spencer5f016e22007-07-11 17:01:13 +00004638 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004639 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff5618bd42008-08-27 16:04:49 +00004640 if (Kind == tok::star)
4641 // Remember that we parsed a pointer type, and remember the type-quals.
4642 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
Chandler Carruthd067c072011-02-23 18:51:59 +00004643 DS.getConstSpecLoc(),
4644 DS.getVolatileSpecLoc(),
John McCall0b7e6782011-03-24 11:26:52 +00004645 DS.getRestrictSpecLoc()),
4646 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004647 SourceLocation());
Steve Naroff5618bd42008-08-27 16:04:49 +00004648 else
4649 // Remember that we parsed a Block type, and remember the type-quals.
Mike Stump1eb44332009-09-09 15:08:12 +00004650 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004651 Loc),
4652 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004653 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004654 } else {
4655 // Is a reference
John McCall0b7e6782011-03-24 11:26:52 +00004656 DeclSpec DS(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00004657
Sebastian Redl743de1f2009-03-23 00:00:23 +00004658 // Complain about rvalue references in C++03, but then go on and build
4659 // the declarator.
Richard Smith7fe62082011-10-15 05:09:34 +00004660 if (Kind == tok::ampamp)
Richard Smith80ad52f2013-01-02 11:42:31 +00004661 Diag(Loc, getLangOpts().CPlusPlus11 ?
Richard Smith7fe62082011-10-15 05:09:34 +00004662 diag::warn_cxx98_compat_rvalue_reference :
4663 diag::ext_rvalue_reference);
Sebastian Redl743de1f2009-03-23 00:00:23 +00004664
Richard Smith6ee326a2012-04-10 01:32:12 +00004665 // GNU-style and C++11 attributes are allowed here, as is restrict.
4666 ParseTypeQualifierListOpt(DS);
4667 D.ExtendWithDeclSpec(DS);
4668
Reid Spencer5f016e22007-07-11 17:01:13 +00004669 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4670 // cv-qualifiers are introduced through the use of a typedef or of a
4671 // template type argument, in which case the cv-qualifiers are ignored.
Reid Spencer5f016e22007-07-11 17:01:13 +00004672 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4673 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4674 Diag(DS.getConstSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004675 diag::err_invalid_reference_qualifier_application) << "const";
Reid Spencer5f016e22007-07-11 17:01:13 +00004676 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4677 Diag(DS.getVolatileSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004678 diag::err_invalid_reference_qualifier_application) << "volatile";
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004679 // 'restrict' is permitted as an extension.
4680 if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
4681 Diag(DS.getAtomicSpecLoc(),
4682 diag::err_invalid_reference_qualifier_application) << "_Atomic";
Reid Spencer5f016e22007-07-11 17:01:13 +00004683 }
4684
4685 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004686 ParseDeclaratorInternal(D, DirectDeclParser);
Reid Spencer5f016e22007-07-11 17:01:13 +00004687
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004688 if (D.getNumTypeObjects() > 0) {
4689 // C++ [dcl.ref]p4: There shall be no references to references.
4690 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4691 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattnerda83bac2008-11-19 07:37:42 +00004692 if (const IdentifierInfo *II = D.getIdentifier())
4693 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4694 << II;
4695 else
4696 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4697 << "type name";
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004698
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004699 // Once we've complained about the reference-to-reference, we
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004700 // can go ahead and build the (technically ill-formed)
4701 // declarator: reference collapsing will take care of it.
4702 }
4703 }
4704
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004705 // Remember that we parsed a reference type.
Chris Lattner76549142008-02-21 01:32:26 +00004706 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redl05532f22009-03-15 22:02:01 +00004707 Kind == tok::amp),
John McCall0b7e6782011-03-24 11:26:52 +00004708 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004709 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004710 }
4711}
4712
Richard Smith9988f282012-03-29 01:16:42 +00004713static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4714 SourceLocation EllipsisLoc) {
4715 if (EllipsisLoc.isValid()) {
4716 FixItHint Insertion;
4717 if (!D.getEllipsisLoc().isValid()) {
4718 Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4719 D.setEllipsisLoc(EllipsisLoc);
4720 }
4721 P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4722 << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4723 }
4724}
4725
Reid Spencer5f016e22007-07-11 17:01:13 +00004726/// ParseDirectDeclarator
4727/// direct-declarator: [C99 6.7.5]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004728/// [C99] identifier
Reid Spencer5f016e22007-07-11 17:01:13 +00004729/// '(' declarator ')'
4730/// [GNU] '(' attributes declarator ')'
4731/// [C90] direct-declarator '[' constant-expression[opt] ']'
4732/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4733/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4734/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4735/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00004736/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4737/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00004738/// direct-declarator '(' parameter-type-list ')'
4739/// direct-declarator '(' identifier-list[opt] ')'
4740/// [GNU] direct-declarator '(' parameter-forward-declarations
4741/// parameter-type-list[opt] ')'
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00004742/// [C++] direct-declarator '(' parameter-declaration-clause ')'
4743/// cv-qualifier-seq[opt] exception-specification[opt]
Richard Smith6ee326a2012-04-10 01:32:12 +00004744/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4745/// attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4746/// ref-qualifier[opt] exception-specification[opt]
Douglas Gregorb48fe382008-10-31 09:07:45 +00004747/// [C++] declarator-id
Richard Smith6ee326a2012-04-10 01:32:12 +00004748/// [C++11] declarator-id attribute-specifier-seq[opt]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004749///
4750/// declarator-id: [C++ 8]
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004751/// '...'[opt] id-expression
Douglas Gregor42a552f2008-11-05 20:51:48 +00004752/// '::'[opt] nested-name-specifier[opt] type-name
4753///
4754/// id-expression: [C++ 5.1]
4755/// unqualified-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004756/// qualified-id
Douglas Gregor42a552f2008-11-05 20:51:48 +00004757///
4758/// unqualified-id: [C++ 5.1]
Mike Stump1eb44332009-09-09 15:08:12 +00004759/// identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004760/// operator-function-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004761/// conversion-function-id
Mike Stump1eb44332009-09-09 15:08:12 +00004762/// '~' class-name
Douglas Gregor39a8de12009-02-25 19:37:18 +00004763/// template-id
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +00004764///
Richard Smith5d8388c2012-03-27 01:42:32 +00004765/// Note, any additional constructs added here may need corresponding changes
4766/// in isConstructorDeclarator.
Reid Spencer5f016e22007-07-11 17:01:13 +00004767void Parser::ParseDirectDeclarator(Declarator &D) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004768 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004769
David Blaikie4e4d0842012-03-11 07:00:24 +00004770 if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004771 // ParseDeclaratorInternal might already have parsed the scope.
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004772 if (D.getCXXScopeSpec().isEmpty()) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004773 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4774 D.getContext() == Declarator::MemberContext;
Chad Rosier8decdee2012-06-26 22:30:43 +00004775 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004776 EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004777 }
4778
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004779 if (D.getCXXScopeSpec().isValid()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00004780 if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
John McCalle7e278b2009-12-11 20:04:54 +00004781 // Change the declaration context for name lookup, until this function
4782 // is exited (and the declarator has been parsed).
4783 DeclScopeObj.EnterDeclaratorScope();
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004784 }
4785
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004786 // C++0x [dcl.fct]p14:
4787 // There is a syntactic ambiguity when an ellipsis occurs at the end
Chad Rosier8decdee2012-06-26 22:30:43 +00004788 // of a parameter-declaration-clause without a preceding comma. In
4789 // this case, the ellipsis is parsed as part of the
4790 // abstract-declarator if the type of the parameter names a template
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004791 // parameter pack that has not been expanded; otherwise, it is parsed
4792 // as part of the parameter-declaration-clause.
Richard Smith9988f282012-03-29 01:16:42 +00004793 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004794 !((D.getContext() == Declarator::PrototypeContext ||
Faisal Valifad9e132013-09-26 19:54:12 +00004795 D.getContext() == Declarator::LambdaExprParameterContext ||
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004796 D.getContext() == Declarator::BlockLiteralContext) &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004797 NextToken().is(tok::r_paren) &&
Richard Smith30f2a742013-02-20 20:19:27 +00004798 !D.hasGroupingParens() &&
Richard Smith9988f282012-03-29 01:16:42 +00004799 !Actions.containsUnexpandedParameterPacks(D))) {
4800 SourceLocation EllipsisLoc = ConsumeToken();
4801 if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4802 // The ellipsis was put in the wrong place. Recover, and explain to
4803 // the user what they should have done.
4804 ParseDeclarator(D);
4805 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4806 return;
4807 } else
4808 D.setEllipsisLoc(EllipsisLoc);
4809
4810 // The ellipsis can't be followed by a parenthesized declarator. We
4811 // check for that in ParseParenDeclarator, after we have disambiguated
4812 // the l_paren token.
4813 }
4814
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004815 if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4816 Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4817 // We found something that indicates the start of an unqualified-id.
4818 // Parse that unqualified-id.
John McCallba9d8532010-04-13 06:39:49 +00004819 bool AllowConstructorName;
4820 if (D.getDeclSpec().hasTypeSpecifier())
4821 AllowConstructorName = false;
4822 else if (D.getCXXScopeSpec().isSet())
4823 AllowConstructorName =
4824 (D.getContext() == Declarator::FileContext ||
Dmitri Gribenko1b9e8f72013-02-12 17:27:41 +00004825 D.getContext() == Declarator::MemberContext);
John McCallba9d8532010-04-13 06:39:49 +00004826 else
4827 AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4828
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004829 SourceLocation TemplateKWLoc;
Chad Rosier8decdee2012-06-26 22:30:43 +00004830 if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4831 /*EnteringContext=*/true,
4832 /*AllowDestructorName=*/true,
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004833 AllowConstructorName,
John McCallb3d87482010-08-24 05:47:05 +00004834 ParsedType(),
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004835 TemplateKWLoc,
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004836 D.getName()) ||
4837 // Once we're past the identifier, if the scope was bad, mark the
4838 // whole declarator bad.
4839 D.getCXXScopeSpec().isInvalid()) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004840 D.SetIdentifier(0, Tok.getLocation());
4841 D.setInvalidType(true);
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004842 } else {
4843 // Parsed the unqualified-id; update range information and move along.
4844 if (D.getSourceRange().getBegin().isInvalid())
4845 D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4846 D.SetRangeEnd(D.getName().getSourceRange().getEnd());
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004847 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004848 goto PastIdentifier;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00004849 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004850 } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004851 assert(!getLangOpts().CPlusPlus &&
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004852 "There's a C++-specific check for tok::identifier above");
4853 assert(Tok.getIdentifierInfo() && "Not an identifier?");
4854 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4855 ConsumeToken();
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004856 goto PastIdentifier;
Richard Smitha38253c2013-07-11 05:10:21 +00004857 } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
Richard Smith8d1ab8a2013-10-13 22:12:28 +00004858 // A virt-specifier isn't treated as an identifier if it appears after a
4859 // trailing-return-type.
4860 if (D.getContext() != Declarator::TrailingReturnContext ||
4861 !isCXX11VirtSpecifier(Tok)) {
4862 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
4863 << FixItHint::CreateRemoval(Tok.getLocation());
4864 D.SetIdentifier(0, Tok.getLocation());
4865 ConsumeToken();
4866 goto PastIdentifier;
4867 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004868 }
Richard Smith9988f282012-03-29 01:16:42 +00004869
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004870 if (Tok.is(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004871 // direct-declarator: '(' declarator ')'
4872 // direct-declarator: '(' attributes declarator ')'
4873 // Example: 'char (*X)' or 'int (*XX)(void)'
4874 ParseParenDeclarator(D);
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004875
4876 // If the declarator was parenthesized, we entered the declarator
4877 // scope when parsing the parenthesized declarator, then exited
4878 // the scope already. Re-enter the scope, if we need to.
4879 if (D.getCXXScopeSpec().isSet()) {
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004880 // If there was an error parsing parenthesized declarator, declarator
Richard Smith9988f282012-03-29 01:16:42 +00004881 // scope may have been entered before. Don't do it again.
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004882 if (!D.isInvalidType() &&
4883 Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004884 // Change the declaration context for name lookup, until this function
4885 // is exited (and the declarator has been parsed).
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004886 DeclScopeObj.EnterDeclaratorScope();
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004887 }
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004888 } else if (D.mayOmitIdentifier()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004889 // This could be something simple like "int" (in which case the declarator
4890 // portion is empty), if an abstract-declarator is allowed.
4891 D.SetIdentifier(0, Tok.getLocation());
Richard Smith30f2a742013-02-20 20:19:27 +00004892
4893 // The grammar for abstract-pack-declarator does not allow grouping parens.
4894 // FIXME: Revisit this once core issue 1488 is resolved.
4895 if (D.hasEllipsis() && D.hasGroupingParens())
4896 Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()),
4897 diag::ext_abstract_pack_declarator_parens);
Reid Spencer5f016e22007-07-11 17:01:13 +00004898 } else {
David Blaikiee75d9cf2012-06-29 22:03:56 +00004899 if (Tok.getKind() == tok::annot_pragma_parser_crash)
David Blaikie377da4c2012-08-21 18:56:49 +00004900 LLVM_BUILTIN_TRAP;
Douglas Gregore950d4b2009-03-06 23:28:18 +00004901 if (D.getContext() == Declarator::MemberContext)
4902 Diag(Tok, diag::err_expected_member_name_or_semi)
4903 << D.getDeclSpec().getSourceRange();
Richard Trieudb55c04c2013-01-26 02:31:38 +00004904 else if (getLangOpts().CPlusPlus) {
4905 if (Tok.is(tok::period) || Tok.is(tok::arrow))
4906 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
Richard Trieuefb288c2013-09-05 02:31:33 +00004907 else {
4908 SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();
4909 if (Tok.isAtStartOfLine() && Loc.isValid())
4910 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
4911 << getLangOpts().CPlusPlus;
4912 else
4913 Diag(Tok, diag::err_expected_unqualified_id)
4914 << getLangOpts().CPlusPlus;
4915 }
Richard Trieudb55c04c2013-01-26 02:31:38 +00004916 } else
Chris Lattner1ab3b962008-11-18 07:48:38 +00004917 Diag(Tok, diag::err_expected_ident_lparen);
Reid Spencer5f016e22007-07-11 17:01:13 +00004918 D.SetIdentifier(0, Tok.getLocation());
Chris Lattner1f6f54b2008-11-11 06:13:16 +00004919 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00004920 }
Mike Stump1eb44332009-09-09 15:08:12 +00004921
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004922 PastIdentifier:
Reid Spencer5f016e22007-07-11 17:01:13 +00004923 assert(D.isPastIdentifier() &&
4924 "Haven't past the location of the identifier yet?");
Mike Stump1eb44332009-09-09 15:08:12 +00004925
Richard Smith6ee326a2012-04-10 01:32:12 +00004926 // Don't parse attributes unless we have parsed an unparenthesized name.
4927 if (D.hasName() && !D.getNumTypeObjects())
Richard Smith4e24f0f2013-01-02 12:01:23 +00004928 MaybeParseCXX11Attributes(D);
Sean Huntbbd37c62009-11-21 08:43:09 +00004929
Reid Spencer5f016e22007-07-11 17:01:13 +00004930 while (1) {
Chris Lattner04d66662007-10-09 17:33:22 +00004931 if (Tok.is(tok::l_paren)) {
David Blaikie42d6d0c2011-12-04 05:04:18 +00004932 // Enter function-declaration scope, limiting any declarators to the
4933 // function prototype scope, including parameter declarators.
4934 ParseScope PrototypeScope(this,
Richard Smith3a2b7a12013-01-28 22:42:45 +00004935 Scope::FunctionPrototypeScope|Scope::DeclScope|
4936 (D.isFunctionDeclaratorAFunctionDeclaration()
4937 ? Scope::FunctionDeclarationScope : 0));
4938
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00004939 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4940 // In such a case, check if we actually have a function declarator; if it
4941 // is not, the declarator has been fully parsed.
Richard Smithb9c62612012-07-30 21:30:52 +00004942 bool IsAmbiguous = false;
Richard Smith05766812012-08-18 00:55:03 +00004943 if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
4944 // The name of the declarator, if any, is tentatively declared within
4945 // a possible direct initializer.
4946 TentativelyDeclaredIdentifiers.push_back(D.getIdentifier());
4947 bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
4948 TentativelyDeclaredIdentifiers.pop_back();
4949 if (!IsFunctionDecl)
4950 break;
4951 }
John McCall0b7e6782011-03-24 11:26:52 +00004952 ParsedAttributes attrs(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004953 BalancedDelimiterTracker T(*this, tok::l_paren);
4954 T.consumeOpen();
Richard Smithb9c62612012-07-30 21:30:52 +00004955 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004956 PrototypeScope.Exit();
Chris Lattner04d66662007-10-09 17:33:22 +00004957 } else if (Tok.is(tok::l_square)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004958 ParseBracketDeclarator(D);
4959 } else {
4960 break;
4961 }
4962 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004963}
Reid Spencer5f016e22007-07-11 17:01:13 +00004964
Chris Lattneref4715c2008-04-06 05:45:57 +00004965/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
4966/// only called before the identifier, so these are most likely just grouping
Mike Stump1eb44332009-09-09 15:08:12 +00004967/// parens for precedence. If we find that these are actually function
Chris Lattneref4715c2008-04-06 05:45:57 +00004968/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4969///
4970/// direct-declarator:
4971/// '(' declarator ')'
4972/// [GNU] '(' attributes declarator ')'
Chris Lattner7399ee02008-10-20 02:05:46 +00004973/// direct-declarator '(' parameter-type-list ')'
4974/// direct-declarator '(' identifier-list[opt] ')'
4975/// [GNU] direct-declarator '(' parameter-forward-declarations
4976/// parameter-type-list[opt] ')'
Chris Lattneref4715c2008-04-06 05:45:57 +00004977///
4978void Parser::ParseParenDeclarator(Declarator &D) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004979 BalancedDelimiterTracker T(*this, tok::l_paren);
4980 T.consumeOpen();
4981
Chris Lattneref4715c2008-04-06 05:45:57 +00004982 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00004983
Chris Lattner7399ee02008-10-20 02:05:46 +00004984 // Eat any attributes before we look at whether this is a grouping or function
4985 // declarator paren. If this is a grouping paren, the attribute applies to
4986 // the type being built up, for example:
4987 // int (__attribute__(()) *x)(long y)
4988 // If this ends up not being a grouping paren, the attribute applies to the
4989 // first argument, for example:
4990 // int (__attribute__(()) int x)
4991 // In either case, we need to eat any attributes to be able to determine what
4992 // sort of paren this is.
4993 //
John McCall0b7e6782011-03-24 11:26:52 +00004994 ParsedAttributes attrs(AttrFactory);
Chris Lattner7399ee02008-10-20 02:05:46 +00004995 bool RequiresArg = false;
4996 if (Tok.is(tok::kw___attribute)) {
John McCall7f040a92010-12-24 02:08:15 +00004997 ParseGNUAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00004998
Chris Lattner7399ee02008-10-20 02:05:46 +00004999 // We require that the argument list (if this is a non-grouping paren) be
5000 // present even if the attribute list was empty.
5001 RequiresArg = true;
5002 }
Chad Rosier9cab1c92012-12-21 21:22:20 +00005003
Steve Naroff239f0732008-12-25 14:16:32 +00005004 // Eat any Microsoft extensions.
Chad Rosier9cab1c92012-12-21 21:22:20 +00005005 ParseMicrosoftTypeAttributes(attrs);
5006
Dawn Perchik52fc3142010-09-03 01:29:35 +00005007 // Eat any Borland extensions.
Ted Kremenek8113ecf2010-11-10 05:59:39 +00005008 if (Tok.is(tok::kw___pascal))
John McCall7f040a92010-12-24 02:08:15 +00005009 ParseBorlandTypeAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00005010
Chris Lattneref4715c2008-04-06 05:45:57 +00005011 // If we haven't past the identifier yet (or where the identifier would be
5012 // stored, if this is an abstract declarator), then this is probably just
5013 // grouping parens. However, if this could be an abstract-declarator, then
5014 // this could also be the start of function arguments (consider 'void()').
5015 bool isGrouping;
Mike Stump1eb44332009-09-09 15:08:12 +00005016
Chris Lattneref4715c2008-04-06 05:45:57 +00005017 if (!D.mayOmitIdentifier()) {
5018 // If this can't be an abstract-declarator, this *must* be a grouping
5019 // paren, because we haven't seen the identifier yet.
5020 isGrouping = true;
5021 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Richard Smith22592862012-03-27 23:05:05 +00005022 (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
5023 NextToken().is(tok::r_paren)) || // C++ int(...)
Richard Smith6ce48a72012-04-11 04:01:28 +00005024 isDeclarationSpecifier() || // 'int(int)' is a function.
5025 isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function.
Chris Lattneref4715c2008-04-06 05:45:57 +00005026 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
5027 // considered to be a type, not a K&R identifier-list.
5028 isGrouping = false;
5029 } else {
5030 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
5031 isGrouping = true;
5032 }
Mike Stump1eb44332009-09-09 15:08:12 +00005033
Chris Lattneref4715c2008-04-06 05:45:57 +00005034 // If this is a grouping paren, handle:
5035 // direct-declarator: '(' declarator ')'
5036 // direct-declarator: '(' attributes declarator ')'
5037 if (isGrouping) {
Richard Smith9988f282012-03-29 01:16:42 +00005038 SourceLocation EllipsisLoc = D.getEllipsisLoc();
5039 D.setEllipsisLoc(SourceLocation());
5040
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00005041 bool hadGroupingParens = D.hasGroupingParens();
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00005042 D.setGroupingParens(true);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00005043 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattneref4715c2008-04-06 05:45:57 +00005044 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005045 T.consumeClose();
Chad Rosier8decdee2012-06-26 22:30:43 +00005046 D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005047 T.getCloseLocation()),
5048 attrs, T.getCloseLocation());
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00005049
5050 D.setGroupingParens(hadGroupingParens);
Richard Smith9988f282012-03-29 01:16:42 +00005051
5052 // An ellipsis cannot be placed outside parentheses.
5053 if (EllipsisLoc.isValid())
5054 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
5055
Chris Lattneref4715c2008-04-06 05:45:57 +00005056 return;
5057 }
Mike Stump1eb44332009-09-09 15:08:12 +00005058
Chris Lattneref4715c2008-04-06 05:45:57 +00005059 // Okay, if this wasn't a grouping paren, it must be the start of a function
5060 // argument list. Recognize that this declarator will never have an
Chris Lattner7399ee02008-10-20 02:05:46 +00005061 // identifier (and remember where it would have been), then call into
5062 // ParseFunctionDeclarator to handle of argument list.
Chris Lattneref4715c2008-04-06 05:45:57 +00005063 D.SetIdentifier(0, Tok.getLocation());
5064
David Blaikie42d6d0c2011-12-04 05:04:18 +00005065 // Enter function-declaration scope, limiting any declarators to the
5066 // function prototype scope, including parameter declarators.
5067 ParseScope PrototypeScope(this,
Richard Smith3a2b7a12013-01-28 22:42:45 +00005068 Scope::FunctionPrototypeScope | Scope::DeclScope |
5069 (D.isFunctionDeclaratorAFunctionDeclaration()
5070 ? Scope::FunctionDeclarationScope : 0));
Richard Smithb9c62612012-07-30 21:30:52 +00005071 ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
David Blaikie42d6d0c2011-12-04 05:04:18 +00005072 PrototypeScope.Exit();
Chris Lattneref4715c2008-04-06 05:45:57 +00005073}
5074
5075/// ParseFunctionDeclarator - We are after the identifier and have parsed the
5076/// declarator D up to a paren, which indicates that we are parsing function
5077/// arguments.
Reid Spencer5f016e22007-07-11 17:01:13 +00005078///
Richard Smith6ee326a2012-04-10 01:32:12 +00005079/// If FirstArgAttrs is non-null, then the caller parsed those arguments
5080/// immediately after the open paren - they should be considered to be the
5081/// first argument of a parameter.
Chris Lattner7399ee02008-10-20 02:05:46 +00005082///
Richard Smith6ee326a2012-04-10 01:32:12 +00005083/// If RequiresArg is true, then the first argument of the function is required
5084/// to be present and required to not be an identifier list.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005085///
Richard Smith6ee326a2012-04-10 01:32:12 +00005086/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
5087/// (C++11) ref-qualifier[opt], exception-specification[opt],
5088/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
5089///
5090/// [C++11] exception-specification:
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005091/// dynamic-exception-specification
5092/// noexcept-specification
5093///
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005094void Parser::ParseFunctionDeclarator(Declarator &D,
Richard Smith6ee326a2012-04-10 01:32:12 +00005095 ParsedAttributes &FirstArgAttrs,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005096 BalancedDelimiterTracker &Tracker,
Richard Smithb9c62612012-07-30 21:30:52 +00005097 bool IsAmbiguous,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005098 bool RequiresArg) {
Chad Rosier8decdee2012-06-26 22:30:43 +00005099 assert(getCurScope()->isFunctionPrototypeScope() &&
David Blaikie42d6d0c2011-12-04 05:04:18 +00005100 "Should call from a Function scope");
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005101 // lparen is already consumed!
5102 assert(D.isPastIdentifier() && "Should not call before identifier!");
5103
5104 // This should be true when the function has typed arguments.
5105 // Otherwise, it is treated as a K&R-style function.
5106 bool HasProto = false;
5107 // Build up an array of information about the parsed arguments.
Chris Lattner5f9e2722011-07-23 10:55:15 +00005108 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005109 // Remember where we see an ellipsis, if any.
5110 SourceLocation EllipsisLoc;
5111
5112 DeclSpec DS(AttrFactory);
5113 bool RefQualifierIsLValueRef = true;
5114 SourceLocation RefQualifierLoc;
Douglas Gregor43f51032011-10-19 06:04:55 +00005115 SourceLocation ConstQualifierLoc;
5116 SourceLocation VolatileQualifierLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005117 ExceptionSpecificationType ESpecType = EST_None;
5118 SourceRange ESpecRange;
Chris Lattner5f9e2722011-07-23 10:55:15 +00005119 SmallVector<ParsedType, 2> DynamicExceptions;
5120 SmallVector<SourceRange, 2> DynamicExceptionRanges;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005121 ExprResult NoexceptExpr;
Richard Smith6ee326a2012-04-10 01:32:12 +00005122 ParsedAttributes FnAttrs(AttrFactory);
Richard Smith54655be2012-06-12 01:51:59 +00005123 TypeResult TrailingReturnType;
Richard Smith6ee326a2012-04-10 01:32:12 +00005124
James Molloy16f1f712012-02-29 10:24:19 +00005125 Actions.ActOnStartFunctionDeclarator();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005126 /* LocalEndLoc is the end location for the local FunctionTypeLoc.
5127 EndLoc is the end location for the function declarator.
5128 They differ for trailing return types. */
5129 SourceLocation StartLoc, LocalEndLoc, EndLoc;
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005130 SourceLocation LParenLoc, RParenLoc;
5131 LParenLoc = Tracker.getOpenLocation();
5132 StartLoc = LParenLoc;
5133
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005134 if (isFunctionDeclaratorIdentifierList()) {
5135 if (RequiresArg)
5136 Diag(Tok, diag::err_argument_required_after_attribute);
5137
5138 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
5139
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005140 Tracker.consumeClose();
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005141 RParenLoc = Tracker.getCloseLocation();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005142 LocalEndLoc = RParenLoc;
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005143 EndLoc = RParenLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005144 } else {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005145 if (Tok.isNot(tok::r_paren))
Faisal Valifad9e132013-09-26 19:54:12 +00005146 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo,
5147 EllipsisLoc);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005148 else if (RequiresArg)
5149 Diag(Tok, diag::err_argument_required_after_attribute);
5150
David Blaikie4e4d0842012-03-11 07:00:24 +00005151 HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005152
5153 // If we have the closing ')', eat it.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005154 Tracker.consumeClose();
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005155 RParenLoc = Tracker.getCloseLocation();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005156 LocalEndLoc = RParenLoc;
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005157 EndLoc = RParenLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005158
David Blaikie4e4d0842012-03-11 07:00:24 +00005159 if (getLangOpts().CPlusPlus) {
Richard Smith6ee326a2012-04-10 01:32:12 +00005160 // FIXME: Accept these components in any order, and produce fixits to
5161 // correct the order if the user gets it wrong. Ideally we should deal
5162 // with the virt-specifier-seq and pure-specifier in the same way.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005163
5164 // Parse cv-qualifier-seq[opt].
Richard Smith4cf4a5e2013-03-28 01:55:44 +00005165 ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false,
5166 /*CXX11AttributesAllowed*/ false,
5167 /*AtomicAllowed*/ false);
Richard Smith6ee326a2012-04-10 01:32:12 +00005168 if (!DS.getSourceRange().getEnd().isInvalid()) {
5169 EndLoc = DS.getSourceRange().getEnd();
5170 ConstQualifierLoc = DS.getConstSpecLoc();
5171 VolatileQualifierLoc = DS.getVolatileSpecLoc();
5172 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005173
5174 // Parse ref-qualifier[opt].
5175 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
Richard Smith80ad52f2013-01-02 11:42:31 +00005176 Diag(Tok, getLangOpts().CPlusPlus11 ?
Richard Smith7fe62082011-10-15 05:09:34 +00005177 diag::warn_cxx98_compat_ref_qualifier :
5178 diag::ext_ref_qualifier);
Richard Smith6ee326a2012-04-10 01:32:12 +00005179
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005180 RefQualifierIsLValueRef = Tok.is(tok::amp);
5181 RefQualifierLoc = ConsumeToken();
5182 EndLoc = RefQualifierLoc;
5183 }
5184
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005185 // C++11 [expr.prim.general]p3:
Chad Rosier8decdee2012-06-26 22:30:43 +00005186 // If a declaration declares a member function or member function
5187 // template of a class X, the expression this is a prvalue of type
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005188 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
Chad Rosier8decdee2012-06-26 22:30:43 +00005189 // and the end of the function-definition, member-declarator, or
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005190 // declarator.
Richard Smithd9227792013-03-15 00:41:52 +00005191 // FIXME: currently, "static" case isn't handled correctly.
Chad Rosier8decdee2012-06-26 22:30:43 +00005192 bool IsCXX11MemberFunction =
Richard Smith80ad52f2013-01-02 11:42:31 +00005193 getLangOpts().CPlusPlus11 &&
Richard Smithd9227792013-03-15 00:41:52 +00005194 (D.getContext() == Declarator::MemberContext
5195 ? !D.getDeclSpec().isFriendSpecified()
5196 : D.getContext() == Declarator::FileContext &&
5197 D.getCXXScopeSpec().isValid() &&
5198 Actions.CurContext->isRecord());
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005199 Sema::CXXThisScopeRAII ThisScope(Actions,
5200 dyn_cast<CXXRecordDecl>(Actions.CurContext),
Richard Smith7b19cb12013-01-14 01:55:13 +00005201 DS.getTypeQualifiers() |
Richard Smith84046262013-04-21 01:08:50 +00005202 (D.getDeclSpec().isConstexprSpecified() &&
5203 !getLangOpts().CPlusPlus1y
Richard Smith7b19cb12013-01-14 01:55:13 +00005204 ? Qualifiers::Const : 0),
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005205 IsCXX11MemberFunction);
Richard Smitha058fd42012-05-02 22:22:32 +00005206
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005207 // Parse exception-specification[opt].
Richard Smitha058fd42012-05-02 22:22:32 +00005208 ESpecType = tryParseExceptionSpecification(ESpecRange,
Douglas Gregor74e2fc32012-04-16 18:27:27 +00005209 DynamicExceptions,
5210 DynamicExceptionRanges,
Richard Smitha058fd42012-05-02 22:22:32 +00005211 NoexceptExpr);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005212 if (ESpecType != EST_None)
5213 EndLoc = ESpecRange.getEnd();
5214
Richard Smith6ee326a2012-04-10 01:32:12 +00005215 // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
5216 // after the exception-specification.
Richard Smith4e24f0f2013-01-02 12:01:23 +00005217 MaybeParseCXX11Attributes(FnAttrs);
Richard Smith6ee326a2012-04-10 01:32:12 +00005218
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005219 // Parse trailing-return-type[opt].
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005220 LocalEndLoc = EndLoc;
Richard Smith80ad52f2013-01-02 11:42:31 +00005221 if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) {
Richard Smith7fe62082011-10-15 05:09:34 +00005222 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005223 if (D.getDeclSpec().getTypeSpecType() == TST_auto)
5224 StartLoc = D.getDeclSpec().getTypeSpecTypeLoc();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005225 LocalEndLoc = Tok.getLocation();
Douglas Gregorae7902c2011-08-04 15:30:47 +00005226 SourceRange Range;
Richard Smith54655be2012-06-12 01:51:59 +00005227 TrailingReturnType = ParseTrailingReturnType(Range);
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005228 EndLoc = Range.getEnd();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005229 }
5230 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005231 }
5232
5233 // Remember that we parsed a function type, and remember the attributes.
5234 D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005235 IsAmbiguous,
5236 LParenLoc,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005237 ParamInfo.data(), ParamInfo.size(),
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005238 EllipsisLoc, RParenLoc,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005239 DS.getTypeQualifiers(),
5240 RefQualifierIsLValueRef,
Douglas Gregor43f51032011-10-19 06:04:55 +00005241 RefQualifierLoc, ConstQualifierLoc,
5242 VolatileQualifierLoc,
Douglas Gregor90ebed02011-07-13 21:47:47 +00005243 /*MutableLoc=*/SourceLocation(),
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005244 ESpecType, ESpecRange.getBegin(),
5245 DynamicExceptions.data(),
5246 DynamicExceptionRanges.data(),
5247 DynamicExceptions.size(),
5248 NoexceptExpr.isUsable() ?
5249 NoexceptExpr.get() : 0,
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005250 StartLoc, LocalEndLoc, D,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005251 TrailingReturnType),
Richard Smith6ee326a2012-04-10 01:32:12 +00005252 FnAttrs, EndLoc);
James Molloy16f1f712012-02-29 10:24:19 +00005253
5254 Actions.ActOnEndFunctionDeclarator();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005255}
5256
5257/// isFunctionDeclaratorIdentifierList - This parameter list may have an
5258/// identifier list form for a K&R-style function: void foo(a,b,c)
5259///
5260/// Note that identifier-lists are only allowed for normal declarators, not for
5261/// abstract-declarators.
5262bool Parser::isFunctionDeclaratorIdentifierList() {
David Blaikie4e4d0842012-03-11 07:00:24 +00005263 return !getLangOpts().CPlusPlus
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005264 && Tok.is(tok::identifier)
5265 && !TryAltiVecVectorToken()
5266 // K&R identifier lists can't have typedefs as identifiers, per C99
5267 // 6.7.5.3p11.
5268 && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
5269 // Identifier lists follow a really simple grammar: the identifiers can
5270 // be followed *only* by a ", identifier" or ")". However, K&R
5271 // identifier lists are really rare in the brave new modern world, and
5272 // it is very common for someone to typo a type in a non-K&R style
5273 // list. If we are presented with something like: "void foo(intptr x,
5274 // float y)", we don't want to start parsing the function declarator as
5275 // though it is a K&R style declarator just because intptr is an
5276 // invalid type.
5277 //
5278 // To handle this, we check to see if the token after the first
5279 // identifier is a "," or ")". Only then do we parse it as an
5280 // identifier list.
5281 && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
5282}
5283
5284/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
5285/// we found a K&R-style identifier list instead of a typed parameter list.
5286///
5287/// After returning, ParamInfo will hold the parsed parameters.
5288///
5289/// identifier-list: [C99 6.7.5]
5290/// identifier
5291/// identifier-list ',' identifier
5292///
5293void Parser::ParseFunctionDeclaratorIdentifierList(
5294 Declarator &D,
Craig Topper6b9240e2013-07-05 19:34:19 +00005295 SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005296 // If there was no identifier specified for the declarator, either we are in
5297 // an abstract-declarator, or we are in a parameter declarator which was found
5298 // to be abstract. In abstract-declarators, identifier lists are not valid:
5299 // diagnose this.
5300 if (!D.getIdentifier())
5301 Diag(Tok, diag::ext_ident_list_in_param);
5302
5303 // Maintain an efficient lookup of params we have seen so far.
5304 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
5305
5306 while (1) {
5307 // If this isn't an identifier, report the error and skip until ')'.
5308 if (Tok.isNot(tok::identifier)) {
5309 Diag(Tok, diag::err_expected_ident);
Alexey Bataev8fe24752013-11-18 08:17:37 +00005310 SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005311 // Forget we parsed anything.
5312 ParamInfo.clear();
5313 return;
5314 }
5315
5316 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
5317
5318 // Reject 'typedef int y; int test(x, y)', but continue parsing.
5319 if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
5320 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
5321
5322 // Verify that the argument identifier has not already been mentioned.
5323 if (!ParamsSoFar.insert(ParmII)) {
5324 Diag(Tok, diag::err_param_redefinition) << ParmII;
5325 } else {
5326 // Remember this identifier in ParamInfo.
5327 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
5328 Tok.getLocation(),
5329 0));
5330 }
5331
5332 // Eat the identifier.
5333 ConsumeToken();
5334
5335 // The list continues if we see a comma.
5336 if (Tok.isNot(tok::comma))
5337 break;
5338 ConsumeToken();
5339 }
5340}
5341
5342/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
5343/// after the opening parenthesis. This function will not parse a K&R-style
5344/// identifier list.
5345///
Richard Smith6ce48a72012-04-11 04:01:28 +00005346/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the
5347/// caller parsed those arguments immediately after the open paren - they should
5348/// be considered to be part of the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005349///
5350/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
5351/// be the location of the ellipsis, if any was parsed.
5352///
Reid Spencer5f016e22007-07-11 17:01:13 +00005353/// parameter-type-list: [C99 6.7.5]
5354/// parameter-list
5355/// parameter-list ',' '...'
Douglas Gregored5d6512009-09-22 21:41:40 +00005356/// [C++] parameter-list '...'
Reid Spencer5f016e22007-07-11 17:01:13 +00005357///
5358/// parameter-list: [C99 6.7.5]
5359/// parameter-declaration
5360/// parameter-list ',' parameter-declaration
5361///
5362/// parameter-declaration: [C99 6.7.5]
5363/// declaration-specifiers declarator
Chris Lattner04421082008-04-08 04:40:51 +00005364/// [C++] declaration-specifiers declarator '=' assignment-expression
Sebastian Redl84407ba2012-03-14 15:54:00 +00005365/// [C++11] initializer-clause
Reid Spencer5f016e22007-07-11 17:01:13 +00005366/// [GNU] declaration-specifiers declarator attributes
Sebastian Redl50de12f2009-03-24 22:27:57 +00005367/// declaration-specifiers abstract-declarator[opt]
5368/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner8123a952008-04-10 02:22:51 +00005369/// '=' assignment-expression
Reid Spencer5f016e22007-07-11 17:01:13 +00005370/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
Richard Smith6ce48a72012-04-11 04:01:28 +00005371/// [C++11] attribute-specifier-seq parameter-declaration
Reid Spencer5f016e22007-07-11 17:01:13 +00005372///
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005373void Parser::ParseParameterDeclarationClause(
5374 Declarator &D,
Richard Smith6ce48a72012-04-11 04:01:28 +00005375 ParsedAttributes &FirstArgAttrs,
Craig Topper6b9240e2013-07-05 19:34:19 +00005376 SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005377 SourceLocation &EllipsisLoc) {
Chris Lattnerf97409f2008-04-06 06:57:35 +00005378 while (1) {
5379 if (Tok.is(tok::ellipsis)) {
Richard Smith6ce48a72012-04-11 04:01:28 +00005380 // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
5381 // before deciding this was a parameter-declaration-clause.
Douglas Gregor965acbb2009-02-18 07:07:28 +00005382 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattnerf97409f2008-04-06 06:57:35 +00005383 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00005384 }
Mike Stump1eb44332009-09-09 15:08:12 +00005385
Chris Lattnerf97409f2008-04-06 06:57:35 +00005386 // Parse the declaration-specifiers.
John McCall54abf7d2009-11-04 02:18:39 +00005387 // Just use the ParsingDeclaration "scope" of the declarator.
John McCall0b7e6782011-03-24 11:26:52 +00005388 DeclSpec DS(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005389
Richard Smith6ce48a72012-04-11 04:01:28 +00005390 // Parse any C++11 attributes.
Richard Smith4e24f0f2013-01-02 12:01:23 +00005391 MaybeParseCXX11Attributes(DS.getAttributes());
Richard Smith6ce48a72012-04-11 04:01:28 +00005392
John McCall7f040a92010-12-24 02:08:15 +00005393 // Skip any Microsoft attributes before a param.
Chad Rosier16f90bf2012-12-20 20:37:53 +00005394 MaybeParseMicrosoftAttributes(DS.getAttributes());
John McCall7f040a92010-12-24 02:08:15 +00005395
5396 SourceLocation DSStart = Tok.getLocation();
Chris Lattner7399ee02008-10-20 02:05:46 +00005397
5398 // If the caller parsed attributes for the first argument, add them now.
John McCall7f040a92010-12-24 02:08:15 +00005399 // Take them so that we only apply the attributes to the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005400 // FIXME: If we can leave the attributes in the token stream somehow, we can
Richard Smith6ce48a72012-04-11 04:01:28 +00005401 // get rid of a parameter (FirstArgAttrs) and this statement. It might be
5402 // too much hassle.
5403 DS.takeAttributesFrom(FirstArgAttrs);
John McCall7f040a92010-12-24 02:08:15 +00005404
Chris Lattnere64c5492009-02-27 18:38:20 +00005405 ParseDeclarationSpecifiers(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00005406
Faisal Valifad9e132013-09-26 19:54:12 +00005407
5408 // Parse the declarator. This is "PrototypeContext" or
5409 // "LambdaExprParameterContext", because we must accept either
5410 // 'declarator' or 'abstract-declarator' here.
5411 Declarator ParmDeclarator(DS,
5412 D.getContext() == Declarator::LambdaExprContext ?
5413 Declarator::LambdaExprParameterContext :
5414 Declarator::PrototypeContext);
5415 ParseDeclarator(ParmDeclarator);
Chris Lattnerf97409f2008-04-06 06:57:35 +00005416
5417 // Parse GNU attributes, if present.
Faisal Valifad9e132013-09-26 19:54:12 +00005418 MaybeParseGNUAttributes(ParmDeclarator);
Mike Stump1eb44332009-09-09 15:08:12 +00005419
Chris Lattnerf97409f2008-04-06 06:57:35 +00005420 // Remember this parsed parameter in ParamInfo.
Faisal Valifad9e132013-09-26 19:54:12 +00005421 IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
Mike Stump1eb44332009-09-09 15:08:12 +00005422
Douglas Gregor72b505b2008-12-16 21:30:33 +00005423 // DefArgToks is used when the parsing of default arguments needs
5424 // to be delayed.
5425 CachedTokens *DefArgToks = 0;
5426
Chris Lattnerf97409f2008-04-06 06:57:35 +00005427 // If no parameter was specified, verify that *something* was specified,
5428 // otherwise we have a missing type and identifier.
Faisal Valifad9e132013-09-26 19:54:12 +00005429 if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 &&
5430 ParmDeclarator.getNumTypeObjects() == 0) {
Chris Lattnerf97409f2008-04-06 06:57:35 +00005431 // Completely missing, emit error.
5432 Diag(DSStart, diag::err_missing_param);
5433 } else {
5434 // Otherwise, we have something. Add it and let semantic analysis try
5435 // to grok it and add the result to the ParamInfo we are building.
Mike Stump1eb44332009-09-09 15:08:12 +00005436
Chris Lattnerf97409f2008-04-06 06:57:35 +00005437 // Inform the actions module about the parameter declarator, so it gets
5438 // added to the current scope.
Faisal Valifad9e132013-09-26 19:54:12 +00005439 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(),
5440 ParmDeclarator);
Chris Lattner04421082008-04-08 04:40:51 +00005441 // Parse the default argument, if any. We parse the default
5442 // arguments in all dialects; the semantic analysis in
5443 // ActOnParamDefaultArgument will reject the default argument in
5444 // C.
5445 if (Tok.is(tok::equal)) {
Douglas Gregor61366e92008-12-24 00:01:03 +00005446 SourceLocation EqualLoc = Tok.getLocation();
5447
Chris Lattner04421082008-04-08 04:40:51 +00005448 // Parse the default argument
Douglas Gregor72b505b2008-12-16 21:30:33 +00005449 if (D.getContext() == Declarator::MemberContext) {
5450 // If we're inside a class definition, cache the tokens
5451 // corresponding to the default argument. We'll actually parse
5452 // them when we see the end of the class definition.
Douglas Gregor72b505b2008-12-16 21:30:33 +00005453 // FIXME: Can we use a smart pointer for Toks?
5454 DefArgToks = new CachedTokens;
5455
Richard Smith9bd3cdc2013-09-12 23:28:08 +00005456 if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) {
Douglas Gregor72b505b2008-12-16 21:30:33 +00005457 delete DefArgToks;
5458 DefArgToks = 0;
Douglas Gregor61366e92008-12-24 00:01:03 +00005459 Actions.ActOnParamDefaultArgumentError(Param);
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00005460 } else {
5461 // Mark the end of the default argument so that we know when to
5462 // stop when we parse it later on.
5463 Token DefArgEnd;
5464 DefArgEnd.startToken();
5465 DefArgEnd.setKind(tok::cxx_defaultarg_end);
5466 DefArgEnd.setLocation(Tok.getLocation());
5467 DefArgToks->push_back(DefArgEnd);
Mike Stump1eb44332009-09-09 15:08:12 +00005468 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
Anders Carlsson5e300d12009-06-12 16:51:40 +00005469 (*DefArgToks)[1].getLocation());
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00005470 }
Chris Lattner04421082008-04-08 04:40:51 +00005471 } else {
Douglas Gregor72b505b2008-12-16 21:30:33 +00005472 // Consume the '='.
Douglas Gregor61366e92008-12-24 00:01:03 +00005473 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005474
Chad Rosier8decdee2012-06-26 22:30:43 +00005475 // The argument isn't actually potentially evaluated unless it is
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00005476 // used.
5477 EnterExpressionEvaluationContext Eval(Actions,
Douglas Gregorccc1b5e2012-02-21 00:37:24 +00005478 Sema::PotentiallyEvaluatedIfUsed,
5479 Param);
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00005480
Sebastian Redl84407ba2012-03-14 15:54:00 +00005481 ExprResult DefArgResult;
Richard Smith80ad52f2013-01-02 11:42:31 +00005482 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
Sebastian Redl3e280b52012-03-18 22:25:45 +00005483 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Sebastian Redl84407ba2012-03-14 15:54:00 +00005484 DefArgResult = ParseBraceInitializer();
Sebastian Redl3e280b52012-03-18 22:25:45 +00005485 } else
Sebastian Redl84407ba2012-03-14 15:54:00 +00005486 DefArgResult = ParseAssignmentExpression();
Douglas Gregor72b505b2008-12-16 21:30:33 +00005487 if (DefArgResult.isInvalid()) {
5488 Actions.ActOnParamDefaultArgumentError(Param);
Alexey Bataev8fe24752013-11-18 08:17:37 +00005489 SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
Douglas Gregor72b505b2008-12-16 21:30:33 +00005490 } else {
5491 // Inform the actions module about the default argument
5492 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
John McCall9ae2f072010-08-23 23:25:46 +00005493 DefArgResult.take());
Douglas Gregor72b505b2008-12-16 21:30:33 +00005494 }
Chris Lattner04421082008-04-08 04:40:51 +00005495 }
5496 }
Mike Stump1eb44332009-09-09 15:08:12 +00005497
5498 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Faisal Valifad9e132013-09-26 19:54:12 +00005499 ParmDeclarator.getIdentifierLoc(),
5500 Param, DefArgToks));
Chris Lattnerf97409f2008-04-06 06:57:35 +00005501 }
5502
5503 // If the next token is a comma, consume it and keep reading arguments.
Douglas Gregored5d6512009-09-22 21:41:40 +00005504 if (Tok.isNot(tok::comma)) {
5505 if (Tok.is(tok::ellipsis)) {
Douglas Gregored5d6512009-09-22 21:41:40 +00005506 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chad Rosier8decdee2012-06-26 22:30:43 +00005507
David Blaikie4e4d0842012-03-11 07:00:24 +00005508 if (!getLangOpts().CPlusPlus) {
Douglas Gregored5d6512009-09-22 21:41:40 +00005509 // We have ellipsis without a preceding ',', which is ill-formed
5510 // in C. Complain and provide the fix.
5511 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
Douglas Gregor849b2432010-03-31 17:46:05 +00005512 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
Douglas Gregored5d6512009-09-22 21:41:40 +00005513 }
5514 }
Chad Rosier8decdee2012-06-26 22:30:43 +00005515
Douglas Gregored5d6512009-09-22 21:41:40 +00005516 break;
5517 }
Mike Stump1eb44332009-09-09 15:08:12 +00005518
Chris Lattnerf97409f2008-04-06 06:57:35 +00005519 // Consume the comma.
5520 ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00005521 }
Mike Stump1eb44332009-09-09 15:08:12 +00005522
Chris Lattner66d28652008-04-06 06:34:08 +00005523}
Chris Lattneref4715c2008-04-06 05:45:57 +00005524
Reid Spencer5f016e22007-07-11 17:01:13 +00005525/// [C90] direct-declarator '[' constant-expression[opt] ']'
5526/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
5527/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
5528/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
5529/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00005530/// [C++11] direct-declarator '[' constant-expression[opt] ']'
5531/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00005532void Parser::ParseBracketDeclarator(Declarator &D) {
Richard Smith6ee326a2012-04-10 01:32:12 +00005533 if (CheckProhibitedCXX11Attribute())
5534 return;
5535
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005536 BalancedDelimiterTracker T(*this, tok::l_square);
5537 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00005538
Chris Lattner378c7e42008-12-18 07:27:21 +00005539 // C array syntax has many features, but by-far the most common is [] and [4].
5540 // This code does a fast path to handle some of the most obvious cases.
5541 if (Tok.getKind() == tok::r_square) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005542 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00005543 ParsedAttributes attrs(AttrFactory);
Richard Smith4e24f0f2013-01-02 12:01:23 +00005544 MaybeParseCXX11Attributes(attrs);
Chad Rosier8decdee2012-06-26 22:30:43 +00005545
Chris Lattner378c7e42008-12-18 07:27:21 +00005546 // Remember that we parsed the empty array type.
John McCall60d7b3a2010-08-24 06:29:42 +00005547 ExprResult NumElements;
John McCall0b7e6782011-03-24 11:26:52 +00005548 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005549 T.getOpenLocation(),
5550 T.getCloseLocation()),
5551 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00005552 return;
5553 } else if (Tok.getKind() == tok::numeric_constant &&
5554 GetLookAheadToken(1).is(tok::r_square)) {
5555 // [4] is very common. Parse the numeric constant expression.
Richard Smith36f5cfe2012-03-09 08:00:36 +00005556 ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
Chris Lattner378c7e42008-12-18 07:27:21 +00005557 ConsumeToken();
5558
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005559 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00005560 ParsedAttributes attrs(AttrFactory);
Richard Smith4e24f0f2013-01-02 12:01:23 +00005561 MaybeParseCXX11Attributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00005562
Chris Lattner378c7e42008-12-18 07:27:21 +00005563 // Remember that we parsed a array type, and remember its features.
Nikola Smiljanicebf0fa82013-01-11 08:33:05 +00005564 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
John McCall7f040a92010-12-24 02:08:15 +00005565 ExprRes.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005566 T.getOpenLocation(),
5567 T.getCloseLocation()),
5568 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00005569 return;
5570 }
Mike Stump1eb44332009-09-09 15:08:12 +00005571
Reid Spencer5f016e22007-07-11 17:01:13 +00005572 // If valid, this location is the position where we read the 'static' keyword.
5573 SourceLocation StaticLoc;
Chris Lattner04d66662007-10-09 17:33:22 +00005574 if (Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00005575 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005576
Reid Spencer5f016e22007-07-11 17:01:13 +00005577 // If there is a type-qualifier-list, read it now.
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005578 // Type qualifiers in an array subscript are a C99 feature.
John McCall0b7e6782011-03-24 11:26:52 +00005579 DeclSpec DS(AttrFactory);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00005580 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Mike Stump1eb44332009-09-09 15:08:12 +00005581
Reid Spencer5f016e22007-07-11 17:01:13 +00005582 // If we haven't already read 'static', check to see if there is one after the
5583 // type-qualifier-list.
Chris Lattner04d66662007-10-09 17:33:22 +00005584 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00005585 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005586
Reid Spencer5f016e22007-07-11 17:01:13 +00005587 // Handle "direct-declarator [ type-qual-list[opt] * ]".
5588 bool isStar = false;
John McCall60d7b3a2010-08-24 06:29:42 +00005589 ExprResult NumElements;
Mike Stump1eb44332009-09-09 15:08:12 +00005590
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005591 // Handle the case where we have '[*]' as the array size. However, a leading
5592 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
Sylvestre Ledrubed28ac2012-07-23 08:59:39 +00005593 // the token after the star is a ']'. Since stars in arrays are
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005594 // infrequent, use of lookahead is not costly here.
5595 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattnera711dd02008-04-06 05:27:21 +00005596 ConsumeToken(); // Eat the '*'.
Reid Spencer5f016e22007-07-11 17:01:13 +00005597
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005598 if (StaticLoc.isValid()) {
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005599 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005600 StaticLoc = SourceLocation(); // Drop the static.
5601 }
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005602 isStar = true;
Chris Lattner04d66662007-10-09 17:33:22 +00005603 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner378c7e42008-12-18 07:27:21 +00005604 // Note, in C89, this production uses the constant-expr production instead
5605 // of assignment-expr. The only difference is that assignment-expr allows
5606 // things like '=' and '*='. Sema rejects these in C89 mode because they
5607 // are not i-c-e's, so we don't need to distinguish between the two here.
Mike Stump1eb44332009-09-09 15:08:12 +00005608
Douglas Gregore0762c92009-06-19 23:52:42 +00005609 // Parse the constant-expression or assignment-expression now (depending
5610 // on dialect).
David Blaikie4e4d0842012-03-11 07:00:24 +00005611 if (getLangOpts().CPlusPlus) {
Douglas Gregore0762c92009-06-19 23:52:42 +00005612 NumElements = ParseConstantExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00005613 } else {
5614 EnterExpressionEvaluationContext Unevaluated(Actions,
5615 Sema::ConstantEvaluated);
Douglas Gregore0762c92009-06-19 23:52:42 +00005616 NumElements = ParseAssignmentExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00005617 }
Reid Spencer5f016e22007-07-11 17:01:13 +00005618 }
Mike Stump1eb44332009-09-09 15:08:12 +00005619
Reid Spencer5f016e22007-07-11 17:01:13 +00005620 // If there was an error parsing the assignment-expression, recover.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00005621 if (NumElements.isInvalid()) {
Chris Lattner5cb10d32009-04-24 22:30:50 +00005622 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00005623 // If the expression was invalid, skip it.
Alexey Bataev8fe24752013-11-18 08:17:37 +00005624 SkipUntil(tok::r_square, StopAtSemi);
Reid Spencer5f016e22007-07-11 17:01:13 +00005625 return;
5626 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00005627
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005628 T.consumeClose();
Sebastian Redlab197ba2009-02-09 18:23:29 +00005629
John McCall0b7e6782011-03-24 11:26:52 +00005630 ParsedAttributes attrs(AttrFactory);
Richard Smith4e24f0f2013-01-02 12:01:23 +00005631 MaybeParseCXX11Attributes(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00005632
Chris Lattner378c7e42008-12-18 07:27:21 +00005633 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00005634 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
Reid Spencer5f016e22007-07-11 17:01:13 +00005635 StaticLoc.isValid(), isStar,
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00005636 NumElements.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005637 T.getOpenLocation(),
5638 T.getCloseLocation()),
5639 attrs, T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00005640}
5641
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005642/// [GNU] typeof-specifier:
5643/// typeof ( expressions )
5644/// typeof ( type-name )
5645/// [GNU/C++] typeof unary-expression
Steve Naroffd1861fd2007-07-31 12:34:36 +00005646///
5647void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner04d66662007-10-09 17:33:22 +00005648 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005649 Token OpTok = Tok;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005650 SourceLocation StartLoc = ConsumeToken();
5651
John McCallcfb708c2010-01-13 20:03:27 +00005652 const bool hasParens = Tok.is(tok::l_paren);
5653
Eli Friedman80bfa3d2012-09-26 04:34:21 +00005654 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
5655 Sema::ReuseLambdaContextDecl);
Eli Friedman71b8fb52012-01-21 01:01:51 +00005656
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005657 bool isCastExpr;
John McCallb3d87482010-08-24 05:47:05 +00005658 ParsedType CastTy;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005659 SourceRange CastRange;
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00005660 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
5661 CastTy, CastRange);
John McCallcfb708c2010-01-13 20:03:27 +00005662 if (hasParens)
5663 DS.setTypeofParensRange(CastRange);
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005664
5665 if (CastRange.getEnd().isInvalid())
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005666 // FIXME: Not accurate, the range gets one token more than it should.
5667 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005668 else
5669 DS.SetRangeEnd(CastRange.getEnd());
Mike Stump1eb44332009-09-09 15:08:12 +00005670
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005671 if (isCastExpr) {
5672 if (!CastTy) {
5673 DS.SetTypeSpecError();
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005674 return;
Douglas Gregor809070a2009-02-18 17:45:20 +00005675 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005676
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005677 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005678 unsigned DiagID;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005679 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5680 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00005681 DiagID, CastTy))
5682 Diag(StartLoc, DiagID) << PrevSpec;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005683 return;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005684 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005685
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005686 // If we get here, the operand to the typeof was an expresion.
5687 if (Operand.isInvalid()) {
5688 DS.SetTypeSpecError();
Steve Naroff9dfa7b42007-08-02 02:53:48 +00005689 return;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005690 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005691
Eli Friedman71b8fb52012-01-21 01:01:51 +00005692 // We might need to transform the operand if it is potentially evaluated.
5693 Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5694 if (Operand.isInvalid()) {
5695 DS.SetTypeSpecError();
5696 return;
5697 }
5698
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005699 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005700 unsigned DiagID;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005701 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5702 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00005703 DiagID, Operand.get()))
John McCallfec54012009-08-03 20:12:06 +00005704 Diag(StartLoc, DiagID) << PrevSpec;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005705}
Chris Lattner1b492422010-02-28 18:33:55 +00005706
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00005707/// [C11] atomic-specifier:
Eli Friedmanb001de72011-10-06 23:00:33 +00005708/// _Atomic ( type-name )
5709///
5710void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
Richard Smith4cf4a5e2013-03-28 01:55:44 +00005711 assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) &&
5712 "Not an atomic specifier");
Eli Friedmanb001de72011-10-06 23:00:33 +00005713
5714 SourceLocation StartLoc = ConsumeToken();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005715 BalancedDelimiterTracker T(*this, tok::l_paren);
Richard Smith4cf4a5e2013-03-28 01:55:44 +00005716 if (T.consumeOpen())
Eli Friedmanb001de72011-10-06 23:00:33 +00005717 return;
Eli Friedmanb001de72011-10-06 23:00:33 +00005718
5719 TypeResult Result = ParseTypeName();
5720 if (Result.isInvalid()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +00005721 SkipUntil(tok::r_paren, StopAtSemi);
Eli Friedmanb001de72011-10-06 23:00:33 +00005722 return;
5723 }
5724
5725 // Match the ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005726 T.consumeClose();
Eli Friedmanb001de72011-10-06 23:00:33 +00005727
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005728 if (T.getCloseLocation().isInvalid())
Eli Friedmanb001de72011-10-06 23:00:33 +00005729 return;
5730
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005731 DS.setTypeofParensRange(T.getRange());
5732 DS.SetRangeEnd(T.getCloseLocation());
Eli Friedmanb001de72011-10-06 23:00:33 +00005733
5734 const char *PrevSpec = 0;
5735 unsigned DiagID;
5736 if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5737 DiagID, Result.release()))
5738 Diag(StartLoc, DiagID) << PrevSpec;
5739}
5740
Chris Lattner1b492422010-02-28 18:33:55 +00005741
5742/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5743/// from TryAltiVecVectorToken.
5744bool Parser::TryAltiVecVectorTokenOutOfLine() {
5745 Token Next = NextToken();
5746 switch (Next.getKind()) {
5747 default: return false;
5748 case tok::kw_short:
5749 case tok::kw_long:
5750 case tok::kw_signed:
5751 case tok::kw_unsigned:
5752 case tok::kw_void:
5753 case tok::kw_char:
5754 case tok::kw_int:
5755 case tok::kw_float:
5756 case tok::kw_double:
5757 case tok::kw_bool:
5758 case tok::kw___pixel:
5759 Tok.setKind(tok::kw___vector);
5760 return true;
5761 case tok::identifier:
5762 if (Next.getIdentifierInfo() == Ident_pixel) {
5763 Tok.setKind(tok::kw___vector);
5764 return true;
5765 }
Bill Schmidt3e3d20b2013-07-03 20:54:09 +00005766 if (Next.getIdentifierInfo() == Ident_bool) {
5767 Tok.setKind(tok::kw___vector);
5768 return true;
5769 }
Chris Lattner1b492422010-02-28 18:33:55 +00005770 return false;
5771 }
5772}
5773
5774bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5775 const char *&PrevSpec, unsigned &DiagID,
5776 bool &isInvalid) {
5777 if (Tok.getIdentifierInfo() == Ident_vector) {
5778 Token Next = NextToken();
5779 switch (Next.getKind()) {
5780 case tok::kw_short:
5781 case tok::kw_long:
5782 case tok::kw_signed:
5783 case tok::kw_unsigned:
5784 case tok::kw_void:
5785 case tok::kw_char:
5786 case tok::kw_int:
5787 case tok::kw_float:
5788 case tok::kw_double:
5789 case tok::kw_bool:
5790 case tok::kw___pixel:
5791 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5792 return true;
5793 case tok::identifier:
5794 if (Next.getIdentifierInfo() == Ident_pixel) {
5795 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5796 return true;
5797 }
Bill Schmidt3e3d20b2013-07-03 20:54:09 +00005798 if (Next.getIdentifierInfo() == Ident_bool) {
5799 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5800 return true;
5801 }
Chris Lattner1b492422010-02-28 18:33:55 +00005802 break;
5803 default:
5804 break;
5805 }
Douglas Gregora8f031f2010-06-16 15:28:57 +00005806 } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
Chris Lattner1b492422010-02-28 18:33:55 +00005807 DS.isTypeAltiVecVector()) {
5808 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5809 return true;
Bill Schmidt3e3d20b2013-07-03 20:54:09 +00005810 } else if ((Tok.getIdentifierInfo() == Ident_bool) &&
5811 DS.isTypeAltiVecVector()) {
5812 isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID);
5813 return true;
Chris Lattner1b492422010-02-28 18:33:55 +00005814 }
5815 return false;
5816}