blob: 61b57a1d90772ccd5e149dfc13ff298d096c8f97 [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 &&
2728 DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2729 Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
2730 Tok.setKind(tok::identifier);
2731 }
2732
2733 // We're done with the declaration-specifiers.
2734 goto DoneWithDeclSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00002735
Chris Lattner3bd934a2008-07-26 01:18:38 +00002736 // typedef-name
David Blaikie42d6d0c2011-12-04 05:04:18 +00002737 case tok::kw_decltype:
Chris Lattner3bd934a2008-07-26 01:18:38 +00002738 case tok::identifier: {
Chris Lattner5e02c472009-01-05 00:07:25 +00002739 // In C++, check to see if this is a scope specifier like foo::bar::, if
2740 // so handle it as such. This is important for ctor parsing.
David Blaikie4e4d0842012-03-11 07:00:24 +00002741 if (getLangOpts().CPlusPlus) {
Eli Friedman5a428202013-08-15 23:59:20 +00002742 if (TryAnnotateCXXScopeToken(EnteringContext)) {
John McCall9ba61662010-02-26 08:45:28 +00002743 if (!DS.hasTypeSpecifier())
2744 DS.SetTypeSpecError();
2745 goto DoneWithDeclSpec;
2746 }
2747 if (!Tok.is(tok::identifier))
2748 continue;
2749 }
Mike Stump1eb44332009-09-09 15:08:12 +00002750
Chris Lattner3bd934a2008-07-26 01:18:38 +00002751 // This identifier can only be a typedef name if we haven't already seen
2752 // a type-specifier. Without this check we misparse:
2753 // typedef int X; struct Y { short X; }; as 'short int'.
2754 if (DS.hasTypeSpecifier())
2755 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00002756
John Thompson82287d12010-02-05 00:12:22 +00002757 // Check for need to substitute AltiVec keyword tokens.
2758 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2759 break;
2760
Richard Smithf63eee72012-05-09 18:56:43 +00002761 // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2762 // allow the use of a typedef name as a type specifier.
2763 if (DS.isTypeAltiVecVector())
2764 goto DoneWithDeclSpec;
2765
John McCallb3d87482010-08-24 05:47:05 +00002766 ParsedType TypeRep =
2767 Actions.getTypeName(*Tok.getIdentifierInfo(),
2768 Tok.getLocation(), getCurScope());
Douglas Gregor55f6b142009-02-09 18:46:07 +00002769
Chris Lattnerc199ab32009-04-12 20:42:31 +00002770 // If this is not a typedef name, don't parse it as part of the declspec,
2771 // it must be an implicit int or an error.
John McCallb3d87482010-08-24 05:47:05 +00002772 if (!TypeRep) {
Michael Han2e397132012-11-26 22:54:45 +00002773 ParsedAttributesWithRange Attrs(AttrFactory);
2774 if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) {
2775 if (!Attrs.empty()) {
2776 AttrsLastTime = true;
2777 attrs.takeAllFrom(Attrs);
2778 }
2779 continue;
2780 }
Chris Lattner3bd934a2008-07-26 01:18:38 +00002781 goto DoneWithDeclSpec;
Chris Lattnerc199ab32009-04-12 20:42:31 +00002782 }
Douglas Gregor55f6b142009-02-09 18:46:07 +00002783
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002784 // If we're in a context where the identifier could be a class name,
2785 // check whether this is a constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002786 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002787 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002788 isConstructorDeclarator())
Douglas Gregorb48fe382008-10-31 09:07:45 +00002789 goto DoneWithDeclSpec;
2790
Douglas Gregor1a51b4a2009-02-09 15:09:02 +00002791 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00002792 DiagID, TypeRep);
Chris Lattner3bd934a2008-07-26 01:18:38 +00002793 if (isInvalid)
2794 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002795
Chris Lattner3bd934a2008-07-26 01:18:38 +00002796 DS.SetRangeEnd(Tok.getLocation());
2797 ConsumeToken(); // The identifier
2798
2799 // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2800 // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
Chad Rosier8decdee2012-06-26 22:30:43 +00002801 // Objective-C interface.
David Blaikie4e4d0842012-03-11 07:00:24 +00002802 if (Tok.is(tok::less) && getLangOpts().ObjC1)
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00002803 ParseObjCProtocolQualifiers(DS);
Chad Rosier8decdee2012-06-26 22:30:43 +00002804
Steve Naroff4f9b9f12008-09-22 10:28:57 +00002805 // Need to support trailing type qualifiers (e.g. "id<p> const").
2806 // If a type specifier follows, it will be diagnosed elsewhere.
2807 continue;
Chris Lattner3bd934a2008-07-26 01:18:38 +00002808 }
Douglas Gregor39a8de12009-02-25 19:37:18 +00002809
2810 // type-name
2811 case tok::annot_template_id: {
Argyrios Kyrtzidis25a76762011-06-22 06:09:49 +00002812 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
Douglas Gregorc45c2322009-03-31 00:43:58 +00002813 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor39a8de12009-02-25 19:37:18 +00002814 // This template-id does not refer to a type name, so we're
2815 // done with the type-specifiers.
2816 goto DoneWithDeclSpec;
2817 }
2818
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002819 // If we're in a context where the template-id could be a
2820 // constructor name or specialization, check whether this is a
2821 // constructor declaration.
David Blaikie4e4d0842012-03-11 07:00:24 +00002822 if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Douglas Gregor23c94db2010-07-02 17:43:08 +00002823 Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
Douglas Gregor0efc2c12010-01-13 17:31:36 +00002824 isConstructorDeclarator())
2825 goto DoneWithDeclSpec;
2826
Douglas Gregor39a8de12009-02-25 19:37:18 +00002827 // Turn the template-id annotation token into a type annotation
2828 // token, then try again to parse it as a type-specifier.
Douglas Gregor31a19b62009-04-01 21:51:26 +00002829 AnnotateTemplateIdTokenAsType();
Douglas Gregor39a8de12009-02-25 19:37:18 +00002830 continue;
2831 }
2832
Reid Spencer5f016e22007-07-11 17:01:13 +00002833 // GNU attributes support.
2834 case tok::kw___attribute:
DeLesley Hutchins2287c5e2012-03-02 22:12:59 +00002835 ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
Reid Spencer5f016e22007-07-11 17:01:13 +00002836 continue;
Steve Narofff59e17e2008-12-24 20:59:21 +00002837
2838 // Microsoft declspec support.
2839 case tok::kw___declspec:
John McCall7f040a92010-12-24 02:08:15 +00002840 ParseMicrosoftDeclSpec(DS.getAttributes());
Steve Narofff59e17e2008-12-24 20:59:21 +00002841 continue;
Mike Stump1eb44332009-09-09 15:08:12 +00002842
Steve Naroff239f0732008-12-25 14:16:32 +00002843 // Microsoft single token adornments.
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002844 case tok::kw___forceinline: {
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002845 isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID);
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002846 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
Richard Smithb3cd3c02012-09-14 18:27:01 +00002847 SourceLocation AttrNameLoc = Tok.getLocation();
Sean Hunt93f95f22012-06-18 16:13:52 +00002848 // FIXME: This does not work correctly if it is set to be a declspec
2849 // attribute, and a GNU attribute is simply incorrect.
Aaron Ballman624421f2013-08-31 01:11:41 +00002850 DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
2851 AttributeList::AS_GNU);
Richard Smithb3cd3c02012-09-14 18:27:01 +00002852 break;
Michael J. Spenceradc6cbf2012-06-18 07:00:48 +00002853 }
Eli Friedman290eeb02009-06-08 23:27:34 +00002854
Aaron Ballmanaa9df092013-05-22 23:25:32 +00002855 case tok::kw___sptr:
2856 case tok::kw___uptr:
Eli Friedman290eeb02009-06-08 23:27:34 +00002857 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00002858 case tok::kw___ptr32:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00002859 case tok::kw___w64:
Steve Naroff239f0732008-12-25 14:16:32 +00002860 case tok::kw___cdecl:
2861 case tok::kw___stdcall:
2862 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00002863 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00002864 case tok::kw___unaligned:
John McCall7f040a92010-12-24 02:08:15 +00002865 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00002866 continue;
2867
Dawn Perchik52fc3142010-09-03 01:29:35 +00002868 // Borland single token adornments.
2869 case tok::kw___pascal:
John McCall7f040a92010-12-24 02:08:15 +00002870 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00002871 continue;
2872
Peter Collingbournef315fa82011-02-14 01:42:53 +00002873 // OpenCL single token adornments.
2874 case tok::kw___kernel:
2875 ParseOpenCLAttributes(DS.getAttributes());
2876 continue;
2877
Reid Spencer5f016e22007-07-11 17:01:13 +00002878 // storage-class-specifier
2879 case tok::kw_typedef:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002880 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2881 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002882 break;
2883 case tok::kw_extern:
Richard Smithec642442013-04-12 22:46:28 +00002884 if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
Chris Lattner1ab3b962008-11-18 07:48:38 +00002885 Diag(Tok, diag::ext_thread_before) << "extern";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002886 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2887 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002888 break;
Steve Naroff8d54bf22007-12-18 00:16:02 +00002889 case tok::kw___private_extern__:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002890 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2891 Loc, PrevSpec, DiagID);
Steve Naroff8d54bf22007-12-18 00:16:02 +00002892 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002893 case tok::kw_static:
Richard Smithec642442013-04-12 22:46:28 +00002894 if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
Chris Lattner1ab3b962008-11-18 07:48:38 +00002895 Diag(Tok, diag::ext_thread_before) << "static";
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002896 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2897 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002898 break;
2899 case tok::kw_auto:
Richard Smith80ad52f2013-01-02 11:42:31 +00002900 if (getLangOpts().CPlusPlus11) {
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002901 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002902 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2903 PrevSpec, DiagID);
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002904 if (!isInvalid)
Richard Smith8f4fb192011-09-04 19:54:14 +00002905 Diag(Tok, diag::ext_auto_storage_class)
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002906 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
Richard Smith8f4fb192011-09-04 19:54:14 +00002907 } else
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00002908 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2909 DiagID);
Richard Smith8f4fb192011-09-04 19:54:14 +00002910 } else
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002911 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2912 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002913 break;
2914 case tok::kw_register:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002915 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2916 PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002917 break;
Sebastian Redl669d5d72008-11-14 23:42:31 +00002918 case tok::kw_mutable:
Peter Collingbourneb8b0e752011-10-06 03:01:00 +00002919 isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2920 PrevSpec, DiagID);
Sebastian Redl669d5d72008-11-14 23:42:31 +00002921 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00002922 case tok::kw___thread:
Richard Smithec642442013-04-12 22:46:28 +00002923 isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,
2924 PrevSpec, DiagID);
2925 break;
2926 case tok::kw_thread_local:
2927 isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc,
2928 PrevSpec, DiagID);
2929 break;
2930 case tok::kw__Thread_local:
2931 isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
2932 Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002933 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002934
Reid Spencer5f016e22007-07-11 17:01:13 +00002935 // function-specifier
2936 case tok::kw_inline:
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002937 isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);
Reid Spencer5f016e22007-07-11 17:01:13 +00002938 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002939 case tok::kw_virtual:
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002940 isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002941 break;
Douglas Gregorb48fe382008-10-31 09:07:45 +00002942 case tok::kw_explicit:
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002943 isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID);
Douglas Gregorb48fe382008-10-31 09:07:45 +00002944 break;
Richard Smithde03c152013-01-17 22:16:11 +00002945 case tok::kw__Noreturn:
2946 if (!getLangOpts().C11)
2947 Diag(Loc, diag::ext_c11_noreturn);
Serge Pavlovd1fa81c2013-11-13 06:57:53 +00002948 isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);
Richard Smithde03c152013-01-17 22:16:11 +00002949 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002950
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002951 // alignment-specifier
2952 case tok::kw__Alignas:
David Blaikie4e4d0842012-03-11 07:00:24 +00002953 if (!getLangOpts().C11)
Jordan Rosef70a8862012-06-30 21:33:57 +00002954 Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
Peter Collingbourne82d0b0a2011-09-29 18:04:28 +00002955 ParseAlignmentSpecifier(DS.getAttributes());
2956 continue;
2957
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002958 // friend
2959 case tok::kw_friend:
John McCall67d1a672009-08-06 02:15:43 +00002960 if (DSContext == DSC_class)
2961 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2962 else {
2963 PrevSpec = ""; // not actually used by the diagnostic
2964 DiagID = diag::err_friend_invalid_in_context;
2965 isInvalid = true;
2966 }
Anders Carlssonf47f7a12009-05-06 04:46:28 +00002967 break;
Mike Stump1eb44332009-09-09 15:08:12 +00002968
Douglas Gregor8d267c52011-09-09 02:06:17 +00002969 // Modules
2970 case tok::kw___module_private__:
2971 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2972 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00002973
Sebastian Redl2ac67232009-11-05 15:47:02 +00002974 // constexpr
2975 case tok::kw_constexpr:
2976 isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2977 break;
2978
Chris Lattner80d0c892009-01-21 19:48:37 +00002979 // type-specifier
2980 case tok::kw_short:
John McCallfec54012009-08-03 20:12:06 +00002981 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2982 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002983 break;
2984 case tok::kw_long:
2985 if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
John McCallfec54012009-08-03 20:12:06 +00002986 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2987 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002988 else
John McCallfec54012009-08-03 20:12:06 +00002989 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2990 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002991 break;
Francois Pichet338d7f72011-04-28 01:59:37 +00002992 case tok::kw___int64:
2993 isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2994 DiagID);
2995 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00002996 case tok::kw_signed:
John McCallfec54012009-08-03 20:12:06 +00002997 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2998 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00002999 break;
3000 case tok::kw_unsigned:
John McCallfec54012009-08-03 20:12:06 +00003001 isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
3002 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003003 break;
3004 case tok::kw__Complex:
John McCallfec54012009-08-03 20:12:06 +00003005 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
3006 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003007 break;
3008 case tok::kw__Imaginary:
John McCallfec54012009-08-03 20:12:06 +00003009 isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
3010 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003011 break;
3012 case tok::kw_void:
John McCallfec54012009-08-03 20:12:06 +00003013 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
3014 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003015 break;
3016 case tok::kw_char:
John McCallfec54012009-08-03 20:12:06 +00003017 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
3018 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003019 break;
3020 case tok::kw_int:
John McCallfec54012009-08-03 20:12:06 +00003021 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
3022 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003023 break;
Richard Smith5a5a9712012-04-04 06:24:32 +00003024 case tok::kw___int128:
3025 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
3026 DiagID);
3027 break;
3028 case tok::kw_half:
3029 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
3030 DiagID);
3031 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00003032 case tok::kw_float:
John McCallfec54012009-08-03 20:12:06 +00003033 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
3034 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003035 break;
3036 case tok::kw_double:
John McCallfec54012009-08-03 20:12:06 +00003037 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
3038 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003039 break;
3040 case tok::kw_wchar_t:
John McCallfec54012009-08-03 20:12:06 +00003041 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
3042 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003043 break;
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003044 case tok::kw_char16_t:
John McCallfec54012009-08-03 20:12:06 +00003045 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
3046 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003047 break;
3048 case tok::kw_char32_t:
John McCallfec54012009-08-03 20:12:06 +00003049 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
3050 DiagID);
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00003051 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00003052 case tok::kw_bool:
3053 case tok::kw__Bool:
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00003054 if (Tok.is(tok::kw_bool) &&
3055 DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
3056 DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
3057 PrevSpec = ""; // Not used by the diagnostic.
3058 DiagID = diag::err_bool_redeclaration;
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00003059 // For better error recovery.
3060 Tok.setKind(tok::identifier);
Argyrios Kyrtzidis4383e182010-11-16 18:18:13 +00003061 isInvalid = true;
3062 } else {
3063 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
3064 DiagID);
3065 }
Chris Lattner80d0c892009-01-21 19:48:37 +00003066 break;
3067 case tok::kw__Decimal32:
John McCallfec54012009-08-03 20:12:06 +00003068 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
3069 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003070 break;
3071 case tok::kw__Decimal64:
John McCallfec54012009-08-03 20:12:06 +00003072 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
3073 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003074 break;
3075 case tok::kw__Decimal128:
John McCallfec54012009-08-03 20:12:06 +00003076 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
3077 DiagID);
Chris Lattner80d0c892009-01-21 19:48:37 +00003078 break;
John Thompson82287d12010-02-05 00:12:22 +00003079 case tok::kw___vector:
3080 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
3081 break;
3082 case tok::kw___pixel:
3083 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
3084 break;
Guy Benyeib13621d2012-12-18 14:38:23 +00003085 case tok::kw_image1d_t:
3086 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc,
3087 PrevSpec, DiagID);
3088 break;
3089 case tok::kw_image1d_array_t:
3090 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc,
3091 PrevSpec, DiagID);
3092 break;
3093 case tok::kw_image1d_buffer_t:
3094 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc,
3095 PrevSpec, DiagID);
3096 break;
3097 case tok::kw_image2d_t:
3098 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc,
3099 PrevSpec, DiagID);
3100 break;
3101 case tok::kw_image2d_array_t:
3102 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc,
3103 PrevSpec, DiagID);
3104 break;
3105 case tok::kw_image3d_t:
3106 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc,
3107 PrevSpec, DiagID);
3108 break;
Guy Benyei21f18c42013-02-07 10:55:47 +00003109 case tok::kw_sampler_t:
3110 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc,
3111 PrevSpec, DiagID);
3112 break;
Guy Benyeie6b9d802013-01-20 12:31:11 +00003113 case tok::kw_event_t:
3114 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc,
3115 PrevSpec, DiagID);
3116 break;
John McCalla5fc4722011-04-09 22:50:59 +00003117 case tok::kw___unknown_anytype:
3118 isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
3119 PrevSpec, DiagID);
3120 break;
Chris Lattner80d0c892009-01-21 19:48:37 +00003121
3122 // class-specifier:
3123 case tok::kw_class:
3124 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00003125 case tok::kw___interface:
Chris Lattner4c97d762009-04-12 21:49:30 +00003126 case tok::kw_union: {
3127 tok::TokenKind Kind = Tok.getKind();
3128 ConsumeToken();
Michael Han2e397132012-11-26 22:54:45 +00003129
3130 // These are attributes following class specifiers.
3131 // To produce better diagnostic, we parse them when
3132 // parsing class specifier.
Bill Wendlingad017fa2012-12-20 19:22:21 +00003133 ParsedAttributesWithRange Attributes(AttrFactory);
Richard Smith69730c12012-03-12 07:56:15 +00003134 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
Bill Wendlingad017fa2012-12-20 19:22:21 +00003135 EnteringContext, DSContext, Attributes);
Michael Han2e397132012-11-26 22:54:45 +00003136
3137 // If there are attributes following class specifier,
3138 // take them over and handle them here.
Bill Wendlingad017fa2012-12-20 19:22:21 +00003139 if (!Attributes.empty()) {
Michael Han2e397132012-11-26 22:54:45 +00003140 AttrsLastTime = true;
Bill Wendlingad017fa2012-12-20 19:22:21 +00003141 attrs.takeAllFrom(Attributes);
Michael Han2e397132012-11-26 22:54:45 +00003142 }
Chris Lattner80d0c892009-01-21 19:48:37 +00003143 continue;
Chris Lattner4c97d762009-04-12 21:49:30 +00003144 }
Chris Lattner80d0c892009-01-21 19:48:37 +00003145
3146 // enum-specifier:
3147 case tok::kw_enum:
Chris Lattner4c97d762009-04-12 21:49:30 +00003148 ConsumeToken();
Richard Smith69730c12012-03-12 07:56:15 +00003149 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
Chris Lattner80d0c892009-01-21 19:48:37 +00003150 continue;
3151
3152 // cv-qualifier:
3153 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00003154 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00003155 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00003156 break;
3157 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00003158 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00003159 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00003160 break;
3161 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00003162 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00003163 getLangOpts());
Chris Lattner80d0c892009-01-21 19:48:37 +00003164 break;
3165
Douglas Gregord57959a2009-03-27 23:10:48 +00003166 // C++ typename-specifier:
3167 case tok::kw_typename:
John McCall9ba61662010-02-26 08:45:28 +00003168 if (TryAnnotateTypeOrScopeToken()) {
3169 DS.SetTypeSpecError();
3170 goto DoneWithDeclSpec;
3171 }
3172 if (!Tok.is(tok::kw_typename))
Douglas Gregord57959a2009-03-27 23:10:48 +00003173 continue;
3174 break;
3175
Chris Lattner80d0c892009-01-21 19:48:37 +00003176 // GNU typeof support.
3177 case tok::kw_typeof:
3178 ParseTypeofSpecifier(DS);
3179 continue;
3180
David Blaikie42d6d0c2011-12-04 05:04:18 +00003181 case tok::annot_decltype:
Anders Carlsson6fd634f2009-06-24 17:47:40 +00003182 ParseDecltypeSpecifier(DS);
3183 continue;
3184
Sean Huntdb5d44b2011-05-19 05:37:45 +00003185 case tok::kw___underlying_type:
3186 ParseUnderlyingTypeSpecifier(DS);
Eli Friedmanb001de72011-10-06 23:00:33 +00003187 continue;
3188
3189 case tok::kw__Atomic:
Richard Smith4cf4a5e2013-03-28 01:55:44 +00003190 // C11 6.7.2.4/4:
3191 // If the _Atomic keyword is immediately followed by a left parenthesis,
3192 // it is interpreted as a type specifier (with a type name), not as a
3193 // type qualifier.
3194 if (NextToken().is(tok::l_paren)) {
3195 ParseAtomicSpecifier(DS);
3196 continue;
3197 }
3198 isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
3199 getLangOpts());
3200 break;
Sean Huntdb5d44b2011-05-19 05:37:45 +00003201
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003202 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00003203 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003204 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003205 goto DoneWithDeclSpec;
3206 case tok::kw___private:
3207 case tok::kw___global:
3208 case tok::kw___local:
3209 case tok::kw___constant:
3210 case tok::kw___read_only:
3211 case tok::kw___write_only:
3212 case tok::kw___read_write:
3213 ParseOpenCLQualifiers(DS);
3214 break;
Chad Rosier8decdee2012-06-26 22:30:43 +00003215
Steve Naroffd3ded1f2008-06-05 00:02:44 +00003216 case tok::less:
Chris Lattner3bd934a2008-07-26 01:18:38 +00003217 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
Chris Lattnerbce61352008-07-26 00:20:22 +00003218 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
3219 // but we support it.
David Blaikie4e4d0842012-03-11 07:00:24 +00003220 if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
Chris Lattnerbce61352008-07-26 00:20:22 +00003221 goto DoneWithDeclSpec;
Mike Stump1eb44332009-09-09 15:08:12 +00003222
Douglas Gregor46f936e2010-11-19 17:10:50 +00003223 if (!ParseObjCProtocolQualifiers(DS))
3224 Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
3225 << FixItHint::CreateInsertion(Loc, "id")
3226 << SourceRange(Loc, DS.getSourceRange().getEnd());
Chad Rosier8decdee2012-06-26 22:30:43 +00003227
Douglas Gregor9bd1d8d2010-10-21 23:17:00 +00003228 // Need to support trailing type qualifiers (e.g. "id<p> const").
3229 // If a type specifier follows, it will be diagnosed elsewhere.
3230 continue;
Reid Spencer5f016e22007-07-11 17:01:13 +00003231 }
John McCallfec54012009-08-03 20:12:06 +00003232 // If the specifier wasn't legal, issue a diagnostic.
Reid Spencer5f016e22007-07-11 17:01:13 +00003233 if (isInvalid) {
3234 assert(PrevSpec && "Method did not return previous specifier!");
John McCallfec54012009-08-03 20:12:06 +00003235 assert(DiagID);
Chad Rosier8decdee2012-06-26 22:30:43 +00003236
Douglas Gregorae2fb142010-08-23 14:34:43 +00003237 if (DiagID == diag::ext_duplicate_declspec)
3238 Diag(Tok, DiagID)
3239 << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
3240 else
3241 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003242 }
Fariborz Jahanian12e3ece2011-02-22 23:17:49 +00003243
Chris Lattner81c018d2008-03-13 06:29:04 +00003244 DS.SetRangeEnd(Tok.getLocation());
Fariborz Jahaniane106a0b2011-04-19 21:42:37 +00003245 if (DiagID != diag::err_bool_redeclaration)
3246 ConsumeToken();
Sean Hunt2edf0a22012-06-23 05:07:58 +00003247
3248 AttrsLastTime = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00003249 }
3250}
Douglas Gregoradcac882008-12-01 23:54:00 +00003251
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003252/// ParseStructDeclaration - Parse a struct declaration without the terminating
3253/// semicolon.
3254///
Reid Spencer5f016e22007-07-11 17:01:13 +00003255/// struct-declaration:
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003256/// specifier-qualifier-list struct-declarator-list
Reid Spencer5f016e22007-07-11 17:01:13 +00003257/// [GNU] __extension__ struct-declaration
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003258/// [GNU] specifier-qualifier-list
Reid Spencer5f016e22007-07-11 17:01:13 +00003259/// struct-declarator-list:
3260/// struct-declarator
3261/// struct-declarator-list ',' struct-declarator
3262/// [GNU] struct-declarator-list ',' attributes[opt] struct-declarator
3263/// struct-declarator:
3264/// declarator
3265/// [GNU] declarator attributes[opt]
3266/// declarator[opt] ':' constant-expression
3267/// [GNU] declarator[opt] ':' constant-expression attributes[opt]
3268///
Chris Lattnere1359422008-04-10 06:46:29 +00003269void Parser::
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003270ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003271
Chris Lattnerc46d1a12008-10-20 06:45:43 +00003272 if (Tok.is(tok::kw___extension__)) {
3273 // __extension__ silences extension warnings in the subexpression.
3274 ExtensionRAIIObject O(Diags); // Use RAII to do this.
Steve Naroff28a7ca82007-08-20 22:28:22 +00003275 ConsumeToken();
Chris Lattnerc46d1a12008-10-20 06:45:43 +00003276 return ParseStructDeclaration(DS, Fields);
3277 }
Mike Stump1eb44332009-09-09 15:08:12 +00003278
Steve Naroff28a7ca82007-08-20 22:28:22 +00003279 // Parse the common specifier-qualifiers-list piece.
Steve Naroff28a7ca82007-08-20 22:28:22 +00003280 ParseSpecifierQualifierList(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00003281
Douglas Gregor4920f1f2009-01-12 22:49:06 +00003282 // If there are no declarators, this is a free-standing declaration
3283 // specifier. Let the actions module cope with it.
Chris Lattner04d66662007-10-09 17:33:22 +00003284 if (Tok.is(tok::semi)) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003285 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
3286 DS);
3287 DS.complete(TheDecl);
Steve Naroff28a7ca82007-08-20 22:28:22 +00003288 return;
3289 }
3290
3291 // Read struct-declarators until we find the semicolon.
John McCallbdd563e2009-11-03 02:38:08 +00003292 bool FirstDeclarator = true;
Richard Smith7984de32012-01-12 23:53:29 +00003293 SourceLocation CommaLoc;
Steve Naroff28a7ca82007-08-20 22:28:22 +00003294 while (1) {
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003295 ParsingFieldDeclarator DeclaratorInfo(*this, DS);
Richard Smith7984de32012-01-12 23:53:29 +00003296 DeclaratorInfo.D.setCommaLoc(CommaLoc);
John McCallbdd563e2009-11-03 02:38:08 +00003297
Bill Wendlingad017fa2012-12-20 19:22:21 +00003298 // Attributes are only allowed here on successive declarators.
John McCall7f040a92010-12-24 02:08:15 +00003299 if (!FirstDeclarator)
3300 MaybeParseGNUAttributes(DeclaratorInfo.D);
Mike Stump1eb44332009-09-09 15:08:12 +00003301
Steve Naroff28a7ca82007-08-20 22:28:22 +00003302 /// struct-declarator: declarator
3303 /// struct-declarator: declarator[opt] ':' constant-expression
Chris Lattnera1efc8c2009-12-10 01:59:24 +00003304 if (Tok.isNot(tok::colon)) {
3305 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
3306 ColonProtectionRAIIObject X(*this);
Chris Lattnere1359422008-04-10 06:46:29 +00003307 ParseDeclarator(DeclaratorInfo.D);
Chris Lattnera1efc8c2009-12-10 01:59:24 +00003308 }
Mike Stump1eb44332009-09-09 15:08:12 +00003309
Chris Lattner04d66662007-10-09 17:33:22 +00003310 if (Tok.is(tok::colon)) {
Steve Naroff28a7ca82007-08-20 22:28:22 +00003311 ConsumeToken();
John McCall60d7b3a2010-08-24 06:29:42 +00003312 ExprResult Res(ParseConstantExpression());
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00003313 if (Res.isInvalid())
Alexey Bataev8fe24752013-11-18 08:17:37 +00003314 SkipUntil(tok::semi, StopBeforeMatch);
Chris Lattner60b1e3e2008-04-10 06:15:14 +00003315 else
Sebastian Redleffa8d12008-12-10 00:02:53 +00003316 DeclaratorInfo.BitfieldSize = Res.release();
Steve Naroff28a7ca82007-08-20 22:28:22 +00003317 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00003318
Steve Naroff28a7ca82007-08-20 22:28:22 +00003319 // If attributes exist after the declarator, parse them.
John McCall7f040a92010-12-24 02:08:15 +00003320 MaybeParseGNUAttributes(DeclaratorInfo.D);
Sebastian Redlab197ba2009-02-09 18:23:29 +00003321
John McCallbdd563e2009-11-03 02:38:08 +00003322 // We're done with this declarator; invoke the callback.
Eli Friedman817a8862012-08-08 23:35:12 +00003323 Fields.invoke(DeclaratorInfo);
John McCallbdd563e2009-11-03 02:38:08 +00003324
Steve Naroff28a7ca82007-08-20 22:28:22 +00003325 // If we don't have a comma, it is either the end of the list (a ';')
3326 // or an error, bail out.
Chris Lattner04d66662007-10-09 17:33:22 +00003327 if (Tok.isNot(tok::comma))
Chris Lattnercd4b83c2007-10-29 04:42:53 +00003328 return;
Sebastian Redlab197ba2009-02-09 18:23:29 +00003329
Steve Naroff28a7ca82007-08-20 22:28:22 +00003330 // Consume the comma.
Richard Smith7984de32012-01-12 23:53:29 +00003331 CommaLoc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00003332
John McCallbdd563e2009-11-03 02:38:08 +00003333 FirstDeclarator = false;
Steve Naroff28a7ca82007-08-20 22:28:22 +00003334 }
Steve Naroff28a7ca82007-08-20 22:28:22 +00003335}
3336
3337/// ParseStructUnionBody
3338/// struct-contents:
3339/// struct-declaration-list
3340/// [EXT] empty
3341/// [GNU] "struct-declaration-list" without terminatoring ';'
3342/// struct-declaration-list:
3343/// struct-declaration
3344/// struct-declaration-list struct-declaration
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003345/// [OBC] '@' 'defs' '(' class-name ')'
Steve Naroff28a7ca82007-08-20 22:28:22 +00003346///
Reid Spencer5f016e22007-07-11 17:01:13 +00003347void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
John McCalld226f652010-08-21 09:40:31 +00003348 unsigned TagType, Decl *TagDecl) {
John McCallf312b1e2010-08-26 23:41:50 +00003349 PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
3350 "parsing struct/union body");
Andy Gibbsf50f3f72013-04-03 09:31:19 +00003351 assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");
Mike Stump1eb44332009-09-09 15:08:12 +00003352
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003353 BalancedDelimiterTracker T(*this, tok::l_brace);
3354 if (T.consumeOpen())
3355 return;
Mike Stump1eb44332009-09-09 15:08:12 +00003356
Douglas Gregor3218c4b2009-01-09 22:42:13 +00003357 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003358 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
Douglas Gregor72de6672009-01-08 20:45:30 +00003359
Chris Lattner5f9e2722011-07-23 10:55:15 +00003360 SmallVector<Decl *, 32> FieldDecls;
Chris Lattnere1359422008-04-10 06:46:29 +00003361
Reid Spencer5f016e22007-07-11 17:01:13 +00003362 // While we still have something to read, read the declarations in the struct.
Chris Lattner04d66662007-10-09 17:33:22 +00003363 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003364 // Each iteration of this loop reads one struct-declaration.
Mike Stump1eb44332009-09-09 15:08:12 +00003365
Reid Spencer5f016e22007-07-11 17:01:13 +00003366 // Check for extraneous top-level semicolon.
Chris Lattner04d66662007-10-09 17:33:22 +00003367 if (Tok.is(tok::semi)) {
Richard Smitheab9d6f2012-07-23 05:45:25 +00003368 ConsumeExtraSemi(InsideStruct, TagType);
Reid Spencer5f016e22007-07-11 17:01:13 +00003369 continue;
3370 }
Chris Lattnere1359422008-04-10 06:46:29 +00003371
Andy Gibbs74b9fa12013-04-03 09:46:04 +00003372 // Parse _Static_assert declaration.
3373 if (Tok.is(tok::kw__Static_assert)) {
3374 SourceLocation DeclEnd;
3375 ParseStaticAssertDeclaration(DeclEnd);
3376 continue;
3377 }
3378
Argyrios Kyrtzidisbd957452013-04-18 01:42:35 +00003379 if (Tok.is(tok::annot_pragma_pack)) {
3380 HandlePragmaPack();
3381 continue;
3382 }
3383
3384 if (Tok.is(tok::annot_pragma_align)) {
3385 HandlePragmaAlign();
3386 continue;
3387 }
3388
John McCallbdd563e2009-11-03 02:38:08 +00003389 if (!Tok.is(tok::at)) {
3390 struct CFieldCallback : FieldCallback {
3391 Parser &P;
John McCalld226f652010-08-21 09:40:31 +00003392 Decl *TagDecl;
Chris Lattner5f9e2722011-07-23 10:55:15 +00003393 SmallVectorImpl<Decl *> &FieldDecls;
John McCallbdd563e2009-11-03 02:38:08 +00003394
John McCalld226f652010-08-21 09:40:31 +00003395 CFieldCallback(Parser &P, Decl *TagDecl,
Chris Lattner5f9e2722011-07-23 10:55:15 +00003396 SmallVectorImpl<Decl *> &FieldDecls) :
John McCallbdd563e2009-11-03 02:38:08 +00003397 P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
3398
Eli Friedmandcdff462012-08-08 23:53:27 +00003399 void invoke(ParsingFieldDeclarator &FD) {
John McCallbdd563e2009-11-03 02:38:08 +00003400 // Install the declarator into the current TagDecl.
John McCalld226f652010-08-21 09:40:31 +00003401 Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
John McCall4ba39712009-11-03 21:13:47 +00003402 FD.D.getDeclSpec().getSourceRange().getBegin(),
3403 FD.D, FD.BitfieldSize);
John McCallbdd563e2009-11-03 02:38:08 +00003404 FieldDecls.push_back(Field);
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003405 FD.complete(Field);
Douglas Gregor91a28862009-08-26 14:27:30 +00003406 }
John McCallbdd563e2009-11-03 02:38:08 +00003407 } Callback(*this, TagDecl, FieldDecls);
3408
Eli Friedmanf66a0dd2012-08-08 23:04:35 +00003409 // Parse all the comma separated declarators.
3410 ParsingDeclSpec DS(*this);
John McCallbdd563e2009-11-03 02:38:08 +00003411 ParseStructDeclaration(DS, Callback);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003412 } else { // Handle @defs
3413 ConsumeToken();
3414 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
3415 Diag(Tok, diag::err_unexpected_at);
Alexey Bataev8fe24752013-11-18 08:17:37 +00003416 SkipUntil(tok::semi);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003417 continue;
3418 }
3419 ConsumeToken();
3420 ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
3421 if (!Tok.is(tok::identifier)) {
3422 Diag(Tok, diag::err_expected_ident);
Alexey Bataev8fe24752013-11-18 08:17:37 +00003423 SkipUntil(tok::semi);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003424 continue;
3425 }
Chris Lattner5f9e2722011-07-23 10:55:15 +00003426 SmallVector<Decl *, 16> Fields;
Douglas Gregor23c94db2010-07-02 17:43:08 +00003427 Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
Douglas Gregor44b43212008-12-11 16:49:14 +00003428 Tok.getIdentifierInfo(), Fields);
Chris Lattner5a6ddbf2008-06-21 19:39:06 +00003429 FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
3430 ConsumeToken();
3431 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
Mike Stump1eb44332009-09-09 15:08:12 +00003432 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003433
Chris Lattner04d66662007-10-09 17:33:22 +00003434 if (Tok.is(tok::semi)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003435 ConsumeToken();
Chris Lattner04d66662007-10-09 17:33:22 +00003436 } else if (Tok.is(tok::r_brace)) {
Chris Lattner3e156ad2010-02-02 00:37:27 +00003437 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
Reid Spencer5f016e22007-07-11 17:01:13 +00003438 break;
3439 } else {
Chris Lattner3e156ad2010-02-02 00:37:27 +00003440 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
3441 // Skip to end of block or statement to avoid ext-warning on extra ';'.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003442 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
Chris Lattner3e156ad2010-02-02 00:37:27 +00003443 // If we stopped at a ';', eat it.
3444 if (Tok.is(tok::semi)) ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00003445 }
3446 }
Mike Stump1eb44332009-09-09 15:08:12 +00003447
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003448 T.consumeClose();
Mike Stump1eb44332009-09-09 15:08:12 +00003449
John McCall0b7e6782011-03-24 11:26:52 +00003450 ParsedAttributes attrs(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00003451 // If attributes exist after struct contents, parse them.
John McCall7f040a92010-12-24 02:08:15 +00003452 MaybeParseGNUAttributes(attrs);
Daniel Dunbar1bfe1c22008-10-03 02:03:53 +00003453
Douglas Gregor23c94db2010-07-02 17:43:08 +00003454 Actions.ActOnFields(getCurScope(),
David Blaikie77b6de02011-09-22 02:58:26 +00003455 RecordLoc, TagDecl, FieldDecls,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003456 T.getOpenLocation(), T.getCloseLocation(),
John McCall7f040a92010-12-24 02:08:15 +00003457 attrs.getList());
Douglas Gregor72de6672009-01-08 20:45:30 +00003458 StructScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003459 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
3460 T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00003461}
3462
Reid Spencer5f016e22007-07-11 17:01:13 +00003463/// ParseEnumSpecifier
3464/// enum-specifier: [C99 6.7.2.2]
3465/// 'enum' identifier[opt] '{' enumerator-list '}'
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003466///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00003467/// [GNU] 'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
3468/// '}' attributes[opt]
Aaron Ballman6454a022012-03-01 04:09:28 +00003469/// [MS] 'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
3470/// '}'
Reid Spencer5f016e22007-07-11 17:01:13 +00003471/// 'enum' identifier
3472/// [GNU] 'enum' attributes[opt] identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003473///
Richard Smith1af83c42012-03-23 03:33:32 +00003474/// [C++11] enum-head '{' enumerator-list[opt] '}'
3475/// [C++11] enum-head '{' enumerator-list ',' '}'
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003476///
Richard Smith1af83c42012-03-23 03:33:32 +00003477/// enum-head: [C++11]
3478/// enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
3479/// enum-key attribute-specifier-seq[opt] nested-name-specifier
3480/// identifier enum-base[opt]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003481///
Richard Smith1af83c42012-03-23 03:33:32 +00003482/// enum-key: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003483/// 'enum'
3484/// 'enum' 'class'
3485/// 'enum' 'struct'
3486///
Richard Smith1af83c42012-03-23 03:33:32 +00003487/// enum-base: [C++11]
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003488/// ':' type-specifier-seq
3489///
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003490/// [C++] elaborated-type-specifier:
3491/// [C++] 'enum' '::'[opt] nested-name-specifier[opt] identifier
3492///
Chris Lattner4c97d762009-04-12 21:49:30 +00003493void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
Douglas Gregor9b9edd62010-03-02 17:53:14 +00003494 const ParsedTemplateInfo &TemplateInfo,
Richard Smith69730c12012-03-12 07:56:15 +00003495 AccessSpecifier AS, DeclSpecContext DSC) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003496 // Parse the tag portion of this.
Douglas Gregor374929f2009-09-18 15:37:17 +00003497 if (Tok.is(tok::code_completion)) {
3498 // Code completion for an enum name.
Douglas Gregor23c94db2010-07-02 17:43:08 +00003499 Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00003500 return cutOffParsing();
Douglas Gregor374929f2009-09-18 15:37:17 +00003501 }
John McCall57c13002011-07-06 05:58:41 +00003502
Sean Hunt2edf0a22012-06-23 05:07:58 +00003503 // If attributes exist after tag, parse them.
3504 ParsedAttributesWithRange attrs(AttrFactory);
3505 MaybeParseGNUAttributes(attrs);
Richard Smith4e24f0f2013-01-02 12:01:23 +00003506 MaybeParseCXX11Attributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003507
3508 // If declspecs exist after tag, parse them.
3509 while (Tok.is(tok::kw___declspec))
3510 ParseMicrosoftDeclSpec(attrs);
3511
Richard Smithbdad7a22012-01-10 01:33:14 +00003512 SourceLocation ScopedEnumKWLoc;
John McCall57c13002011-07-06 05:58:41 +00003513 bool IsScopedUsingClassTag = false;
3514
John McCall1e12b3d2012-06-23 22:30:04 +00003515 // In C++11, recognize 'enum class' and 'enum struct'.
Richard Trieued5a2922013-04-23 02:47:36 +00003516 if (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct)) {
3517 Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum
3518 : diag::ext_scoped_enum);
John McCall57c13002011-07-06 05:58:41 +00003519 IsScopedUsingClassTag = Tok.is(tok::kw_class);
Richard Smithbdad7a22012-01-10 01:33:14 +00003520 ScopedEnumKWLoc = ConsumeToken();
Chad Rosier8decdee2012-06-26 22:30:43 +00003521
Bill Wendlingad017fa2012-12-20 19:22:21 +00003522 // Attributes are not allowed between these keywords. Diagnose,
John McCall1e12b3d2012-06-23 22:30:04 +00003523 // but then just treat them like they appeared in the right place.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003524 ProhibitAttributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003525
3526 // They are allowed afterwards, though.
3527 MaybeParseGNUAttributes(attrs);
Richard Smith4e24f0f2013-01-02 12:01:23 +00003528 MaybeParseCXX11Attributes(attrs);
John McCall1e12b3d2012-06-23 22:30:04 +00003529 while (Tok.is(tok::kw___declspec))
3530 ParseMicrosoftDeclSpec(attrs);
John McCall57c13002011-07-06 05:58:41 +00003531 }
Richard Smith1af83c42012-03-23 03:33:32 +00003532
John McCall13489672012-05-07 06:16:58 +00003533 // C++11 [temp.explicit]p12:
3534 // The usual access controls do not apply to names used to specify
3535 // explicit instantiations.
3536 // We extend this to also cover explicit specializations. Note that
3537 // we don't suppress if this turns out to be an elaborated type
3538 // specifier.
3539 bool shouldDelayDiagsInTag =
3540 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3541 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3542 SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
Richard Smith1af83c42012-03-23 03:33:32 +00003543
Richard Smith7796eb52012-03-12 08:56:40 +00003544 // Enum definitions should not be parsed in a trailing-return-type.
3545 bool AllowDeclaration = DSC != DSC_trailing;
3546
3547 bool AllowFixedUnderlyingType = AllowDeclaration &&
Richard Smith80ad52f2013-01-02 11:42:31 +00003548 (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt ||
Richard Smith7796eb52012-03-12 08:56:40 +00003549 getLangOpts().ObjC2);
John McCall57c13002011-07-06 05:58:41 +00003550
Abramo Bagnarae4da7a02010-05-19 21:37:53 +00003551 CXXScopeSpec &SS = DS.getTypeSpecScope();
David Blaikie4e4d0842012-03-11 07:00:24 +00003552 if (getLangOpts().CPlusPlus) {
John McCall57c13002011-07-06 05:58:41 +00003553 // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3554 // if a fixed underlying type is allowed.
3555 ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
Chad Rosier8decdee2012-06-26 22:30:43 +00003556
3557 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Richard Smith725fe0e2013-04-01 21:43:41 +00003558 /*EnteringContext=*/true))
John McCall9ba61662010-02-26 08:45:28 +00003559 return;
3560
3561 if (SS.isSet() && Tok.isNot(tok::identifier)) {
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003562 Diag(Tok, diag::err_expected_ident);
3563 if (Tok.isNot(tok::l_brace)) {
3564 // Has no name and is not a definition.
3565 // Skip the rest of this declarator, up until the comma or semicolon.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003566 SkipUntil(tok::comma, StopAtSemi);
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00003567 return;
3568 }
3569 }
3570 }
Mike Stump1eb44332009-09-09 15:08:12 +00003571
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003572 // Must have either 'enum name' or 'enum {...}'.
Douglas Gregorb9075602011-02-22 02:55:24 +00003573 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
Richard Smith7796eb52012-03-12 08:56:40 +00003574 !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003575 Diag(Tok, diag::err_expected_ident_lbrace);
Mike Stump1eb44332009-09-09 15:08:12 +00003576
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003577 // Skip the rest of this declarator, up until the comma or semicolon.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003578 SkipUntil(tok::comma, StopAtSemi);
Reid Spencer5f016e22007-07-11 17:01:13 +00003579 return;
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003580 }
Mike Stump1eb44332009-09-09 15:08:12 +00003581
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003582 // If an identifier is present, consume and remember it.
3583 IdentifierInfo *Name = 0;
3584 SourceLocation NameLoc;
3585 if (Tok.is(tok::identifier)) {
3586 Name = Tok.getIdentifierInfo();
3587 NameLoc = ConsumeToken();
3588 }
Mike Stump1eb44332009-09-09 15:08:12 +00003589
Richard Smithbdad7a22012-01-10 01:33:14 +00003590 if (!Name && ScopedEnumKWLoc.isValid()) {
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003591 // C++0x 7.2p2: The optional identifier shall not be omitted in the
3592 // declaration of a scoped enumeration.
3593 Diag(Tok, diag::err_scoped_enum_missing_identifier);
Richard Smithbdad7a22012-01-10 01:33:14 +00003594 ScopedEnumKWLoc = SourceLocation();
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003595 IsScopedUsingClassTag = false;
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003596 }
3597
John McCall13489672012-05-07 06:16:58 +00003598 // Okay, end the suppression area. We'll decide whether to emit the
3599 // diagnostics in a second.
3600 if (shouldDelayDiagsInTag)
3601 diagsFromTag.done();
Richard Smith1af83c42012-03-23 03:33:32 +00003602
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003603 TypeResult BaseType;
3604
Douglas Gregora61b3e72010-12-01 17:42:47 +00003605 // Parse the fixed underlying type.
Richard Smith139be702012-07-02 19:14:01 +00003606 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
Douglas Gregorb9075602011-02-22 02:55:24 +00003607 if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003608 bool PossibleBitfield = false;
Richard Smith139be702012-07-02 19:14:01 +00003609 if (CanBeBitfield) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003610 // If we're in class scope, this can either be an enum declaration with
3611 // an underlying type, or a declaration of a bitfield member. We try to
3612 // use a simple disambiguation scheme first to catch the common cases
Chad Rosier8decdee2012-06-26 22:30:43 +00003613 // (integer literal, sizeof); if it's still ambiguous, we then consider
3614 // anything that's a simple-type-specifier followed by '(' as an
3615 // expression. This suffices because function types are not valid
Douglas Gregora61b3e72010-12-01 17:42:47 +00003616 // underlying types anyway.
Richard Smith05766812012-08-18 00:55:03 +00003617 EnterExpressionEvaluationContext Unevaluated(Actions,
3618 Sema::ConstantEvaluated);
Douglas Gregora61b3e72010-12-01 17:42:47 +00003619 TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
Chad Rosier8decdee2012-06-26 22:30:43 +00003620 // If the next token starts an expression, we know we're parsing a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003621 // bit-field. This is the common case.
3622 if (TPR == TPResult::True())
3623 PossibleBitfield = true;
3624 // If the next token starts a type-specifier-seq, it may be either a
3625 // a fixed underlying type or the start of a function-style cast in C++;
Chad Rosier8decdee2012-06-26 22:30:43 +00003626 // lookahead one more token to see if it's obvious that we have a
Douglas Gregora61b3e72010-12-01 17:42:47 +00003627 // fixed underlying type.
Chad Rosier8decdee2012-06-26 22:30:43 +00003628 else if (TPR == TPResult::False() &&
Douglas Gregora61b3e72010-12-01 17:42:47 +00003629 GetLookAheadToken(2).getKind() == tok::semi) {
3630 // Consume the ':'.
3631 ConsumeToken();
3632 } else {
3633 // We have the start of a type-specifier-seq, so we have to perform
3634 // tentative parsing to determine whether we have an expression or a
3635 // type.
3636 TentativeParsingAction TPA(*this);
3637
3638 // Consume the ':'.
3639 ConsumeToken();
Richard Smithd81e9612012-02-23 01:36:12 +00003640
3641 // If we see a type specifier followed by an open-brace, we have an
3642 // ambiguity between an underlying type and a C++11 braced
3643 // function-style cast. Resolve this by always treating it as an
3644 // underlying type.
3645 // FIXME: The standard is not entirely clear on how to disambiguate in
3646 // this case.
David Blaikie4e4d0842012-03-11 07:00:24 +00003647 if ((getLangOpts().CPlusPlus &&
Richard Smithd81e9612012-02-23 01:36:12 +00003648 isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
David Blaikie4e4d0842012-03-11 07:00:24 +00003649 (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
Douglas Gregora61b3e72010-12-01 17:42:47 +00003650 // We'll parse this as a bitfield later.
3651 PossibleBitfield = true;
3652 TPA.Revert();
3653 } else {
3654 // We have a type-specifier-seq.
3655 TPA.Commit();
3656 }
3657 }
3658 } else {
3659 // Consume the ':'.
3660 ConsumeToken();
3661 }
3662
3663 if (!PossibleBitfield) {
3664 SourceRange Range;
3665 BaseType = ParseTypeName(&Range);
Chad Rosier8decdee2012-06-26 22:30:43 +00003666
Richard Smith80ad52f2013-01-02 11:42:31 +00003667 if (getLangOpts().CPlusPlus11) {
Richard Smith7fe62082011-10-15 05:09:34 +00003668 Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
Eli Friedmancef3a7b2012-11-02 01:34:28 +00003669 } else if (!getLangOpts().ObjC2) {
3670 if (getLangOpts().CPlusPlus)
3671 Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range;
3672 else
3673 Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range;
3674 }
Douglas Gregora61b3e72010-12-01 17:42:47 +00003675 }
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003676 }
3677
Richard Smithbdad7a22012-01-10 01:33:14 +00003678 // There are four options here. If we have 'friend enum foo;' then this is a
3679 // friend declaration, and cannot have an accompanying definition. If we have
3680 // 'enum foo;', then this is a forward declaration. If we have
3681 // 'enum foo {...' then this is a definition. Otherwise we have something
3682 // like 'enum foo xyz', a reference.
Argyrios Kyrtzidise281b4c2008-09-11 00:21:41 +00003683 //
3684 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3685 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
3686 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
3687 //
John McCallf312b1e2010-08-26 23:41:50 +00003688 Sema::TagUseKind TUK;
John McCall13489672012-05-07 06:16:58 +00003689 if (!AllowDeclaration) {
Richard Smith7796eb52012-03-12 08:56:40 +00003690 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003691 } else if (Tok.is(tok::l_brace)) {
3692 if (DS.isFriendSpecified()) {
3693 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3694 << SourceRange(DS.getFriendSpecLoc());
3695 ConsumeBrace();
Alexey Bataev8fe24752013-11-18 08:17:37 +00003696 SkipUntil(tok::r_brace, StopAtSemi);
John McCall13489672012-05-07 06:16:58 +00003697 TUK = Sema::TUK_Friend;
3698 } else {
3699 TUK = Sema::TUK_Definition;
3700 }
Richard Smithc9f35172012-06-25 21:37:02 +00003701 } else if (DSC != DSC_type_specifier &&
3702 (Tok.is(tok::semi) ||
Richard Smith139be702012-07-02 19:14:01 +00003703 (Tok.isAtStartOfLine() &&
3704 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
Richard Smithc9f35172012-06-25 21:37:02 +00003705 TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3706 if (Tok.isNot(tok::semi)) {
3707 // A semicolon was missing after this declaration. Diagnose and recover.
3708 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3709 "enum");
3710 PP.EnterToken(Tok);
3711 Tok.setKind(tok::semi);
3712 }
John McCall13489672012-05-07 06:16:58 +00003713 } else {
John McCallf312b1e2010-08-26 23:41:50 +00003714 TUK = Sema::TUK_Reference;
John McCall13489672012-05-07 06:16:58 +00003715 }
3716
3717 // If this is an elaborated type specifier, and we delayed
3718 // diagnostics before, just merge them into the current pool.
3719 if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3720 diagsFromTag.redelay();
3721 }
Richard Smith1af83c42012-03-23 03:33:32 +00003722
3723 MultiTemplateParamsArg TParams;
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003724 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
John McCallf312b1e2010-08-26 23:41:50 +00003725 TUK != Sema::TUK_Reference) {
Richard Smith80ad52f2013-01-02 11:42:31 +00003726 if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {
Richard Smith1af83c42012-03-23 03:33:32 +00003727 // Skip the rest of this declarator, up until the comma or semicolon.
3728 Diag(Tok, diag::err_enum_template);
Alexey Bataev8fe24752013-11-18 08:17:37 +00003729 SkipUntil(tok::comma, StopAtSemi);
Richard Smith1af83c42012-03-23 03:33:32 +00003730 return;
3731 }
3732
3733 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3734 // Enumerations can't be explicitly instantiated.
3735 DS.SetTypeSpecError();
3736 Diag(StartLoc, diag::err_explicit_instantiation_enum);
3737 return;
3738 }
3739
3740 assert(TemplateInfo.TemplateParams && "no template parameters");
3741 TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3742 TemplateInfo.TemplateParams->size());
Douglas Gregor8fc6d232010-05-03 17:48:54 +00003743 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003744
Sean Hunt2edf0a22012-06-23 05:07:58 +00003745 if (TUK == Sema::TUK_Reference)
3746 ProhibitAttributes(attrs);
Richard Smith1af83c42012-03-23 03:33:32 +00003747
Douglas Gregorb9075602011-02-22 02:55:24 +00003748 if (!Name && TUK != Sema::TUK_Definition) {
3749 Diag(Tok, diag::err_enumerator_unnamed_no_def);
Richard Smith1af83c42012-03-23 03:33:32 +00003750
Douglas Gregorb9075602011-02-22 02:55:24 +00003751 // Skip the rest of this declarator, up until the comma or semicolon.
Alexey Bataev8fe24752013-11-18 08:17:37 +00003752 SkipUntil(tok::comma, StopAtSemi);
Douglas Gregorb9075602011-02-22 02:55:24 +00003753 return;
3754 }
Richard Smith1af83c42012-03-23 03:33:32 +00003755
Douglas Gregor402abb52009-05-28 23:31:59 +00003756 bool Owned = false;
John McCallc4e70192009-09-11 04:59:25 +00003757 bool IsDependent = false;
Douglas Gregor48c89f42010-04-24 16:38:41 +00003758 const char *PrevSpec = 0;
3759 unsigned DiagID;
John McCalld226f652010-08-21 09:40:31 +00003760 Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
John McCall7f040a92010-12-24 02:08:15 +00003761 StartLoc, SS, Name, NameLoc, attrs.getList(),
Richard Smith1af83c42012-03-23 03:33:32 +00003762 AS, DS.getModulePrivateSpecLoc(), TParams,
Richard Smithbdad7a22012-01-10 01:33:14 +00003763 Owned, IsDependent, ScopedEnumKWLoc,
Abramo Bagnaraa88cefd2010-12-03 18:54:17 +00003764 IsScopedUsingClassTag, BaseType);
Douglas Gregor1274ccd2010-10-08 23:50:27 +00003765
Douglas Gregor48c89f42010-04-24 16:38:41 +00003766 if (IsDependent) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003767 // This enum has a dependent nested-name-specifier. Handle it as a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003768 // dependent tag.
3769 if (!Name) {
3770 DS.SetTypeSpecError();
3771 Diag(Tok, diag::err_expected_type_name_after_typename);
3772 return;
3773 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003774
Douglas Gregor23c94db2010-07-02 17:43:08 +00003775 TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
Chad Rosier8decdee2012-06-26 22:30:43 +00003776 TUK, SS, Name, StartLoc,
Douglas Gregor48c89f42010-04-24 16:38:41 +00003777 NameLoc);
3778 if (Type.isInvalid()) {
3779 DS.SetTypeSpecError();
3780 return;
3781 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003782
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003783 if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3784 NameLoc.isValid() ? NameLoc : StartLoc,
3785 PrevSpec, DiagID, Type.get()))
Douglas Gregor48c89f42010-04-24 16:38:41 +00003786 Diag(StartLoc, DiagID) << PrevSpec;
Chad Rosier8decdee2012-06-26 22:30:43 +00003787
Douglas Gregor48c89f42010-04-24 16:38:41 +00003788 return;
3789 }
Mike Stump1eb44332009-09-09 15:08:12 +00003790
John McCalld226f652010-08-21 09:40:31 +00003791 if (!TagDecl) {
Chad Rosier8decdee2012-06-26 22:30:43 +00003792 // The action failed to produce an enumeration tag. If this is a
Douglas Gregor48c89f42010-04-24 16:38:41 +00003793 // definition, consume the entire definition.
Richard Smith7796eb52012-03-12 08:56:40 +00003794 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
Douglas Gregor48c89f42010-04-24 16:38:41 +00003795 ConsumeBrace();
Alexey Bataev8fe24752013-11-18 08:17:37 +00003796 SkipUntil(tok::r_brace, StopAtSemi);
Douglas Gregor48c89f42010-04-24 16:38:41 +00003797 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003798
Douglas Gregor48c89f42010-04-24 16:38:41 +00003799 DS.SetTypeSpecError();
3800 return;
3801 }
Richard Smithbdad7a22012-01-10 01:33:14 +00003802
Richard Smithc9f35172012-06-25 21:37:02 +00003803 if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
John McCall13489672012-05-07 06:16:58 +00003804 ParseEnumBody(StartLoc, TagDecl);
Mike Stump1eb44332009-09-09 15:08:12 +00003805
Abramo Bagnara0daaf322011-03-16 20:16:18 +00003806 if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3807 NameLoc.isValid() ? NameLoc : StartLoc,
3808 PrevSpec, DiagID, TagDecl, Owned))
John McCallfec54012009-08-03 20:12:06 +00003809 Diag(StartLoc, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00003810}
3811
3812/// ParseEnumBody - Parse a {} enclosed enumerator-list.
3813/// enumerator-list:
3814/// enumerator
3815/// enumerator-list ',' enumerator
3816/// enumerator:
3817/// enumeration-constant
3818/// enumeration-constant '=' constant-expression
3819/// enumeration-constant:
3820/// identifier
3821///
John McCalld226f652010-08-21 09:40:31 +00003822void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
Douglas Gregor074149e2009-01-05 19:45:36 +00003823 // Enter the scope of the enum body and start the definition.
3824 ParseScope EnumScope(this, Scope::DeclScope);
Douglas Gregor23c94db2010-07-02 17:43:08 +00003825 Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
Douglas Gregor074149e2009-01-05 19:45:36 +00003826
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003827 BalancedDelimiterTracker T(*this, tok::l_brace);
3828 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00003829
Chris Lattner7946dd32007-08-27 17:24:30 +00003830 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
David Blaikie4e4d0842012-03-11 07:00:24 +00003831 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
Fariborz Jahanian05115522010-05-28 22:23:22 +00003832 Diag(Tok, diag::error_empty_enum);
Mike Stump1eb44332009-09-09 15:08:12 +00003833
Chris Lattner5f9e2722011-07-23 10:55:15 +00003834 SmallVector<Decl *, 32> EnumConstantDecls;
Reid Spencer5f016e22007-07-11 17:01:13 +00003835
John McCalld226f652010-08-21 09:40:31 +00003836 Decl *LastEnumConstDecl = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00003837
Reid Spencer5f016e22007-07-11 17:01:13 +00003838 // Parse the enumerator-list.
Chris Lattner04d66662007-10-09 17:33:22 +00003839 while (Tok.is(tok::identifier)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003840 IdentifierInfo *Ident = Tok.getIdentifierInfo();
3841 SourceLocation IdentLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003842
John McCall5b629aa2010-10-22 23:36:17 +00003843 // If attributes exist after the enumerator, parse them.
Sean Hunt2edf0a22012-06-23 05:07:58 +00003844 ParsedAttributesWithRange attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003845 MaybeParseGNUAttributes(attrs);
Richard Smith4e24f0f2013-01-02 12:01:23 +00003846 MaybeParseCXX11Attributes(attrs);
Sean Hunt2edf0a22012-06-23 05:07:58 +00003847 ProhibitAttributes(attrs);
John McCall5b629aa2010-10-22 23:36:17 +00003848
Reid Spencer5f016e22007-07-11 17:01:13 +00003849 SourceLocation EqualLoc;
John McCall60d7b3a2010-08-24 06:29:42 +00003850 ExprResult AssignedVal;
John McCall92576642012-05-07 06:16:41 +00003851 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
Chad Rosier8decdee2012-06-26 22:30:43 +00003852
Chris Lattner04d66662007-10-09 17:33:22 +00003853 if (Tok.is(tok::equal)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00003854 EqualLoc = ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00003855 AssignedVal = ParseConstantExpression();
3856 if (AssignedVal.isInvalid())
Alexey Bataev8fe24752013-11-18 08:17:37 +00003857 SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
Reid Spencer5f016e22007-07-11 17:01:13 +00003858 }
Mike Stump1eb44332009-09-09 15:08:12 +00003859
Reid Spencer5f016e22007-07-11 17:01:13 +00003860 // Install the enumerator constant into EnumDecl.
John McCalld226f652010-08-21 09:40:31 +00003861 Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3862 LastEnumConstDecl,
3863 IdentLoc, Ident,
John McCall7f040a92010-12-24 02:08:15 +00003864 attrs.getList(), EqualLoc,
John McCalld226f652010-08-21 09:40:31 +00003865 AssignedVal.release());
Fariborz Jahanian5a477db2011-12-09 01:15:54 +00003866 PD.complete(EnumConstDecl);
Chad Rosier8decdee2012-06-26 22:30:43 +00003867
Reid Spencer5f016e22007-07-11 17:01:13 +00003868 EnumConstantDecls.push_back(EnumConstDecl);
3869 LastEnumConstDecl = EnumConstDecl;
Mike Stump1eb44332009-09-09 15:08:12 +00003870
Douglas Gregor751f6922010-09-07 14:51:08 +00003871 if (Tok.is(tok::identifier)) {
3872 // We're missing a comma between enumerators.
3873 SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
Chad Rosier8decdee2012-06-26 22:30:43 +00003874 Diag(Loc, diag::err_enumerator_list_missing_comma)
Douglas Gregor751f6922010-09-07 14:51:08 +00003875 << FixItHint::CreateInsertion(Loc, ", ");
3876 continue;
3877 }
Chad Rosier8decdee2012-06-26 22:30:43 +00003878
Chris Lattner04d66662007-10-09 17:33:22 +00003879 if (Tok.isNot(tok::comma))
Reid Spencer5f016e22007-07-11 17:01:13 +00003880 break;
3881 SourceLocation CommaLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00003882
Richard Smith7fe62082011-10-15 05:09:34 +00003883 if (Tok.isNot(tok::identifier)) {
Richard Smith80ad52f2013-01-02 11:42:31 +00003884 if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)
Richard Smitheab9d6f2012-07-23 05:45:25 +00003885 Diag(CommaLoc, getLangOpts().CPlusPlus ?
3886 diag::ext_enumerator_list_comma_cxx :
3887 diag::ext_enumerator_list_comma_c)
Richard Smith7fe62082011-10-15 05:09:34 +00003888 << FixItHint::CreateRemoval(CommaLoc);
Richard Smith80ad52f2013-01-02 11:42:31 +00003889 else if (getLangOpts().CPlusPlus11)
Richard Smith7fe62082011-10-15 05:09:34 +00003890 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3891 << FixItHint::CreateRemoval(CommaLoc);
3892 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003893 }
Mike Stump1eb44332009-09-09 15:08:12 +00003894
Reid Spencer5f016e22007-07-11 17:01:13 +00003895 // Eat the }.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003896 T.consumeClose();
Reid Spencer5f016e22007-07-11 17:01:13 +00003897
Reid Spencer5f016e22007-07-11 17:01:13 +00003898 // If attributes exist after the identifier list, parse them.
John McCall0b7e6782011-03-24 11:26:52 +00003899 ParsedAttributes attrs(AttrFactory);
John McCall7f040a92010-12-24 02:08:15 +00003900 MaybeParseGNUAttributes(attrs);
Douglas Gregor72de6672009-01-08 20:45:30 +00003901
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003902 Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
Dmitri Gribenko9ff2b422013-04-27 20:23:52 +00003903 EnumDecl, EnumConstantDecls,
3904 getCurScope(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003905 attrs.getList());
Mike Stump1eb44332009-09-09 15:08:12 +00003906
Douglas Gregor72de6672009-01-08 20:45:30 +00003907 EnumScope.Exit();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00003908 Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3909 T.getCloseLocation());
Richard Smithc9f35172012-06-25 21:37:02 +00003910
3911 // The next token must be valid after an enum definition. If not, a ';'
3912 // was probably forgotten.
Richard Smith139be702012-07-02 19:14:01 +00003913 bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3914 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
Richard Smithc9f35172012-06-25 21:37:02 +00003915 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3916 // Push this token back into the preprocessor and change our current token
3917 // to ';' so that the rest of the code recovers as though there were an
3918 // ';' after the definition.
3919 PP.EnterToken(Tok);
3920 Tok.setKind(tok::semi);
3921 }
Reid Spencer5f016e22007-07-11 17:01:13 +00003922}
3923
3924/// isTypeSpecifierQualifier - Return true if the current token could be the
Steve Naroff5f8aa692008-02-11 23:15:56 +00003925/// start of a type-qualifier-list.
3926bool Parser::isTypeQualifier() const {
3927 switch (Tok.getKind()) {
3928 default: return false;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003929
3930 // type-qualifier only in OpenCL
3931 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00003932 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003933
Steve Naroff5f8aa692008-02-11 23:15:56 +00003934 // type-qualifier
3935 case tok::kw_const:
3936 case tok::kw_volatile:
3937 case tok::kw_restrict:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00003938 case tok::kw___private:
3939 case tok::kw___local:
3940 case tok::kw___global:
3941 case tok::kw___constant:
3942 case tok::kw___read_only:
3943 case tok::kw___read_write:
3944 case tok::kw___write_only:
Steve Naroff5f8aa692008-02-11 23:15:56 +00003945 return true;
3946 }
3947}
3948
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003949/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3950/// is definitely a type-specifier. Return false if it isn't part of a type
3951/// specifier or if we're not sure.
3952bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3953 switch (Tok.getKind()) {
3954 default: return false;
3955 // type-specifiers
3956 case tok::kw_short:
3957 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00003958 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00003959 case tok::kw___int128:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003960 case tok::kw_signed:
3961 case tok::kw_unsigned:
3962 case tok::kw__Complex:
3963 case tok::kw__Imaginary:
3964 case tok::kw_void:
3965 case tok::kw_char:
3966 case tok::kw_wchar_t:
3967 case tok::kw_char16_t:
3968 case tok::kw_char32_t:
3969 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00003970 case tok::kw_half:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003971 case tok::kw_float:
3972 case tok::kw_double:
3973 case tok::kw_bool:
3974 case tok::kw__Bool:
3975 case tok::kw__Decimal32:
3976 case tok::kw__Decimal64:
3977 case tok::kw__Decimal128:
3978 case tok::kw___vector:
Chad Rosier8decdee2012-06-26 22:30:43 +00003979
Guy Benyeib13621d2012-12-18 14:38:23 +00003980 // OpenCL specific types:
3981 case tok::kw_image1d_t:
3982 case tok::kw_image1d_array_t:
3983 case tok::kw_image1d_buffer_t:
3984 case tok::kw_image2d_t:
3985 case tok::kw_image2d_array_t:
3986 case tok::kw_image3d_t:
Guy Benyei21f18c42013-02-07 10:55:47 +00003987 case tok::kw_sampler_t:
Guy Benyeie6b9d802013-01-20 12:31:11 +00003988 case tok::kw_event_t:
Guy Benyeib13621d2012-12-18 14:38:23 +00003989
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003990 // struct-or-union-specifier (C99) or class-specifier (C++)
3991 case tok::kw_class:
3992 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00003993 case tok::kw___interface:
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003994 case tok::kw_union:
3995 // enum-specifier
3996 case tok::kw_enum:
Chad Rosier8decdee2012-06-26 22:30:43 +00003997
Chris Lattnerb3a4e432010-02-28 18:18:36 +00003998 // typedef-name
3999 case tok::annot_typename:
4000 return true;
4001 }
4002}
4003
Steve Naroff5f8aa692008-02-11 23:15:56 +00004004/// isTypeSpecifierQualifier - Return true if the current token could be the
Reid Spencer5f016e22007-07-11 17:01:13 +00004005/// start of a specifier-qualifier-list.
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004006bool Parser::isTypeSpecifierQualifier() {
Reid Spencer5f016e22007-07-11 17:01:13 +00004007 switch (Tok.getKind()) {
4008 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00004009
Chris Lattner166a8fc2009-01-04 23:41:41 +00004010 case tok::identifier: // foo::bar
John Thompson82287d12010-02-05 00:12:22 +00004011 if (TryAltiVecVectorToken())
4012 return true;
4013 // Fall through.
Douglas Gregord57959a2009-03-27 23:10:48 +00004014 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00004015 // Annotate typenames and C++ scope specifiers. If we get one, just
4016 // recurse to handle whatever we get.
4017 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004018 return true;
4019 if (Tok.is(tok::identifier))
4020 return false;
4021 return isTypeSpecifierQualifier();
Douglas Gregord57959a2009-03-27 23:10:48 +00004022
Chris Lattner166a8fc2009-01-04 23:41:41 +00004023 case tok::coloncolon: // ::foo::bar
4024 if (NextToken().is(tok::kw_new) || // ::new
4025 NextToken().is(tok::kw_delete)) // ::delete
4026 return false;
4027
Chris Lattner166a8fc2009-01-04 23:41:41 +00004028 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004029 return true;
4030 return isTypeSpecifierQualifier();
Mike Stump1eb44332009-09-09 15:08:12 +00004031
Reid Spencer5f016e22007-07-11 17:01:13 +00004032 // GNU attributes support.
4033 case tok::kw___attribute:
Steve Naroffd1861fd2007-07-31 12:34:36 +00004034 // GNU typeof support.
4035 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00004036
Reid Spencer5f016e22007-07-11 17:01:13 +00004037 // type-specifiers
4038 case tok::kw_short:
4039 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00004040 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00004041 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00004042 case tok::kw_signed:
4043 case tok::kw_unsigned:
4044 case tok::kw__Complex:
4045 case tok::kw__Imaginary:
4046 case tok::kw_void:
4047 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00004048 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00004049 case tok::kw_char16_t:
4050 case tok::kw_char32_t:
Reid Spencer5f016e22007-07-11 17:01:13 +00004051 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00004052 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00004053 case tok::kw_float:
4054 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00004055 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00004056 case tok::kw__Bool:
4057 case tok::kw__Decimal32:
4058 case tok::kw__Decimal64:
4059 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00004060 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00004061
Guy Benyeib13621d2012-12-18 14:38:23 +00004062 // OpenCL specific types:
4063 case tok::kw_image1d_t:
4064 case tok::kw_image1d_array_t:
4065 case tok::kw_image1d_buffer_t:
4066 case tok::kw_image2d_t:
4067 case tok::kw_image2d_array_t:
4068 case tok::kw_image3d_t:
Guy Benyei21f18c42013-02-07 10:55:47 +00004069 case tok::kw_sampler_t:
Guy Benyeie6b9d802013-01-20 12:31:11 +00004070 case tok::kw_event_t:
Guy Benyeib13621d2012-12-18 14:38:23 +00004071
Chris Lattner99dc9142008-04-13 18:59:07 +00004072 // struct-or-union-specifier (C99) or class-specifier (C++)
4073 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00004074 case tok::kw_struct:
Joao Matos6666ed42012-08-31 18:45:21 +00004075 case tok::kw___interface:
Reid Spencer5f016e22007-07-11 17:01:13 +00004076 case tok::kw_union:
4077 // enum-specifier
4078 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00004079
Reid Spencer5f016e22007-07-11 17:01:13 +00004080 // type-qualifier
4081 case tok::kw_const:
4082 case tok::kw_volatile:
4083 case tok::kw_restrict:
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004084
John McCallb8a8de32012-11-14 00:49:39 +00004085 // Debugger support.
4086 case tok::kw___unknown_anytype:
4087
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004088 // typedef-name
Chris Lattnerb31757b2009-01-06 05:06:21 +00004089 case tok::annot_typename:
Reid Spencer5f016e22007-07-11 17:01:13 +00004090 return true;
Mike Stump1eb44332009-09-09 15:08:12 +00004091
Chris Lattner7c186be2008-10-20 00:25:30 +00004092 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4093 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00004094 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00004095
Steve Naroff239f0732008-12-25 14:16:32 +00004096 case tok::kw___cdecl:
4097 case tok::kw___stdcall:
4098 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004099 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00004100 case tok::kw___w64:
4101 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00004102 case tok::kw___ptr32:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004103 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004104 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004105
4106 case tok::kw___private:
4107 case tok::kw___local:
4108 case tok::kw___global:
4109 case tok::kw___constant:
4110 case tok::kw___read_only:
4111 case tok::kw___read_write:
4112 case tok::kw___write_only:
4113
Eli Friedman290eeb02009-06-08 23:27:34 +00004114 return true;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004115
4116 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00004117 return getLangOpts().OpenCL;
Eli Friedmanb001de72011-10-06 23:00:33 +00004118
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004119 // C11 _Atomic
Eli Friedmanb001de72011-10-06 23:00:33 +00004120 case tok::kw__Atomic:
4121 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00004122 }
4123}
4124
4125/// isDeclarationSpecifier() - Return true if the current token is part of a
4126/// declaration specifier.
Douglas Gregor9497a732010-09-16 01:51:54 +00004127///
4128/// \param DisambiguatingWithExpression True to indicate that the purpose of
4129/// this check is to disambiguate between an expression and a declaration.
4130bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004131 switch (Tok.getKind()) {
4132 default: return false;
Mike Stump1eb44332009-09-09 15:08:12 +00004133
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004134 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00004135 return getLangOpts().OpenCL;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004136
Chris Lattner166a8fc2009-01-04 23:41:41 +00004137 case tok::identifier: // foo::bar
Steve Naroff61f72cb2009-03-09 21:12:44 +00004138 // Unfortunate hack to support "Class.factoryMethod" notation.
David Blaikie4e4d0842012-03-11 07:00:24 +00004139 if (getLangOpts().ObjC1 && NextToken().is(tok::period))
Steve Naroff61f72cb2009-03-09 21:12:44 +00004140 return false;
John Thompson82287d12010-02-05 00:12:22 +00004141 if (TryAltiVecVectorToken())
4142 return true;
4143 // Fall through.
David Blaikie42d6d0c2011-12-04 05:04:18 +00004144 case tok::kw_decltype: // decltype(T())::type
Douglas Gregord57959a2009-03-27 23:10:48 +00004145 case tok::kw_typename: // typename T::type
Chris Lattner166a8fc2009-01-04 23:41:41 +00004146 // Annotate typenames and C++ scope specifiers. If we get one, just
4147 // recurse to handle whatever we get.
4148 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004149 return true;
4150 if (Tok.is(tok::identifier))
4151 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00004152
Douglas Gregor9497a732010-09-16 01:51:54 +00004153 // If we're in Objective-C and we have an Objective-C class type followed
Chad Rosier8decdee2012-06-26 22:30:43 +00004154 // by an identifier and then either ':' or ']', in a place where an
Douglas Gregor9497a732010-09-16 01:51:54 +00004155 // expression is permitted, then this is probably a class message send
4156 // missing the initial '['. In this case, we won't consider this to be
4157 // the start of a declaration.
Chad Rosier8decdee2012-06-26 22:30:43 +00004158 if (DisambiguatingWithExpression &&
Douglas Gregor9497a732010-09-16 01:51:54 +00004159 isStartOfObjCClassMessageMissingOpenBracket())
4160 return false;
Chad Rosier8decdee2012-06-26 22:30:43 +00004161
John McCall9ba61662010-02-26 08:45:28 +00004162 return isDeclarationSpecifier();
4163
Chris Lattner166a8fc2009-01-04 23:41:41 +00004164 case tok::coloncolon: // ::foo::bar
4165 if (NextToken().is(tok::kw_new) || // ::new
4166 NextToken().is(tok::kw_delete)) // ::delete
4167 return false;
Mike Stump1eb44332009-09-09 15:08:12 +00004168
Chris Lattner166a8fc2009-01-04 23:41:41 +00004169 // Annotate typenames and C++ scope specifiers. If we get one, just
4170 // recurse to handle whatever we get.
4171 if (TryAnnotateTypeOrScopeToken())
John McCall9ba61662010-02-26 08:45:28 +00004172 return true;
4173 return isDeclarationSpecifier();
Mike Stump1eb44332009-09-09 15:08:12 +00004174
Reid Spencer5f016e22007-07-11 17:01:13 +00004175 // storage-class-specifier
4176 case tok::kw_typedef:
4177 case tok::kw_extern:
Steve Naroff8d54bf22007-12-18 00:16:02 +00004178 case tok::kw___private_extern__:
Reid Spencer5f016e22007-07-11 17:01:13 +00004179 case tok::kw_static:
4180 case tok::kw_auto:
4181 case tok::kw_register:
4182 case tok::kw___thread:
Richard Smithec642442013-04-12 22:46:28 +00004183 case tok::kw_thread_local:
4184 case tok::kw__Thread_local:
Mike Stump1eb44332009-09-09 15:08:12 +00004185
Douglas Gregor8d267c52011-09-09 02:06:17 +00004186 // Modules
4187 case tok::kw___module_private__:
Chad Rosier8decdee2012-06-26 22:30:43 +00004188
John McCallb8a8de32012-11-14 00:49:39 +00004189 // Debugger support
4190 case tok::kw___unknown_anytype:
4191
Reid Spencer5f016e22007-07-11 17:01:13 +00004192 // type-specifiers
4193 case tok::kw_short:
4194 case tok::kw_long:
Francois Pichet338d7f72011-04-28 01:59:37 +00004195 case tok::kw___int64:
Richard Smith5a5a9712012-04-04 06:24:32 +00004196 case tok::kw___int128:
Reid Spencer5f016e22007-07-11 17:01:13 +00004197 case tok::kw_signed:
4198 case tok::kw_unsigned:
4199 case tok::kw__Complex:
4200 case tok::kw__Imaginary:
4201 case tok::kw_void:
4202 case tok::kw_char:
Argyrios Kyrtzidis64c438a2008-08-09 16:51:54 +00004203 case tok::kw_wchar_t:
Alisdair Meredithf5c209d2009-07-14 06:30:34 +00004204 case tok::kw_char16_t:
4205 case tok::kw_char32_t:
4206
Reid Spencer5f016e22007-07-11 17:01:13 +00004207 case tok::kw_int:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +00004208 case tok::kw_half:
Reid Spencer5f016e22007-07-11 17:01:13 +00004209 case tok::kw_float:
4210 case tok::kw_double:
Chris Lattner9298d962007-11-15 05:25:19 +00004211 case tok::kw_bool:
Reid Spencer5f016e22007-07-11 17:01:13 +00004212 case tok::kw__Bool:
4213 case tok::kw__Decimal32:
4214 case tok::kw__Decimal64:
4215 case tok::kw__Decimal128:
John Thompson82287d12010-02-05 00:12:22 +00004216 case tok::kw___vector:
Mike Stump1eb44332009-09-09 15:08:12 +00004217
Guy Benyeib13621d2012-12-18 14:38:23 +00004218 // OpenCL specific types:
4219 case tok::kw_image1d_t:
4220 case tok::kw_image1d_array_t:
4221 case tok::kw_image1d_buffer_t:
4222 case tok::kw_image2d_t:
4223 case tok::kw_image2d_array_t:
4224 case tok::kw_image3d_t:
Guy Benyei21f18c42013-02-07 10:55:47 +00004225 case tok::kw_sampler_t:
Guy Benyeie6b9d802013-01-20 12:31:11 +00004226 case tok::kw_event_t:
Guy Benyeib13621d2012-12-18 14:38:23 +00004227
Chris Lattner99dc9142008-04-13 18:59:07 +00004228 // struct-or-union-specifier (C99) or class-specifier (C++)
4229 case tok::kw_class:
Reid Spencer5f016e22007-07-11 17:01:13 +00004230 case tok::kw_struct:
4231 case tok::kw_union:
Joao Matos6666ed42012-08-31 18:45:21 +00004232 case tok::kw___interface:
Reid Spencer5f016e22007-07-11 17:01:13 +00004233 // enum-specifier
4234 case tok::kw_enum:
Mike Stump1eb44332009-09-09 15:08:12 +00004235
Reid Spencer5f016e22007-07-11 17:01:13 +00004236 // type-qualifier
4237 case tok::kw_const:
4238 case tok::kw_volatile:
4239 case tok::kw_restrict:
Steve Naroffd1861fd2007-07-31 12:34:36 +00004240
Reid Spencer5f016e22007-07-11 17:01:13 +00004241 // function-specifier
4242 case tok::kw_inline:
Douglas Gregorb48fe382008-10-31 09:07:45 +00004243 case tok::kw_virtual:
4244 case tok::kw_explicit:
Richard Smithde03c152013-01-17 22:16:11 +00004245 case tok::kw__Noreturn:
Chris Lattnerd6c7c182007-08-09 16:40:21 +00004246
Richard Smith4cd81c52013-01-29 09:02:09 +00004247 // alignment-specifier
4248 case tok::kw__Alignas:
4249
Richard Smith53aec2a2012-10-25 00:00:53 +00004250 // friend keyword.
4251 case tok::kw_friend:
4252
Peter Collingbournec6eb44b2011-04-15 00:35:57 +00004253 // static_assert-declaration
4254 case tok::kw__Static_assert:
4255
Chris Lattner1ef08762007-08-09 17:01:07 +00004256 // GNU typeof support.
4257 case tok::kw_typeof:
Mike Stump1eb44332009-09-09 15:08:12 +00004258
Chris Lattner1ef08762007-08-09 17:01:07 +00004259 // GNU attributes.
Chris Lattnerd6c7c182007-08-09 16:40:21 +00004260 case tok::kw___attribute:
Mike Stump1eb44332009-09-09 15:08:12 +00004261
Richard Smith53aec2a2012-10-25 00:00:53 +00004262 // C++11 decltype and constexpr.
David Blaikie42d6d0c2011-12-04 05:04:18 +00004263 case tok::annot_decltype:
Richard Smith53aec2a2012-10-25 00:00:53 +00004264 case tok::kw_constexpr:
Francois Pichete3d49b42011-06-19 08:02:06 +00004265
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004266 // C11 _Atomic
Eli Friedmanb001de72011-10-06 23:00:33 +00004267 case tok::kw__Atomic:
4268 return true;
4269
Chris Lattnerf3948c42008-07-26 03:38:44 +00004270 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4271 case tok::less:
David Blaikie4e4d0842012-03-11 07:00:24 +00004272 return getLangOpts().ObjC1;
Mike Stump1eb44332009-09-09 15:08:12 +00004273
Douglas Gregord9d75e52011-04-27 05:41:15 +00004274 // typedef-name
4275 case tok::annot_typename:
4276 return !DisambiguatingWithExpression ||
4277 !isStartOfObjCClassMessageMissingOpenBracket();
Chad Rosier8decdee2012-06-26 22:30:43 +00004278
Steve Naroff47f52092009-01-06 19:34:12 +00004279 case tok::kw___declspec:
Steve Naroff239f0732008-12-25 14:16:32 +00004280 case tok::kw___cdecl:
4281 case tok::kw___stdcall:
4282 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004283 case tok::kw___thiscall:
Eli Friedman290eeb02009-06-08 23:27:34 +00004284 case tok::kw___w64:
Aaron Ballmanaa9df092013-05-22 23:25:32 +00004285 case tok::kw___sptr:
4286 case tok::kw___uptr:
Eli Friedman290eeb02009-06-08 23:27:34 +00004287 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00004288 case tok::kw___ptr32:
Eli Friedman290eeb02009-06-08 23:27:34 +00004289 case tok::kw___forceinline:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004290 case tok::kw___pascal:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004291 case tok::kw___unaligned:
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004292
4293 case tok::kw___private:
4294 case tok::kw___local:
4295 case tok::kw___global:
4296 case tok::kw___constant:
4297 case tok::kw___read_only:
4298 case tok::kw___read_write:
4299 case tok::kw___write_only:
4300
Eli Friedman290eeb02009-06-08 23:27:34 +00004301 return true;
Reid Spencer5f016e22007-07-11 17:01:13 +00004302 }
4303}
4304
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004305bool Parser::isConstructorDeclarator() {
4306 TentativeParsingAction TPA(*this);
4307
4308 // Parse the C++ scope specifier.
4309 CXXScopeSpec SS;
Chad Rosier8decdee2012-06-26 22:30:43 +00004310 if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004311 /*EnteringContext=*/true)) {
John McCall9ba61662010-02-26 08:45:28 +00004312 TPA.Revert();
4313 return false;
4314 }
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004315
4316 // Parse the constructor name.
4317 if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
4318 // We already know that we have a constructor name; just consume
4319 // the token.
4320 ConsumeToken();
4321 } else {
4322 TPA.Revert();
4323 return false;
4324 }
4325
Richard Smith22592862012-03-27 23:05:05 +00004326 // Current class name must be followed by a left parenthesis.
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004327 if (Tok.isNot(tok::l_paren)) {
4328 TPA.Revert();
4329 return false;
4330 }
4331 ConsumeParen();
4332
Richard Smith22592862012-03-27 23:05:05 +00004333 // A right parenthesis, or ellipsis followed by a right parenthesis signals
4334 // that we have a constructor.
4335 if (Tok.is(tok::r_paren) ||
4336 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004337 TPA.Revert();
4338 return true;
4339 }
4340
Richard Smith9ec28912013-09-06 00:12:20 +00004341 // A C++11 attribute here signals that we have a constructor, and is an
4342 // attribute on the first constructor parameter.
4343 if (getLangOpts().CPlusPlus11 &&
4344 isCXX11AttributeSpecifier(/*Disambiguate*/ false,
4345 /*OuterMightBeMessageSend*/ true)) {
4346 TPA.Revert();
4347 return true;
4348 }
4349
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004350 // If we need to, enter the specified scope.
4351 DeclaratorScopeObj DeclScopeObj(*this, SS);
Douglas Gregor23c94db2010-07-02 17:43:08 +00004352 if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004353 DeclScopeObj.EnterDeclaratorScope();
4354
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00004355 // Optionally skip Microsoft attributes.
John McCall0b7e6782011-03-24 11:26:52 +00004356 ParsedAttributes Attrs(AttrFactory);
Francois Pichetdfaa5fb2011-01-31 04:54:32 +00004357 MaybeParseMicrosoftAttributes(Attrs);
4358
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004359 // Check whether the next token(s) are part of a declaration
4360 // specifier, in which case we have the start of a parameter and,
4361 // therefore, we know that this is a constructor.
Richard Smith412e0cc2012-03-27 00:56:56 +00004362 bool IsConstructor = false;
4363 if (isDeclarationSpecifier())
4364 IsConstructor = true;
4365 else if (Tok.is(tok::identifier) ||
4366 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
4367 // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
4368 // This might be a parenthesized member name, but is more likely to
4369 // be a constructor declaration with an invalid argument type. Keep
4370 // looking.
4371 if (Tok.is(tok::annot_cxxscope))
4372 ConsumeToken();
4373 ConsumeToken();
4374
4375 // If this is not a constructor, we must be parsing a declarator,
Richard Smith5d8388c2012-03-27 01:42:32 +00004376 // which must have one of the following syntactic forms (see the
4377 // grammar extract at the start of ParseDirectDeclarator):
Richard Smith412e0cc2012-03-27 00:56:56 +00004378 switch (Tok.getKind()) {
4379 case tok::l_paren:
4380 // C(X ( int));
4381 case tok::l_square:
4382 // C(X [ 5]);
4383 // C(X [ [attribute]]);
4384 case tok::coloncolon:
4385 // C(X :: Y);
4386 // C(X :: *p);
4387 case tok::r_paren:
4388 // C(X )
4389 // Assume this isn't a constructor, rather than assuming it's a
4390 // constructor with an unnamed parameter of an ill-formed type.
4391 break;
4392
4393 default:
4394 IsConstructor = true;
4395 break;
4396 }
4397 }
4398
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004399 TPA.Revert();
4400 return IsConstructor;
4401}
Reid Spencer5f016e22007-07-11 17:01:13 +00004402
4403/// ParseTypeQualifierListOpt
Dawn Perchik52fc3142010-09-03 01:29:35 +00004404/// type-qualifier-list: [C99 6.7.5]
4405/// type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00004406/// [vendor] attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00004407/// [ only if VendorAttributesAllowed=true ]
4408/// type-qualifier-list type-qualifier
Chad Rosier8decdee2012-06-26 22:30:43 +00004409/// [vendor] type-qualifier-list attributes
Dawn Perchik52fc3142010-09-03 01:29:35 +00004410/// [ only if VendorAttributesAllowed=true ]
4411/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq
Richard Smith4e24f0f2013-01-02 12:01:23 +00004412/// [ only if CXX11AttributesAllowed=true ]
Dawn Perchik52fc3142010-09-03 01:29:35 +00004413/// Note: vendor can be GNU, MS, etc.
Reid Spencer5f016e22007-07-11 17:01:13 +00004414///
Dawn Perchik52fc3142010-09-03 01:29:35 +00004415void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
4416 bool VendorAttributesAllowed,
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004417 bool CXX11AttributesAllowed,
Bill Wendling7f3ec662013-11-26 04:10:07 +00004418 bool AtomicAllowed,
4419 bool IdentifierRequired) {
Richard Smith80ad52f2013-01-02 11:42:31 +00004420 if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed &&
Richard Smith6ee326a2012-04-10 01:32:12 +00004421 isCXX11AttributeSpecifier()) {
John McCall0b7e6782011-03-24 11:26:52 +00004422 ParsedAttributesWithRange attrs(AttrFactory);
Richard Smithc56298d2012-04-10 03:25:07 +00004423 ParseCXX11Attributes(attrs);
Richard Smith6ee326a2012-04-10 01:32:12 +00004424 DS.takeAttributesFrom(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00004425 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00004426
4427 SourceLocation EndLoc;
4428
Reid Spencer5f016e22007-07-11 17:01:13 +00004429 while (1) {
John McCallfec54012009-08-03 20:12:06 +00004430 bool isInvalid = false;
Reid Spencer5f016e22007-07-11 17:01:13 +00004431 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00004432 unsigned DiagID = 0;
Reid Spencer5f016e22007-07-11 17:01:13 +00004433 SourceLocation Loc = Tok.getLocation();
4434
4435 switch (Tok.getKind()) {
Douglas Gregor1a480c42010-08-27 17:35:51 +00004436 case tok::code_completion:
4437 Actions.CodeCompleteTypeQualifiers(DS);
Argyrios Kyrtzidis7d100872011-09-04 03:32:15 +00004438 return cutOffParsing();
Chad Rosier8decdee2012-06-26 22:30:43 +00004439
Reid Spencer5f016e22007-07-11 17:01:13 +00004440 case tok::kw_const:
John McCallfec54012009-08-03 20:12:06 +00004441 isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00004442 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00004443 break;
4444 case tok::kw_volatile:
John McCallfec54012009-08-03 20:12:06 +00004445 isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00004446 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00004447 break;
4448 case tok::kw_restrict:
John McCallfec54012009-08-03 20:12:06 +00004449 isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
Richard Smithd654f2d2012-10-17 23:31:46 +00004450 getLangOpts());
Reid Spencer5f016e22007-07-11 17:01:13 +00004451 break;
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004452 case tok::kw__Atomic:
4453 if (!AtomicAllowed)
4454 goto DoneWithTypeQuals;
4455 isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
4456 getLangOpts());
4457 break;
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004458
4459 // OpenCL qualifiers:
Chad Rosier8decdee2012-06-26 22:30:43 +00004460 case tok::kw_private:
David Blaikie4e4d0842012-03-11 07:00:24 +00004461 if (!getLangOpts().OpenCL)
Peter Collingbourne207f4d82011-03-18 22:38:29 +00004462 goto DoneWithTypeQuals;
4463 case tok::kw___private:
4464 case tok::kw___global:
4465 case tok::kw___local:
4466 case tok::kw___constant:
4467 case tok::kw___read_only:
4468 case tok::kw___write_only:
4469 case tok::kw___read_write:
4470 ParseOpenCLQualifiers(DS);
4471 break;
4472
Aaron Ballmanaa9df092013-05-22 23:25:32 +00004473 case tok::kw___uptr:
Bill Wendling7f3ec662013-11-26 04:10:07 +00004474 // GNU libc headers in C mode use '__uptr' as an identifer which conflicts
4475 // with the MS modifier keyword.
4476 if (VendorAttributesAllowed && !getLangOpts().CPlusPlus &&
4477 IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi) &&
4478 PP.getSourceManager().isInSystemHeader(Loc)) {
4479 Tok.setKind(tok::identifier);
4480 continue;
4481 }
4482 case tok::kw___sptr:
Eli Friedman290eeb02009-06-08 23:27:34 +00004483 case tok::kw___w64:
Steve Naroff86bc6cf2008-12-25 14:41:26 +00004484 case tok::kw___ptr64:
Francois Pichet58fd97a2011-08-25 00:36:46 +00004485 case tok::kw___ptr32:
Steve Naroff239f0732008-12-25 14:16:32 +00004486 case tok::kw___cdecl:
4487 case tok::kw___stdcall:
4488 case tok::kw___fastcall:
Douglas Gregorf813a2c2010-05-18 16:57:00 +00004489 case tok::kw___thiscall:
Francois Pichet3bd9aa42011-08-18 09:59:55 +00004490 case tok::kw___unaligned:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004491 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00004492 ParseMicrosoftTypeAttributes(DS.getAttributes());
Eli Friedman290eeb02009-06-08 23:27:34 +00004493 continue;
4494 }
4495 goto DoneWithTypeQuals;
Dawn Perchik52fc3142010-09-03 01:29:35 +00004496 case tok::kw___pascal:
4497 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00004498 ParseBorlandTypeAttributes(DS.getAttributes());
Dawn Perchik52fc3142010-09-03 01:29:35 +00004499 continue;
4500 }
4501 goto DoneWithTypeQuals;
Reid Spencer5f016e22007-07-11 17:01:13 +00004502 case tok::kw___attribute:
Dawn Perchik52fc3142010-09-03 01:29:35 +00004503 if (VendorAttributesAllowed) {
John McCall7f040a92010-12-24 02:08:15 +00004504 ParseGNUAttributes(DS.getAttributes());
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004505 continue; // do *not* consume the next token!
4506 }
4507 // otherwise, FALL THROUGH!
4508 default:
Steve Naroff239f0732008-12-25 14:16:32 +00004509 DoneWithTypeQuals:
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004510 // If this is not a type-qualifier token, we're done reading type
4511 // qualifiers. First verify that DeclSpec's are consistent.
Douglas Gregor9b3064b2009-04-01 22:41:11 +00004512 DS.Finish(Diags, PP);
Abramo Bagnara796aa442011-03-12 11:17:06 +00004513 if (EndLoc.isValid())
4514 DS.SetRangeEnd(EndLoc);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00004515 return;
Reid Spencer5f016e22007-07-11 17:01:13 +00004516 }
Chris Lattnera1fcbad2008-12-18 06:50:14 +00004517
Reid Spencer5f016e22007-07-11 17:01:13 +00004518 // If the specifier combination wasn't legal, issue a diagnostic.
4519 if (isInvalid) {
4520 assert(PrevSpec && "Method did not return previous specifier!");
Chris Lattner1ab3b962008-11-18 07:48:38 +00004521 Diag(Tok, DiagID) << PrevSpec;
Reid Spencer5f016e22007-07-11 17:01:13 +00004522 }
Abramo Bagnara796aa442011-03-12 11:17:06 +00004523 EndLoc = ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00004524 }
4525}
4526
4527
4528/// ParseDeclarator - Parse and verify a newly-initialized declarator.
4529///
4530void Parser::ParseDeclarator(Declarator &D) {
4531 /// This implements the 'declarator' production in the C grammar, then checks
4532 /// for well-formedness and issues diagnostics.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004533 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Reid Spencer5f016e22007-07-11 17:01:13 +00004534}
4535
Richard Smith9988f282012-03-29 01:16:42 +00004536static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
4537 if (Kind == tok::star || Kind == tok::caret)
4538 return true;
4539
4540 // We parse rvalue refs in C++03, because otherwise the errors are scary.
4541 if (!Lang.CPlusPlus)
4542 return false;
4543
4544 return Kind == tok::amp || Kind == tok::ampamp;
4545}
4546
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004547/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
4548/// is parsed by the function passed to it. Pass null, and the direct-declarator
4549/// isn't parsed at all, making this function effectively parse the C++
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004550/// ptr-operator production.
4551///
Richard Smith0706df42011-10-19 21:33:05 +00004552/// If the grammar of this construct is extended, matching changes must also be
Richard Smith5d8388c2012-03-27 01:42:32 +00004553/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
4554/// isConstructorDeclarator.
Richard Smith0706df42011-10-19 21:33:05 +00004555///
Sebastian Redlf30208a2009-01-24 21:16:55 +00004556/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
4557/// [C] pointer[opt] direct-declarator
4558/// [C++] direct-declarator
4559/// [C++] ptr-operator declarator
Reid Spencer5f016e22007-07-11 17:01:13 +00004560///
4561/// pointer: [C99 6.7.5]
4562/// '*' type-qualifier-list[opt]
4563/// '*' type-qualifier-list[opt] pointer
4564///
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004565/// ptr-operator:
4566/// '*' cv-qualifier-seq[opt]
4567/// '&'
Sebastian Redl05532f22009-03-15 22:02:01 +00004568/// [C++0x] '&&'
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004569/// [GNU] '&' restrict[opt] attributes[opt]
Sebastian Redl05532f22009-03-15 22:02:01 +00004570/// [GNU?] '&&' restrict[opt] attributes[opt]
Sebastian Redlf30208a2009-01-24 21:16:55 +00004571/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004572void Parser::ParseDeclaratorInternal(Declarator &D,
4573 DirectDeclParseFunction DirectDeclParser) {
Douglas Gregor91a28862009-08-26 14:27:30 +00004574 if (Diags.hasAllExtensionsSilenced())
4575 D.setExtension();
Chad Rosier8decdee2012-06-26 22:30:43 +00004576
Sebastian Redlf30208a2009-01-24 21:16:55 +00004577 // C++ member pointers start with a '::' or a nested-name.
4578 // Member pointers get special handling, since there's no place for the
4579 // scope spec in the generic path below.
David Blaikie4e4d0842012-03-11 07:00:24 +00004580 if (getLangOpts().CPlusPlus &&
Chris Lattnerf919bfe2009-03-24 17:04:48 +00004581 (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
4582 Tok.is(tok::annot_cxxscope))) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004583 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4584 D.getContext() == Declarator::MemberContext;
Sebastian Redlf30208a2009-01-24 21:16:55 +00004585 CXXScopeSpec SS;
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004586 ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004587
Jeffrey Yasskinedc28772010-04-07 23:29:58 +00004588 if (SS.isNotEmpty()) {
Mike Stump1eb44332009-09-09 15:08:12 +00004589 if (Tok.isNot(tok::star)) {
Sebastian Redlf30208a2009-01-24 21:16:55 +00004590 // The scope spec really belongs to the direct-declarator.
Richard Smith6a502c42013-01-08 22:43:49 +00004591 if (D.mayHaveIdentifier())
4592 D.getCXXScopeSpec() = SS;
4593 else
4594 AnnotateScopeToken(SS, true);
4595
Sebastian Redlf30208a2009-01-24 21:16:55 +00004596 if (DirectDeclParser)
4597 (this->*DirectDeclParser)(D);
4598 return;
4599 }
4600
4601 SourceLocation Loc = ConsumeToken();
Sebastian Redlab197ba2009-02-09 18:23:29 +00004602 D.SetRangeEnd(Loc);
John McCall0b7e6782011-03-24 11:26:52 +00004603 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004604 ParseTypeQualifierListOpt(DS);
Sebastian Redlab197ba2009-02-09 18:23:29 +00004605 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004606
4607 // Recurse to parse whatever is left.
4608 ParseDeclaratorInternal(D, DirectDeclParser);
4609
4610 // Sema will have to catch (syntactically invalid) pointers into global
4611 // scope. It has to catch pointers into namespace scope anyway.
4612 D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004613 Loc),
4614 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004615 /* Don't replace range end. */SourceLocation());
Sebastian Redlf30208a2009-01-24 21:16:55 +00004616 return;
4617 }
4618 }
4619
4620 tok::TokenKind Kind = Tok.getKind();
Steve Naroff5618bd42008-08-27 16:04:49 +00004621 // Not a pointer, C++ reference, or block.
Richard Smith9988f282012-03-29 01:16:42 +00004622 if (!isPtrOperatorToken(Kind, getLangOpts())) {
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004623 if (DirectDeclParser)
4624 (this->*DirectDeclParser)(D);
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004625 return;
4626 }
Sebastian Redlf30208a2009-01-24 21:16:55 +00004627
Sebastian Redl05532f22009-03-15 22:02:01 +00004628 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4629 // '&&' -> rvalue reference
Sebastian Redl743de1f2009-03-23 00:00:23 +00004630 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
Sebastian Redlab197ba2009-02-09 18:23:29 +00004631 D.SetRangeEnd(Loc);
Reid Spencer5f016e22007-07-11 17:01:13 +00004632
Chris Lattner9af55002009-03-27 04:18:06 +00004633 if (Kind == tok::star || Kind == tok::caret) {
Chris Lattner76549142008-02-21 01:32:26 +00004634 // Is a pointer.
John McCall0b7e6782011-03-24 11:26:52 +00004635 DeclSpec DS(AttrFactory);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004636
Richard Smith6ee326a2012-04-10 01:32:12 +00004637 // FIXME: GNU attributes are not allowed here in a new-type-id.
Bill Wendling7f3ec662013-11-26 04:10:07 +00004638 ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier());
Sebastian Redlab197ba2009-02-09 18:23:29 +00004639 D.ExtendWithDeclSpec(DS);
Sebastian Redlf30208a2009-01-24 21:16:55 +00004640
Reid Spencer5f016e22007-07-11 17:01:13 +00004641 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004642 ParseDeclaratorInternal(D, DirectDeclParser);
Steve Naroff5618bd42008-08-27 16:04:49 +00004643 if (Kind == tok::star)
4644 // Remember that we parsed a pointer type, and remember the type-quals.
4645 D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
Chandler Carruthd067c072011-02-23 18:51:59 +00004646 DS.getConstSpecLoc(),
4647 DS.getVolatileSpecLoc(),
John McCall0b7e6782011-03-24 11:26:52 +00004648 DS.getRestrictSpecLoc()),
4649 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004650 SourceLocation());
Steve Naroff5618bd42008-08-27 16:04:49 +00004651 else
4652 // Remember that we parsed a Block type, and remember the type-quals.
Mike Stump1eb44332009-09-09 15:08:12 +00004653 D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
John McCall0b7e6782011-03-24 11:26:52 +00004654 Loc),
4655 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004656 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004657 } else {
4658 // Is a reference
John McCall0b7e6782011-03-24 11:26:52 +00004659 DeclSpec DS(AttrFactory);
Reid Spencer5f016e22007-07-11 17:01:13 +00004660
Sebastian Redl743de1f2009-03-23 00:00:23 +00004661 // Complain about rvalue references in C++03, but then go on and build
4662 // the declarator.
Richard Smith7fe62082011-10-15 05:09:34 +00004663 if (Kind == tok::ampamp)
Richard Smith80ad52f2013-01-02 11:42:31 +00004664 Diag(Loc, getLangOpts().CPlusPlus11 ?
Richard Smith7fe62082011-10-15 05:09:34 +00004665 diag::warn_cxx98_compat_rvalue_reference :
4666 diag::ext_rvalue_reference);
Sebastian Redl743de1f2009-03-23 00:00:23 +00004667
Richard Smith6ee326a2012-04-10 01:32:12 +00004668 // GNU-style and C++11 attributes are allowed here, as is restrict.
4669 ParseTypeQualifierListOpt(DS);
4670 D.ExtendWithDeclSpec(DS);
4671
Reid Spencer5f016e22007-07-11 17:01:13 +00004672 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4673 // cv-qualifiers are introduced through the use of a typedef or of a
4674 // template type argument, in which case the cv-qualifiers are ignored.
Reid Spencer5f016e22007-07-11 17:01:13 +00004675 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4676 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4677 Diag(DS.getConstSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004678 diag::err_invalid_reference_qualifier_application) << "const";
Reid Spencer5f016e22007-07-11 17:01:13 +00004679 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4680 Diag(DS.getVolatileSpecLoc(),
Chris Lattner1ab3b962008-11-18 07:48:38 +00004681 diag::err_invalid_reference_qualifier_application) << "volatile";
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004682 // 'restrict' is permitted as an extension.
4683 if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
4684 Diag(DS.getAtomicSpecLoc(),
4685 diag::err_invalid_reference_qualifier_application) << "_Atomic";
Reid Spencer5f016e22007-07-11 17:01:13 +00004686 }
4687
4688 // Recursively parse the declarator.
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004689 ParseDeclaratorInternal(D, DirectDeclParser);
Reid Spencer5f016e22007-07-11 17:01:13 +00004690
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004691 if (D.getNumTypeObjects() > 0) {
4692 // C++ [dcl.ref]p4: There shall be no references to references.
4693 DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4694 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
Chris Lattnerda83bac2008-11-19 07:37:42 +00004695 if (const IdentifierInfo *II = D.getIdentifier())
4696 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4697 << II;
4698 else
4699 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4700 << "type name";
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004701
Sebastian Redl4c5d3202008-11-21 19:14:01 +00004702 // Once we've complained about the reference-to-reference, we
Douglas Gregorf1f9b4e2008-11-03 15:51:28 +00004703 // can go ahead and build the (technically ill-formed)
4704 // declarator: reference collapsing will take care of it.
4705 }
4706 }
4707
Richard Smith4cf4a5e2013-03-28 01:55:44 +00004708 // Remember that we parsed a reference type.
Chris Lattner76549142008-02-21 01:32:26 +00004709 D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
Sebastian Redl05532f22009-03-15 22:02:01 +00004710 Kind == tok::amp),
John McCall0b7e6782011-03-24 11:26:52 +00004711 DS.getAttributes(),
Sebastian Redlab197ba2009-02-09 18:23:29 +00004712 SourceLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00004713 }
4714}
4715
Richard Smith9988f282012-03-29 01:16:42 +00004716static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4717 SourceLocation EllipsisLoc) {
4718 if (EllipsisLoc.isValid()) {
4719 FixItHint Insertion;
4720 if (!D.getEllipsisLoc().isValid()) {
4721 Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4722 D.setEllipsisLoc(EllipsisLoc);
4723 }
4724 P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4725 << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4726 }
4727}
4728
Reid Spencer5f016e22007-07-11 17:01:13 +00004729/// ParseDirectDeclarator
4730/// direct-declarator: [C99 6.7.5]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004731/// [C99] identifier
Reid Spencer5f016e22007-07-11 17:01:13 +00004732/// '(' declarator ')'
4733/// [GNU] '(' attributes declarator ')'
4734/// [C90] direct-declarator '[' constant-expression[opt] ']'
4735/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4736/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4737/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4738/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00004739/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4740/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00004741/// direct-declarator '(' parameter-type-list ')'
4742/// direct-declarator '(' identifier-list[opt] ')'
4743/// [GNU] direct-declarator '(' parameter-forward-declarations
4744/// parameter-type-list[opt] ')'
Argyrios Kyrtzidis971c4fa2008-10-24 21:46:40 +00004745/// [C++] direct-declarator '(' parameter-declaration-clause ')'
4746/// cv-qualifier-seq[opt] exception-specification[opt]
Richard Smith6ee326a2012-04-10 01:32:12 +00004747/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4748/// attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4749/// ref-qualifier[opt] exception-specification[opt]
Douglas Gregorb48fe382008-10-31 09:07:45 +00004750/// [C++] declarator-id
Richard Smith6ee326a2012-04-10 01:32:12 +00004751/// [C++11] declarator-id attribute-specifier-seq[opt]
Douglas Gregor42a552f2008-11-05 20:51:48 +00004752///
4753/// declarator-id: [C++ 8]
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004754/// '...'[opt] id-expression
Douglas Gregor42a552f2008-11-05 20:51:48 +00004755/// '::'[opt] nested-name-specifier[opt] type-name
4756///
4757/// id-expression: [C++ 5.1]
4758/// unqualified-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004759/// qualified-id
Douglas Gregor42a552f2008-11-05 20:51:48 +00004760///
4761/// unqualified-id: [C++ 5.1]
Mike Stump1eb44332009-09-09 15:08:12 +00004762/// identifier
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004763/// operator-function-id
Douglas Gregordb422df2009-09-25 21:45:23 +00004764/// conversion-function-id
Mike Stump1eb44332009-09-09 15:08:12 +00004765/// '~' class-name
Douglas Gregor39a8de12009-02-25 19:37:18 +00004766/// template-id
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +00004767///
Richard Smith5d8388c2012-03-27 01:42:32 +00004768/// Note, any additional constructs added here may need corresponding changes
4769/// in isConstructorDeclarator.
Reid Spencer5f016e22007-07-11 17:01:13 +00004770void Parser::ParseDirectDeclarator(Declarator &D) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004771 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +00004772
David Blaikie4e4d0842012-03-11 07:00:24 +00004773 if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004774 // ParseDeclaratorInternal might already have parsed the scope.
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004775 if (D.getCXXScopeSpec().isEmpty()) {
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004776 bool EnteringContext = D.getContext() == Declarator::FileContext ||
4777 D.getContext() == Declarator::MemberContext;
Chad Rosier8decdee2012-06-26 22:30:43 +00004778 ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
Douglas Gregorefaa93a2011-11-07 17:33:42 +00004779 EnteringContext);
John McCall9ba61662010-02-26 08:45:28 +00004780 }
4781
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004782 if (D.getCXXScopeSpec().isValid()) {
Douglas Gregor23c94db2010-07-02 17:43:08 +00004783 if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
John McCalle7e278b2009-12-11 20:04:54 +00004784 // Change the declaration context for name lookup, until this function
4785 // is exited (and the declarator has been parsed).
4786 DeclScopeObj.EnterDeclaratorScope();
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004787 }
4788
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004789 // C++0x [dcl.fct]p14:
4790 // There is a syntactic ambiguity when an ellipsis occurs at the end
Chad Rosier8decdee2012-06-26 22:30:43 +00004791 // of a parameter-declaration-clause without a preceding comma. In
4792 // this case, the ellipsis is parsed as part of the
4793 // abstract-declarator if the type of the parameter names a template
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004794 // parameter pack that has not been expanded; otherwise, it is parsed
4795 // as part of the parameter-declaration-clause.
Richard Smith9988f282012-03-29 01:16:42 +00004796 if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004797 !((D.getContext() == Declarator::PrototypeContext ||
Faisal Valifad9e132013-09-26 19:54:12 +00004798 D.getContext() == Declarator::LambdaExprParameterContext ||
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004799 D.getContext() == Declarator::BlockLiteralContext) &&
Douglas Gregora8bc8c92010-12-23 22:44:42 +00004800 NextToken().is(tok::r_paren) &&
Richard Smith30f2a742013-02-20 20:19:27 +00004801 !D.hasGroupingParens() &&
Richard Smith9988f282012-03-29 01:16:42 +00004802 !Actions.containsUnexpandedParameterPacks(D))) {
4803 SourceLocation EllipsisLoc = ConsumeToken();
4804 if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4805 // The ellipsis was put in the wrong place. Recover, and explain to
4806 // the user what they should have done.
4807 ParseDeclarator(D);
4808 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4809 return;
4810 } else
4811 D.setEllipsisLoc(EllipsisLoc);
4812
4813 // The ellipsis can't be followed by a parenthesized declarator. We
4814 // check for that in ParseParenDeclarator, after we have disambiguated
4815 // the l_paren token.
4816 }
4817
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004818 if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4819 Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4820 // We found something that indicates the start of an unqualified-id.
4821 // Parse that unqualified-id.
John McCallba9d8532010-04-13 06:39:49 +00004822 bool AllowConstructorName;
4823 if (D.getDeclSpec().hasTypeSpecifier())
4824 AllowConstructorName = false;
4825 else if (D.getCXXScopeSpec().isSet())
4826 AllowConstructorName =
4827 (D.getContext() == Declarator::FileContext ||
Dmitri Gribenko1b9e8f72013-02-12 17:27:41 +00004828 D.getContext() == Declarator::MemberContext);
John McCallba9d8532010-04-13 06:39:49 +00004829 else
4830 AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4831
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004832 SourceLocation TemplateKWLoc;
Chad Rosier8decdee2012-06-26 22:30:43 +00004833 if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4834 /*EnteringContext=*/true,
4835 /*AllowDestructorName=*/true,
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004836 AllowConstructorName,
John McCallb3d87482010-08-24 05:47:05 +00004837 ParsedType(),
Abramo Bagnarae4b92762012-01-27 09:46:47 +00004838 TemplateKWLoc,
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00004839 D.getName()) ||
4840 // Once we're past the identifier, if the scope was bad, mark the
4841 // whole declarator bad.
4842 D.getCXXScopeSpec().isInvalid()) {
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004843 D.SetIdentifier(0, Tok.getLocation());
4844 D.setInvalidType(true);
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004845 } else {
4846 // Parsed the unqualified-id; update range information and move along.
4847 if (D.getSourceRange().getBegin().isInvalid())
4848 D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4849 D.SetRangeEnd(D.getName().getSourceRange().getEnd());
Douglas Gregor2f1bc522008-11-07 20:08:42 +00004850 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004851 goto PastIdentifier;
Douglas Gregor1cd1b1e2008-11-06 22:13:31 +00004852 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004853 } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
David Blaikie4e4d0842012-03-11 07:00:24 +00004854 assert(!getLangOpts().CPlusPlus &&
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004855 "There's a C++-specific check for tok::identifier above");
4856 assert(Tok.getIdentifierInfo() && "Not an identifier?");
4857 D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4858 ConsumeToken();
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004859 goto PastIdentifier;
Richard Smitha38253c2013-07-11 05:10:21 +00004860 } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
Richard Smith8d1ab8a2013-10-13 22:12:28 +00004861 // A virt-specifier isn't treated as an identifier if it appears after a
4862 // trailing-return-type.
4863 if (D.getContext() != Declarator::TrailingReturnContext ||
4864 !isCXX11VirtSpecifier(Tok)) {
4865 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
4866 << FixItHint::CreateRemoval(Tok.getLocation());
4867 D.SetIdentifier(0, Tok.getLocation());
4868 ConsumeToken();
4869 goto PastIdentifier;
4870 }
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004871 }
Richard Smith9988f282012-03-29 01:16:42 +00004872
Douglas Gregor3f9a0562009-11-03 01:35:08 +00004873 if (Tok.is(tok::l_paren)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004874 // direct-declarator: '(' declarator ')'
4875 // direct-declarator: '(' attributes declarator ')'
4876 // Example: 'char (*X)' or 'int (*XX)(void)'
4877 ParseParenDeclarator(D);
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004878
4879 // If the declarator was parenthesized, we entered the declarator
4880 // scope when parsing the parenthesized declarator, then exited
4881 // the scope already. Re-enter the scope, if we need to.
4882 if (D.getCXXScopeSpec().isSet()) {
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004883 // If there was an error parsing parenthesized declarator, declarator
Richard Smith9988f282012-03-29 01:16:42 +00004884 // scope may have been entered before. Don't do it again.
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004885 if (!D.isInvalidType() &&
4886 Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004887 // Change the declaration context for name lookup, until this function
4888 // is exited (and the declarator has been parsed).
Fariborz Jahanian46877cd2010-08-17 23:50:37 +00004889 DeclScopeObj.EnterDeclaratorScope();
Douglas Gregor0efc2c12010-01-13 17:31:36 +00004890 }
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004891 } else if (D.mayOmitIdentifier()) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004892 // This could be something simple like "int" (in which case the declarator
4893 // portion is empty), if an abstract-declarator is allowed.
4894 D.SetIdentifier(0, Tok.getLocation());
Richard Smith30f2a742013-02-20 20:19:27 +00004895
4896 // The grammar for abstract-pack-declarator does not allow grouping parens.
4897 // FIXME: Revisit this once core issue 1488 is resolved.
4898 if (D.hasEllipsis() && D.hasGroupingParens())
4899 Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()),
4900 diag::ext_abstract_pack_declarator_parens);
Reid Spencer5f016e22007-07-11 17:01:13 +00004901 } else {
David Blaikiee75d9cf2012-06-29 22:03:56 +00004902 if (Tok.getKind() == tok::annot_pragma_parser_crash)
David Blaikie377da4c2012-08-21 18:56:49 +00004903 LLVM_BUILTIN_TRAP;
Douglas Gregore950d4b2009-03-06 23:28:18 +00004904 if (D.getContext() == Declarator::MemberContext)
4905 Diag(Tok, diag::err_expected_member_name_or_semi)
4906 << D.getDeclSpec().getSourceRange();
Richard Trieudb55c04c2013-01-26 02:31:38 +00004907 else if (getLangOpts().CPlusPlus) {
4908 if (Tok.is(tok::period) || Tok.is(tok::arrow))
4909 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
Richard Trieuefb288c2013-09-05 02:31:33 +00004910 else {
4911 SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();
4912 if (Tok.isAtStartOfLine() && Loc.isValid())
4913 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
4914 << getLangOpts().CPlusPlus;
4915 else
4916 Diag(Tok, diag::err_expected_unqualified_id)
4917 << getLangOpts().CPlusPlus;
4918 }
Richard Trieudb55c04c2013-01-26 02:31:38 +00004919 } else
Chris Lattner1ab3b962008-11-18 07:48:38 +00004920 Diag(Tok, diag::err_expected_ident_lparen);
Reid Spencer5f016e22007-07-11 17:01:13 +00004921 D.SetIdentifier(0, Tok.getLocation());
Chris Lattner1f6f54b2008-11-11 06:13:16 +00004922 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00004923 }
Mike Stump1eb44332009-09-09 15:08:12 +00004924
Argyrios Kyrtzidis314fe782008-11-26 22:40:03 +00004925 PastIdentifier:
Reid Spencer5f016e22007-07-11 17:01:13 +00004926 assert(D.isPastIdentifier() &&
4927 "Haven't past the location of the identifier yet?");
Mike Stump1eb44332009-09-09 15:08:12 +00004928
Richard Smith6ee326a2012-04-10 01:32:12 +00004929 // Don't parse attributes unless we have parsed an unparenthesized name.
4930 if (D.hasName() && !D.getNumTypeObjects())
Richard Smith4e24f0f2013-01-02 12:01:23 +00004931 MaybeParseCXX11Attributes(D);
Sean Huntbbd37c62009-11-21 08:43:09 +00004932
Reid Spencer5f016e22007-07-11 17:01:13 +00004933 while (1) {
Chris Lattner04d66662007-10-09 17:33:22 +00004934 if (Tok.is(tok::l_paren)) {
David Blaikie42d6d0c2011-12-04 05:04:18 +00004935 // Enter function-declaration scope, limiting any declarators to the
4936 // function prototype scope, including parameter declarators.
4937 ParseScope PrototypeScope(this,
Richard Smith3a2b7a12013-01-28 22:42:45 +00004938 Scope::FunctionPrototypeScope|Scope::DeclScope|
4939 (D.isFunctionDeclaratorAFunctionDeclaration()
4940 ? Scope::FunctionDeclarationScope : 0));
4941
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00004942 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4943 // In such a case, check if we actually have a function declarator; if it
4944 // is not, the declarator has been fully parsed.
Richard Smithb9c62612012-07-30 21:30:52 +00004945 bool IsAmbiguous = false;
Richard Smith05766812012-08-18 00:55:03 +00004946 if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
4947 // The name of the declarator, if any, is tentatively declared within
4948 // a possible direct initializer.
4949 TentativelyDeclaredIdentifiers.push_back(D.getIdentifier());
4950 bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
4951 TentativelyDeclaredIdentifiers.pop_back();
4952 if (!IsFunctionDecl)
4953 break;
4954 }
John McCall0b7e6782011-03-24 11:26:52 +00004955 ParsedAttributes attrs(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004956 BalancedDelimiterTracker T(*this, tok::l_paren);
4957 T.consumeOpen();
Richard Smithb9c62612012-07-30 21:30:52 +00004958 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
David Blaikie42d6d0c2011-12-04 05:04:18 +00004959 PrototypeScope.Exit();
Chris Lattner04d66662007-10-09 17:33:22 +00004960 } else if (Tok.is(tok::l_square)) {
Reid Spencer5f016e22007-07-11 17:01:13 +00004961 ParseBracketDeclarator(D);
4962 } else {
4963 break;
4964 }
4965 }
Chad Rosier8decdee2012-06-26 22:30:43 +00004966}
Reid Spencer5f016e22007-07-11 17:01:13 +00004967
Chris Lattneref4715c2008-04-06 05:45:57 +00004968/// ParseParenDeclarator - We parsed the declarator D up to a paren. This is
4969/// only called before the identifier, so these are most likely just grouping
Mike Stump1eb44332009-09-09 15:08:12 +00004970/// parens for precedence. If we find that these are actually function
Chris Lattneref4715c2008-04-06 05:45:57 +00004971/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4972///
4973/// direct-declarator:
4974/// '(' declarator ')'
4975/// [GNU] '(' attributes declarator ')'
Chris Lattner7399ee02008-10-20 02:05:46 +00004976/// direct-declarator '(' parameter-type-list ')'
4977/// direct-declarator '(' identifier-list[opt] ')'
4978/// [GNU] direct-declarator '(' parameter-forward-declarations
4979/// parameter-type-list[opt] ')'
Chris Lattneref4715c2008-04-06 05:45:57 +00004980///
4981void Parser::ParseParenDeclarator(Declarator &D) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00004982 BalancedDelimiterTracker T(*this, tok::l_paren);
4983 T.consumeOpen();
4984
Chris Lattneref4715c2008-04-06 05:45:57 +00004985 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
Mike Stump1eb44332009-09-09 15:08:12 +00004986
Chris Lattner7399ee02008-10-20 02:05:46 +00004987 // Eat any attributes before we look at whether this is a grouping or function
4988 // declarator paren. If this is a grouping paren, the attribute applies to
4989 // the type being built up, for example:
4990 // int (__attribute__(()) *x)(long y)
4991 // If this ends up not being a grouping paren, the attribute applies to the
4992 // first argument, for example:
4993 // int (__attribute__(()) int x)
4994 // In either case, we need to eat any attributes to be able to determine what
4995 // sort of paren this is.
4996 //
John McCall0b7e6782011-03-24 11:26:52 +00004997 ParsedAttributes attrs(AttrFactory);
Chris Lattner7399ee02008-10-20 02:05:46 +00004998 bool RequiresArg = false;
4999 if (Tok.is(tok::kw___attribute)) {
John McCall7f040a92010-12-24 02:08:15 +00005000 ParseGNUAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00005001
Chris Lattner7399ee02008-10-20 02:05:46 +00005002 // We require that the argument list (if this is a non-grouping paren) be
5003 // present even if the attribute list was empty.
5004 RequiresArg = true;
5005 }
Chad Rosier9cab1c92012-12-21 21:22:20 +00005006
Steve Naroff239f0732008-12-25 14:16:32 +00005007 // Eat any Microsoft extensions.
Chad Rosier9cab1c92012-12-21 21:22:20 +00005008 ParseMicrosoftTypeAttributes(attrs);
5009
Dawn Perchik52fc3142010-09-03 01:29:35 +00005010 // Eat any Borland extensions.
Ted Kremenek8113ecf2010-11-10 05:59:39 +00005011 if (Tok.is(tok::kw___pascal))
John McCall7f040a92010-12-24 02:08:15 +00005012 ParseBorlandTypeAttributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00005013
Chris Lattneref4715c2008-04-06 05:45:57 +00005014 // If we haven't past the identifier yet (or where the identifier would be
5015 // stored, if this is an abstract declarator), then this is probably just
5016 // grouping parens. However, if this could be an abstract-declarator, then
5017 // this could also be the start of function arguments (consider 'void()').
5018 bool isGrouping;
Mike Stump1eb44332009-09-09 15:08:12 +00005019
Chris Lattneref4715c2008-04-06 05:45:57 +00005020 if (!D.mayOmitIdentifier()) {
5021 // If this can't be an abstract-declarator, this *must* be a grouping
5022 // paren, because we haven't seen the identifier yet.
5023 isGrouping = true;
5024 } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
Richard Smith22592862012-03-27 23:05:05 +00005025 (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
5026 NextToken().is(tok::r_paren)) || // C++ int(...)
Richard Smith6ce48a72012-04-11 04:01:28 +00005027 isDeclarationSpecifier() || // 'int(int)' is a function.
5028 isCXX11AttributeSpecifier()) { // 'int([[]]int)' is a function.
Chris Lattneref4715c2008-04-06 05:45:57 +00005029 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
5030 // considered to be a type, not a K&R identifier-list.
5031 isGrouping = false;
5032 } else {
5033 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
5034 isGrouping = true;
5035 }
Mike Stump1eb44332009-09-09 15:08:12 +00005036
Chris Lattneref4715c2008-04-06 05:45:57 +00005037 // If this is a grouping paren, handle:
5038 // direct-declarator: '(' declarator ')'
5039 // direct-declarator: '(' attributes declarator ')'
5040 if (isGrouping) {
Richard Smith9988f282012-03-29 01:16:42 +00005041 SourceLocation EllipsisLoc = D.getEllipsisLoc();
5042 D.setEllipsisLoc(SourceLocation());
5043
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00005044 bool hadGroupingParens = D.hasGroupingParens();
Argyrios Kyrtzidis73a0d882008-10-06 17:10:33 +00005045 D.setGroupingParens(true);
Sebastian Redl4c5d3202008-11-21 19:14:01 +00005046 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
Chris Lattneref4715c2008-04-06 05:45:57 +00005047 // Match the ')'.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005048 T.consumeClose();
Chad Rosier8decdee2012-06-26 22:30:43 +00005049 D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005050 T.getCloseLocation()),
5051 attrs, T.getCloseLocation());
Argyrios Kyrtzidis3f2a8a02008-10-07 10:21:57 +00005052
5053 D.setGroupingParens(hadGroupingParens);
Richard Smith9988f282012-03-29 01:16:42 +00005054
5055 // An ellipsis cannot be placed outside parentheses.
5056 if (EllipsisLoc.isValid())
5057 diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
5058
Chris Lattneref4715c2008-04-06 05:45:57 +00005059 return;
5060 }
Mike Stump1eb44332009-09-09 15:08:12 +00005061
Chris Lattneref4715c2008-04-06 05:45:57 +00005062 // Okay, if this wasn't a grouping paren, it must be the start of a function
5063 // argument list. Recognize that this declarator will never have an
Chris Lattner7399ee02008-10-20 02:05:46 +00005064 // identifier (and remember where it would have been), then call into
5065 // ParseFunctionDeclarator to handle of argument list.
Chris Lattneref4715c2008-04-06 05:45:57 +00005066 D.SetIdentifier(0, Tok.getLocation());
5067
David Blaikie42d6d0c2011-12-04 05:04:18 +00005068 // Enter function-declaration scope, limiting any declarators to the
5069 // function prototype scope, including parameter declarators.
5070 ParseScope PrototypeScope(this,
Richard Smith3a2b7a12013-01-28 22:42:45 +00005071 Scope::FunctionPrototypeScope | Scope::DeclScope |
5072 (D.isFunctionDeclaratorAFunctionDeclaration()
5073 ? Scope::FunctionDeclarationScope : 0));
Richard Smithb9c62612012-07-30 21:30:52 +00005074 ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
David Blaikie42d6d0c2011-12-04 05:04:18 +00005075 PrototypeScope.Exit();
Chris Lattneref4715c2008-04-06 05:45:57 +00005076}
5077
5078/// ParseFunctionDeclarator - We are after the identifier and have parsed the
5079/// declarator D up to a paren, which indicates that we are parsing function
5080/// arguments.
Reid Spencer5f016e22007-07-11 17:01:13 +00005081///
Richard Smith6ee326a2012-04-10 01:32:12 +00005082/// If FirstArgAttrs is non-null, then the caller parsed those arguments
5083/// immediately after the open paren - they should be considered to be the
5084/// first argument of a parameter.
Chris Lattner7399ee02008-10-20 02:05:46 +00005085///
Richard Smith6ee326a2012-04-10 01:32:12 +00005086/// If RequiresArg is true, then the first argument of the function is required
5087/// to be present and required to not be an identifier list.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005088///
Richard Smith6ee326a2012-04-10 01:32:12 +00005089/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
5090/// (C++11) ref-qualifier[opt], exception-specification[opt],
5091/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
5092///
5093/// [C++11] exception-specification:
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005094/// dynamic-exception-specification
5095/// noexcept-specification
5096///
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005097void Parser::ParseFunctionDeclarator(Declarator &D,
Richard Smith6ee326a2012-04-10 01:32:12 +00005098 ParsedAttributes &FirstArgAttrs,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005099 BalancedDelimiterTracker &Tracker,
Richard Smithb9c62612012-07-30 21:30:52 +00005100 bool IsAmbiguous,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005101 bool RequiresArg) {
Chad Rosier8decdee2012-06-26 22:30:43 +00005102 assert(getCurScope()->isFunctionPrototypeScope() &&
David Blaikie42d6d0c2011-12-04 05:04:18 +00005103 "Should call from a Function scope");
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005104 // lparen is already consumed!
5105 assert(D.isPastIdentifier() && "Should not call before identifier!");
5106
5107 // This should be true when the function has typed arguments.
5108 // Otherwise, it is treated as a K&R-style function.
5109 bool HasProto = false;
5110 // Build up an array of information about the parsed arguments.
Chris Lattner5f9e2722011-07-23 10:55:15 +00005111 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005112 // Remember where we see an ellipsis, if any.
5113 SourceLocation EllipsisLoc;
5114
5115 DeclSpec DS(AttrFactory);
5116 bool RefQualifierIsLValueRef = true;
5117 SourceLocation RefQualifierLoc;
Douglas Gregor43f51032011-10-19 06:04:55 +00005118 SourceLocation ConstQualifierLoc;
5119 SourceLocation VolatileQualifierLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005120 ExceptionSpecificationType ESpecType = EST_None;
5121 SourceRange ESpecRange;
Chris Lattner5f9e2722011-07-23 10:55:15 +00005122 SmallVector<ParsedType, 2> DynamicExceptions;
5123 SmallVector<SourceRange, 2> DynamicExceptionRanges;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005124 ExprResult NoexceptExpr;
Richard Smith6ee326a2012-04-10 01:32:12 +00005125 ParsedAttributes FnAttrs(AttrFactory);
Richard Smith54655be2012-06-12 01:51:59 +00005126 TypeResult TrailingReturnType;
Richard Smith6ee326a2012-04-10 01:32:12 +00005127
James Molloy16f1f712012-02-29 10:24:19 +00005128 Actions.ActOnStartFunctionDeclarator();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005129 /* LocalEndLoc is the end location for the local FunctionTypeLoc.
5130 EndLoc is the end location for the function declarator.
5131 They differ for trailing return types. */
5132 SourceLocation StartLoc, LocalEndLoc, EndLoc;
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005133 SourceLocation LParenLoc, RParenLoc;
5134 LParenLoc = Tracker.getOpenLocation();
5135 StartLoc = LParenLoc;
5136
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005137 if (isFunctionDeclaratorIdentifierList()) {
5138 if (RequiresArg)
5139 Diag(Tok, diag::err_argument_required_after_attribute);
5140
5141 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
5142
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005143 Tracker.consumeClose();
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005144 RParenLoc = Tracker.getCloseLocation();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005145 LocalEndLoc = RParenLoc;
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005146 EndLoc = RParenLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005147 } else {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005148 if (Tok.isNot(tok::r_paren))
Faisal Valifad9e132013-09-26 19:54:12 +00005149 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo,
5150 EllipsisLoc);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005151 else if (RequiresArg)
5152 Diag(Tok, diag::err_argument_required_after_attribute);
5153
David Blaikie4e4d0842012-03-11 07:00:24 +00005154 HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005155
5156 // If we have the closing ')', eat it.
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005157 Tracker.consumeClose();
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005158 RParenLoc = Tracker.getCloseLocation();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005159 LocalEndLoc = RParenLoc;
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005160 EndLoc = RParenLoc;
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005161
David Blaikie4e4d0842012-03-11 07:00:24 +00005162 if (getLangOpts().CPlusPlus) {
Richard Smith6ee326a2012-04-10 01:32:12 +00005163 // FIXME: Accept these components in any order, and produce fixits to
5164 // correct the order if the user gets it wrong. Ideally we should deal
5165 // with the virt-specifier-seq and pure-specifier in the same way.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005166
5167 // Parse cv-qualifier-seq[opt].
Richard Smith4cf4a5e2013-03-28 01:55:44 +00005168 ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false,
5169 /*CXX11AttributesAllowed*/ false,
5170 /*AtomicAllowed*/ false);
Richard Smith6ee326a2012-04-10 01:32:12 +00005171 if (!DS.getSourceRange().getEnd().isInvalid()) {
5172 EndLoc = DS.getSourceRange().getEnd();
5173 ConstQualifierLoc = DS.getConstSpecLoc();
5174 VolatileQualifierLoc = DS.getVolatileSpecLoc();
5175 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005176
5177 // Parse ref-qualifier[opt].
5178 if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
Richard Smith80ad52f2013-01-02 11:42:31 +00005179 Diag(Tok, getLangOpts().CPlusPlus11 ?
Richard Smith7fe62082011-10-15 05:09:34 +00005180 diag::warn_cxx98_compat_ref_qualifier :
5181 diag::ext_ref_qualifier);
Richard Smith6ee326a2012-04-10 01:32:12 +00005182
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005183 RefQualifierIsLValueRef = Tok.is(tok::amp);
5184 RefQualifierLoc = ConsumeToken();
5185 EndLoc = RefQualifierLoc;
5186 }
5187
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005188 // C++11 [expr.prim.general]p3:
Chad Rosier8decdee2012-06-26 22:30:43 +00005189 // If a declaration declares a member function or member function
5190 // template of a class X, the expression this is a prvalue of type
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005191 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
Chad Rosier8decdee2012-06-26 22:30:43 +00005192 // and the end of the function-definition, member-declarator, or
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005193 // declarator.
Richard Smithd9227792013-03-15 00:41:52 +00005194 // FIXME: currently, "static" case isn't handled correctly.
Chad Rosier8decdee2012-06-26 22:30:43 +00005195 bool IsCXX11MemberFunction =
Richard Smith80ad52f2013-01-02 11:42:31 +00005196 getLangOpts().CPlusPlus11 &&
Richard Smithd9227792013-03-15 00:41:52 +00005197 (D.getContext() == Declarator::MemberContext
5198 ? !D.getDeclSpec().isFriendSpecified()
5199 : D.getContext() == Declarator::FileContext &&
5200 D.getCXXScopeSpec().isValid() &&
5201 Actions.CurContext->isRecord());
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005202 Sema::CXXThisScopeRAII ThisScope(Actions,
5203 dyn_cast<CXXRecordDecl>(Actions.CurContext),
Richard Smith7b19cb12013-01-14 01:55:13 +00005204 DS.getTypeQualifiers() |
Richard Smith84046262013-04-21 01:08:50 +00005205 (D.getDeclSpec().isConstexprSpecified() &&
5206 !getLangOpts().CPlusPlus1y
Richard Smith7b19cb12013-01-14 01:55:13 +00005207 ? Qualifiers::Const : 0),
Douglas Gregorcefc3af2012-04-16 07:05:22 +00005208 IsCXX11MemberFunction);
Richard Smitha058fd42012-05-02 22:22:32 +00005209
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005210 // Parse exception-specification[opt].
Richard Smitha058fd42012-05-02 22:22:32 +00005211 ESpecType = tryParseExceptionSpecification(ESpecRange,
Douglas Gregor74e2fc32012-04-16 18:27:27 +00005212 DynamicExceptions,
5213 DynamicExceptionRanges,
Richard Smitha058fd42012-05-02 22:22:32 +00005214 NoexceptExpr);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005215 if (ESpecType != EST_None)
5216 EndLoc = ESpecRange.getEnd();
5217
Richard Smith6ee326a2012-04-10 01:32:12 +00005218 // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
5219 // after the exception-specification.
Richard Smith4e24f0f2013-01-02 12:01:23 +00005220 MaybeParseCXX11Attributes(FnAttrs);
Richard Smith6ee326a2012-04-10 01:32:12 +00005221
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005222 // Parse trailing-return-type[opt].
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005223 LocalEndLoc = EndLoc;
Richard Smith80ad52f2013-01-02 11:42:31 +00005224 if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) {
Richard Smith7fe62082011-10-15 05:09:34 +00005225 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005226 if (D.getDeclSpec().getTypeSpecType() == TST_auto)
5227 StartLoc = D.getDeclSpec().getTypeSpecTypeLoc();
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005228 LocalEndLoc = Tok.getLocation();
Douglas Gregorae7902c2011-08-04 15:30:47 +00005229 SourceRange Range;
Richard Smith54655be2012-06-12 01:51:59 +00005230 TrailingReturnType = ParseTrailingReturnType(Range);
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005231 EndLoc = Range.getEnd();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005232 }
5233 }
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005234 }
5235
5236 // Remember that we parsed a function type, and remember the attributes.
5237 D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005238 IsAmbiguous,
5239 LParenLoc,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005240 ParamInfo.data(), ParamInfo.size(),
Abramo Bagnara59c0a812012-10-04 21:42:10 +00005241 EllipsisLoc, RParenLoc,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005242 DS.getTypeQualifiers(),
5243 RefQualifierIsLValueRef,
Douglas Gregor43f51032011-10-19 06:04:55 +00005244 RefQualifierLoc, ConstQualifierLoc,
5245 VolatileQualifierLoc,
Douglas Gregor90ebed02011-07-13 21:47:47 +00005246 /*MutableLoc=*/SourceLocation(),
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005247 ESpecType, ESpecRange.getBegin(),
5248 DynamicExceptions.data(),
5249 DynamicExceptionRanges.data(),
5250 DynamicExceptions.size(),
5251 NoexceptExpr.isUsable() ?
5252 NoexceptExpr.get() : 0,
Abramo Bagnaraac8ea052012-10-15 21:05:46 +00005253 StartLoc, LocalEndLoc, D,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005254 TrailingReturnType),
Richard Smith6ee326a2012-04-10 01:32:12 +00005255 FnAttrs, EndLoc);
James Molloy16f1f712012-02-29 10:24:19 +00005256
5257 Actions.ActOnEndFunctionDeclarator();
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005258}
5259
5260/// isFunctionDeclaratorIdentifierList - This parameter list may have an
5261/// identifier list form for a K&R-style function: void foo(a,b,c)
5262///
5263/// Note that identifier-lists are only allowed for normal declarators, not for
5264/// abstract-declarators.
5265bool Parser::isFunctionDeclaratorIdentifierList() {
David Blaikie4e4d0842012-03-11 07:00:24 +00005266 return !getLangOpts().CPlusPlus
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005267 && Tok.is(tok::identifier)
5268 && !TryAltiVecVectorToken()
5269 // K&R identifier lists can't have typedefs as identifiers, per C99
5270 // 6.7.5.3p11.
5271 && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
5272 // Identifier lists follow a really simple grammar: the identifiers can
5273 // be followed *only* by a ", identifier" or ")". However, K&R
5274 // identifier lists are really rare in the brave new modern world, and
5275 // it is very common for someone to typo a type in a non-K&R style
5276 // list. If we are presented with something like: "void foo(intptr x,
5277 // float y)", we don't want to start parsing the function declarator as
5278 // though it is a K&R style declarator just because intptr is an
5279 // invalid type.
5280 //
5281 // To handle this, we check to see if the token after the first
5282 // identifier is a "," or ")". Only then do we parse it as an
5283 // identifier list.
5284 && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
5285}
5286
5287/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
5288/// we found a K&R-style identifier list instead of a typed parameter list.
5289///
5290/// After returning, ParamInfo will hold the parsed parameters.
5291///
5292/// identifier-list: [C99 6.7.5]
5293/// identifier
5294/// identifier-list ',' identifier
5295///
5296void Parser::ParseFunctionDeclaratorIdentifierList(
5297 Declarator &D,
Craig Topper6b9240e2013-07-05 19:34:19 +00005298 SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005299 // If there was no identifier specified for the declarator, either we are in
5300 // an abstract-declarator, or we are in a parameter declarator which was found
5301 // to be abstract. In abstract-declarators, identifier lists are not valid:
5302 // diagnose this.
5303 if (!D.getIdentifier())
5304 Diag(Tok, diag::ext_ident_list_in_param);
5305
5306 // Maintain an efficient lookup of params we have seen so far.
5307 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
5308
5309 while (1) {
5310 // If this isn't an identifier, report the error and skip until ')'.
5311 if (Tok.isNot(tok::identifier)) {
5312 Diag(Tok, diag::err_expected_ident);
Alexey Bataev8fe24752013-11-18 08:17:37 +00005313 SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005314 // Forget we parsed anything.
5315 ParamInfo.clear();
5316 return;
5317 }
5318
5319 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
5320
5321 // Reject 'typedef int y; int test(x, y)', but continue parsing.
5322 if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
5323 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
5324
5325 // Verify that the argument identifier has not already been mentioned.
5326 if (!ParamsSoFar.insert(ParmII)) {
5327 Diag(Tok, diag::err_param_redefinition) << ParmII;
5328 } else {
5329 // Remember this identifier in ParamInfo.
5330 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
5331 Tok.getLocation(),
5332 0));
5333 }
5334
5335 // Eat the identifier.
5336 ConsumeToken();
5337
5338 // The list continues if we see a comma.
5339 if (Tok.isNot(tok::comma))
5340 break;
5341 ConsumeToken();
5342 }
5343}
5344
5345/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
5346/// after the opening parenthesis. This function will not parse a K&R-style
5347/// identifier list.
5348///
Richard Smith6ce48a72012-04-11 04:01:28 +00005349/// D is the declarator being parsed. If FirstArgAttrs is non-null, then the
5350/// caller parsed those arguments immediately after the open paren - they should
5351/// be considered to be part of the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005352///
5353/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
5354/// be the location of the ellipsis, if any was parsed.
5355///
Reid Spencer5f016e22007-07-11 17:01:13 +00005356/// parameter-type-list: [C99 6.7.5]
5357/// parameter-list
5358/// parameter-list ',' '...'
Douglas Gregored5d6512009-09-22 21:41:40 +00005359/// [C++] parameter-list '...'
Reid Spencer5f016e22007-07-11 17:01:13 +00005360///
5361/// parameter-list: [C99 6.7.5]
5362/// parameter-declaration
5363/// parameter-list ',' parameter-declaration
5364///
5365/// parameter-declaration: [C99 6.7.5]
5366/// declaration-specifiers declarator
Chris Lattner04421082008-04-08 04:40:51 +00005367/// [C++] declaration-specifiers declarator '=' assignment-expression
Sebastian Redl84407ba2012-03-14 15:54:00 +00005368/// [C++11] initializer-clause
Reid Spencer5f016e22007-07-11 17:01:13 +00005369/// [GNU] declaration-specifiers declarator attributes
Sebastian Redl50de12f2009-03-24 22:27:57 +00005370/// declaration-specifiers abstract-declarator[opt]
5371/// [C++] declaration-specifiers abstract-declarator[opt]
Chris Lattner8123a952008-04-10 02:22:51 +00005372/// '=' assignment-expression
Reid Spencer5f016e22007-07-11 17:01:13 +00005373/// [GNU] declaration-specifiers abstract-declarator[opt] attributes
Richard Smith6ce48a72012-04-11 04:01:28 +00005374/// [C++11] attribute-specifier-seq parameter-declaration
Reid Spencer5f016e22007-07-11 17:01:13 +00005375///
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005376void Parser::ParseParameterDeclarationClause(
5377 Declarator &D,
Richard Smith6ce48a72012-04-11 04:01:28 +00005378 ParsedAttributes &FirstArgAttrs,
Craig Topper6b9240e2013-07-05 19:34:19 +00005379 SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005380 SourceLocation &EllipsisLoc) {
Chris Lattnerf97409f2008-04-06 06:57:35 +00005381 while (1) {
5382 if (Tok.is(tok::ellipsis)) {
Richard Smith6ce48a72012-04-11 04:01:28 +00005383 // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
5384 // before deciding this was a parameter-declaration-clause.
Douglas Gregor965acbb2009-02-18 07:07:28 +00005385 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chris Lattnerf97409f2008-04-06 06:57:35 +00005386 break;
Reid Spencer5f016e22007-07-11 17:01:13 +00005387 }
Mike Stump1eb44332009-09-09 15:08:12 +00005388
Chris Lattnerf97409f2008-04-06 06:57:35 +00005389 // Parse the declaration-specifiers.
John McCall54abf7d2009-11-04 02:18:39 +00005390 // Just use the ParsingDeclaration "scope" of the declarator.
John McCall0b7e6782011-03-24 11:26:52 +00005391 DeclSpec DS(AttrFactory);
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005392
Richard Smith6ce48a72012-04-11 04:01:28 +00005393 // Parse any C++11 attributes.
Richard Smith4e24f0f2013-01-02 12:01:23 +00005394 MaybeParseCXX11Attributes(DS.getAttributes());
Richard Smith6ce48a72012-04-11 04:01:28 +00005395
John McCall7f040a92010-12-24 02:08:15 +00005396 // Skip any Microsoft attributes before a param.
Chad Rosier16f90bf2012-12-20 20:37:53 +00005397 MaybeParseMicrosoftAttributes(DS.getAttributes());
John McCall7f040a92010-12-24 02:08:15 +00005398
5399 SourceLocation DSStart = Tok.getLocation();
Chris Lattner7399ee02008-10-20 02:05:46 +00005400
5401 // If the caller parsed attributes for the first argument, add them now.
John McCall7f040a92010-12-24 02:08:15 +00005402 // Take them so that we only apply the attributes to the first parameter.
Douglas Gregor3fd1ba02011-07-05 16:44:18 +00005403 // FIXME: If we can leave the attributes in the token stream somehow, we can
Richard Smith6ce48a72012-04-11 04:01:28 +00005404 // get rid of a parameter (FirstArgAttrs) and this statement. It might be
5405 // too much hassle.
5406 DS.takeAttributesFrom(FirstArgAttrs);
John McCall7f040a92010-12-24 02:08:15 +00005407
Chris Lattnere64c5492009-02-27 18:38:20 +00005408 ParseDeclarationSpecifiers(DS);
Mike Stump1eb44332009-09-09 15:08:12 +00005409
Faisal Valifad9e132013-09-26 19:54:12 +00005410
5411 // Parse the declarator. This is "PrototypeContext" or
5412 // "LambdaExprParameterContext", because we must accept either
5413 // 'declarator' or 'abstract-declarator' here.
5414 Declarator ParmDeclarator(DS,
5415 D.getContext() == Declarator::LambdaExprContext ?
5416 Declarator::LambdaExprParameterContext :
5417 Declarator::PrototypeContext);
5418 ParseDeclarator(ParmDeclarator);
Chris Lattnerf97409f2008-04-06 06:57:35 +00005419
5420 // Parse GNU attributes, if present.
Faisal Valifad9e132013-09-26 19:54:12 +00005421 MaybeParseGNUAttributes(ParmDeclarator);
Mike Stump1eb44332009-09-09 15:08:12 +00005422
Chris Lattnerf97409f2008-04-06 06:57:35 +00005423 // Remember this parsed parameter in ParamInfo.
Faisal Valifad9e132013-09-26 19:54:12 +00005424 IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
Mike Stump1eb44332009-09-09 15:08:12 +00005425
Douglas Gregor72b505b2008-12-16 21:30:33 +00005426 // DefArgToks is used when the parsing of default arguments needs
5427 // to be delayed.
5428 CachedTokens *DefArgToks = 0;
5429
Chris Lattnerf97409f2008-04-06 06:57:35 +00005430 // If no parameter was specified, verify that *something* was specified,
5431 // otherwise we have a missing type and identifier.
Faisal Valifad9e132013-09-26 19:54:12 +00005432 if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 &&
5433 ParmDeclarator.getNumTypeObjects() == 0) {
Chris Lattnerf97409f2008-04-06 06:57:35 +00005434 // Completely missing, emit error.
5435 Diag(DSStart, diag::err_missing_param);
5436 } else {
5437 // Otherwise, we have something. Add it and let semantic analysis try
5438 // to grok it and add the result to the ParamInfo we are building.
Mike Stump1eb44332009-09-09 15:08:12 +00005439
Chris Lattnerf97409f2008-04-06 06:57:35 +00005440 // Inform the actions module about the parameter declarator, so it gets
5441 // added to the current scope.
Faisal Valifad9e132013-09-26 19:54:12 +00005442 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(),
5443 ParmDeclarator);
Chris Lattner04421082008-04-08 04:40:51 +00005444 // Parse the default argument, if any. We parse the default
5445 // arguments in all dialects; the semantic analysis in
5446 // ActOnParamDefaultArgument will reject the default argument in
5447 // C.
5448 if (Tok.is(tok::equal)) {
Douglas Gregor61366e92008-12-24 00:01:03 +00005449 SourceLocation EqualLoc = Tok.getLocation();
5450
Chris Lattner04421082008-04-08 04:40:51 +00005451 // Parse the default argument
Douglas Gregor72b505b2008-12-16 21:30:33 +00005452 if (D.getContext() == Declarator::MemberContext) {
5453 // If we're inside a class definition, cache the tokens
5454 // corresponding to the default argument. We'll actually parse
5455 // them when we see the end of the class definition.
Douglas Gregor72b505b2008-12-16 21:30:33 +00005456 // FIXME: Can we use a smart pointer for Toks?
5457 DefArgToks = new CachedTokens;
5458
Richard Smith9bd3cdc2013-09-12 23:28:08 +00005459 if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) {
Douglas Gregor72b505b2008-12-16 21:30:33 +00005460 delete DefArgToks;
5461 DefArgToks = 0;
Douglas Gregor61366e92008-12-24 00:01:03 +00005462 Actions.ActOnParamDefaultArgumentError(Param);
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00005463 } else {
5464 // Mark the end of the default argument so that we know when to
5465 // stop when we parse it later on.
5466 Token DefArgEnd;
5467 DefArgEnd.startToken();
5468 DefArgEnd.setKind(tok::cxx_defaultarg_end);
5469 DefArgEnd.setLocation(Tok.getLocation());
5470 DefArgToks->push_back(DefArgEnd);
Mike Stump1eb44332009-09-09 15:08:12 +00005471 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
Anders Carlsson5e300d12009-06-12 16:51:40 +00005472 (*DefArgToks)[1].getLocation());
Argyrios Kyrtzidis2b602ad2010-08-06 09:47:24 +00005473 }
Chris Lattner04421082008-04-08 04:40:51 +00005474 } else {
Douglas Gregor72b505b2008-12-16 21:30:33 +00005475 // Consume the '='.
Douglas Gregor61366e92008-12-24 00:01:03 +00005476 ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005477
Chad Rosier8decdee2012-06-26 22:30:43 +00005478 // The argument isn't actually potentially evaluated unless it is
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00005479 // used.
5480 EnterExpressionEvaluationContext Eval(Actions,
Douglas Gregorccc1b5e2012-02-21 00:37:24 +00005481 Sema::PotentiallyEvaluatedIfUsed,
5482 Param);
Douglas Gregorbe0f7bd2010-09-11 20:24:53 +00005483
Sebastian Redl84407ba2012-03-14 15:54:00 +00005484 ExprResult DefArgResult;
Richard Smith80ad52f2013-01-02 11:42:31 +00005485 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
Sebastian Redl3e280b52012-03-18 22:25:45 +00005486 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Sebastian Redl84407ba2012-03-14 15:54:00 +00005487 DefArgResult = ParseBraceInitializer();
Sebastian Redl3e280b52012-03-18 22:25:45 +00005488 } else
Sebastian Redl84407ba2012-03-14 15:54:00 +00005489 DefArgResult = ParseAssignmentExpression();
Douglas Gregor72b505b2008-12-16 21:30:33 +00005490 if (DefArgResult.isInvalid()) {
5491 Actions.ActOnParamDefaultArgumentError(Param);
Alexey Bataev8fe24752013-11-18 08:17:37 +00005492 SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
Douglas Gregor72b505b2008-12-16 21:30:33 +00005493 } else {
5494 // Inform the actions module about the default argument
5495 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
John McCall9ae2f072010-08-23 23:25:46 +00005496 DefArgResult.take());
Douglas Gregor72b505b2008-12-16 21:30:33 +00005497 }
Chris Lattner04421082008-04-08 04:40:51 +00005498 }
5499 }
Mike Stump1eb44332009-09-09 15:08:12 +00005500
5501 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
Faisal Valifad9e132013-09-26 19:54:12 +00005502 ParmDeclarator.getIdentifierLoc(),
5503 Param, DefArgToks));
Chris Lattnerf97409f2008-04-06 06:57:35 +00005504 }
5505
5506 // If the next token is a comma, consume it and keep reading arguments.
Douglas Gregored5d6512009-09-22 21:41:40 +00005507 if (Tok.isNot(tok::comma)) {
5508 if (Tok.is(tok::ellipsis)) {
Douglas Gregored5d6512009-09-22 21:41:40 +00005509 EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
Chad Rosier8decdee2012-06-26 22:30:43 +00005510
David Blaikie4e4d0842012-03-11 07:00:24 +00005511 if (!getLangOpts().CPlusPlus) {
Douglas Gregored5d6512009-09-22 21:41:40 +00005512 // We have ellipsis without a preceding ',', which is ill-formed
5513 // in C. Complain and provide the fix.
5514 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
Douglas Gregor849b2432010-03-31 17:46:05 +00005515 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
Douglas Gregored5d6512009-09-22 21:41:40 +00005516 }
5517 }
Chad Rosier8decdee2012-06-26 22:30:43 +00005518
Douglas Gregored5d6512009-09-22 21:41:40 +00005519 break;
5520 }
Mike Stump1eb44332009-09-09 15:08:12 +00005521
Chris Lattnerf97409f2008-04-06 06:57:35 +00005522 // Consume the comma.
5523 ConsumeToken();
Reid Spencer5f016e22007-07-11 17:01:13 +00005524 }
Mike Stump1eb44332009-09-09 15:08:12 +00005525
Chris Lattner66d28652008-04-06 06:34:08 +00005526}
Chris Lattneref4715c2008-04-06 05:45:57 +00005527
Reid Spencer5f016e22007-07-11 17:01:13 +00005528/// [C90] direct-declarator '[' constant-expression[opt] ']'
5529/// [C99] direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
5530/// [C99] direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
5531/// [C99] direct-declarator '[' type-qual-list 'static' assignment-expr ']'
5532/// [C99] direct-declarator '[' type-qual-list[opt] '*' ']'
Richard Smith6ee326a2012-04-10 01:32:12 +00005533/// [C++11] direct-declarator '[' constant-expression[opt] ']'
5534/// attribute-specifier-seq[opt]
Reid Spencer5f016e22007-07-11 17:01:13 +00005535void Parser::ParseBracketDeclarator(Declarator &D) {
Richard Smith6ee326a2012-04-10 01:32:12 +00005536 if (CheckProhibitedCXX11Attribute())
5537 return;
5538
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005539 BalancedDelimiterTracker T(*this, tok::l_square);
5540 T.consumeOpen();
Mike Stump1eb44332009-09-09 15:08:12 +00005541
Chris Lattner378c7e42008-12-18 07:27:21 +00005542 // C array syntax has many features, but by-far the most common is [] and [4].
5543 // This code does a fast path to handle some of the most obvious cases.
5544 if (Tok.getKind() == tok::r_square) {
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005545 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00005546 ParsedAttributes attrs(AttrFactory);
Richard Smith4e24f0f2013-01-02 12:01:23 +00005547 MaybeParseCXX11Attributes(attrs);
Chad Rosier8decdee2012-06-26 22:30:43 +00005548
Chris Lattner378c7e42008-12-18 07:27:21 +00005549 // Remember that we parsed the empty array type.
John McCall60d7b3a2010-08-24 06:29:42 +00005550 ExprResult NumElements;
John McCall0b7e6782011-03-24 11:26:52 +00005551 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005552 T.getOpenLocation(),
5553 T.getCloseLocation()),
5554 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00005555 return;
5556 } else if (Tok.getKind() == tok::numeric_constant &&
5557 GetLookAheadToken(1).is(tok::r_square)) {
5558 // [4] is very common. Parse the numeric constant expression.
Richard Smith36f5cfe2012-03-09 08:00:36 +00005559 ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
Chris Lattner378c7e42008-12-18 07:27:21 +00005560 ConsumeToken();
5561
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005562 T.consumeClose();
John McCall0b7e6782011-03-24 11:26:52 +00005563 ParsedAttributes attrs(AttrFactory);
Richard Smith4e24f0f2013-01-02 12:01:23 +00005564 MaybeParseCXX11Attributes(attrs);
Mike Stump1eb44332009-09-09 15:08:12 +00005565
Chris Lattner378c7e42008-12-18 07:27:21 +00005566 // Remember that we parsed a array type, and remember its features.
Nikola Smiljanicebf0fa82013-01-11 08:33:05 +00005567 D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
John McCall7f040a92010-12-24 02:08:15 +00005568 ExprRes.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005569 T.getOpenLocation(),
5570 T.getCloseLocation()),
5571 attrs, T.getCloseLocation());
Chris Lattner378c7e42008-12-18 07:27:21 +00005572 return;
5573 }
Mike Stump1eb44332009-09-09 15:08:12 +00005574
Reid Spencer5f016e22007-07-11 17:01:13 +00005575 // If valid, this location is the position where we read the 'static' keyword.
5576 SourceLocation StaticLoc;
Chris Lattner04d66662007-10-09 17:33:22 +00005577 if (Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00005578 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005579
Reid Spencer5f016e22007-07-11 17:01:13 +00005580 // If there is a type-qualifier-list, read it now.
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005581 // Type qualifiers in an array subscript are a C99 feature.
John McCall0b7e6782011-03-24 11:26:52 +00005582 DeclSpec DS(AttrFactory);
Chris Lattner5a69d1c2008-12-18 07:02:59 +00005583 ParseTypeQualifierListOpt(DS, false /*no attributes*/);
Mike Stump1eb44332009-09-09 15:08:12 +00005584
Reid Spencer5f016e22007-07-11 17:01:13 +00005585 // If we haven't already read 'static', check to see if there is one after the
5586 // type-qualifier-list.
Chris Lattner04d66662007-10-09 17:33:22 +00005587 if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
Reid Spencer5f016e22007-07-11 17:01:13 +00005588 StaticLoc = ConsumeToken();
Mike Stump1eb44332009-09-09 15:08:12 +00005589
Reid Spencer5f016e22007-07-11 17:01:13 +00005590 // Handle "direct-declarator [ type-qual-list[opt] * ]".
5591 bool isStar = false;
John McCall60d7b3a2010-08-24 06:29:42 +00005592 ExprResult NumElements;
Mike Stump1eb44332009-09-09 15:08:12 +00005593
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005594 // Handle the case where we have '[*]' as the array size. However, a leading
5595 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
Sylvestre Ledrubed28ac2012-07-23 08:59:39 +00005596 // the token after the star is a ']'. Since stars in arrays are
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005597 // infrequent, use of lookahead is not costly here.
5598 if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
Chris Lattnera711dd02008-04-06 05:27:21 +00005599 ConsumeToken(); // Eat the '*'.
Reid Spencer5f016e22007-07-11 17:01:13 +00005600
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005601 if (StaticLoc.isValid()) {
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005602 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
Chris Lattnera1fcbad2008-12-18 06:50:14 +00005603 StaticLoc = SourceLocation(); // Drop the static.
5604 }
Chris Lattner5dcc6ce2008-04-06 05:26:30 +00005605 isStar = true;
Chris Lattner04d66662007-10-09 17:33:22 +00005606 } else if (Tok.isNot(tok::r_square)) {
Chris Lattner378c7e42008-12-18 07:27:21 +00005607 // Note, in C89, this production uses the constant-expr production instead
5608 // of assignment-expr. The only difference is that assignment-expr allows
5609 // things like '=' and '*='. Sema rejects these in C89 mode because they
5610 // are not i-c-e's, so we don't need to distinguish between the two here.
Mike Stump1eb44332009-09-09 15:08:12 +00005611
Douglas Gregore0762c92009-06-19 23:52:42 +00005612 // Parse the constant-expression or assignment-expression now (depending
5613 // on dialect).
David Blaikie4e4d0842012-03-11 07:00:24 +00005614 if (getLangOpts().CPlusPlus) {
Douglas Gregore0762c92009-06-19 23:52:42 +00005615 NumElements = ParseConstantExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00005616 } else {
5617 EnterExpressionEvaluationContext Unevaluated(Actions,
5618 Sema::ConstantEvaluated);
Douglas Gregore0762c92009-06-19 23:52:42 +00005619 NumElements = ParseAssignmentExpression();
Eli Friedman71b8fb52012-01-21 01:01:51 +00005620 }
Reid Spencer5f016e22007-07-11 17:01:13 +00005621 }
Mike Stump1eb44332009-09-09 15:08:12 +00005622
Reid Spencer5f016e22007-07-11 17:01:13 +00005623 // If there was an error parsing the assignment-expression, recover.
Sebastian Redl0e9eabc2008-12-09 13:15:23 +00005624 if (NumElements.isInvalid()) {
Chris Lattner5cb10d32009-04-24 22:30:50 +00005625 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +00005626 // If the expression was invalid, skip it.
Alexey Bataev8fe24752013-11-18 08:17:37 +00005627 SkipUntil(tok::r_square, StopAtSemi);
Reid Spencer5f016e22007-07-11 17:01:13 +00005628 return;
5629 }
Sebastian Redlab197ba2009-02-09 18:23:29 +00005630
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005631 T.consumeClose();
Sebastian Redlab197ba2009-02-09 18:23:29 +00005632
John McCall0b7e6782011-03-24 11:26:52 +00005633 ParsedAttributes attrs(AttrFactory);
Richard Smith4e24f0f2013-01-02 12:01:23 +00005634 MaybeParseCXX11Attributes(attrs);
Sean Huntbbd37c62009-11-21 08:43:09 +00005635
Chris Lattner378c7e42008-12-18 07:27:21 +00005636 // Remember that we parsed a array type, and remember its features.
John McCall0b7e6782011-03-24 11:26:52 +00005637 D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
Reid Spencer5f016e22007-07-11 17:01:13 +00005638 StaticLoc.isValid(), isStar,
Douglas Gregor7e7eb3d2009-07-06 15:59:29 +00005639 NumElements.release(),
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005640 T.getOpenLocation(),
5641 T.getCloseLocation()),
5642 attrs, T.getCloseLocation());
Reid Spencer5f016e22007-07-11 17:01:13 +00005643}
5644
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005645/// [GNU] typeof-specifier:
5646/// typeof ( expressions )
5647/// typeof ( type-name )
5648/// [GNU/C++] typeof unary-expression
Steve Naroffd1861fd2007-07-31 12:34:36 +00005649///
5650void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
Chris Lattner04d66662007-10-09 17:33:22 +00005651 assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005652 Token OpTok = Tok;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005653 SourceLocation StartLoc = ConsumeToken();
5654
John McCallcfb708c2010-01-13 20:03:27 +00005655 const bool hasParens = Tok.is(tok::l_paren);
5656
Eli Friedman80bfa3d2012-09-26 04:34:21 +00005657 EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
5658 Sema::ReuseLambdaContextDecl);
Eli Friedman71b8fb52012-01-21 01:01:51 +00005659
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005660 bool isCastExpr;
John McCallb3d87482010-08-24 05:47:05 +00005661 ParsedType CastTy;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005662 SourceRange CastRange;
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00005663 ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
5664 CastTy, CastRange);
John McCallcfb708c2010-01-13 20:03:27 +00005665 if (hasParens)
5666 DS.setTypeofParensRange(CastRange);
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005667
5668 if (CastRange.getEnd().isInvalid())
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005669 // FIXME: Not accurate, the range gets one token more than it should.
5670 DS.SetRangeEnd(Tok.getLocation());
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005671 else
5672 DS.SetRangeEnd(CastRange.getEnd());
Mike Stump1eb44332009-09-09 15:08:12 +00005673
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005674 if (isCastExpr) {
5675 if (!CastTy) {
5676 DS.SetTypeSpecError();
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005677 return;
Douglas Gregor809070a2009-02-18 17:45:20 +00005678 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005679
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005680 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005681 unsigned DiagID;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005682 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5683 if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
John McCallfec54012009-08-03 20:12:06 +00005684 DiagID, CastTy))
5685 Diag(StartLoc, DiagID) << PrevSpec;
Argyrios Kyrtzidis5ab06402009-05-22 10:22:50 +00005686 return;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005687 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005688
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005689 // If we get here, the operand to the typeof was an expresion.
5690 if (Operand.isInvalid()) {
5691 DS.SetTypeSpecError();
Steve Naroff9dfa7b42007-08-02 02:53:48 +00005692 return;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005693 }
Argyrios Kyrtzidis0f072032008-09-05 11:26:19 +00005694
Eli Friedman71b8fb52012-01-21 01:01:51 +00005695 // We might need to transform the operand if it is potentially evaluated.
5696 Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5697 if (Operand.isInvalid()) {
5698 DS.SetTypeSpecError();
5699 return;
5700 }
5701
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005702 const char *PrevSpec = 0;
John McCallfec54012009-08-03 20:12:06 +00005703 unsigned DiagID;
Argyrios Kyrtzidis64096252009-05-22 10:22:18 +00005704 // Check for duplicate type specifiers (e.g. "int typeof(int)").
5705 if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
John McCallb3d87482010-08-24 05:47:05 +00005706 DiagID, Operand.get()))
John McCallfec54012009-08-03 20:12:06 +00005707 Diag(StartLoc, DiagID) << PrevSpec;
Steve Naroffd1861fd2007-07-31 12:34:36 +00005708}
Chris Lattner1b492422010-02-28 18:33:55 +00005709
Benjamin Kramerffbe9b92011-12-23 17:00:35 +00005710/// [C11] atomic-specifier:
Eli Friedmanb001de72011-10-06 23:00:33 +00005711/// _Atomic ( type-name )
5712///
5713void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
Richard Smith4cf4a5e2013-03-28 01:55:44 +00005714 assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) &&
5715 "Not an atomic specifier");
Eli Friedmanb001de72011-10-06 23:00:33 +00005716
5717 SourceLocation StartLoc = ConsumeToken();
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005718 BalancedDelimiterTracker T(*this, tok::l_paren);
Richard Smith4cf4a5e2013-03-28 01:55:44 +00005719 if (T.consumeOpen())
Eli Friedmanb001de72011-10-06 23:00:33 +00005720 return;
Eli Friedmanb001de72011-10-06 23:00:33 +00005721
5722 TypeResult Result = ParseTypeName();
5723 if (Result.isInvalid()) {
Alexey Bataev8fe24752013-11-18 08:17:37 +00005724 SkipUntil(tok::r_paren, StopAtSemi);
Eli Friedmanb001de72011-10-06 23:00:33 +00005725 return;
5726 }
5727
5728 // Match the ')'
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005729 T.consumeClose();
Eli Friedmanb001de72011-10-06 23:00:33 +00005730
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005731 if (T.getCloseLocation().isInvalid())
Eli Friedmanb001de72011-10-06 23:00:33 +00005732 return;
5733
Douglas Gregor4a8dfb52011-10-12 16:37:45 +00005734 DS.setTypeofParensRange(T.getRange());
5735 DS.SetRangeEnd(T.getCloseLocation());
Eli Friedmanb001de72011-10-06 23:00:33 +00005736
5737 const char *PrevSpec = 0;
5738 unsigned DiagID;
5739 if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5740 DiagID, Result.release()))
5741 Diag(StartLoc, DiagID) << PrevSpec;
5742}
5743
Chris Lattner1b492422010-02-28 18:33:55 +00005744
5745/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5746/// from TryAltiVecVectorToken.
5747bool Parser::TryAltiVecVectorTokenOutOfLine() {
5748 Token Next = NextToken();
5749 switch (Next.getKind()) {
5750 default: return false;
5751 case tok::kw_short:
5752 case tok::kw_long:
5753 case tok::kw_signed:
5754 case tok::kw_unsigned:
5755 case tok::kw_void:
5756 case tok::kw_char:
5757 case tok::kw_int:
5758 case tok::kw_float:
5759 case tok::kw_double:
5760 case tok::kw_bool:
5761 case tok::kw___pixel:
5762 Tok.setKind(tok::kw___vector);
5763 return true;
5764 case tok::identifier:
5765 if (Next.getIdentifierInfo() == Ident_pixel) {
5766 Tok.setKind(tok::kw___vector);
5767 return true;
5768 }
Bill Schmidt3e3d20b2013-07-03 20:54:09 +00005769 if (Next.getIdentifierInfo() == Ident_bool) {
5770 Tok.setKind(tok::kw___vector);
5771 return true;
5772 }
Chris Lattner1b492422010-02-28 18:33:55 +00005773 return false;
5774 }
5775}
5776
5777bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5778 const char *&PrevSpec, unsigned &DiagID,
5779 bool &isInvalid) {
5780 if (Tok.getIdentifierInfo() == Ident_vector) {
5781 Token Next = NextToken();
5782 switch (Next.getKind()) {
5783 case tok::kw_short:
5784 case tok::kw_long:
5785 case tok::kw_signed:
5786 case tok::kw_unsigned:
5787 case tok::kw_void:
5788 case tok::kw_char:
5789 case tok::kw_int:
5790 case tok::kw_float:
5791 case tok::kw_double:
5792 case tok::kw_bool:
5793 case tok::kw___pixel:
5794 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5795 return true;
5796 case tok::identifier:
5797 if (Next.getIdentifierInfo() == Ident_pixel) {
5798 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5799 return true;
5800 }
Bill Schmidt3e3d20b2013-07-03 20:54:09 +00005801 if (Next.getIdentifierInfo() == Ident_bool) {
5802 isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5803 return true;
5804 }
Chris Lattner1b492422010-02-28 18:33:55 +00005805 break;
5806 default:
5807 break;
5808 }
Douglas Gregora8f031f2010-06-16 15:28:57 +00005809 } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
Chris Lattner1b492422010-02-28 18:33:55 +00005810 DS.isTypeAltiVecVector()) {
5811 isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5812 return true;
Bill Schmidt3e3d20b2013-07-03 20:54:09 +00005813 } else if ((Tok.getIdentifierInfo() == Ident_bool) &&
5814 DS.isTypeAltiVecVector()) {
5815 isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID);
5816 return true;
Chris Lattner1b492422010-02-28 18:33:55 +00005817 }
5818 return false;
5819}