ParseDecl.cpp revision 239462
1193326Sed//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file implements the Declaration portions of the Parser interfaces.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/Parse/Parser.h"
15193326Sed#include "clang/Parse/ParseDiagnostic.h"
16221345Sdim#include "clang/Basic/OpenCL.h"
17239462Sdim#include "clang/Sema/Lookup.h"
18212904Sdim#include "clang/Sema/Scope.h"
19212904Sdim#include "clang/Sema/ParsedTemplate.h"
20212904Sdim#include "clang/Sema/PrettyDeclStackTrace.h"
21200583Srdivacky#include "RAIIObjectsForParser.h"
22193326Sed#include "llvm/ADT/SmallSet.h"
23234353Sdim#include "llvm/ADT/SmallString.h"
24226633Sdim#include "llvm/ADT/StringSwitch.h"
25193326Sedusing namespace clang;
26193326Sed
27193326Sed//===----------------------------------------------------------------------===//
28193326Sed// C99 6.7: Declarations.
29193326Sed//===----------------------------------------------------------------------===//
30193326Sed
31193326Sed/// ParseTypeName
32193326Sed///       type-name: [C99 6.7.6]
33193326Sed///         specifier-qualifier-list abstract-declarator[opt]
34193326Sed///
35193326Sed/// Called type-id in C++.
36218893SdimTypeResult Parser::ParseTypeName(SourceRange *Range,
37224145Sdim                                 Declarator::TheContext Context,
38224145Sdim                                 AccessSpecifier AS,
39224145Sdim                                 Decl **OwnedType) {
40234353Sdim  DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
41239462Sdim  if (DSC == DSC_normal)
42239462Sdim    DSC = DSC_type_specifier;
43234353Sdim
44193326Sed  // Parse the common declaration-specifiers piece.
45221345Sdim  DeclSpec DS(AttrFactory);
46234353Sdim  ParseSpecifierQualifierList(DS, AS, DSC);
47224145Sdim  if (OwnedType)
48224145Sdim    *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
49193326Sed
50193326Sed  // Parse the abstract-declarator, if present.
51218893Sdim  Declarator DeclaratorInfo(DS, Context);
52193326Sed  ParseDeclarator(DeclaratorInfo);
53193326Sed  if (Range)
54193326Sed    *Range = DeclaratorInfo.getSourceRange();
55193326Sed
56193326Sed  if (DeclaratorInfo.isInvalidType())
57193326Sed    return true;
58193326Sed
59210299Sed  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
60193326Sed}
61193326Sed
62226633Sdim
63226633Sdim/// isAttributeLateParsed - Return true if the attribute has arguments that
64226633Sdim/// require late parsing.
65226633Sdimstatic bool isAttributeLateParsed(const IdentifierInfo &II) {
66226633Sdim    return llvm::StringSwitch<bool>(II.getName())
67226633Sdim#include "clang/Parse/AttrLateParsed.inc"
68226633Sdim        .Default(false);
69226633Sdim}
70226633Sdim
71199990Srdivacky/// ParseGNUAttributes - Parse a non-empty attributes list.
72193326Sed///
73193326Sed/// [GNU] attributes:
74193326Sed///         attribute
75193326Sed///         attributes attribute
76193326Sed///
77193326Sed/// [GNU]  attribute:
78193326Sed///          '__attribute__' '(' '(' attribute-list ')' ')'
79193326Sed///
80193326Sed/// [GNU]  attribute-list:
81193326Sed///          attrib
82193326Sed///          attribute_list ',' attrib
83193326Sed///
84193326Sed/// [GNU]  attrib:
85193326Sed///          empty
86193326Sed///          attrib-name
87193326Sed///          attrib-name '(' identifier ')'
88193326Sed///          attrib-name '(' identifier ',' nonempty-expr-list ')'
89193326Sed///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
90193326Sed///
91193326Sed/// [GNU]  attrib-name:
92193326Sed///          identifier
93193326Sed///          typespec
94193326Sed///          typequal
95193326Sed///          storageclass
96198092Srdivacky///
97193326Sed/// FIXME: The GCC grammar/code for this construct implies we need two
98198092Srdivacky/// token lookahead. Comment from gcc: "If they start with an identifier
99198092Srdivacky/// which is followed by a comma or close parenthesis, then the arguments
100193326Sed/// start with that identifier; otherwise they are an expression list."
101193326Sed///
102234353Sdim/// GCC does not require the ',' between attribs in an attribute-list.
103234353Sdim///
104193326Sed/// At the moment, I am not doing 2 token lookahead. I am also unaware of
105193326Sed/// any attributes that don't work (based on my limited testing). Most
106193326Sed/// attributes are very simple in practice. Until we find a bug, I don't see
107193326Sed/// a pressing need to implement the 2 token lookahead.
108193326Sed
109218893Sdimvoid Parser::ParseGNUAttributes(ParsedAttributes &attrs,
110226633Sdim                                SourceLocation *endLoc,
111226633Sdim                                LateParsedAttrList *LateAttrs) {
112199990Srdivacky  assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
113198092Srdivacky
114193326Sed  while (Tok.is(tok::kw___attribute)) {
115193326Sed    ConsumeToken();
116193326Sed    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
117193326Sed                         "attribute")) {
118193326Sed      SkipUntil(tok::r_paren, true); // skip until ) or ;
119218893Sdim      return;
120193326Sed    }
121193326Sed    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
122193326Sed      SkipUntil(tok::r_paren, true); // skip until ) or ;
123218893Sdim      return;
124193326Sed    }
125193326Sed    // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
126193326Sed    while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
127193326Sed           Tok.is(tok::comma)) {
128198092Srdivacky      if (Tok.is(tok::comma)) {
129193326Sed        // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
130193326Sed        ConsumeToken();
131193326Sed        continue;
132193326Sed      }
133193326Sed      // we have an identifier or declaration specifier (const, int, etc.)
134193326Sed      IdentifierInfo *AttrName = Tok.getIdentifierInfo();
135193326Sed      SourceLocation AttrNameLoc = ConsumeToken();
136198092Srdivacky
137226633Sdim      if (Tok.is(tok::l_paren)) {
138226633Sdim        // handle "parameterized" attributes
139234353Sdim        if (LateAttrs && isAttributeLateParsed(*AttrName)) {
140226633Sdim          LateParsedAttribute *LA =
141226633Sdim            new LateParsedAttribute(this, *AttrName, AttrNameLoc);
142226633Sdim          LateAttrs->push_back(LA);
143198092Srdivacky
144234353Sdim          // Attributes in a class are parsed at the end of the class, along
145234353Sdim          // with other late-parsed declarations.
146234353Sdim          if (!ClassStack.empty())
147234353Sdim            getCurrentClass().LateParsedDeclarations.push_back(LA);
148234353Sdim
149226633Sdim          // consume everything up to and including the matching right parens
150226633Sdim          ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
151198092Srdivacky
152226633Sdim          Token Eof;
153226633Sdim          Eof.startToken();
154226633Sdim          Eof.setLocation(Tok.getLocation());
155226633Sdim          LA->Toks.push_back(Eof);
156226633Sdim        } else {
157226633Sdim          ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc);
158193326Sed        }
159193326Sed      } else {
160221345Sdim        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
161239462Sdim                     0, SourceLocation(), 0, 0, AttributeList::AS_GNU);
162193326Sed      }
163193326Sed    }
164193326Sed    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
165193326Sed      SkipUntil(tok::r_paren, false);
166199990Srdivacky    SourceLocation Loc = Tok.getLocation();
167193326Sed    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
168193326Sed      SkipUntil(tok::r_paren, false);
169193326Sed    }
170218893Sdim    if (endLoc)
171218893Sdim      *endLoc = Loc;
172193326Sed  }
173193326Sed}
174193326Sed
175226633Sdim
176226633Sdim/// Parse the arguments to a parameterized GNU attribute
177226633Sdimvoid Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
178226633Sdim                                   SourceLocation AttrNameLoc,
179226633Sdim                                   ParsedAttributes &Attrs,
180226633Sdim                                   SourceLocation *EndLoc) {
181226633Sdim
182226633Sdim  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
183226633Sdim
184226633Sdim  // Availability attributes have their own grammar.
185226633Sdim  if (AttrName->isStr("availability")) {
186226633Sdim    ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
187226633Sdim    return;
188226633Sdim  }
189226633Sdim  // Thread safety attributes fit into the FIXME case above, so we
190226633Sdim  // just parse the arguments as a list of expressions
191226633Sdim  if (IsThreadSafetyAttribute(AttrName->getName())) {
192226633Sdim    ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
193226633Sdim    return;
194226633Sdim  }
195239462Sdim  // Type safety attributes have their own grammar.
196239462Sdim  if (AttrName->isStr("type_tag_for_datatype")) {
197239462Sdim    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
198239462Sdim    return;
199239462Sdim  }
200226633Sdim
201226633Sdim  ConsumeParen(); // ignore the left paren loc for now
202226633Sdim
203234353Sdim  IdentifierInfo *ParmName = 0;
204234353Sdim  SourceLocation ParmLoc;
205234353Sdim  bool BuiltinType = false;
206226633Sdim
207234353Sdim  switch (Tok.getKind()) {
208234353Sdim  case tok::kw_char:
209234353Sdim  case tok::kw_wchar_t:
210234353Sdim  case tok::kw_char16_t:
211234353Sdim  case tok::kw_char32_t:
212234353Sdim  case tok::kw_bool:
213234353Sdim  case tok::kw_short:
214234353Sdim  case tok::kw_int:
215234353Sdim  case tok::kw_long:
216234353Sdim  case tok::kw___int64:
217234353Sdim  case tok::kw___int128:
218234353Sdim  case tok::kw_signed:
219234353Sdim  case tok::kw_unsigned:
220234353Sdim  case tok::kw_float:
221234353Sdim  case tok::kw_double:
222234353Sdim  case tok::kw_void:
223234353Sdim  case tok::kw_typeof:
224234353Sdim    // __attribute__(( vec_type_hint(char) ))
225234353Sdim    // FIXME: Don't just discard the builtin type token.
226234353Sdim    ConsumeToken();
227234353Sdim    BuiltinType = true;
228234353Sdim    break;
229234353Sdim
230234353Sdim  case tok::identifier:
231234353Sdim    ParmName = Tok.getIdentifierInfo();
232234353Sdim    ParmLoc = ConsumeToken();
233234353Sdim    break;
234234353Sdim
235234353Sdim  default:
236234353Sdim    break;
237234353Sdim  }
238234353Sdim
239234353Sdim  ExprVector ArgExprs(Actions);
240234353Sdim
241234353Sdim  if (!BuiltinType &&
242234353Sdim      (ParmLoc.isValid() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren))) {
243234353Sdim    // Eat the comma.
244234353Sdim    if (ParmLoc.isValid())
245226633Sdim      ConsumeToken();
246226633Sdim
247234353Sdim    // Parse the non-empty comma-separated list of expressions.
248234353Sdim    while (1) {
249234353Sdim      ExprResult ArgExpr(ParseAssignmentExpression());
250234353Sdim      if (ArgExpr.isInvalid()) {
251234353Sdim        SkipUntil(tok::r_paren);
252234353Sdim        return;
253226633Sdim      }
254234353Sdim      ArgExprs.push_back(ArgExpr.release());
255234353Sdim      if (Tok.isNot(tok::comma))
256234353Sdim        break;
257234353Sdim      ConsumeToken(); // Eat the comma, move to the next argument
258226633Sdim    }
259234353Sdim  }
260234353Sdim  else if (Tok.is(tok::less) && AttrName->isStr("iboutletcollection")) {
261234353Sdim    if (!ExpectAndConsume(tok::less, diag::err_expected_less_after, "<",
262234353Sdim                          tok::greater)) {
263234353Sdim      while (Tok.is(tok::identifier)) {
264234353Sdim        ConsumeToken();
265234353Sdim        if (Tok.is(tok::greater))
266226633Sdim          break;
267234353Sdim        if (Tok.is(tok::comma)) {
268234353Sdim          ConsumeToken();
269234353Sdim          continue;
270226633Sdim        }
271226633Sdim      }
272234353Sdim      if (Tok.isNot(tok::greater))
273234353Sdim        Diag(Tok, diag::err_iboutletcollection_with_protocol);
274234353Sdim      SkipUntil(tok::r_paren, false, true); // skip until ')'
275226633Sdim    }
276226633Sdim  }
277234353Sdim
278234353Sdim  SourceLocation RParen = Tok.getLocation();
279234353Sdim  if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
280234353Sdim    AttributeList *attr =
281234353Sdim      Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0, AttrNameLoc,
282239462Sdim                   ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size(),
283239462Sdim                   AttributeList::AS_GNU);
284239462Sdim    if (BuiltinType && attr->getKind() == AttributeList::AT_IBOutletCollection)
285234353Sdim      Diag(Tok, diag::err_iboutletcollection_builtintype);
286234353Sdim  }
287226633Sdim}
288226633Sdim
289239462Sdim/// \brief Parses a single argument for a declspec, including the
290239462Sdim/// surrounding parens.
291239462Sdimvoid Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
292239462Sdim                                                 SourceLocation AttrNameLoc,
293239462Sdim                                                 ParsedAttributes &Attrs)
294239462Sdim{
295239462Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
296239462Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after,
297239462Sdim                         AttrName->getNameStart(), tok::r_paren))
298239462Sdim    return;
299226633Sdim
300239462Sdim  ExprResult ArgExpr(ParseConstantExpression());
301239462Sdim  if (ArgExpr.isInvalid()) {
302239462Sdim    T.skipToEnd();
303239462Sdim    return;
304239462Sdim  }
305239462Sdim  Expr *ExprList = ArgExpr.take();
306239462Sdim  Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
307239462Sdim               &ExprList, 1, AttributeList::AS_Declspec);
308239462Sdim
309239462Sdim  T.consumeClose();
310239462Sdim}
311239462Sdim
312239462Sdim/// \brief Determines whether a declspec is a "simple" one requiring no
313239462Sdim/// arguments.
314239462Sdimbool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) {
315239462Sdim  return llvm::StringSwitch<bool>(Ident->getName())
316239462Sdim    .Case("dllimport", true)
317239462Sdim    .Case("dllexport", true)
318239462Sdim    .Case("noreturn", true)
319239462Sdim    .Case("nothrow", true)
320239462Sdim    .Case("noinline", true)
321239462Sdim    .Case("naked", true)
322239462Sdim    .Case("appdomain", true)
323239462Sdim    .Case("process", true)
324239462Sdim    .Case("jitintrinsic", true)
325239462Sdim    .Case("noalias", true)
326239462Sdim    .Case("restrict", true)
327239462Sdim    .Case("novtable", true)
328239462Sdim    .Case("selectany", true)
329239462Sdim    .Case("thread", true)
330239462Sdim    .Default(false);
331239462Sdim}
332239462Sdim
333239462Sdim/// \brief Attempts to parse a declspec which is not simple (one that takes
334239462Sdim/// parameters).  Will return false if we properly handled the declspec, or
335239462Sdim/// true if it is an unknown declspec.
336239462Sdimvoid Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
337239462Sdim                                           SourceLocation Loc,
338239462Sdim                                           ParsedAttributes &Attrs) {
339239462Sdim  // Try to handle the easy case first -- these declspecs all take a single
340239462Sdim  // parameter as their argument.
341239462Sdim  if (llvm::StringSwitch<bool>(Ident->getName())
342239462Sdim      .Case("uuid", true)
343239462Sdim      .Case("align", true)
344239462Sdim      .Case("allocate", true)
345239462Sdim      .Default(false)) {
346239462Sdim    ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
347239462Sdim  } else if (Ident->getName() == "deprecated") {
348239462Sdim    // The deprecated declspec has an optional single argument, so we will
349239462Sdim    // check for a l-paren to decide whether we should parse an argument or
350239462Sdim    // not.
351239462Sdim    if (Tok.getKind() == tok::l_paren)
352239462Sdim      ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
353239462Sdim    else
354239462Sdim      Attrs.addNew(Ident, Loc, 0, Loc, 0, SourceLocation(), 0, 0,
355239462Sdim                   AttributeList::AS_Declspec);
356239462Sdim  } else if (Ident->getName() == "property") {
357239462Sdim    // The property declspec is more complex in that it can take one or two
358239462Sdim    // assignment expressions as a parameter, but the lhs of the assignment
359239462Sdim    // must be named get or put.
360239462Sdim    //
361239462Sdim    // For right now, we will just skip to the closing right paren of the
362239462Sdim    // property expression.
363239462Sdim    //
364239462Sdim    // FIXME: we should deal with __declspec(property) at some point because it
365239462Sdim    // is used in the platform SDK headers for the Parallel Patterns Library
366239462Sdim    // and ATL.
367239462Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
368239462Sdim    if (T.expectAndConsume(diag::err_expected_lparen_after,
369239462Sdim                           Ident->getNameStart(), tok::r_paren))
370239462Sdim      return;
371239462Sdim    T.skipToEnd();
372239462Sdim  } else {
373239462Sdim    // We don't recognize this as a valid declspec, but instead of creating the
374239462Sdim    // attribute and allowing sema to warn about it, we will warn here instead.
375239462Sdim    // This is because some attributes have multiple spellings, but we need to
376239462Sdim    // disallow that for declspecs (such as align vs aligned).  If we made the
377239462Sdim    // attribute, we'd have to split the valid declspec spelling logic into
378239462Sdim    // both locations.
379239462Sdim    Diag(Loc, diag::warn_ms_declspec_unknown) << Ident;
380239462Sdim
381239462Sdim    // If there's an open paren, we should eat the open and close parens under
382239462Sdim    // the assumption that this unknown declspec has parameters.
383239462Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
384239462Sdim    if (!T.consumeOpen())
385239462Sdim      T.skipToEnd();
386239462Sdim  }
387239462Sdim}
388239462Sdim
389193725Sed/// [MS] decl-specifier:
390193725Sed///             __declspec ( extended-decl-modifier-seq )
391193725Sed///
392193725Sed/// [MS] extended-decl-modifier-seq:
393193725Sed///             extended-decl-modifier[opt]
394193725Sed///             extended-decl-modifier extended-decl-modifier-seq
395239462Sdimvoid Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
396193326Sed  assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
397193725Sed
398193326Sed  ConsumeToken();
399239462Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
400239462Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
401239462Sdim                         tok::r_paren))
402218893Sdim    return;
403223017Sdim
404239462Sdim  // An empty declspec is perfectly legal and should not warn.  Additionally,
405239462Sdim  // you can specify multiple attributes per declspec.
406239462Sdim  while (Tok.getKind() != tok::r_paren) {
407239462Sdim    // We expect either a well-known identifier or a generic string.  Anything
408239462Sdim    // else is a malformed declspec.
409239462Sdim    bool IsString = Tok.getKind() == tok::string_literal ? true : false;
410239462Sdim    if (!IsString && Tok.getKind() != tok::identifier &&
411239462Sdim        Tok.getKind() != tok::kw_restrict) {
412239462Sdim      Diag(Tok, diag::err_ms_declspec_type);
413239462Sdim      T.skipToEnd();
414239462Sdim      return;
415223017Sdim    }
416239462Sdim
417239462Sdim    IdentifierInfo *AttrName;
418239462Sdim    SourceLocation AttrNameLoc;
419239462Sdim    if (IsString) {
420239462Sdim      SmallString<8> StrBuffer;
421239462Sdim      bool Invalid = false;
422239462Sdim      StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
423239462Sdim      if (Invalid) {
424239462Sdim        T.skipToEnd();
425239462Sdim        return;
426193725Sed      }
427239462Sdim      AttrName = PP.getIdentifierInfo(Str);
428239462Sdim      AttrNameLoc = ConsumeStringToken();
429193725Sed    } else {
430239462Sdim      AttrName = Tok.getIdentifierInfo();
431239462Sdim      AttrNameLoc = ConsumeToken();
432193725Sed    }
433239462Sdim
434239462Sdim    if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
435239462Sdim      // If we have a generic string, we will allow it because there is no
436239462Sdim      // documented list of allowable string declspecs, but we know they exist
437239462Sdim      // (for instance, SAL declspecs in older versions of MSVC).
438239462Sdim      //
439239462Sdim      // Alternatively, if the identifier is a simple one, then it requires no
440239462Sdim      // arguments and can be turned into an attribute directly.
441239462Sdim      Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
442239462Sdim                   0, 0, AttributeList::AS_Declspec);
443239462Sdim    else
444239462Sdim      ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
445193725Sed  }
446239462Sdim  T.consumeClose();
447193326Sed}
448193326Sed
449218893Sdimvoid Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
450194179Sed  // Treat these like attributes
451194179Sed  while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
452208600Srdivacky         Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl)   ||
453226633Sdim         Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
454226633Sdim         Tok.is(tok::kw___ptr32) ||
455226633Sdim         Tok.is(tok::kw___unaligned)) {
456194179Sed    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
457194179Sed    SourceLocation AttrNameLoc = ConsumeToken();
458221345Sdim    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
459239462Sdim                 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
460194179Sed  }
461194179Sed}
462194179Sed
463218893Sdimvoid Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
464212904Sdim  // Treat these like attributes
465212904Sdim  while (Tok.is(tok::kw___pascal)) {
466212904Sdim    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
467212904Sdim    SourceLocation AttrNameLoc = ConsumeToken();
468221345Sdim    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
469239462Sdim                 SourceLocation(), 0, 0, AttributeList::AS_MSTypespec);
470212904Sdim  }
471212904Sdim}
472212904Sdim
473218893Sdimvoid Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
474218893Sdim  // Treat these like attributes
475218893Sdim  while (Tok.is(tok::kw___kernel)) {
476218893Sdim    SourceLocation AttrNameLoc = ConsumeToken();
477221345Sdim    attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
478221345Sdim                 AttrNameLoc, 0, AttrNameLoc, 0,
479239462Sdim                 SourceLocation(), 0, 0, AttributeList::AS_GNU);
480218893Sdim  }
481218893Sdim}
482218893Sdim
483221345Sdimvoid Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
484221345Sdim  SourceLocation Loc = Tok.getLocation();
485221345Sdim  switch(Tok.getKind()) {
486221345Sdim    // OpenCL qualifiers:
487221345Sdim    case tok::kw___private:
488239462Sdim    case tok::kw_private:
489221345Sdim      DS.getAttributes().addNewInteger(
490239462Sdim          Actions.getASTContext(),
491221345Sdim          PP.getIdentifierInfo("address_space"), Loc, 0);
492221345Sdim      break;
493239462Sdim
494221345Sdim    case tok::kw___global:
495221345Sdim      DS.getAttributes().addNewInteger(
496221345Sdim          Actions.getASTContext(),
497221345Sdim          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
498221345Sdim      break;
499239462Sdim
500221345Sdim    case tok::kw___local:
501221345Sdim      DS.getAttributes().addNewInteger(
502221345Sdim          Actions.getASTContext(),
503221345Sdim          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
504221345Sdim      break;
505239462Sdim
506221345Sdim    case tok::kw___constant:
507221345Sdim      DS.getAttributes().addNewInteger(
508221345Sdim          Actions.getASTContext(),
509221345Sdim          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
510221345Sdim      break;
511239462Sdim
512221345Sdim    case tok::kw___read_only:
513221345Sdim      DS.getAttributes().addNewInteger(
514239462Sdim          Actions.getASTContext(),
515221345Sdim          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
516221345Sdim      break;
517239462Sdim
518221345Sdim    case tok::kw___write_only:
519221345Sdim      DS.getAttributes().addNewInteger(
520239462Sdim          Actions.getASTContext(),
521221345Sdim          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
522221345Sdim      break;
523239462Sdim
524221345Sdim    case tok::kw___read_write:
525221345Sdim      DS.getAttributes().addNewInteger(
526221345Sdim          Actions.getASTContext(),
527221345Sdim          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
528221345Sdim      break;
529221345Sdim    default: break;
530221345Sdim  }
531221345Sdim}
532221345Sdim
533221345Sdim/// \brief Parse a version number.
534221345Sdim///
535221345Sdim/// version:
536221345Sdim///   simple-integer
537221345Sdim///   simple-integer ',' simple-integer
538221345Sdim///   simple-integer ',' simple-integer ',' simple-integer
539221345SdimVersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
540221345Sdim  Range = Tok.getLocation();
541221345Sdim
542221345Sdim  if (!Tok.is(tok::numeric_constant)) {
543221345Sdim    Diag(Tok, diag::err_expected_version);
544221345Sdim    SkipUntil(tok::comma, tok::r_paren, true, true, true);
545221345Sdim    return VersionTuple();
546221345Sdim  }
547221345Sdim
548221345Sdim  // Parse the major (and possibly minor and subminor) versions, which
549221345Sdim  // are stored in the numeric constant. We utilize a quirk of the
550221345Sdim  // lexer, which is that it handles something like 1.2.3 as a single
551221345Sdim  // numeric constant, rather than two separate tokens.
552234353Sdim  SmallString<512> Buffer;
553221345Sdim  Buffer.resize(Tok.getLength()+1);
554221345Sdim  const char *ThisTokBegin = &Buffer[0];
555221345Sdim
556221345Sdim  // Get the spelling of the token, which eliminates trigraphs, etc.
557221345Sdim  bool Invalid = false;
558221345Sdim  unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
559221345Sdim  if (Invalid)
560221345Sdim    return VersionTuple();
561221345Sdim
562221345Sdim  // Parse the major version.
563221345Sdim  unsigned AfterMajor = 0;
564221345Sdim  unsigned Major = 0;
565221345Sdim  while (AfterMajor < ActualLength && isdigit(ThisTokBegin[AfterMajor])) {
566221345Sdim    Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';
567221345Sdim    ++AfterMajor;
568221345Sdim  }
569221345Sdim
570221345Sdim  if (AfterMajor == 0) {
571221345Sdim    Diag(Tok, diag::err_expected_version);
572221345Sdim    SkipUntil(tok::comma, tok::r_paren, true, true, true);
573221345Sdim    return VersionTuple();
574221345Sdim  }
575221345Sdim
576221345Sdim  if (AfterMajor == ActualLength) {
577221345Sdim    ConsumeToken();
578221345Sdim
579221345Sdim    // We only had a single version component.
580221345Sdim    if (Major == 0) {
581221345Sdim      Diag(Tok, diag::err_zero_version);
582221345Sdim      return VersionTuple();
583221345Sdim    }
584221345Sdim
585221345Sdim    return VersionTuple(Major);
586221345Sdim  }
587221345Sdim
588221345Sdim  if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) {
589221345Sdim    Diag(Tok, diag::err_expected_version);
590221345Sdim    SkipUntil(tok::comma, tok::r_paren, true, true, true);
591221345Sdim    return VersionTuple();
592221345Sdim  }
593221345Sdim
594221345Sdim  // Parse the minor version.
595221345Sdim  unsigned AfterMinor = AfterMajor + 1;
596221345Sdim  unsigned Minor = 0;
597221345Sdim  while (AfterMinor < ActualLength && isdigit(ThisTokBegin[AfterMinor])) {
598221345Sdim    Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';
599221345Sdim    ++AfterMinor;
600221345Sdim  }
601221345Sdim
602221345Sdim  if (AfterMinor == ActualLength) {
603221345Sdim    ConsumeToken();
604239462Sdim
605221345Sdim    // We had major.minor.
606221345Sdim    if (Major == 0 && Minor == 0) {
607221345Sdim      Diag(Tok, diag::err_zero_version);
608221345Sdim      return VersionTuple();
609221345Sdim    }
610221345Sdim
611239462Sdim    return VersionTuple(Major, Minor);
612221345Sdim  }
613221345Sdim
614221345Sdim  // If what follows is not a '.', we have a problem.
615221345Sdim  if (ThisTokBegin[AfterMinor] != '.') {
616221345Sdim    Diag(Tok, diag::err_expected_version);
617221345Sdim    SkipUntil(tok::comma, tok::r_paren, true, true, true);
618239462Sdim    return VersionTuple();
619221345Sdim  }
620221345Sdim
621221345Sdim  // Parse the subminor version.
622221345Sdim  unsigned AfterSubminor = AfterMinor + 1;
623221345Sdim  unsigned Subminor = 0;
624221345Sdim  while (AfterSubminor < ActualLength && isdigit(ThisTokBegin[AfterSubminor])) {
625221345Sdim    Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';
626221345Sdim    ++AfterSubminor;
627221345Sdim  }
628221345Sdim
629221345Sdim  if (AfterSubminor != ActualLength) {
630221345Sdim    Diag(Tok, diag::err_expected_version);
631221345Sdim    SkipUntil(tok::comma, tok::r_paren, true, true, true);
632221345Sdim    return VersionTuple();
633221345Sdim  }
634221345Sdim  ConsumeToken();
635221345Sdim  return VersionTuple(Major, Minor, Subminor);
636221345Sdim}
637221345Sdim
638221345Sdim/// \brief Parse the contents of the "availability" attribute.
639221345Sdim///
640221345Sdim/// availability-attribute:
641234353Sdim///   'availability' '(' platform ',' version-arg-list, opt-message')'
642221345Sdim///
643221345Sdim/// platform:
644221345Sdim///   identifier
645221345Sdim///
646221345Sdim/// version-arg-list:
647221345Sdim///   version-arg
648221345Sdim///   version-arg ',' version-arg-list
649221345Sdim///
650221345Sdim/// version-arg:
651221345Sdim///   'introduced' '=' version
652221345Sdim///   'deprecated' '=' version
653234353Sdim///   'obsoleted' = version
654221345Sdim///   'unavailable'
655234353Sdim/// opt-message:
656234353Sdim///   'message' '=' <string>
657221345Sdimvoid Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
658221345Sdim                                        SourceLocation AvailabilityLoc,
659221345Sdim                                        ParsedAttributes &attrs,
660221345Sdim                                        SourceLocation *endLoc) {
661221345Sdim  SourceLocation PlatformLoc;
662221345Sdim  IdentifierInfo *Platform = 0;
663221345Sdim
664221345Sdim  enum { Introduced, Deprecated, Obsoleted, Unknown };
665221345Sdim  AvailabilityChange Changes[Unknown];
666234353Sdim  ExprResult MessageExpr;
667221345Sdim
668221345Sdim  // Opening '('.
669226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
670226633Sdim  if (T.consumeOpen()) {
671221345Sdim    Diag(Tok, diag::err_expected_lparen);
672221345Sdim    return;
673221345Sdim  }
674221345Sdim
675221345Sdim  // Parse the platform name,
676221345Sdim  if (Tok.isNot(tok::identifier)) {
677221345Sdim    Diag(Tok, diag::err_availability_expected_platform);
678221345Sdim    SkipUntil(tok::r_paren);
679221345Sdim    return;
680221345Sdim  }
681221345Sdim  Platform = Tok.getIdentifierInfo();
682221345Sdim  PlatformLoc = ConsumeToken();
683221345Sdim
684221345Sdim  // Parse the ',' following the platform name.
685221345Sdim  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
686221345Sdim    return;
687221345Sdim
688221345Sdim  // If we haven't grabbed the pointers for the identifiers
689221345Sdim  // "introduced", "deprecated", and "obsoleted", do so now.
690221345Sdim  if (!Ident_introduced) {
691221345Sdim    Ident_introduced = PP.getIdentifierInfo("introduced");
692221345Sdim    Ident_deprecated = PP.getIdentifierInfo("deprecated");
693221345Sdim    Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
694221345Sdim    Ident_unavailable = PP.getIdentifierInfo("unavailable");
695234353Sdim    Ident_message = PP.getIdentifierInfo("message");
696221345Sdim  }
697221345Sdim
698221345Sdim  // Parse the set of introductions/deprecations/removals.
699221345Sdim  SourceLocation UnavailableLoc;
700221345Sdim  do {
701221345Sdim    if (Tok.isNot(tok::identifier)) {
702221345Sdim      Diag(Tok, diag::err_availability_expected_change);
703221345Sdim      SkipUntil(tok::r_paren);
704221345Sdim      return;
705221345Sdim    }
706221345Sdim    IdentifierInfo *Keyword = Tok.getIdentifierInfo();
707221345Sdim    SourceLocation KeywordLoc = ConsumeToken();
708221345Sdim
709221345Sdim    if (Keyword == Ident_unavailable) {
710221345Sdim      if (UnavailableLoc.isValid()) {
711221345Sdim        Diag(KeywordLoc, diag::err_availability_redundant)
712221345Sdim          << Keyword << SourceRange(UnavailableLoc);
713239462Sdim      }
714221345Sdim      UnavailableLoc = KeywordLoc;
715221345Sdim
716221345Sdim      if (Tok.isNot(tok::comma))
717221345Sdim        break;
718221345Sdim
719221345Sdim      ConsumeToken();
720221345Sdim      continue;
721239462Sdim    }
722239462Sdim
723221345Sdim    if (Tok.isNot(tok::equal)) {
724221345Sdim      Diag(Tok, diag::err_expected_equal_after)
725221345Sdim        << Keyword;
726221345Sdim      SkipUntil(tok::r_paren);
727221345Sdim      return;
728221345Sdim    }
729221345Sdim    ConsumeToken();
730234353Sdim    if (Keyword == Ident_message) {
731234353Sdim      if (!isTokenStringLiteral()) {
732234353Sdim        Diag(Tok, diag::err_expected_string_literal);
733234353Sdim        SkipUntil(tok::r_paren);
734234353Sdim        return;
735234353Sdim      }
736234353Sdim      MessageExpr = ParseStringLiteralExpression();
737234353Sdim      break;
738234353Sdim    }
739239462Sdim
740221345Sdim    SourceRange VersionRange;
741221345Sdim    VersionTuple Version = ParseVersionTuple(VersionRange);
742239462Sdim
743221345Sdim    if (Version.empty()) {
744221345Sdim      SkipUntil(tok::r_paren);
745221345Sdim      return;
746221345Sdim    }
747221345Sdim
748221345Sdim    unsigned Index;
749221345Sdim    if (Keyword == Ident_introduced)
750221345Sdim      Index = Introduced;
751221345Sdim    else if (Keyword == Ident_deprecated)
752221345Sdim      Index = Deprecated;
753221345Sdim    else if (Keyword == Ident_obsoleted)
754221345Sdim      Index = Obsoleted;
755239462Sdim    else
756221345Sdim      Index = Unknown;
757221345Sdim
758221345Sdim    if (Index < Unknown) {
759221345Sdim      if (!Changes[Index].KeywordLoc.isInvalid()) {
760221345Sdim        Diag(KeywordLoc, diag::err_availability_redundant)
761239462Sdim          << Keyword
762221345Sdim          << SourceRange(Changes[Index].KeywordLoc,
763221345Sdim                         Changes[Index].VersionRange.getEnd());
764221345Sdim      }
765221345Sdim
766221345Sdim      Changes[Index].KeywordLoc = KeywordLoc;
767221345Sdim      Changes[Index].Version = Version;
768221345Sdim      Changes[Index].VersionRange = VersionRange;
769221345Sdim    } else {
770221345Sdim      Diag(KeywordLoc, diag::err_availability_unknown_change)
771221345Sdim        << Keyword << VersionRange;
772221345Sdim    }
773221345Sdim
774221345Sdim    if (Tok.isNot(tok::comma))
775221345Sdim      break;
776221345Sdim
777221345Sdim    ConsumeToken();
778221345Sdim  } while (true);
779221345Sdim
780221345Sdim  // Closing ')'.
781226633Sdim  if (T.consumeClose())
782221345Sdim    return;
783221345Sdim
784221345Sdim  if (endLoc)
785226633Sdim    *endLoc = T.getCloseLocation();
786221345Sdim
787221345Sdim  // The 'unavailable' availability cannot be combined with any other
788221345Sdim  // availability changes. Make sure that hasn't happened.
789221345Sdim  if (UnavailableLoc.isValid()) {
790221345Sdim    bool Complained = false;
791221345Sdim    for (unsigned Index = Introduced; Index != Unknown; ++Index) {
792221345Sdim      if (Changes[Index].KeywordLoc.isValid()) {
793221345Sdim        if (!Complained) {
794221345Sdim          Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
795221345Sdim            << SourceRange(Changes[Index].KeywordLoc,
796221345Sdim                           Changes[Index].VersionRange.getEnd());
797221345Sdim          Complained = true;
798221345Sdim        }
799221345Sdim
800221345Sdim        // Clear out the availability.
801221345Sdim        Changes[Index] = AvailabilityChange();
802221345Sdim      }
803221345Sdim    }
804221345Sdim  }
805221345Sdim
806221345Sdim  // Record this attribute
807239462Sdim  attrs.addNew(&Availability,
808239462Sdim               SourceRange(AvailabilityLoc, T.getCloseLocation()),
809234353Sdim               0, AvailabilityLoc,
810221345Sdim               Platform, PlatformLoc,
811221345Sdim               Changes[Introduced],
812221345Sdim               Changes[Deprecated],
813239462Sdim               Changes[Obsoleted],
814234353Sdim               UnavailableLoc, MessageExpr.take(),
815239462Sdim               AttributeList::AS_GNU);
816221345Sdim}
817221345Sdim
818226633Sdim
819226633Sdim// Late Parsed Attributes:
820226633Sdim// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
821226633Sdim
822226633Sdimvoid Parser::LateParsedDeclaration::ParseLexedAttributes() {}
823226633Sdim
824226633Sdimvoid Parser::LateParsedClass::ParseLexedAttributes() {
825226633Sdim  Self->ParseLexedAttributes(*Class);
826226633Sdim}
827226633Sdim
828226633Sdimvoid Parser::LateParsedAttribute::ParseLexedAttributes() {
829234353Sdim  Self->ParseLexedAttribute(*this, true, false);
830226633Sdim}
831226633Sdim
832226633Sdim/// Wrapper class which calls ParseLexedAttribute, after setting up the
833226633Sdim/// scope appropriately.
834226633Sdimvoid Parser::ParseLexedAttributes(ParsingClass &Class) {
835226633Sdim  // Deal with templates
836226633Sdim  // FIXME: Test cases to make sure this does the right thing for templates.
837226633Sdim  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
838226633Sdim  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
839226633Sdim                                HasTemplateScope);
840226633Sdim  if (HasTemplateScope)
841226633Sdim    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
842226633Sdim
843234982Sdim  // Set or update the scope flags.
844226633Sdim  bool AlreadyHasClassScope = Class.TopLevelClass;
845234982Sdim  unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
846226633Sdim  ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
847226633Sdim  ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
848226633Sdim
849234353Sdim  // Enter the scope of nested classes
850234353Sdim  if (!AlreadyHasClassScope)
851234353Sdim    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
852234353Sdim                                                Class.TagOrTemplate);
853239462Sdim  if (!Class.LateParsedDeclarations.empty()) {
854234982Sdim    // Allow 'this' within late-parsed attributes.
855239462Sdim    Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
856234982Sdim                                     /*TypeQuals=*/0);
857239462Sdim
858234982Sdim    for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
859234982Sdim      Class.LateParsedDeclarations[i]->ParseLexedAttributes();
860234982Sdim    }
861226633Sdim  }
862239462Sdim
863234353Sdim  if (!AlreadyHasClassScope)
864234353Sdim    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
865234353Sdim                                                 Class.TagOrTemplate);
866226633Sdim}
867226633Sdim
868234353Sdim
869234353Sdim/// \brief Parse all attributes in LAs, and attach them to Decl D.
870234353Sdimvoid Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
871234353Sdim                                     bool EnterScope, bool OnDefinition) {
872234353Sdim  for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
873239462Sdim    if (D)
874239462Sdim      LAs[i]->addDecl(D);
875234353Sdim    ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
876234982Sdim    delete LAs[i];
877234353Sdim  }
878234353Sdim  LAs.clear();
879234353Sdim}
880234353Sdim
881234353Sdim
882226633Sdim/// \brief Finish parsing an attribute for which parsing was delayed.
883226633Sdim/// This will be called at the end of parsing a class declaration
884226633Sdim/// for each LateParsedAttribute. We consume the saved tokens and
885239462Sdim/// create an attribute with the arguments filled in. We add this
886226633Sdim/// to the Attribute list for the decl.
887234353Sdimvoid Parser::ParseLexedAttribute(LateParsedAttribute &LA,
888234353Sdim                                 bool EnterScope, bool OnDefinition) {
889226633Sdim  // Save the current token position.
890226633Sdim  SourceLocation OrigLoc = Tok.getLocation();
891226633Sdim
892226633Sdim  // Append the current token at the end of the new token stream so that it
893226633Sdim  // doesn't get lost.
894226633Sdim  LA.Toks.push_back(Tok);
895226633Sdim  PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
896226633Sdim  // Consume the previously pushed token.
897226633Sdim  ConsumeAnyToken();
898226633Sdim
899234353Sdim  if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
900234353Sdim    Diag(Tok, diag::warn_attribute_on_function_definition)
901234353Sdim      << LA.AttrName.getName();
902234353Sdim  }
903234353Sdim
904226633Sdim  ParsedAttributes Attrs(AttrFactory);
905226633Sdim  SourceLocation endLoc;
906226633Sdim
907234353Sdim  if (LA.Decls.size() == 1) {
908234353Sdim    Decl *D = LA.Decls[0];
909226633Sdim
910234353Sdim    // If the Decl is templatized, add template parameters to scope.
911234353Sdim    bool HasTemplateScope = EnterScope && D->isTemplateDecl();
912234353Sdim    ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
913234353Sdim    if (HasTemplateScope)
914234353Sdim      Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
915226633Sdim
916234353Sdim    // If the Decl is on a function, add function parameters to the scope.
917234353Sdim    bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate();
918234353Sdim    ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope);
919234353Sdim    if (HasFunctionScope)
920234353Sdim      Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
921226633Sdim
922234353Sdim    ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
923234353Sdim
924234353Sdim    if (HasFunctionScope) {
925234353Sdim      Actions.ActOnExitFunctionContext();
926234353Sdim      FnScope.Exit();  // Pop scope, and remove Decls from IdResolver
927234353Sdim    }
928234353Sdim    if (HasTemplateScope) {
929234353Sdim      TempScope.Exit();
930234353Sdim    }
931234353Sdim  } else if (LA.Decls.size() > 0) {
932234353Sdim    // If there are multiple decls, then the decl cannot be within the
933234353Sdim    // function scope.
934234353Sdim    ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
935234353Sdim  } else {
936234353Sdim    Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
937226633Sdim  }
938234353Sdim
939234353Sdim  for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
940234353Sdim    Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
941226633Sdim  }
942226633Sdim
943226633Sdim  if (Tok.getLocation() != OrigLoc) {
944226633Sdim    // Due to a parsing error, we either went over the cached tokens or
945226633Sdim    // there are still cached tokens left, so we skip the leftover tokens.
946226633Sdim    // Since this is an uncommon situation that should be avoided, use the
947226633Sdim    // expensive isBeforeInTranslationUnit call.
948226633Sdim    if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
949226633Sdim                                                        OrigLoc))
950226633Sdim    while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
951234353Sdim      ConsumeAnyToken();
952226633Sdim  }
953226633Sdim}
954226633Sdim
955226633Sdim/// \brief Wrapper around a case statement checking if AttrName is
956226633Sdim/// one of the thread safety attributes
957226633Sdimbool Parser::IsThreadSafetyAttribute(llvm::StringRef AttrName){
958226633Sdim  return llvm::StringSwitch<bool>(AttrName)
959226633Sdim      .Case("guarded_by", true)
960226633Sdim      .Case("guarded_var", true)
961226633Sdim      .Case("pt_guarded_by", true)
962226633Sdim      .Case("pt_guarded_var", true)
963226633Sdim      .Case("lockable", true)
964226633Sdim      .Case("scoped_lockable", true)
965226633Sdim      .Case("no_thread_safety_analysis", true)
966226633Sdim      .Case("acquired_after", true)
967226633Sdim      .Case("acquired_before", true)
968226633Sdim      .Case("exclusive_lock_function", true)
969226633Sdim      .Case("shared_lock_function", true)
970226633Sdim      .Case("exclusive_trylock_function", true)
971226633Sdim      .Case("shared_trylock_function", true)
972226633Sdim      .Case("unlock_function", true)
973226633Sdim      .Case("lock_returned", true)
974226633Sdim      .Case("locks_excluded", true)
975226633Sdim      .Case("exclusive_locks_required", true)
976226633Sdim      .Case("shared_locks_required", true)
977226633Sdim      .Default(false);
978226633Sdim}
979226633Sdim
980226633Sdim/// \brief Parse the contents of thread safety attributes. These
981226633Sdim/// should always be parsed as an expression list.
982226633Sdim///
983226633Sdim/// We need to special case the parsing due to the fact that if the first token
984226633Sdim/// of the first argument is an identifier, the main parse loop will store
985226633Sdim/// that token as a "parameter" and the rest of
986226633Sdim/// the arguments will be added to a list of "arguments". However,
987226633Sdim/// subsequent tokens in the first argument are lost. We instead parse each
988226633Sdim/// argument as an expression and add all arguments to the list of "arguments".
989226633Sdim/// In future, we will take advantage of this special case to also
990226633Sdim/// deal with some argument scoping issues here (for example, referring to a
991226633Sdim/// function parameter in the attribute on that function).
992226633Sdimvoid Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
993226633Sdim                                        SourceLocation AttrNameLoc,
994226633Sdim                                        ParsedAttributes &Attrs,
995226633Sdim                                        SourceLocation *EndLoc) {
996226633Sdim  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
997226633Sdim
998226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
999226633Sdim  T.consumeOpen();
1000239462Sdim
1001226633Sdim  ExprVector ArgExprs(Actions);
1002226633Sdim  bool ArgExprsOk = true;
1003239462Sdim
1004226633Sdim  // now parse the list of expressions
1005234353Sdim  while (Tok.isNot(tok::r_paren)) {
1006226633Sdim    ExprResult ArgExpr(ParseAssignmentExpression());
1007226633Sdim    if (ArgExpr.isInvalid()) {
1008226633Sdim      ArgExprsOk = false;
1009226633Sdim      T.consumeClose();
1010226633Sdim      break;
1011226633Sdim    } else {
1012226633Sdim      ArgExprs.push_back(ArgExpr.release());
1013226633Sdim    }
1014226633Sdim    if (Tok.isNot(tok::comma))
1015226633Sdim      break;
1016226633Sdim    ConsumeToken(); // Eat the comma, move to the next argument
1017226633Sdim  }
1018226633Sdim  // Match the ')'.
1019226633Sdim  if (ArgExprsOk && !T.consumeClose()) {
1020226633Sdim    Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(),
1021239462Sdim                 ArgExprs.take(), ArgExprs.size(), AttributeList::AS_GNU);
1022226633Sdim  }
1023226633Sdim  if (EndLoc)
1024226633Sdim    *EndLoc = T.getCloseLocation();
1025226633Sdim}
1026226633Sdim
1027239462Sdimvoid Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
1028239462Sdim                                              SourceLocation AttrNameLoc,
1029239462Sdim                                              ParsedAttributes &Attrs,
1030239462Sdim                                              SourceLocation *EndLoc) {
1031239462Sdim  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1032239462Sdim
1033239462Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
1034239462Sdim  T.consumeOpen();
1035239462Sdim
1036239462Sdim  if (Tok.isNot(tok::identifier)) {
1037239462Sdim    Diag(Tok, diag::err_expected_ident);
1038239462Sdim    T.skipToEnd();
1039239462Sdim    return;
1040239462Sdim  }
1041239462Sdim  IdentifierInfo *ArgumentKind = Tok.getIdentifierInfo();
1042239462Sdim  SourceLocation ArgumentKindLoc = ConsumeToken();
1043239462Sdim
1044239462Sdim  if (Tok.isNot(tok::comma)) {
1045239462Sdim    Diag(Tok, diag::err_expected_comma);
1046239462Sdim    T.skipToEnd();
1047239462Sdim    return;
1048239462Sdim  }
1049239462Sdim  ConsumeToken();
1050239462Sdim
1051239462Sdim  SourceRange MatchingCTypeRange;
1052239462Sdim  TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);
1053239462Sdim  if (MatchingCType.isInvalid()) {
1054239462Sdim    T.skipToEnd();
1055239462Sdim    return;
1056239462Sdim  }
1057239462Sdim
1058239462Sdim  bool LayoutCompatible = false;
1059239462Sdim  bool MustBeNull = false;
1060239462Sdim  while (Tok.is(tok::comma)) {
1061239462Sdim    ConsumeToken();
1062239462Sdim    if (Tok.isNot(tok::identifier)) {
1063239462Sdim      Diag(Tok, diag::err_expected_ident);
1064239462Sdim      T.skipToEnd();
1065239462Sdim      return;
1066239462Sdim    }
1067239462Sdim    IdentifierInfo *Flag = Tok.getIdentifierInfo();
1068239462Sdim    if (Flag->isStr("layout_compatible"))
1069239462Sdim      LayoutCompatible = true;
1070239462Sdim    else if (Flag->isStr("must_be_null"))
1071239462Sdim      MustBeNull = true;
1072239462Sdim    else {
1073239462Sdim      Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1074239462Sdim      T.skipToEnd();
1075239462Sdim      return;
1076239462Sdim    }
1077239462Sdim    ConsumeToken(); // consume flag
1078239462Sdim  }
1079239462Sdim
1080239462Sdim  if (!T.consumeClose()) {
1081239462Sdim    Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
1082239462Sdim                                   ArgumentKind, ArgumentKindLoc,
1083239462Sdim                                   MatchingCType.release(), LayoutCompatible,
1084239462Sdim                                   MustBeNull, AttributeList::AS_GNU);
1085239462Sdim  }
1086239462Sdim
1087239462Sdim  if (EndLoc)
1088239462Sdim    *EndLoc = T.getCloseLocation();
1089239462Sdim}
1090239462Sdim
1091234353Sdim/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
1092234353Sdim/// of a C++11 attribute-specifier in a location where an attribute is not
1093234353Sdim/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
1094234353Sdim/// situation.
1095234353Sdim///
1096234353Sdim/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
1097234353Sdim/// this doesn't appear to actually be an attribute-specifier, and the caller
1098234353Sdim/// should try to parse it.
1099234353Sdimbool Parser::DiagnoseProhibitedCXX11Attribute() {
1100234353Sdim  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1101234353Sdim
1102234353Sdim  switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1103234353Sdim  case CAK_NotAttributeSpecifier:
1104234353Sdim    // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1105234353Sdim    return false;
1106234353Sdim
1107234353Sdim  case CAK_InvalidAttributeSpecifier:
1108234353Sdim    Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1109234353Sdim    return false;
1110234353Sdim
1111234353Sdim  case CAK_AttributeSpecifier:
1112234353Sdim    // Parse and discard the attributes.
1113234353Sdim    SourceLocation BeginLoc = ConsumeBracket();
1114234353Sdim    ConsumeBracket();
1115234353Sdim    SkipUntil(tok::r_square, /*StopAtSemi*/ false);
1116234353Sdim    assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1117234353Sdim    SourceLocation EndLoc = ConsumeBracket();
1118234353Sdim    Diag(BeginLoc, diag::err_attributes_not_allowed)
1119234353Sdim      << SourceRange(BeginLoc, EndLoc);
1120234353Sdim    return true;
1121234353Sdim  }
1122234353Sdim  llvm_unreachable("All cases handled above.");
1123234353Sdim}
1124234353Sdim
1125218893Sdimvoid Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1126218893Sdim  Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1127218893Sdim    << attrs.Range;
1128218893Sdim}
1129218893Sdim
1130193326Sed/// ParseDeclaration - Parse a full 'declaration', which consists of
1131193326Sed/// declaration-specifiers, some number of declarators, and a semicolon.
1132193326Sed/// 'Context' should be a Declarator::TheContext value.  This returns the
1133193326Sed/// location of the semicolon in DeclEnd.
1134193326Sed///
1135193326Sed///       declaration: [C99 6.7]
1136193326Sed///         block-declaration ->
1137193326Sed///           simple-declaration
1138193326Sed///           others                   [FIXME]
1139193326Sed/// [C++]   template-declaration
1140193326Sed/// [C++]   namespace-definition
1141193326Sed/// [C++]   using-directive
1142194711Sed/// [C++]   using-declaration
1143234982Sdim/// [C++11/C11] static_assert-declaration
1144193326Sed///         others... [FIXME]
1145193326Sed///
1146218893SdimParser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1147218893Sdim                                                unsigned Context,
1148199990Srdivacky                                                SourceLocation &DeclEnd,
1149218893Sdim                                          ParsedAttributesWithRange &attrs) {
1150210299Sed  ParenBraceBracketBalancer BalancerRAIIObj(*this);
1151226633Sdim  // Must temporarily exit the objective-c container scope for
1152226633Sdim  // parsing c none objective-c decls.
1153226633Sdim  ObjCDeclContextSwitch ObjCDC(*this);
1154239462Sdim
1155212904Sdim  Decl *SingleDecl = 0;
1156224145Sdim  Decl *OwnedType = 0;
1157193326Sed  switch (Tok.getKind()) {
1158193326Sed  case tok::kw_template:
1159193326Sed  case tok::kw_export:
1160218893Sdim    ProhibitAttributes(attrs);
1161193326Sed    SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
1162193326Sed    break;
1163212904Sdim  case tok::kw_inline:
1164212904Sdim    // Could be the start of an inline namespace. Allowed as an ext in C++03.
1165234353Sdim    if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
1166218893Sdim      ProhibitAttributes(attrs);
1167212904Sdim      SourceLocation InlineLoc = ConsumeToken();
1168212904Sdim      SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1169212904Sdim      break;
1170212904Sdim    }
1171239462Sdim    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
1172218893Sdim                                  true);
1173193326Sed  case tok::kw_namespace:
1174218893Sdim    ProhibitAttributes(attrs);
1175193326Sed    SingleDecl = ParseNamespace(Context, DeclEnd);
1176193326Sed    break;
1177193326Sed  case tok::kw_using:
1178218893Sdim    SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1179224145Sdim                                                  DeclEnd, attrs, &OwnedType);
1180193326Sed    break;
1181193326Sed  case tok::kw_static_assert:
1182221345Sdim  case tok::kw__Static_assert:
1183218893Sdim    ProhibitAttributes(attrs);
1184193326Sed    SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1185193326Sed    break;
1186193326Sed  default:
1187218893Sdim    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
1188193326Sed  }
1189239462Sdim
1190193326Sed  // This routine returns a DeclGroup, if the thing we parsed only contains a
1191224145Sdim  // single decl, convert it now. Alias declarations can also declare a type;
1192224145Sdim  // include that too if it is present.
1193224145Sdim  return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
1194193326Sed}
1195193326Sed
1196193326Sed///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
1197193326Sed///         declaration-specifiers init-declarator-list[opt] ';'
1198239462Sdim/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1199239462Sdim///             init-declarator-list ';'
1200193326Sed///[C90/C++]init-declarator-list ';'                             [TODO]
1201193326Sed/// [OMP]   threadprivate-directive                              [TODO]
1202193326Sed///
1203239462Sdim///       for-range-declaration: [C++11 6.5p1: stmt.ranged]
1204221345Sdim///         attribute-specifier-seq[opt] type-specifier-seq declarator
1205221345Sdim///
1206193326Sed/// If RequireSemi is false, this does not check for a ';' at the end of the
1207206275Srdivacky/// declaration.  If it is true, it checks for and eats it.
1208221345Sdim///
1209221345Sdim/// If FRI is non-null, we might be parsing a for-range-declaration instead
1210221345Sdim/// of a simple-declaration. If we find that we are, we also parse the
1211221345Sdim/// for-range-initializer, and place it here.
1212239462SdimParser::DeclGroupPtrTy
1213239462SdimParser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1214239462Sdim                               SourceLocation &DeclEnd,
1215239462Sdim                               ParsedAttributesWithRange &attrs,
1216239462Sdim                               bool RequireSemi, ForRangeInit *FRI) {
1217193326Sed  // Parse the common declaration-specifiers piece.
1218198893Srdivacky  ParsingDeclSpec DS(*this);
1219218893Sdim  DS.takeAttributesFrom(attrs);
1220221345Sdim
1221202379Srdivacky  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
1222218893Sdim                             getDeclSpecContextFromDeclaratorContext(Context));
1223234353Sdim
1224193326Sed  // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1225193326Sed  // declaration-specifiers init-declarator-list[opt] ';'
1226193326Sed  if (Tok.is(tok::semi)) {
1227239462Sdim    DeclEnd = Tok.getLocation();
1228206275Srdivacky    if (RequireSemi) ConsumeToken();
1229212904Sdim    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
1230221345Sdim                                                       DS);
1231198893Srdivacky    DS.complete(TheDecl);
1232193326Sed    return Actions.ConvertDeclToDeclGroup(TheDecl);
1233193326Sed  }
1234239462Sdim
1235239462Sdim  return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
1236198893Srdivacky}
1237198092Srdivacky
1238234353Sdim/// Returns true if this might be the start of a declarator, or a common typo
1239234353Sdim/// for a declarator.
1240234353Sdimbool Parser::MightBeDeclarator(unsigned Context) {
1241234353Sdim  switch (Tok.getKind()) {
1242234353Sdim  case tok::annot_cxxscope:
1243234353Sdim  case tok::annot_template_id:
1244234353Sdim  case tok::caret:
1245234353Sdim  case tok::code_completion:
1246234353Sdim  case tok::coloncolon:
1247234353Sdim  case tok::ellipsis:
1248234353Sdim  case tok::kw___attribute:
1249234353Sdim  case tok::kw_operator:
1250234353Sdim  case tok::l_paren:
1251234353Sdim  case tok::star:
1252234353Sdim    return true;
1253234353Sdim
1254234353Sdim  case tok::amp:
1255234353Sdim  case tok::ampamp:
1256234353Sdim    return getLangOpts().CPlusPlus;
1257234353Sdim
1258234353Sdim  case tok::l_square: // Might be an attribute on an unnamed bit-field.
1259234353Sdim    return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x &&
1260234353Sdim           NextToken().is(tok::l_square);
1261234353Sdim
1262234353Sdim  case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
1263234353Sdim    return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
1264234353Sdim
1265234353Sdim  case tok::identifier:
1266234353Sdim    switch (NextToken().getKind()) {
1267234353Sdim    case tok::code_completion:
1268234353Sdim    case tok::coloncolon:
1269234353Sdim    case tok::comma:
1270234353Sdim    case tok::equal:
1271234353Sdim    case tok::equalequal: // Might be a typo for '='.
1272234353Sdim    case tok::kw_alignas:
1273234353Sdim    case tok::kw_asm:
1274234353Sdim    case tok::kw___attribute:
1275234353Sdim    case tok::l_brace:
1276234353Sdim    case tok::l_paren:
1277234353Sdim    case tok::l_square:
1278234353Sdim    case tok::less:
1279234353Sdim    case tok::r_brace:
1280234353Sdim    case tok::r_paren:
1281234353Sdim    case tok::r_square:
1282234353Sdim    case tok::semi:
1283234353Sdim      return true;
1284234353Sdim
1285234353Sdim    case tok::colon:
1286234353Sdim      // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
1287234353Sdim      // and in block scope it's probably a label. Inside a class definition,
1288234353Sdim      // this is a bit-field.
1289234353Sdim      return Context == Declarator::MemberContext ||
1290234353Sdim             (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
1291234353Sdim
1292234353Sdim    case tok::identifier: // Possible virt-specifier.
1293234353Sdim      return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
1294234353Sdim
1295234353Sdim    default:
1296234353Sdim      return false;
1297234353Sdim    }
1298234353Sdim
1299234353Sdim  default:
1300234353Sdim    return false;
1301234353Sdim  }
1302234353Sdim}
1303234353Sdim
1304234353Sdim/// Skip until we reach something which seems like a sensible place to pick
1305234353Sdim/// up parsing after a malformed declaration. This will sometimes stop sooner
1306234353Sdim/// than SkipUntil(tok::r_brace) would, but will never stop later.
1307234353Sdimvoid Parser::SkipMalformedDecl() {
1308234353Sdim  while (true) {
1309234353Sdim    switch (Tok.getKind()) {
1310234353Sdim    case tok::l_brace:
1311234353Sdim      // Skip until matching }, then stop. We've probably skipped over
1312234353Sdim      // a malformed class or function definition or similar.
1313234353Sdim      ConsumeBrace();
1314234353Sdim      SkipUntil(tok::r_brace, /*StopAtSemi*/false);
1315234353Sdim      if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
1316234353Sdim        // This declaration isn't over yet. Keep skipping.
1317234353Sdim        continue;
1318234353Sdim      }
1319234353Sdim      if (Tok.is(tok::semi))
1320234353Sdim        ConsumeToken();
1321234353Sdim      return;
1322234353Sdim
1323234353Sdim    case tok::l_square:
1324234353Sdim      ConsumeBracket();
1325234353Sdim      SkipUntil(tok::r_square, /*StopAtSemi*/false);
1326234353Sdim      continue;
1327234353Sdim
1328234353Sdim    case tok::l_paren:
1329234353Sdim      ConsumeParen();
1330234353Sdim      SkipUntil(tok::r_paren, /*StopAtSemi*/false);
1331234353Sdim      continue;
1332234353Sdim
1333234353Sdim    case tok::r_brace:
1334234353Sdim      return;
1335234353Sdim
1336234353Sdim    case tok::semi:
1337234353Sdim      ConsumeToken();
1338234353Sdim      return;
1339234353Sdim
1340234353Sdim    case tok::kw_inline:
1341234353Sdim      // 'inline namespace' at the start of a line is almost certainly
1342239462Sdim      // a good place to pick back up parsing, except in an Objective-C
1343239462Sdim      // @interface context.
1344239462Sdim      if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&
1345239462Sdim          (!ParsingInObjCContainer || CurParsedObjCImpl))
1346234353Sdim        return;
1347234353Sdim      break;
1348234353Sdim
1349234353Sdim    case tok::kw_namespace:
1350234353Sdim      // 'namespace' at the start of a line is almost certainly a good
1351239462Sdim      // place to pick back up parsing, except in an Objective-C
1352239462Sdim      // @interface context.
1353239462Sdim      if (Tok.isAtStartOfLine() &&
1354239462Sdim          (!ParsingInObjCContainer || CurParsedObjCImpl))
1355234353Sdim        return;
1356234353Sdim      break;
1357234353Sdim
1358239462Sdim    case tok::at:
1359239462Sdim      // @end is very much like } in Objective-C contexts.
1360239462Sdim      if (NextToken().isObjCAtKeyword(tok::objc_end) &&
1361239462Sdim          ParsingInObjCContainer)
1362239462Sdim        return;
1363239462Sdim      break;
1364239462Sdim
1365239462Sdim    case tok::minus:
1366239462Sdim    case tok::plus:
1367239462Sdim      // - and + probably start new method declarations in Objective-C contexts.
1368239462Sdim      if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
1369239462Sdim        return;
1370239462Sdim      break;
1371239462Sdim
1372234353Sdim    case tok::eof:
1373234353Sdim      return;
1374234353Sdim
1375234353Sdim    default:
1376234353Sdim      break;
1377234353Sdim    }
1378234353Sdim
1379234353Sdim    ConsumeAnyToken();
1380234353Sdim  }
1381234353Sdim}
1382234353Sdim
1383198893Srdivacky/// ParseDeclGroup - Having concluded that this is either a function
1384198893Srdivacky/// definition or a group of object declarations, actually parse the
1385198893Srdivacky/// result.
1386198893SrdivackyParser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1387198893Srdivacky                                              unsigned Context,
1388198893Srdivacky                                              bool AllowFunctionDefinitions,
1389221345Sdim                                              SourceLocation *DeclEnd,
1390221345Sdim                                              ForRangeInit *FRI) {
1391198893Srdivacky  // Parse the first declarator.
1392198893Srdivacky  ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
1393198893Srdivacky  ParseDeclarator(D);
1394193326Sed
1395198893Srdivacky  // Bail out if the first declarator didn't seem well-formed.
1396198893Srdivacky  if (!D.hasName() && !D.mayOmitIdentifier()) {
1397234353Sdim    SkipMalformedDecl();
1398198893Srdivacky    return DeclGroupPtrTy();
1399198893Srdivacky  }
1400198092Srdivacky
1401234353Sdim  // Save late-parsed attributes for now; they need to be parsed in the
1402234353Sdim  // appropriate function scope after the function Decl has been constructed.
1403234353Sdim  LateParsedAttrList LateParsedAttrs;
1404234353Sdim  if (D.isFunctionDeclarator())
1405234353Sdim    MaybeParseGNUAttributes(D, &LateParsedAttrs);
1406234353Sdim
1407210299Sed  // Check to see if we have a function *definition* which must have a body.
1408210299Sed  if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
1409210299Sed      // Look at the next token to make sure that this isn't a function
1410210299Sed      // declaration.  We have to check this because __attribute__ might be the
1411210299Sed      // start of a function definition in GCC-extended K&R C.
1412210299Sed      !isDeclarationAfterDeclarator()) {
1413239462Sdim
1414210299Sed    if (isStartOfFunctionDefinition(D)) {
1415198893Srdivacky      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
1416198893Srdivacky        Diag(Tok, diag::err_function_declared_typedef);
1417198092Srdivacky
1418198893Srdivacky        // Recover by treating the 'typedef' as spurious.
1419198893Srdivacky        DS.ClearStorageClassSpecs();
1420198893Srdivacky      }
1421198893Srdivacky
1422234353Sdim      Decl *TheDecl =
1423234353Sdim        ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
1424198893Srdivacky      return Actions.ConvertDeclToDeclGroup(TheDecl);
1425210299Sed    }
1426239462Sdim
1427210299Sed    if (isDeclarationSpecifier()) {
1428210299Sed      // If there is an invalid declaration specifier right after the function
1429210299Sed      // prototype, then we must be in a missing semicolon case where this isn't
1430210299Sed      // actually a body.  Just fall through into the code that handles it as a
1431210299Sed      // prototype, and let the top-level code handle the erroneous declspec
1432210299Sed      // where it would otherwise expect a comma or semicolon.
1433198893Srdivacky    } else {
1434198893Srdivacky      Diag(Tok, diag::err_expected_fn_body);
1435198893Srdivacky      SkipUntil(tok::semi);
1436198893Srdivacky      return DeclGroupPtrTy();
1437198893Srdivacky    }
1438198893Srdivacky  }
1439198893Srdivacky
1440234353Sdim  if (ParseAsmAttributesAfterDeclarator(D))
1441221345Sdim    return DeclGroupPtrTy();
1442221345Sdim
1443221345Sdim  // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
1444221345Sdim  // must parse and analyze the for-range-initializer before the declaration is
1445221345Sdim  // analyzed.
1446221345Sdim  if (FRI && Tok.is(tok::colon)) {
1447221345Sdim    FRI->ColonLoc = ConsumeToken();
1448223017Sdim    if (Tok.is(tok::l_brace))
1449223017Sdim      FRI->RangeExpr = ParseBraceInitializer();
1450223017Sdim    else
1451223017Sdim      FRI->RangeExpr = ParseExpression();
1452221345Sdim    Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1453221345Sdim    Actions.ActOnCXXForRangeDecl(ThisDecl);
1454221345Sdim    Actions.FinalizeDeclaration(ThisDecl);
1455234353Sdim    D.complete(ThisDecl);
1456221345Sdim    return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1);
1457221345Sdim  }
1458221345Sdim
1459226633Sdim  SmallVector<Decl *, 8> DeclsInGroup;
1460221345Sdim  Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
1461234353Sdim  if (LateParsedAttrs.size() > 0)
1462234353Sdim    ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
1463198893Srdivacky  D.complete(FirstDecl);
1464212904Sdim  if (FirstDecl)
1465198893Srdivacky    DeclsInGroup.push_back(FirstDecl);
1466198893Srdivacky
1467234353Sdim  bool ExpectSemi = Context != Declarator::ForContext;
1468239462Sdim
1469198893Srdivacky  // If we don't have a comma, it is either the end of the list (a ';') or an
1470198893Srdivacky  // error, bail out.
1471198893Srdivacky  while (Tok.is(tok::comma)) {
1472234353Sdim    SourceLocation CommaLoc = ConsumeToken();
1473198893Srdivacky
1474234353Sdim    if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1475234353Sdim      // This comma was followed by a line-break and something which can't be
1476234353Sdim      // the start of a declarator. The comma was probably a typo for a
1477234353Sdim      // semicolon.
1478234353Sdim      Diag(CommaLoc, diag::err_expected_semi_declaration)
1479234353Sdim        << FixItHint::CreateReplacement(CommaLoc, ";");
1480234353Sdim      ExpectSemi = false;
1481234353Sdim      break;
1482234353Sdim    }
1483234353Sdim
1484198893Srdivacky    // Parse the next declarator.
1485198893Srdivacky    D.clear();
1486234353Sdim    D.setCommaLoc(CommaLoc);
1487198893Srdivacky
1488198893Srdivacky    // Accept attributes in an init-declarator.  In the first declarator in a
1489198893Srdivacky    // declaration, these would be part of the declspec.  In subsequent
1490198893Srdivacky    // declarators, they become part of the declarator itself, so that they
1491198893Srdivacky    // don't apply to declarators after *this* one.  Examples:
1492198893Srdivacky    //    short __attribute__((common)) var;    -> declspec
1493198893Srdivacky    //    short var __attribute__((common));    -> declarator
1494198893Srdivacky    //    short x, __attribute__((common)) var;    -> declarator
1495218893Sdim    MaybeParseGNUAttributes(D);
1496198893Srdivacky
1497198893Srdivacky    ParseDeclarator(D);
1498234353Sdim    if (!D.isInvalidType()) {
1499234353Sdim      Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1500234353Sdim      D.complete(ThisDecl);
1501234353Sdim      if (ThisDecl)
1502239462Sdim        DeclsInGroup.push_back(ThisDecl);
1503234353Sdim    }
1504193326Sed  }
1505198092Srdivacky
1506198893Srdivacky  if (DeclEnd)
1507198893Srdivacky    *DeclEnd = Tok.getLocation();
1508198893Srdivacky
1509234353Sdim  if (ExpectSemi &&
1510239462Sdim      ExpectAndConsumeSemi(Context == Declarator::FileContext
1511239462Sdim                           ? diag::err_invalid_token_after_toplevel_declarator
1512239462Sdim                           : diag::err_expected_semi_declaration)) {
1513210299Sed    // Okay, there was no semicolon and one was expected.  If we see a
1514210299Sed    // declaration specifier, just assume it was missing and continue parsing.
1515210299Sed    // Otherwise things are very confused and we skip to recover.
1516210299Sed    if (!isDeclarationSpecifier()) {
1517210299Sed      SkipUntil(tok::r_brace, true, true);
1518210299Sed      if (Tok.is(tok::semi))
1519210299Sed        ConsumeToken();
1520210299Sed    }
1521198893Srdivacky  }
1522198893Srdivacky
1523210299Sed  return Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
1524198893Srdivacky                                         DeclsInGroup.data(),
1525198893Srdivacky                                         DeclsInGroup.size());
1526193326Sed}
1527193326Sed
1528221345Sdim/// Parse an optional simple-asm-expr and attributes, and attach them to a
1529221345Sdim/// declarator. Returns true on an error.
1530234353Sdimbool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
1531221345Sdim  // If a simple-asm-expr is present, parse it.
1532221345Sdim  if (Tok.is(tok::kw_asm)) {
1533221345Sdim    SourceLocation Loc;
1534221345Sdim    ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1535221345Sdim    if (AsmLabel.isInvalid()) {
1536221345Sdim      SkipUntil(tok::semi, true, true);
1537221345Sdim      return true;
1538221345Sdim    }
1539221345Sdim
1540221345Sdim    D.setAsmLabel(AsmLabel.release());
1541221345Sdim    D.SetRangeEnd(Loc);
1542221345Sdim  }
1543221345Sdim
1544221345Sdim  MaybeParseGNUAttributes(D);
1545221345Sdim  return false;
1546221345Sdim}
1547221345Sdim
1548193326Sed/// \brief Parse 'declaration' after parsing 'declaration-specifiers
1549193326Sed/// declarator'. This method parses the remainder of the declaration
1550193326Sed/// (including any attributes or initializer, among other things) and
1551193326Sed/// finalizes the declaration.
1552193326Sed///
1553193326Sed///       init-declarator: [C99 6.7]
1554193326Sed///         declarator
1555193326Sed///         declarator '=' initializer
1556193326Sed/// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
1557193326Sed/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
1558193326Sed/// [C++]   declarator initializer[opt]
1559193326Sed///
1560193326Sed/// [C++] initializer:
1561193326Sed/// [C++]   '=' initializer-clause
1562193326Sed/// [C++]   '(' expression-list ')'
1563193326Sed/// [C++0x] '=' 'default'                                                [TODO]
1564193326Sed/// [C++0x] '=' 'delete'
1565223017Sdim/// [C++0x] braced-init-list
1566193326Sed///
1567193326Sed/// According to the standard grammar, =default and =delete are function
1568193326Sed/// definitions, but that definitely doesn't fit with the parser here.
1569193326Sed///
1570212904SdimDecl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
1571195099Sed                                     const ParsedTemplateInfo &TemplateInfo) {
1572234353Sdim  if (ParseAsmAttributesAfterDeclarator(D))
1573221345Sdim    return 0;
1574198092Srdivacky
1575221345Sdim  return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1576221345Sdim}
1577198092Srdivacky
1578221345SdimDecl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1579221345Sdim                                     const ParsedTemplateInfo &TemplateInfo) {
1580193326Sed  // Inform the current actions module that we just parsed this declarator.
1581212904Sdim  Decl *ThisDecl = 0;
1582198092Srdivacky  switch (TemplateInfo.Kind) {
1583198092Srdivacky  case ParsedTemplateInfo::NonTemplate:
1584210299Sed    ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1585198092Srdivacky    break;
1586239462Sdim
1587198092Srdivacky  case ParsedTemplateInfo::Template:
1588198092Srdivacky  case ParsedTemplateInfo::ExplicitSpecialization:
1589210299Sed    ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
1590212904Sdim                             MultiTemplateParamsArg(Actions,
1591195099Sed                                          TemplateInfo.TemplateParams->data(),
1592195099Sed                                          TemplateInfo.TemplateParams->size()),
1593198092Srdivacky                                               D);
1594198092Srdivacky    break;
1595239462Sdim
1596198092Srdivacky  case ParsedTemplateInfo::ExplicitInstantiation: {
1597239462Sdim    DeclResult ThisRes
1598210299Sed      = Actions.ActOnExplicitInstantiation(getCurScope(),
1599198092Srdivacky                                           TemplateInfo.ExternLoc,
1600198092Srdivacky                                           TemplateInfo.TemplateLoc,
1601198092Srdivacky                                           D);
1602198092Srdivacky    if (ThisRes.isInvalid()) {
1603198092Srdivacky      SkipUntil(tok::semi, true, true);
1604212904Sdim      return 0;
1605198092Srdivacky    }
1606239462Sdim
1607198092Srdivacky    ThisDecl = ThisRes.get();
1608198092Srdivacky    break;
1609198092Srdivacky    }
1610198092Srdivacky  }
1611198092Srdivacky
1612218893Sdim  bool TypeContainsAuto =
1613218893Sdim    D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
1614218893Sdim
1615193326Sed  // Parse declarator '=' initializer.
1616234353Sdim  // If a '==' or '+=' is found, suggest a fixit to '='.
1617234353Sdim  if (isTokenEqualOrEqualTypo()) {
1618193326Sed    ConsumeToken();
1619218893Sdim    if (Tok.is(tok::kw_delete)) {
1620223017Sdim      if (D.isFunctionDeclarator())
1621223017Sdim        Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1622223017Sdim          << 1 /* delete */;
1623223017Sdim      else
1624223017Sdim        Diag(ConsumeToken(), diag::err_deleted_non_function);
1625223017Sdim    } else if (Tok.is(tok::kw_default)) {
1626223017Sdim      if (D.isFunctionDeclarator())
1627234353Sdim        Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1628234353Sdim          << 0 /* default */;
1629223017Sdim      else
1630223017Sdim        Diag(ConsumeToken(), diag::err_default_special_members);
1631193326Sed    } else {
1632234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1633201361Srdivacky        EnterScope(0);
1634210299Sed        Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1635201361Srdivacky      }
1636194613Sed
1637210299Sed      if (Tok.is(tok::code_completion)) {
1638210299Sed        Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
1639239462Sdim        Actions.FinalizeDeclaration(ThisDecl);
1640226633Sdim        cutOffParsing();
1641226633Sdim        return 0;
1642210299Sed      }
1643239462Sdim
1644212904Sdim      ExprResult Init(ParseInitializer());
1645194613Sed
1646234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1647210299Sed        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1648201361Srdivacky        ExitScope();
1649201361Srdivacky      }
1650194613Sed
1651193326Sed      if (Init.isInvalid()) {
1652204643Srdivacky        SkipUntil(tok::comma, true, true);
1653204643Srdivacky        Actions.ActOnInitializerError(ThisDecl);
1654204643Srdivacky      } else
1655218893Sdim        Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1656218893Sdim                                     /*DirectInit=*/false, TypeContainsAuto);
1657193326Sed    }
1658193326Sed  } else if (Tok.is(tok::l_paren)) {
1659193326Sed    // Parse C++ direct initializer: '(' expression-list ')'
1660226633Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
1661226633Sdim    T.consumeOpen();
1662226633Sdim
1663193326Sed    ExprVector Exprs(Actions);
1664193326Sed    CommaLocsTy CommaLocs;
1665193326Sed
1666234353Sdim    if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1667201361Srdivacky      EnterScope(0);
1668210299Sed      Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1669201361Srdivacky    }
1670201361Srdivacky
1671193326Sed    if (ParseExpressionList(Exprs, CommaLocs)) {
1672193326Sed      SkipUntil(tok::r_paren);
1673201361Srdivacky
1674234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1675210299Sed        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1676201361Srdivacky        ExitScope();
1677201361Srdivacky      }
1678193326Sed    } else {
1679193326Sed      // Match the ')'.
1680226633Sdim      T.consumeClose();
1681193326Sed
1682193326Sed      assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1683193326Sed             "Unexpected number of commas!");
1684201361Srdivacky
1685234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1686210299Sed        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1687201361Srdivacky        ExitScope();
1688201361Srdivacky      }
1689201361Srdivacky
1690234353Sdim      ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
1691234353Sdim                                                          T.getCloseLocation(),
1692234353Sdim                                                          move_arg(Exprs));
1693234353Sdim      Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
1694234353Sdim                                   /*DirectInit=*/true, TypeContainsAuto);
1695193326Sed    }
1696239462Sdim  } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace) &&
1697239462Sdim             (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
1698223017Sdim    // Parse C++0x braced-init-list.
1699234353Sdim    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1700234353Sdim
1701223017Sdim    if (D.getCXXScopeSpec().isSet()) {
1702223017Sdim      EnterScope(0);
1703223017Sdim      Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1704223017Sdim    }
1705223017Sdim
1706223017Sdim    ExprResult Init(ParseBraceInitializer());
1707223017Sdim
1708223017Sdim    if (D.getCXXScopeSpec().isSet()) {
1709223017Sdim      Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1710223017Sdim      ExitScope();
1711223017Sdim    }
1712223017Sdim
1713223017Sdim    if (Init.isInvalid()) {
1714223017Sdim      Actions.ActOnInitializerError(ThisDecl);
1715223017Sdim    } else
1716223017Sdim      Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1717223017Sdim                                   /*DirectInit=*/true, TypeContainsAuto);
1718223017Sdim
1719193326Sed  } else {
1720218893Sdim    Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
1721193326Sed  }
1722193326Sed
1723219077Sdim  Actions.FinalizeDeclaration(ThisDecl);
1724219077Sdim
1725193326Sed  return ThisDecl;
1726193326Sed}
1727193326Sed
1728193326Sed/// ParseSpecifierQualifierList
1729193326Sed///        specifier-qualifier-list:
1730193326Sed///          type-specifier specifier-qualifier-list[opt]
1731193326Sed///          type-qualifier specifier-qualifier-list[opt]
1732193326Sed/// [GNU]    attributes     specifier-qualifier-list[opt]
1733193326Sed///
1734234353Sdimvoid Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1735234353Sdim                                         DeclSpecContext DSC) {
1736193326Sed  /// specifier-qualifier-list is a subset of declaration-specifiers.  Just
1737193326Sed  /// parse declaration-specifiers and complain about extra stuff.
1738226633Sdim  /// TODO: diagnose attribute-specifiers and alignment-specifiers.
1739234353Sdim  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
1740198092Srdivacky
1741193326Sed  // Validate declspec for type-name.
1742193326Sed  unsigned Specs = DS.getParsedSpecifiers();
1743239462Sdim  if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1744239462Sdim      !DS.hasTypeSpecifier()) {
1745234353Sdim    Diag(Tok, diag::err_expected_type);
1746234353Sdim    DS.SetTypeSpecError();
1747234353Sdim  } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
1748234353Sdim             !DS.hasAttributes()) {
1749193326Sed    Diag(Tok, diag::err_typename_requires_specqual);
1750234353Sdim    if (!DS.hasTypeSpecifier())
1751234353Sdim      DS.SetTypeSpecError();
1752234353Sdim  }
1753198092Srdivacky
1754193326Sed  // Issue diagnostic and remove storage class if present.
1755193326Sed  if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
1756193326Sed    if (DS.getStorageClassSpecLoc().isValid())
1757193326Sed      Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1758193326Sed    else
1759193326Sed      Diag(DS.getThreadSpecLoc(), diag::err_typename_invalid_storageclass);
1760193326Sed    DS.ClearStorageClassSpecs();
1761193326Sed  }
1762198092Srdivacky
1763193326Sed  // Issue diagnostic and remove function specfier if present.
1764193326Sed  if (Specs & DeclSpec::PQ_FunctionSpecifier) {
1765193326Sed    if (DS.isInlineSpecified())
1766193326Sed      Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
1767193326Sed    if (DS.isVirtualSpecified())
1768193326Sed      Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
1769193326Sed    if (DS.isExplicitSpecified())
1770193326Sed      Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
1771193326Sed    DS.ClearFunctionSpecs();
1772193326Sed  }
1773234353Sdim
1774234353Sdim  // Issue diagnostic and remove constexpr specfier if present.
1775234353Sdim  if (DS.isConstexprSpecified()) {
1776234353Sdim    Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
1777234353Sdim    DS.ClearConstexprSpec();
1778234353Sdim  }
1779193326Sed}
1780193326Sed
1781193326Sed/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
1782193326Sed/// specified token is valid after the identifier in a declarator which
1783193326Sed/// immediately follows the declspec.  For example, these things are valid:
1784193326Sed///
1785193326Sed///      int x   [             4];         // direct-declarator
1786193326Sed///      int x   (             int y);     // direct-declarator
1787193326Sed///  int(int x   )                         // direct-declarator
1788193326Sed///      int x   ;                         // simple-declaration
1789193326Sed///      int x   =             17;         // init-declarator-list
1790193326Sed///      int x   ,             y;          // init-declarator-list
1791193326Sed///      int x   __asm__       ("foo");    // init-declarator-list
1792193326Sed///      int x   :             4;          // struct-declarator
1793193326Sed///      int x   {             5};         // C++'0x unified initializers
1794193326Sed///
1795193326Sed/// This is not, because 'x' does not immediately follow the declspec (though
1796193326Sed/// ')' happens to be valid anyway).
1797193326Sed///    int (x)
1798193326Sed///
1799193326Sedstatic bool isValidAfterIdentifierInDeclarator(const Token &T) {
1800193326Sed  return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
1801193326Sed         T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
1802193326Sed         T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
1803193326Sed}
1804193326Sed
1805193326Sed
1806193326Sed/// ParseImplicitInt - This method is called when we have an non-typename
1807193326Sed/// identifier in a declspec (which normally terminates the decl spec) when
1808193326Sed/// the declspec has no type specifier.  In this case, the declspec is either
1809193326Sed/// malformed or is "implicit int" (in K&R and C89).
1810193326Sed///
1811193326Sed/// This method handles diagnosing this prettily and returns false if the
1812193326Sed/// declspec is done being processed.  If it recovers and thinks there may be
1813193326Sed/// other pieces of declspec after it, it returns true.
1814193326Sed///
1815193326Sedbool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
1816193326Sed                              const ParsedTemplateInfo &TemplateInfo,
1817234353Sdim                              AccessSpecifier AS, DeclSpecContext DSC) {
1818193326Sed  assert(Tok.is(tok::identifier) && "should have identifier");
1819198092Srdivacky
1820193326Sed  SourceLocation Loc = Tok.getLocation();
1821193326Sed  // If we see an identifier that is not a type name, we normally would
1822193326Sed  // parse it as the identifer being declared.  However, when a typename
1823193326Sed  // is typo'd or the definition is not included, this will incorrectly
1824193326Sed  // parse the typename as the identifier name and fall over misparsing
1825193326Sed  // later parts of the diagnostic.
1826193326Sed  //
1827193326Sed  // As such, we try to do some look-ahead in cases where this would
1828193326Sed  // otherwise be an "implicit-int" case to see if this is invalid.  For
1829193326Sed  // example: "static foo_t x = 4;"  In this case, if we parsed foo_t as
1830193326Sed  // an identifier with implicit int, we'd get a parse error because the
1831193326Sed  // next token is obviously invalid for a type.  Parse these as a case
1832193326Sed  // with an invalid type specifier.
1833193326Sed  assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
1834198092Srdivacky
1835193326Sed  // Since we know that this either implicit int (which is rare) or an
1836239462Sdim  // error, do lookahead to try to do better recovery. This never applies
1837239462Sdim  // within a type specifier. Outside of C++, we allow this even if the
1838239462Sdim  // language doesn't "officially" support implicit int -- we support
1839239462Sdim  // implicit int as an extension in C99 and C11. Allegedly, MS also
1840239462Sdim  // supports implicit int in C++ mode.
1841239462Sdim  if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
1842239462Sdim      (!getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt) &&
1843234353Sdim      isValidAfterIdentifierInDeclarator(NextToken())) {
1844193326Sed    // If this token is valid for implicit int, e.g. "static x = 4", then
1845193326Sed    // we just avoid eating the identifier, so it will be parsed as the
1846193326Sed    // identifier in the declarator.
1847193326Sed    return false;
1848193326Sed  }
1849198092Srdivacky
1850239462Sdim  if (getLangOpts().CPlusPlus &&
1851239462Sdim      DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
1852239462Sdim    // Don't require a type specifier if we have the 'auto' storage class
1853239462Sdim    // specifier in C++98 -- we'll promote it to a type specifier.
1854239462Sdim    return false;
1855239462Sdim  }
1856239462Sdim
1857193326Sed  // Otherwise, if we don't consume this token, we are going to emit an
1858193326Sed  // error anyway.  Try to recover from various common problems.  Check
1859193326Sed  // to see if this was a reference to a tag name without a tag specified.
1860193326Sed  // This is a common problem in C (saying 'foo' instead of 'struct foo').
1861193326Sed  //
1862193326Sed  // C++ doesn't need this, and isTagName doesn't take SS.
1863193326Sed  if (SS == 0) {
1864221345Sdim    const char *TagName = 0, *FixitTagName = 0;
1865193326Sed    tok::TokenKind TagKind = tok::unknown;
1866198092Srdivacky
1867210299Sed    switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
1868193326Sed      default: break;
1869221345Sdim      case DeclSpec::TST_enum:
1870221345Sdim        TagName="enum"  ; FixitTagName = "enum "  ; TagKind=tok::kw_enum ;break;
1871221345Sdim      case DeclSpec::TST_union:
1872221345Sdim        TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
1873221345Sdim      case DeclSpec::TST_struct:
1874221345Sdim        TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
1875221345Sdim      case DeclSpec::TST_class:
1876221345Sdim        TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
1877193326Sed    }
1878198092Srdivacky
1879193326Sed    if (TagName) {
1880239462Sdim      IdentifierInfo *TokenName = Tok.getIdentifierInfo();
1881239462Sdim      LookupResult R(Actions, TokenName, SourceLocation(),
1882239462Sdim                     Sema::LookupOrdinaryName);
1883239462Sdim
1884193326Sed      Diag(Loc, diag::err_use_of_tag_name_without_tag)
1885239462Sdim        << TokenName << TagName << getLangOpts().CPlusPlus
1886239462Sdim        << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
1887198092Srdivacky
1888239462Sdim      if (Actions.LookupParsedName(R, getCurScope(), SS)) {
1889239462Sdim        for (LookupResult::iterator I = R.begin(), IEnd = R.end();
1890239462Sdim             I != IEnd; ++I)
1891239462Sdim          Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
1892239462Sdim            << TokenName << TagName;
1893239462Sdim      }
1894239462Sdim
1895193326Sed      // Parse this as a tag as if the missing tag were present.
1896193326Sed      if (TagKind == tok::kw_enum)
1897234353Sdim        ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
1898193326Sed      else
1899234353Sdim        ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
1900234353Sdim                            /*EnteringContext*/ false, DSC_normal);
1901193326Sed      return true;
1902193326Sed    }
1903193326Sed  }
1904198092Srdivacky
1905239462Sdim  // Determine whether this identifier could plausibly be the name of something
1906239462Sdim  // being declared (with a missing type).
1907239462Sdim  if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
1908239462Sdim      (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
1909239462Sdim    // Look ahead to the next token to try to figure out what this declaration
1910239462Sdim    // was supposed to be.
1911239462Sdim    switch (NextToken().getKind()) {
1912239462Sdim    case tok::comma:
1913239462Sdim    case tok::equal:
1914239462Sdim    case tok::kw_asm:
1915239462Sdim    case tok::l_brace:
1916239462Sdim    case tok::l_square:
1917239462Sdim    case tok::semi:
1918239462Sdim      // This looks like a variable declaration. The type is probably missing.
1919239462Sdim      // We're done parsing decl-specifiers.
1920239462Sdim      return false;
1921239462Sdim
1922239462Sdim    case tok::l_paren: {
1923239462Sdim      // static x(4); // 'x' is not a type
1924239462Sdim      // x(int n);    // 'x' is not a type
1925239462Sdim      // x (*p)[];    // 'x' is a type
1926239462Sdim      //
1927239462Sdim      // Since we're in an error case (or the rare 'implicit int in C++' MS
1928239462Sdim      // extension), we can afford to perform a tentative parse to determine
1929239462Sdim      // which case we're in.
1930239462Sdim      TentativeParsingAction PA(*this);
1931239462Sdim      ConsumeToken();
1932239462Sdim      TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
1933239462Sdim      PA.Revert();
1934239462Sdim      if (TPR == TPResult::False())
1935239462Sdim        return false;
1936239462Sdim      // The identifier is followed by a parenthesized declarator.
1937239462Sdim      // It's supposed to be a type.
1938239462Sdim      break;
1939239462Sdim    }
1940239462Sdim
1941239462Sdim    default:
1942239462Sdim      // This is probably supposed to be a type. This includes cases like:
1943239462Sdim      //   int f(itn);
1944239462Sdim      //   struct S { unsinged : 4; };
1945239462Sdim      break;
1946239462Sdim    }
1947239462Sdim  }
1948239462Sdim
1949239462Sdim  // This is almost certainly an invalid type name. Let the action emit a
1950198092Srdivacky  // diagnostic and attempt to recover.
1951212904Sdim  ParsedType T;
1952239462Sdim  IdentifierInfo *II = Tok.getIdentifierInfo();
1953239462Sdim  if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
1954198092Srdivacky    // The action emitted a diagnostic, so we don't have to.
1955198092Srdivacky    if (T) {
1956198092Srdivacky      // The action has suggested that the type T could be used. Set that as
1957198092Srdivacky      // the type in the declaration specifiers, consume the would-be type
1958198092Srdivacky      // name token, and we're done.
1959198092Srdivacky      const char *PrevSpec;
1960198092Srdivacky      unsigned DiagID;
1961212904Sdim      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
1962198092Srdivacky      DS.SetRangeEnd(Tok.getLocation());
1963198092Srdivacky      ConsumeToken();
1964198092Srdivacky      // There may be other declaration specifiers after this.
1965198092Srdivacky      return true;
1966239462Sdim    } else if (II != Tok.getIdentifierInfo()) {
1967239462Sdim      // If no type was suggested, the correction is to a keyword
1968239462Sdim      Tok.setKind(II->getTokenID());
1969239462Sdim      // There may be other declaration specifiers after this.
1970239462Sdim      return true;
1971198092Srdivacky    }
1972239462Sdim
1973198092Srdivacky    // Fall through; the action had no suggestion for us.
1974198092Srdivacky  } else {
1975198092Srdivacky    // The action did not emit a diagnostic, so emit one now.
1976198092Srdivacky    SourceRange R;
1977198092Srdivacky    if (SS) R = SS->getRange();
1978198092Srdivacky    Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
1979198092Srdivacky  }
1980198092Srdivacky
1981198092Srdivacky  // Mark this as an error.
1982234353Sdim  DS.SetTypeSpecError();
1983193326Sed  DS.SetRangeEnd(Tok.getLocation());
1984193326Sed  ConsumeToken();
1985198092Srdivacky
1986193326Sed  // TODO: Could inject an invalid typedef decl in an enclosing scope to
1987193326Sed  // avoid rippling error messages on subsequent uses of the same type,
1988193326Sed  // could be useful if #include was forgotten.
1989193326Sed  return false;
1990193326Sed}
1991193326Sed
1992202379Srdivacky/// \brief Determine the declaration specifier context from the declarator
1993202379Srdivacky/// context.
1994202379Srdivacky///
1995202379Srdivacky/// \param Context the declarator context, which is one of the
1996202379Srdivacky/// Declarator::TheContext enumerator values.
1997239462SdimParser::DeclSpecContext
1998202379SrdivackyParser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
1999202379Srdivacky  if (Context == Declarator::MemberContext)
2000202379Srdivacky    return DSC_class;
2001202379Srdivacky  if (Context == Declarator::FileContext)
2002202379Srdivacky    return DSC_top_level;
2003234353Sdim  if (Context == Declarator::TrailingReturnContext)
2004234353Sdim    return DSC_trailing;
2005202379Srdivacky  return DSC_normal;
2006202379Srdivacky}
2007202379Srdivacky
2008226633Sdim/// ParseAlignArgument - Parse the argument to an alignment-specifier.
2009226633Sdim///
2010226633Sdim/// FIXME: Simply returns an alignof() expression if the argument is a
2011226633Sdim/// type. Ideally, the type should be propagated directly into Sema.
2012226633Sdim///
2013234353Sdim/// [C11]   type-id
2014234353Sdim/// [C11]   constant-expression
2015234353Sdim/// [C++0x] type-id ...[opt]
2016234353Sdim/// [C++0x] assignment-expression ...[opt]
2017234353SdimExprResult Parser::ParseAlignArgument(SourceLocation Start,
2018234353Sdim                                      SourceLocation &EllipsisLoc) {
2019234353Sdim  ExprResult ER;
2020226633Sdim  if (isTypeIdInParens()) {
2021226633Sdim    SourceLocation TypeLoc = Tok.getLocation();
2022226633Sdim    ParsedType Ty = ParseTypeName().get();
2023226633Sdim    SourceRange TypeRange(Start, Tok.getLocation());
2024234353Sdim    ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
2025234353Sdim                                               Ty.getAsOpaquePtr(), TypeRange);
2026226633Sdim  } else
2027234353Sdim    ER = ParseConstantExpression();
2028234353Sdim
2029234353Sdim  if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis))
2030234353Sdim    EllipsisLoc = ConsumeToken();
2031234353Sdim
2032234353Sdim  return ER;
2033226633Sdim}
2034226633Sdim
2035226633Sdim/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
2036226633Sdim/// attribute to Attrs.
2037226633Sdim///
2038226633Sdim/// alignment-specifier:
2039234353Sdim/// [C11]   '_Alignas' '(' type-id ')'
2040234353Sdim/// [C11]   '_Alignas' '(' constant-expression ')'
2041234353Sdim/// [C++0x] 'alignas' '(' type-id ...[opt] ')'
2042234353Sdim/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')'
2043226633Sdimvoid Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
2044226633Sdim                                     SourceLocation *endLoc) {
2045226633Sdim  assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
2046226633Sdim         "Not an alignment-specifier!");
2047226633Sdim
2048226633Sdim  SourceLocation KWLoc = Tok.getLocation();
2049226633Sdim  ConsumeToken();
2050226633Sdim
2051226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
2052226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen))
2053226633Sdim    return;
2054226633Sdim
2055234353Sdim  SourceLocation EllipsisLoc;
2056234353Sdim  ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
2057226633Sdim  if (ArgExpr.isInvalid()) {
2058226633Sdim    SkipUntil(tok::r_paren);
2059226633Sdim    return;
2060226633Sdim  }
2061226633Sdim
2062226633Sdim  T.consumeClose();
2063226633Sdim  if (endLoc)
2064226633Sdim    *endLoc = T.getCloseLocation();
2065226633Sdim
2066234353Sdim  // FIXME: Handle pack-expansions here.
2067234353Sdim  if (EllipsisLoc.isValid()) {
2068234353Sdim    Diag(EllipsisLoc, diag::err_alignas_pack_exp_unsupported);
2069234353Sdim    return;
2070234353Sdim  }
2071234353Sdim
2072226633Sdim  ExprVector ArgExprs(Actions);
2073226633Sdim  ArgExprs.push_back(ArgExpr.release());
2074239462Sdim  // FIXME: This should not be GNU, but we since the attribute used is
2075239462Sdim  //        based on the spelling, and there is no true spelling for
2076239462Sdim  //        C++11 attributes, this isn't accepted.
2077226633Sdim  Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
2078239462Sdim               0, T.getOpenLocation(), ArgExprs.take(), 1,
2079239462Sdim               AttributeList::AS_GNU);
2080226633Sdim}
2081226633Sdim
2082193326Sed/// ParseDeclarationSpecifiers
2083193326Sed///       declaration-specifiers: [C99 6.7]
2084193326Sed///         storage-class-specifier declaration-specifiers[opt]
2085193326Sed///         type-specifier declaration-specifiers[opt]
2086193326Sed/// [C99]   function-specifier declaration-specifiers[opt]
2087234353Sdim/// [C11]   alignment-specifier declaration-specifiers[opt]
2088193326Sed/// [GNU]   attributes declaration-specifiers[opt]
2089226633Sdim/// [Clang] '__module_private__' declaration-specifiers[opt]
2090193326Sed///
2091193326Sed///       storage-class-specifier: [C99 6.7.1]
2092193326Sed///         'typedef'
2093193326Sed///         'extern'
2094193326Sed///         'static'
2095193326Sed///         'auto'
2096193326Sed///         'register'
2097193326Sed/// [C++]   'mutable'
2098193326Sed/// [GNU]   '__thread'
2099193326Sed///       function-specifier: [C99 6.7.4]
2100193326Sed/// [C99]   'inline'
2101193326Sed/// [C++]   'virtual'
2102193326Sed/// [C++]   'explicit'
2103218893Sdim/// [OpenCL] '__kernel'
2104193326Sed///       'friend': [C++ dcl.friend]
2105198954Srdivacky///       'constexpr': [C++0x dcl.constexpr]
2106193326Sed
2107193326Sed///
2108193326Sedvoid Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
2109193326Sed                                        const ParsedTemplateInfo &TemplateInfo,
2110198092Srdivacky                                        AccessSpecifier AS,
2111234353Sdim                                        DeclSpecContext DSContext,
2112234353Sdim                                        LateParsedAttrList *LateAttrs) {
2113221345Sdim  if (DS.getSourceRange().isInvalid()) {
2114221345Sdim    DS.SetRangeStart(Tok.getLocation());
2115221345Sdim    DS.SetRangeEnd(Tok.getLocation());
2116221345Sdim  }
2117239462Sdim
2118234353Sdim  bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2119239462Sdim  bool AttrsLastTime = false;
2120239462Sdim  ParsedAttributesWithRange attrs(AttrFactory);
2121193326Sed  while (1) {
2122198092Srdivacky    bool isInvalid = false;
2123193326Sed    const char *PrevSpec = 0;
2124198092Srdivacky    unsigned DiagID = 0;
2125198092Srdivacky
2126193326Sed    SourceLocation Loc = Tok.getLocation();
2127193326Sed
2128193326Sed    switch (Tok.getKind()) {
2129198092Srdivacky    default:
2130193326Sed    DoneWithDeclSpec:
2131239462Sdim      if (!AttrsLastTime)
2132239462Sdim        ProhibitAttributes(attrs);
2133239462Sdim      else
2134239462Sdim        DS.takeAttributesFrom(attrs);
2135226633Sdim
2136193326Sed      // If this is not a declaration specifier token, we're done reading decl
2137193326Sed      // specifiers.  First verify that DeclSpec's are consistent.
2138193326Sed      DS.Finish(Diags, PP);
2139193326Sed      return;
2140198092Srdivacky
2141239462Sdim    case tok::l_square:
2142239462Sdim    case tok::kw_alignas:
2143239462Sdim      if (!isCXX11AttributeSpecifier())
2144239462Sdim        goto DoneWithDeclSpec;
2145239462Sdim
2146239462Sdim      ProhibitAttributes(attrs);
2147239462Sdim      // FIXME: It would be good to recover by accepting the attributes,
2148239462Sdim      //        but attempting to do that now would cause serious
2149239462Sdim      //        madness in terms of diagnostics.
2150239462Sdim      attrs.clear();
2151239462Sdim      attrs.Range = SourceRange();
2152239462Sdim
2153239462Sdim      ParseCXX11Attributes(attrs);
2154239462Sdim      AttrsLastTime = true;
2155239462Sdim      continue;
2156239462Sdim
2157212904Sdim    case tok::code_completion: {
2158212904Sdim      Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
2159212904Sdim      if (DS.hasTypeSpecifier()) {
2160212904Sdim        bool AllowNonIdentifiers
2161212904Sdim          = (getCurScope()->getFlags() & (Scope::ControlScope |
2162212904Sdim                                          Scope::BlockScope |
2163212904Sdim                                          Scope::TemplateParamScope |
2164212904Sdim                                          Scope::FunctionPrototypeScope |
2165212904Sdim                                          Scope::AtCatchScope)) == 0;
2166212904Sdim        bool AllowNestedNameSpecifiers
2167239462Sdim          = DSContext == DSC_top_level ||
2168212904Sdim            (DSContext == DSC_class && DS.isFriendSpecified());
2169212904Sdim
2170218893Sdim        Actions.CodeCompleteDeclSpec(getCurScope(), DS,
2171239462Sdim                                     AllowNonIdentifiers,
2172218893Sdim                                     AllowNestedNameSpecifiers);
2173226633Sdim        return cutOffParsing();
2174239462Sdim      }
2175239462Sdim
2176218893Sdim      if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2177218893Sdim        CCC = Sema::PCC_LocalDeclarationSpecifiers;
2178218893Sdim      else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
2179239462Sdim        CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
2180212904Sdim                                    : Sema::PCC_Template;
2181212904Sdim      else if (DSContext == DSC_class)
2182212904Sdim        CCC = Sema::PCC_Class;
2183234353Sdim      else if (CurParsedObjCImpl)
2184212904Sdim        CCC = Sema::PCC_ObjCImplementation;
2185239462Sdim
2186212904Sdim      Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
2187226633Sdim      return cutOffParsing();
2188212904Sdim    }
2189212904Sdim
2190193326Sed    case tok::coloncolon: // ::foo::bar
2191204643Srdivacky      // C++ scope specifier.  Annotate and loop, or bail out on error.
2192204643Srdivacky      if (TryAnnotateCXXScopeToken(true)) {
2193204643Srdivacky        if (!DS.hasTypeSpecifier())
2194204643Srdivacky          DS.SetTypeSpecError();
2195204643Srdivacky        goto DoneWithDeclSpec;
2196204643Srdivacky      }
2197204643Srdivacky      if (Tok.is(tok::coloncolon)) // ::new or ::delete
2198204643Srdivacky        goto DoneWithDeclSpec;
2199204643Srdivacky      continue;
2200193326Sed
2201193326Sed    case tok::annot_cxxscope: {
2202239462Sdim      if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
2203193326Sed        goto DoneWithDeclSpec;
2204193326Sed
2205200583Srdivacky      CXXScopeSpec SS;
2206219077Sdim      Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2207219077Sdim                                                   Tok.getAnnotationRange(),
2208219077Sdim                                                   SS);
2209200583Srdivacky
2210193326Sed      // We are looking for a qualified typename.
2211193326Sed      Token Next = NextToken();
2212198092Srdivacky      if (Next.is(tok::annot_template_id) &&
2213193326Sed          static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
2214193326Sed            ->Kind == TNK_Type_template) {
2215193326Sed        // We have a qualified template-id, e.g., N::A<int>
2216202379Srdivacky
2217202379Srdivacky        // C++ [class.qual]p2:
2218202379Srdivacky        //   In a lookup in which the constructor is an acceptable lookup
2219202379Srdivacky        //   result and the nested-name-specifier nominates a class C:
2220202379Srdivacky        //
2221202379Srdivacky        //     - if the name specified after the
2222202379Srdivacky        //       nested-name-specifier, when looked up in C, is the
2223202379Srdivacky        //       injected-class-name of C (Clause 9), or
2224202379Srdivacky        //
2225202379Srdivacky        //     - if the name specified after the nested-name-specifier
2226202379Srdivacky        //       is the same as the identifier or the
2227202379Srdivacky        //       simple-template-id's template-name in the last
2228202379Srdivacky        //       component of the nested-name-specifier,
2229202379Srdivacky        //
2230202379Srdivacky        //   the name is instead considered to name the constructor of
2231202379Srdivacky        //   class C.
2232239462Sdim        //
2233202379Srdivacky        // Thus, if the template-name is actually the constructor
2234202379Srdivacky        // name, then the code is ill-formed; this interpretation is
2235239462Sdim        // reinforced by the NAD status of core issue 635.
2236224145Sdim        TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
2237207619Srdivacky        if ((DSContext == DSC_top_level ||
2238207619Srdivacky             (DSContext == DSC_class && DS.isFriendSpecified())) &&
2239207619Srdivacky            TemplateId->Name &&
2240210299Sed            Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
2241202379Srdivacky          if (isConstructorDeclarator()) {
2242202379Srdivacky            // The user meant this to be an out-of-line constructor
2243202379Srdivacky            // definition, but template arguments are not allowed
2244202379Srdivacky            // there.  Just allow this as a constructor; we'll
2245202379Srdivacky            // complain about it later.
2246202379Srdivacky            goto DoneWithDeclSpec;
2247202379Srdivacky          }
2248202379Srdivacky
2249202379Srdivacky          // The user meant this to name a type, but it actually names
2250202379Srdivacky          // a constructor with some extraneous template
2251202379Srdivacky          // arguments. Complain, then parse it as a type as the user
2252202379Srdivacky          // intended.
2253202379Srdivacky          Diag(TemplateId->TemplateNameLoc,
2254202379Srdivacky               diag::err_out_of_line_template_id_names_constructor)
2255202379Srdivacky            << TemplateId->Name;
2256202379Srdivacky        }
2257202379Srdivacky
2258200583Srdivacky        DS.getTypeSpecScope() = SS;
2259200583Srdivacky        ConsumeToken(); // The C++ scope.
2260198092Srdivacky        assert(Tok.is(tok::annot_template_id) &&
2261193326Sed               "ParseOptionalCXXScopeSpecifier not working");
2262221345Sdim        AnnotateTemplateIdTokenAsType();
2263193326Sed        continue;
2264193326Sed      }
2265193326Sed
2266198092Srdivacky      if (Next.is(tok::annot_typename)) {
2267200583Srdivacky        DS.getTypeSpecScope() = SS;
2268200583Srdivacky        ConsumeToken(); // The C++ scope.
2269212904Sdim        if (Tok.getAnnotationValue()) {
2270212904Sdim          ParsedType T = getTypeAnnotation(Tok);
2271218893Sdim          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
2272239462Sdim                                         Tok.getAnnotationEndLoc(),
2273212904Sdim                                         PrevSpec, DiagID, T);
2274212904Sdim        }
2275198092Srdivacky        else
2276198092Srdivacky          DS.SetTypeSpecError();
2277198092Srdivacky        DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2278198092Srdivacky        ConsumeToken(); // The typename
2279198092Srdivacky      }
2280198092Srdivacky
2281193326Sed      if (Next.isNot(tok::identifier))
2282193326Sed        goto DoneWithDeclSpec;
2283193326Sed
2284202379Srdivacky      // If we're in a context where the identifier could be a class name,
2285202379Srdivacky      // check whether this is a constructor declaration.
2286207619Srdivacky      if ((DSContext == DSC_top_level ||
2287207619Srdivacky           (DSContext == DSC_class && DS.isFriendSpecified())) &&
2288239462Sdim          Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
2289202379Srdivacky                                     &SS)) {
2290202379Srdivacky        if (isConstructorDeclarator())
2291202379Srdivacky          goto DoneWithDeclSpec;
2292193326Sed
2293202379Srdivacky        // As noted in C++ [class.qual]p2 (cited above), when the name
2294202379Srdivacky        // of the class is qualified in a context where it could name
2295202379Srdivacky        // a constructor, its a constructor name. However, we've
2296202379Srdivacky        // looked at the declarator, and the user probably meant this
2297202379Srdivacky        // to be a type. Complain that it isn't supposed to be treated
2298202379Srdivacky        // as a type, then proceed to parse it as a type.
2299202379Srdivacky        Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
2300202379Srdivacky          << Next.getIdentifierInfo();
2301202379Srdivacky      }
2302202379Srdivacky
2303212904Sdim      ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2304212904Sdim                                               Next.getLocation(),
2305221345Sdim                                               getCurScope(), &SS,
2306221345Sdim                                               false, false, ParsedType(),
2307234353Sdim                                               /*IsCtorOrDtorName=*/false,
2308221345Sdim                                               /*NonTrivialSourceInfo=*/true);
2309193326Sed
2310193326Sed      // If the referenced identifier is not a type, then this declspec is
2311193326Sed      // erroneous: We already checked about that it has no type specifier, and
2312193326Sed      // C++ doesn't have implicit int.  Diagnose it as a typo w.r.t. to the
2313198092Srdivacky      // typename.
2314193326Sed      if (TypeRep == 0) {
2315193326Sed        ConsumeToken();   // Eat the scope spec so the identifier is current.
2316234353Sdim        if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue;
2317193326Sed        goto DoneWithDeclSpec;
2318193326Sed      }
2319198092Srdivacky
2320200583Srdivacky      DS.getTypeSpecScope() = SS;
2321193326Sed      ConsumeToken(); // The C++ scope.
2322193326Sed
2323193326Sed      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2324198092Srdivacky                                     DiagID, TypeRep);
2325193326Sed      if (isInvalid)
2326193326Sed        break;
2327198092Srdivacky
2328193326Sed      DS.SetRangeEnd(Tok.getLocation());
2329193326Sed      ConsumeToken(); // The typename.
2330193326Sed
2331193326Sed      continue;
2332193326Sed    }
2333198092Srdivacky
2334193326Sed    case tok::annot_typename: {
2335212904Sdim      if (Tok.getAnnotationValue()) {
2336212904Sdim        ParsedType T = getTypeAnnotation(Tok);
2337193326Sed        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2338212904Sdim                                       DiagID, T);
2339212904Sdim      } else
2340193326Sed        DS.SetTypeSpecError();
2341239462Sdim
2342206275Srdivacky      if (isInvalid)
2343206275Srdivacky        break;
2344206275Srdivacky
2345193326Sed      DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2346193326Sed      ConsumeToken(); // The typename
2347198092Srdivacky
2348193326Sed      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2349193326Sed      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
2350239462Sdim      // Objective-C interface.
2351234353Sdim      if (Tok.is(tok::less) && getLangOpts().ObjC1)
2352218893Sdim        ParseObjCProtocolQualifiers(DS);
2353239462Sdim
2354193326Sed      continue;
2355193326Sed    }
2356198092Srdivacky
2357221345Sdim    case tok::kw___is_signed:
2358221345Sdim      // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
2359221345Sdim      // typically treats it as a trait. If we see __is_signed as it appears
2360221345Sdim      // in libstdc++, e.g.,
2361221345Sdim      //
2362221345Sdim      //   static const bool __is_signed;
2363221345Sdim      //
2364221345Sdim      // then treat __is_signed as an identifier rather than as a keyword.
2365221345Sdim      if (DS.getTypeSpecType() == TST_bool &&
2366221345Sdim          DS.getTypeQualifiers() == DeclSpec::TQ_const &&
2367221345Sdim          DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2368221345Sdim        Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
2369221345Sdim        Tok.setKind(tok::identifier);
2370221345Sdim      }
2371221345Sdim
2372221345Sdim      // We're done with the declaration-specifiers.
2373221345Sdim      goto DoneWithDeclSpec;
2374239462Sdim
2375193326Sed      // typedef-name
2376234353Sdim    case tok::kw_decltype:
2377193326Sed    case tok::identifier: {
2378193326Sed      // In C++, check to see if this is a scope specifier like foo::bar::, if
2379193326Sed      // so handle it as such.  This is important for ctor parsing.
2380234353Sdim      if (getLangOpts().CPlusPlus) {
2381204643Srdivacky        if (TryAnnotateCXXScopeToken(true)) {
2382204643Srdivacky          if (!DS.hasTypeSpecifier())
2383204643Srdivacky            DS.SetTypeSpecError();
2384204643Srdivacky          goto DoneWithDeclSpec;
2385204643Srdivacky        }
2386204643Srdivacky        if (!Tok.is(tok::identifier))
2387204643Srdivacky          continue;
2388204643Srdivacky      }
2389198092Srdivacky
2390193326Sed      // This identifier can only be a typedef name if we haven't already seen
2391193326Sed      // a type-specifier.  Without this check we misparse:
2392193326Sed      //  typedef int X; struct Y { short X; };  as 'short int'.
2393193326Sed      if (DS.hasTypeSpecifier())
2394193326Sed        goto DoneWithDeclSpec;
2395198092Srdivacky
2396203955Srdivacky      // Check for need to substitute AltiVec keyword tokens.
2397203955Srdivacky      if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2398203955Srdivacky        break;
2399203955Srdivacky
2400239462Sdim      // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2401239462Sdim      //                allow the use of a typedef name as a type specifier.
2402239462Sdim      if (DS.isTypeAltiVecVector())
2403239462Sdim        goto DoneWithDeclSpec;
2404239462Sdim
2405212904Sdim      ParsedType TypeRep =
2406212904Sdim        Actions.getTypeName(*Tok.getIdentifierInfo(),
2407212904Sdim                            Tok.getLocation(), getCurScope());
2408193326Sed
2409193326Sed      // If this is not a typedef name, don't parse it as part of the declspec,
2410193326Sed      // it must be an implicit int or an error.
2411212904Sdim      if (!TypeRep) {
2412234353Sdim        if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue;
2413193326Sed        goto DoneWithDeclSpec;
2414193326Sed      }
2415193326Sed
2416202379Srdivacky      // If we're in a context where the identifier could be a class name,
2417202379Srdivacky      // check whether this is a constructor declaration.
2418234353Sdim      if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
2419210299Sed          Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
2420202379Srdivacky          isConstructorDeclarator())
2421193326Sed        goto DoneWithDeclSpec;
2422193326Sed
2423193326Sed      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2424198092Srdivacky                                     DiagID, TypeRep);
2425193326Sed      if (isInvalid)
2426193326Sed        break;
2427198092Srdivacky
2428193326Sed      DS.SetRangeEnd(Tok.getLocation());
2429193326Sed      ConsumeToken(); // The identifier
2430193326Sed
2431193326Sed      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2432193326Sed      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
2433239462Sdim      // Objective-C interface.
2434234353Sdim      if (Tok.is(tok::less) && getLangOpts().ObjC1)
2435218893Sdim        ParseObjCProtocolQualifiers(DS);
2436239462Sdim
2437193326Sed      // Need to support trailing type qualifiers (e.g. "id<p> const").
2438193326Sed      // If a type specifier follows, it will be diagnosed elsewhere.
2439193326Sed      continue;
2440193326Sed    }
2441193326Sed
2442193326Sed      // type-name
2443193326Sed    case tok::annot_template_id: {
2444224145Sdim      TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2445193326Sed      if (TemplateId->Kind != TNK_Type_template) {
2446193326Sed        // This template-id does not refer to a type name, so we're
2447193326Sed        // done with the type-specifiers.
2448193326Sed        goto DoneWithDeclSpec;
2449193326Sed      }
2450193326Sed
2451202379Srdivacky      // If we're in a context where the template-id could be a
2452202379Srdivacky      // constructor name or specialization, check whether this is a
2453202379Srdivacky      // constructor declaration.
2454234353Sdim      if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
2455210299Sed          Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
2456202379Srdivacky          isConstructorDeclarator())
2457202379Srdivacky        goto DoneWithDeclSpec;
2458202379Srdivacky
2459193326Sed      // Turn the template-id annotation token into a type annotation
2460193326Sed      // token, then try again to parse it as a type-specifier.
2461193326Sed      AnnotateTemplateIdTokenAsType();
2462193326Sed      continue;
2463193326Sed    }
2464193326Sed
2465193326Sed    // GNU attributes support.
2466193326Sed    case tok::kw___attribute:
2467234353Sdim      ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
2468193326Sed      continue;
2469193326Sed
2470193326Sed    // Microsoft declspec support.
2471193326Sed    case tok::kw___declspec:
2472218893Sdim      ParseMicrosoftDeclSpec(DS.getAttributes());
2473193326Sed      continue;
2474198092Srdivacky
2475193326Sed    // Microsoft single token adornments.
2476239462Sdim    case tok::kw___forceinline: {
2477239462Sdim      isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
2478239462Sdim      IdentifierInfo *AttrName = Tok.getIdentifierInfo();
2479239462Sdim      SourceLocation AttrNameLoc = ConsumeToken();
2480239462Sdim      // FIXME: This does not work correctly if it is set to be a declspec
2481239462Sdim      //        attribute, and a GNU attribute is simply incorrect.
2482239462Sdim      DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
2483239462Sdim                                SourceLocation(), 0, 0, AttributeList::AS_GNU);
2484239462Sdim      continue;
2485239462Sdim    }
2486194179Sed
2487194179Sed    case tok::kw___ptr64:
2488226633Sdim    case tok::kw___ptr32:
2489193326Sed    case tok::kw___w64:
2490193326Sed    case tok::kw___cdecl:
2491193326Sed    case tok::kw___stdcall:
2492193326Sed    case tok::kw___fastcall:
2493208600Srdivacky    case tok::kw___thiscall:
2494226633Sdim    case tok::kw___unaligned:
2495218893Sdim      ParseMicrosoftTypeAttributes(DS.getAttributes());
2496194179Sed      continue;
2497194179Sed
2498212904Sdim    // Borland single token adornments.
2499212904Sdim    case tok::kw___pascal:
2500218893Sdim      ParseBorlandTypeAttributes(DS.getAttributes());
2501212904Sdim      continue;
2502212904Sdim
2503218893Sdim    // OpenCL single token adornments.
2504218893Sdim    case tok::kw___kernel:
2505218893Sdim      ParseOpenCLAttributes(DS.getAttributes());
2506218893Sdim      continue;
2507218893Sdim
2508193326Sed    // storage-class-specifier
2509193326Sed    case tok::kw_typedef:
2510226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2511226633Sdim                                         PrevSpec, DiagID);
2512193326Sed      break;
2513193326Sed    case tok::kw_extern:
2514193326Sed      if (DS.isThreadSpecified())
2515193326Sed        Diag(Tok, diag::ext_thread_before) << "extern";
2516226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2517226633Sdim                                         PrevSpec, DiagID);
2518193326Sed      break;
2519193326Sed    case tok::kw___private_extern__:
2520226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2521226633Sdim                                         Loc, PrevSpec, DiagID);
2522193326Sed      break;
2523193326Sed    case tok::kw_static:
2524193326Sed      if (DS.isThreadSpecified())
2525193326Sed        Diag(Tok, diag::ext_thread_before) << "static";
2526226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2527226633Sdim                                         PrevSpec, DiagID);
2528193326Sed      break;
2529193326Sed    case tok::kw_auto:
2530234353Sdim      if (getLangOpts().CPlusPlus0x) {
2531219077Sdim        if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
2532226633Sdim          isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2533226633Sdim                                             PrevSpec, DiagID);
2534219077Sdim          if (!isInvalid)
2535226633Sdim            Diag(Tok, diag::ext_auto_storage_class)
2536219077Sdim              << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
2537226633Sdim        } else
2538219077Sdim          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2539219077Sdim                                         DiagID);
2540226633Sdim      } else
2541226633Sdim        isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2542226633Sdim                                           PrevSpec, DiagID);
2543193326Sed      break;
2544193326Sed    case tok::kw_register:
2545226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2546226633Sdim                                         PrevSpec, DiagID);
2547193326Sed      break;
2548193326Sed    case tok::kw_mutable:
2549226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2550226633Sdim                                         PrevSpec, DiagID);
2551193326Sed      break;
2552193326Sed    case tok::kw___thread:
2553198092Srdivacky      isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
2554193326Sed      break;
2555198092Srdivacky
2556193326Sed    // function-specifier
2557193326Sed    case tok::kw_inline:
2558198092Srdivacky      isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
2559193326Sed      break;
2560193326Sed    case tok::kw_virtual:
2561198092Srdivacky      isInvalid = DS.SetFunctionSpecVirtual(Loc, PrevSpec, DiagID);
2562193326Sed      break;
2563193326Sed    case tok::kw_explicit:
2564198092Srdivacky      isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
2565193326Sed      break;
2566193326Sed
2567226633Sdim    // alignment-specifier
2568226633Sdim    case tok::kw__Alignas:
2569234353Sdim      if (!getLangOpts().C11)
2570239462Sdim        Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
2571226633Sdim      ParseAlignmentSpecifier(DS.getAttributes());
2572226633Sdim      continue;
2573226633Sdim
2574193326Sed    // friend
2575193326Sed    case tok::kw_friend:
2576198092Srdivacky      if (DSContext == DSC_class)
2577198092Srdivacky        isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2578198092Srdivacky      else {
2579198092Srdivacky        PrevSpec = ""; // not actually used by the diagnostic
2580198092Srdivacky        DiagID = diag::err_friend_invalid_in_context;
2581198092Srdivacky        isInvalid = true;
2582198092Srdivacky      }
2583193326Sed      break;
2584198092Srdivacky
2585226633Sdim    // Modules
2586226633Sdim    case tok::kw___module_private__:
2587226633Sdim      isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2588226633Sdim      break;
2589239462Sdim
2590198954Srdivacky    // constexpr
2591198954Srdivacky    case tok::kw_constexpr:
2592198954Srdivacky      isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2593198954Srdivacky      break;
2594198954Srdivacky
2595193326Sed    // type-specifier
2596193326Sed    case tok::kw_short:
2597198092Srdivacky      isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2598198092Srdivacky                                      DiagID);
2599193326Sed      break;
2600193326Sed    case tok::kw_long:
2601193326Sed      if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
2602198092Srdivacky        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2603198092Srdivacky                                        DiagID);
2604193326Sed      else
2605198092Srdivacky        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2606198092Srdivacky                                        DiagID);
2607193326Sed      break;
2608221345Sdim    case tok::kw___int64:
2609221345Sdim        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2610221345Sdim                                        DiagID);
2611221345Sdim      break;
2612193326Sed    case tok::kw_signed:
2613198092Srdivacky      isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2614198092Srdivacky                                     DiagID);
2615193326Sed      break;
2616193326Sed    case tok::kw_unsigned:
2617198092Srdivacky      isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
2618198092Srdivacky                                     DiagID);
2619193326Sed      break;
2620193326Sed    case tok::kw__Complex:
2621198092Srdivacky      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
2622198092Srdivacky                                        DiagID);
2623193326Sed      break;
2624193326Sed    case tok::kw__Imaginary:
2625198092Srdivacky      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
2626198092Srdivacky                                        DiagID);
2627193326Sed      break;
2628193326Sed    case tok::kw_void:
2629198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
2630198092Srdivacky                                     DiagID);
2631193326Sed      break;
2632193326Sed    case tok::kw_char:
2633198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
2634198092Srdivacky                                     DiagID);
2635193326Sed      break;
2636193326Sed    case tok::kw_int:
2637198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
2638198092Srdivacky                                     DiagID);
2639193326Sed      break;
2640234353Sdim    case tok::kw___int128:
2641234353Sdim      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
2642234353Sdim                                     DiagID);
2643234353Sdim      break;
2644234353Sdim    case tok::kw_half:
2645234353Sdim      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
2646234353Sdim                                     DiagID);
2647234353Sdim      break;
2648193326Sed    case tok::kw_float:
2649198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
2650198092Srdivacky                                     DiagID);
2651193326Sed      break;
2652193326Sed    case tok::kw_double:
2653198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
2654198092Srdivacky                                     DiagID);
2655193326Sed      break;
2656193326Sed    case tok::kw_wchar_t:
2657198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
2658198092Srdivacky                                     DiagID);
2659193326Sed      break;
2660198092Srdivacky    case tok::kw_char16_t:
2661198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
2662198092Srdivacky                                     DiagID);
2663198092Srdivacky      break;
2664198092Srdivacky    case tok::kw_char32_t:
2665198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
2666198092Srdivacky                                     DiagID);
2667198092Srdivacky      break;
2668193326Sed    case tok::kw_bool:
2669193326Sed    case tok::kw__Bool:
2670218893Sdim      if (Tok.is(tok::kw_bool) &&
2671218893Sdim          DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
2672218893Sdim          DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
2673218893Sdim        PrevSpec = ""; // Not used by the diagnostic.
2674218893Sdim        DiagID = diag::err_bool_redeclaration;
2675221345Sdim        // For better error recovery.
2676221345Sdim        Tok.setKind(tok::identifier);
2677218893Sdim        isInvalid = true;
2678218893Sdim      } else {
2679218893Sdim        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
2680218893Sdim                                       DiagID);
2681218893Sdim      }
2682193326Sed      break;
2683193326Sed    case tok::kw__Decimal32:
2684198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
2685198092Srdivacky                                     DiagID);
2686193326Sed      break;
2687193326Sed    case tok::kw__Decimal64:
2688198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
2689198092Srdivacky                                     DiagID);
2690193326Sed      break;
2691193326Sed    case tok::kw__Decimal128:
2692198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
2693198092Srdivacky                                     DiagID);
2694193326Sed      break;
2695203955Srdivacky    case tok::kw___vector:
2696203955Srdivacky      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
2697203955Srdivacky      break;
2698203955Srdivacky    case tok::kw___pixel:
2699203955Srdivacky      isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
2700203955Srdivacky      break;
2701221345Sdim    case tok::kw___unknown_anytype:
2702221345Sdim      isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
2703221345Sdim                                     PrevSpec, DiagID);
2704221345Sdim      break;
2705193326Sed
2706193326Sed    // class-specifier:
2707193326Sed    case tok::kw_class:
2708193326Sed    case tok::kw_struct:
2709193326Sed    case tok::kw_union: {
2710193326Sed      tok::TokenKind Kind = Tok.getKind();
2711193326Sed      ConsumeToken();
2712234353Sdim      ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
2713234353Sdim                          EnteringContext, DSContext);
2714193326Sed      continue;
2715193326Sed    }
2716193326Sed
2717193326Sed    // enum-specifier:
2718193326Sed    case tok::kw_enum:
2719193326Sed      ConsumeToken();
2720234353Sdim      ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
2721193326Sed      continue;
2722193326Sed
2723193326Sed    // cv-qualifier:
2724193326Sed    case tok::kw_const:
2725198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
2726239462Sdim                                 getLangOpts(), /*IsTypeSpec*/true);
2727193326Sed      break;
2728193326Sed    case tok::kw_volatile:
2729198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
2730239462Sdim                                 getLangOpts(), /*IsTypeSpec*/true);
2731193326Sed      break;
2732193326Sed    case tok::kw_restrict:
2733198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
2734239462Sdim                                 getLangOpts(), /*IsTypeSpec*/true);
2735193326Sed      break;
2736193326Sed
2737193326Sed    // C++ typename-specifier:
2738193326Sed    case tok::kw_typename:
2739204643Srdivacky      if (TryAnnotateTypeOrScopeToken()) {
2740204643Srdivacky        DS.SetTypeSpecError();
2741204643Srdivacky        goto DoneWithDeclSpec;
2742204643Srdivacky      }
2743204643Srdivacky      if (!Tok.is(tok::kw_typename))
2744193326Sed        continue;
2745193326Sed      break;
2746193326Sed
2747193326Sed    // GNU typeof support.
2748193326Sed    case tok::kw_typeof:
2749193326Sed      ParseTypeofSpecifier(DS);
2750193326Sed      continue;
2751193326Sed
2752234353Sdim    case tok::annot_decltype:
2753195099Sed      ParseDecltypeSpecifier(DS);
2754195099Sed      continue;
2755195099Sed
2756223017Sdim    case tok::kw___underlying_type:
2757223017Sdim      ParseUnderlyingTypeSpecifier(DS);
2758226633Sdim      continue;
2759223017Sdim
2760226633Sdim    case tok::kw__Atomic:
2761226633Sdim      ParseAtomicSpecifier(DS);
2762226633Sdim      continue;
2763226633Sdim
2764221345Sdim    // OpenCL qualifiers:
2765239462Sdim    case tok::kw_private:
2766234353Sdim      if (!getLangOpts().OpenCL)
2767221345Sdim        goto DoneWithDeclSpec;
2768221345Sdim    case tok::kw___private:
2769221345Sdim    case tok::kw___global:
2770221345Sdim    case tok::kw___local:
2771221345Sdim    case tok::kw___constant:
2772221345Sdim    case tok::kw___read_only:
2773221345Sdim    case tok::kw___write_only:
2774221345Sdim    case tok::kw___read_write:
2775221345Sdim      ParseOpenCLQualifiers(DS);
2776221345Sdim      break;
2777239462Sdim
2778193326Sed    case tok::less:
2779193326Sed      // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
2780193326Sed      // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,
2781193326Sed      // but we support it.
2782234353Sdim      if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
2783193326Sed        goto DoneWithDeclSpec;
2784198092Srdivacky
2785218893Sdim      if (!ParseObjCProtocolQualifiers(DS))
2786193326Sed        Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
2787206084Srdivacky          << FixItHint::CreateInsertion(Loc, "id")
2788218893Sdim          << SourceRange(Loc, DS.getSourceRange().getEnd());
2789239462Sdim
2790218893Sdim      // Need to support trailing type qualifiers (e.g. "id<p> const").
2791218893Sdim      // If a type specifier follows, it will be diagnosed elsewhere.
2792218893Sdim      continue;
2793193326Sed    }
2794198092Srdivacky    // If the specifier wasn't legal, issue a diagnostic.
2795193326Sed    if (isInvalid) {
2796193326Sed      assert(PrevSpec && "Method did not return previous specifier!");
2797198092Srdivacky      assert(DiagID);
2798239462Sdim
2799212904Sdim      if (DiagID == diag::ext_duplicate_declspec)
2800212904Sdim        Diag(Tok, DiagID)
2801212904Sdim          << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
2802212904Sdim      else
2803212904Sdim        Diag(Tok, DiagID) << PrevSpec;
2804193326Sed    }
2805219077Sdim
2806193326Sed    DS.SetRangeEnd(Tok.getLocation());
2807221345Sdim    if (DiagID != diag::err_bool_redeclaration)
2808221345Sdim      ConsumeToken();
2809239462Sdim
2810239462Sdim    AttrsLastTime = false;
2811193326Sed  }
2812193326Sed}
2813193326Sed
2814193326Sed/// ParseStructDeclaration - Parse a struct declaration without the terminating
2815193326Sed/// semicolon.
2816193326Sed///
2817193326Sed///       struct-declaration:
2818193326Sed///         specifier-qualifier-list struct-declarator-list
2819193326Sed/// [GNU]   __extension__ struct-declaration
2820193326Sed/// [GNU]   specifier-qualifier-list
2821193326Sed///       struct-declarator-list:
2822193326Sed///         struct-declarator
2823193326Sed///         struct-declarator-list ',' struct-declarator
2824193326Sed/// [GNU]   struct-declarator-list ',' attributes[opt] struct-declarator
2825193326Sed///       struct-declarator:
2826193326Sed///         declarator
2827193326Sed/// [GNU]   declarator attributes[opt]
2828193326Sed///         declarator[opt] ':' constant-expression
2829193326Sed/// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
2830193326Sed///
2831193326Sedvoid Parser::
2832239462SdimParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
2833239462Sdim
2834193326Sed  if (Tok.is(tok::kw___extension__)) {
2835193326Sed    // __extension__ silences extension warnings in the subexpression.
2836193326Sed    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
2837193326Sed    ConsumeToken();
2838193326Sed    return ParseStructDeclaration(DS, Fields);
2839193326Sed  }
2840198092Srdivacky
2841193326Sed  // Parse the common specifier-qualifiers-list piece.
2842193326Sed  ParseSpecifierQualifierList(DS);
2843198092Srdivacky
2844193326Sed  // If there are no declarators, this is a free-standing declaration
2845193326Sed  // specifier. Let the actions module cope with it.
2846193326Sed  if (Tok.is(tok::semi)) {
2847239462Sdim    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
2848239462Sdim                                                       DS);
2849239462Sdim    DS.complete(TheDecl);
2850193326Sed    return;
2851193326Sed  }
2852193326Sed
2853193326Sed  // Read struct-declarators until we find the semicolon.
2854198893Srdivacky  bool FirstDeclarator = true;
2855234353Sdim  SourceLocation CommaLoc;
2856193326Sed  while (1) {
2857239462Sdim    ParsingFieldDeclarator DeclaratorInfo(*this, DS);
2858234353Sdim    DeclaratorInfo.D.setCommaLoc(CommaLoc);
2859198092Srdivacky
2860198893Srdivacky    // Attributes are only allowed here on successive declarators.
2861218893Sdim    if (!FirstDeclarator)
2862218893Sdim      MaybeParseGNUAttributes(DeclaratorInfo.D);
2863198893Srdivacky
2864193326Sed    /// struct-declarator: declarator
2865193326Sed    /// struct-declarator: declarator[opt] ':' constant-expression
2866200583Srdivacky    if (Tok.isNot(tok::colon)) {
2867200583Srdivacky      // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
2868200583Srdivacky      ColonProtectionRAIIObject X(*this);
2869193326Sed      ParseDeclarator(DeclaratorInfo.D);
2870200583Srdivacky    }
2871198092Srdivacky
2872193326Sed    if (Tok.is(tok::colon)) {
2873193326Sed      ConsumeToken();
2874212904Sdim      ExprResult Res(ParseConstantExpression());
2875193326Sed      if (Res.isInvalid())
2876193326Sed        SkipUntil(tok::semi, true, true);
2877193326Sed      else
2878193326Sed        DeclaratorInfo.BitfieldSize = Res.release();
2879193326Sed    }
2880193326Sed
2881193326Sed    // If attributes exist after the declarator, parse them.
2882218893Sdim    MaybeParseGNUAttributes(DeclaratorInfo.D);
2883193326Sed
2884198893Srdivacky    // We're done with this declarator;  invoke the callback.
2885239462Sdim    Fields.invoke(DeclaratorInfo);
2886198893Srdivacky
2887193326Sed    // If we don't have a comma, it is either the end of the list (a ';')
2888193326Sed    // or an error, bail out.
2889193326Sed    if (Tok.isNot(tok::comma))
2890193326Sed      return;
2891193326Sed
2892193326Sed    // Consume the comma.
2893234353Sdim    CommaLoc = ConsumeToken();
2894193326Sed
2895198893Srdivacky    FirstDeclarator = false;
2896193326Sed  }
2897193326Sed}
2898193326Sed
2899193326Sed/// ParseStructUnionBody
2900193326Sed///       struct-contents:
2901193326Sed///         struct-declaration-list
2902193326Sed/// [EXT]   empty
2903193326Sed/// [GNU]   "struct-declaration-list" without terminatoring ';'
2904193326Sed///       struct-declaration-list:
2905193326Sed///         struct-declaration
2906193326Sed///         struct-declaration-list struct-declaration
2907193326Sed/// [OBC]   '@' 'defs' '(' class-name ')'
2908193326Sed///
2909193326Sedvoid Parser::ParseStructUnionBody(SourceLocation RecordLoc,
2910212904Sdim                                  unsigned TagType, Decl *TagDecl) {
2911212904Sdim  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2912212904Sdim                                      "parsing struct/union body");
2913198092Srdivacky
2914226633Sdim  BalancedDelimiterTracker T(*this, tok::l_brace);
2915226633Sdim  if (T.consumeOpen())
2916226633Sdim    return;
2917198092Srdivacky
2918193326Sed  ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
2919210299Sed  Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
2920193326Sed
2921193326Sed  // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
2922193326Sed  // C++.
2923234353Sdim  if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {
2924234353Sdim    Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union);
2925234353Sdim    Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union);
2926234353Sdim  }
2927193326Sed
2928226633Sdim  SmallVector<Decl *, 32> FieldDecls;
2929193326Sed
2930193326Sed  // While we still have something to read, read the declarations in the struct.
2931193326Sed  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
2932193326Sed    // Each iteration of this loop reads one struct-declaration.
2933198092Srdivacky
2934193326Sed    // Check for extraneous top-level semicolon.
2935193326Sed    if (Tok.is(tok::semi)) {
2936239462Sdim      ConsumeExtraSemi(InsideStruct, TagType);
2937193326Sed      continue;
2938193326Sed    }
2939193326Sed
2940193326Sed    if (!Tok.is(tok::at)) {
2941198893Srdivacky      struct CFieldCallback : FieldCallback {
2942198893Srdivacky        Parser &P;
2943212904Sdim        Decl *TagDecl;
2944226633Sdim        SmallVectorImpl<Decl *> &FieldDecls;
2945198092Srdivacky
2946212904Sdim        CFieldCallback(Parser &P, Decl *TagDecl,
2947226633Sdim                       SmallVectorImpl<Decl *> &FieldDecls) :
2948198893Srdivacky          P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
2949198893Srdivacky
2950239462Sdim        void invoke(ParsingFieldDeclarator &FD) {
2951198893Srdivacky          // Install the declarator into the current TagDecl.
2952212904Sdim          Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
2953198893Srdivacky                              FD.D.getDeclSpec().getSourceRange().getBegin(),
2954198893Srdivacky                                                 FD.D, FD.BitfieldSize);
2955198893Srdivacky          FieldDecls.push_back(Field);
2956239462Sdim          FD.complete(Field);
2957198092Srdivacky        }
2958198893Srdivacky      } Callback(*this, TagDecl, FieldDecls);
2959198893Srdivacky
2960239462Sdim      // Parse all the comma separated declarators.
2961239462Sdim      ParsingDeclSpec DS(*this);
2962198893Srdivacky      ParseStructDeclaration(DS, Callback);
2963193326Sed    } else { // Handle @defs
2964193326Sed      ConsumeToken();
2965193326Sed      if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
2966193326Sed        Diag(Tok, diag::err_unexpected_at);
2967203955Srdivacky        SkipUntil(tok::semi, true);
2968193326Sed        continue;
2969193326Sed      }
2970193326Sed      ConsumeToken();
2971193326Sed      ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
2972193326Sed      if (!Tok.is(tok::identifier)) {
2973193326Sed        Diag(Tok, diag::err_expected_ident);
2974203955Srdivacky        SkipUntil(tok::semi, true);
2975193326Sed        continue;
2976193326Sed      }
2977226633Sdim      SmallVector<Decl *, 16> Fields;
2978210299Sed      Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
2979193326Sed                        Tok.getIdentifierInfo(), Fields);
2980193326Sed      FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
2981193326Sed      ConsumeToken();
2982193326Sed      ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
2983198092Srdivacky    }
2984193326Sed
2985193326Sed    if (Tok.is(tok::semi)) {
2986193326Sed      ConsumeToken();
2987193326Sed    } else if (Tok.is(tok::r_brace)) {
2988203955Srdivacky      ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
2989193326Sed      break;
2990193326Sed    } else {
2991203955Srdivacky      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
2992203955Srdivacky      // Skip to end of block or statement to avoid ext-warning on extra ';'.
2993193326Sed      SkipUntil(tok::r_brace, true, true);
2994203955Srdivacky      // If we stopped at a ';', eat it.
2995203955Srdivacky      if (Tok.is(tok::semi)) ConsumeToken();
2996193326Sed    }
2997193326Sed  }
2998198092Srdivacky
2999226633Sdim  T.consumeClose();
3000198092Srdivacky
3001221345Sdim  ParsedAttributes attrs(AttrFactory);
3002193326Sed  // If attributes exist after struct contents, parse them.
3003218893Sdim  MaybeParseGNUAttributes(attrs);
3004193326Sed
3005210299Sed  Actions.ActOnFields(getCurScope(),
3006226633Sdim                      RecordLoc, TagDecl, FieldDecls,
3007226633Sdim                      T.getOpenLocation(), T.getCloseLocation(),
3008218893Sdim                      attrs.getList());
3009193326Sed  StructScope.Exit();
3010226633Sdim  Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
3011226633Sdim                                   T.getCloseLocation());
3012193326Sed}
3013193326Sed
3014193326Sed/// ParseEnumSpecifier
3015193326Sed///       enum-specifier: [C99 6.7.2.2]
3016193326Sed///         'enum' identifier[opt] '{' enumerator-list '}'
3017193326Sed///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
3018193326Sed/// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
3019193326Sed///                                                 '}' attributes[opt]
3020234353Sdim/// [MS]    'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
3021234353Sdim///                                                 '}'
3022193326Sed///         'enum' identifier
3023193326Sed/// [GNU]   'enum' attributes[opt] identifier
3024193326Sed///
3025234353Sdim/// [C++11] enum-head '{' enumerator-list[opt] '}'
3026234353Sdim/// [C++11] enum-head '{' enumerator-list ','  '}'
3027218893Sdim///
3028234353Sdim///       enum-head: [C++11]
3029234353Sdim///         enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
3030234353Sdim///         enum-key attribute-specifier-seq[opt] nested-name-specifier
3031234353Sdim///             identifier enum-base[opt]
3032218893Sdim///
3033234353Sdim///       enum-key: [C++11]
3034218893Sdim///         'enum'
3035218893Sdim///         'enum' 'class'
3036218893Sdim///         'enum' 'struct'
3037218893Sdim///
3038234353Sdim///       enum-base: [C++11]
3039218893Sdim///         ':' type-specifier-seq
3040218893Sdim///
3041193326Sed/// [C++] elaborated-type-specifier:
3042193326Sed/// [C++]   'enum' '::'[opt] nested-name-specifier[opt] identifier
3043193326Sed///
3044193326Sedvoid Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
3045204643Srdivacky                                const ParsedTemplateInfo &TemplateInfo,
3046234353Sdim                                AccessSpecifier AS, DeclSpecContext DSC) {
3047193326Sed  // Parse the tag portion of this.
3048198092Srdivacky  if (Tok.is(tok::code_completion)) {
3049198092Srdivacky    // Code completion for an enum name.
3050210299Sed    Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
3051226633Sdim    return cutOffParsing();
3052198092Srdivacky  }
3053224145Sdim
3054239462Sdim  // If attributes exist after tag, parse them.
3055239462Sdim  ParsedAttributesWithRange attrs(AttrFactory);
3056239462Sdim  MaybeParseGNUAttributes(attrs);
3057239462Sdim  MaybeParseCXX0XAttributes(attrs);
3058239462Sdim
3059239462Sdim  // If declspecs exist after tag, parse them.
3060239462Sdim  while (Tok.is(tok::kw___declspec))
3061239462Sdim    ParseMicrosoftDeclSpec(attrs);
3062239462Sdim
3063234353Sdim  SourceLocation ScopedEnumKWLoc;
3064224145Sdim  bool IsScopedUsingClassTag = false;
3065224145Sdim
3066239462Sdim  // In C++11, recognize 'enum class' and 'enum struct'.
3067234353Sdim  if (getLangOpts().CPlusPlus0x &&
3068224145Sdim      (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
3069234353Sdim    Diag(Tok, diag::warn_cxx98_compat_scoped_enum);
3070224145Sdim    IsScopedUsingClassTag = Tok.is(tok::kw_class);
3071234353Sdim    ScopedEnumKWLoc = ConsumeToken();
3072234353Sdim
3073239462Sdim    // Attributes are not allowed between these keywords.  Diagnose,
3074239462Sdim    // but then just treat them like they appeared in the right place.
3075239462Sdim    ProhibitAttributes(attrs);
3076234353Sdim
3077239462Sdim    // They are allowed afterwards, though.
3078239462Sdim    MaybeParseGNUAttributes(attrs);
3079239462Sdim    MaybeParseCXX0XAttributes(attrs);
3080239462Sdim    while (Tok.is(tok::kw___declspec))
3081239462Sdim      ParseMicrosoftDeclSpec(attrs);
3082239462Sdim  }
3083193326Sed
3084239462Sdim  // C++11 [temp.explicit]p12:
3085239462Sdim  //   The usual access controls do not apply to names used to specify
3086239462Sdim  //   explicit instantiations.
3087239462Sdim  // We extend this to also cover explicit specializations.  Note that
3088239462Sdim  // we don't suppress if this turns out to be an elaborated type
3089239462Sdim  // specifier.
3090239462Sdim  bool shouldDelayDiagsInTag =
3091239462Sdim    (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3092239462Sdim     TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3093239462Sdim  SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
3094224145Sdim
3095234353Sdim  // Enum definitions should not be parsed in a trailing-return-type.
3096234353Sdim  bool AllowDeclaration = DSC != DSC_trailing;
3097234353Sdim
3098234353Sdim  bool AllowFixedUnderlyingType = AllowDeclaration &&
3099234353Sdim    (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt ||
3100234353Sdim     getLangOpts().ObjC2);
3101234353Sdim
3102208600Srdivacky  CXXScopeSpec &SS = DS.getTypeSpecScope();
3103234353Sdim  if (getLangOpts().CPlusPlus) {
3104224145Sdim    // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3105224145Sdim    // if a fixed underlying type is allowed.
3106224145Sdim    ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
3107239462Sdim
3108239462Sdim    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
3109234353Sdim                                       /*EnteringContext=*/false))
3110204643Srdivacky      return;
3111204643Srdivacky
3112204643Srdivacky    if (SS.isSet() && Tok.isNot(tok::identifier)) {
3113193326Sed      Diag(Tok, diag::err_expected_ident);
3114193326Sed      if (Tok.isNot(tok::l_brace)) {
3115193326Sed        // Has no name and is not a definition.
3116193326Sed        // Skip the rest of this declarator, up until the comma or semicolon.
3117193326Sed        SkipUntil(tok::comma, true);
3118193326Sed        return;
3119193326Sed      }
3120193326Sed    }
3121193326Sed  }
3122198092Srdivacky
3123193326Sed  // Must have either 'enum name' or 'enum {...}'.
3124219077Sdim  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
3125234353Sdim      !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
3126193326Sed    Diag(Tok, diag::err_expected_ident_lbrace);
3127198092Srdivacky
3128193326Sed    // Skip the rest of this declarator, up until the comma or semicolon.
3129193326Sed    SkipUntil(tok::comma, true);
3130193326Sed    return;
3131193326Sed  }
3132198092Srdivacky
3133193326Sed  // If an identifier is present, consume and remember it.
3134193326Sed  IdentifierInfo *Name = 0;
3135193326Sed  SourceLocation NameLoc;
3136193326Sed  if (Tok.is(tok::identifier)) {
3137193326Sed    Name = Tok.getIdentifierInfo();
3138193326Sed    NameLoc = ConsumeToken();
3139193326Sed  }
3140198092Srdivacky
3141234353Sdim  if (!Name && ScopedEnumKWLoc.isValid()) {
3142218893Sdim    // C++0x 7.2p2: The optional identifier shall not be omitted in the
3143218893Sdim    // declaration of a scoped enumeration.
3144218893Sdim    Diag(Tok, diag::err_scoped_enum_missing_identifier);
3145234353Sdim    ScopedEnumKWLoc = SourceLocation();
3146218893Sdim    IsScopedUsingClassTag = false;
3147218893Sdim  }
3148218893Sdim
3149239462Sdim  // Okay, end the suppression area.  We'll decide whether to emit the
3150239462Sdim  // diagnostics in a second.
3151239462Sdim  if (shouldDelayDiagsInTag)
3152239462Sdim    diagsFromTag.done();
3153234353Sdim
3154218893Sdim  TypeResult BaseType;
3155218893Sdim
3156218893Sdim  // Parse the fixed underlying type.
3157239462Sdim  bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3158219077Sdim  if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
3159218893Sdim    bool PossibleBitfield = false;
3160239462Sdim    if (CanBeBitfield) {
3161218893Sdim      // If we're in class scope, this can either be an enum declaration with
3162218893Sdim      // an underlying type, or a declaration of a bitfield member. We try to
3163218893Sdim      // use a simple disambiguation scheme first to catch the common cases
3164239462Sdim      // (integer literal, sizeof); if it's still ambiguous, we then consider
3165239462Sdim      // anything that's a simple-type-specifier followed by '(' as an
3166239462Sdim      // expression. This suffices because function types are not valid
3167218893Sdim      // underlying types anyway.
3168218893Sdim      TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
3169239462Sdim      // If the next token starts an expression, we know we're parsing a
3170218893Sdim      // bit-field. This is the common case.
3171218893Sdim      if (TPR == TPResult::True())
3172218893Sdim        PossibleBitfield = true;
3173218893Sdim      // If the next token starts a type-specifier-seq, it may be either a
3174218893Sdim      // a fixed underlying type or the start of a function-style cast in C++;
3175239462Sdim      // lookahead one more token to see if it's obvious that we have a
3176218893Sdim      // fixed underlying type.
3177239462Sdim      else if (TPR == TPResult::False() &&
3178218893Sdim               GetLookAheadToken(2).getKind() == tok::semi) {
3179218893Sdim        // Consume the ':'.
3180218893Sdim        ConsumeToken();
3181218893Sdim      } else {
3182218893Sdim        // We have the start of a type-specifier-seq, so we have to perform
3183218893Sdim        // tentative parsing to determine whether we have an expression or a
3184218893Sdim        // type.
3185218893Sdim        TentativeParsingAction TPA(*this);
3186218893Sdim
3187218893Sdim        // Consume the ':'.
3188218893Sdim        ConsumeToken();
3189234353Sdim
3190234353Sdim        // If we see a type specifier followed by an open-brace, we have an
3191234353Sdim        // ambiguity between an underlying type and a C++11 braced
3192234353Sdim        // function-style cast. Resolve this by always treating it as an
3193234353Sdim        // underlying type.
3194234353Sdim        // FIXME: The standard is not entirely clear on how to disambiguate in
3195234353Sdim        // this case.
3196234353Sdim        if ((getLangOpts().CPlusPlus &&
3197234353Sdim             isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
3198234353Sdim            (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
3199218893Sdim          // We'll parse this as a bitfield later.
3200218893Sdim          PossibleBitfield = true;
3201218893Sdim          TPA.Revert();
3202218893Sdim        } else {
3203218893Sdim          // We have a type-specifier-seq.
3204218893Sdim          TPA.Commit();
3205218893Sdim        }
3206218893Sdim      }
3207218893Sdim    } else {
3208218893Sdim      // Consume the ':'.
3209218893Sdim      ConsumeToken();
3210218893Sdim    }
3211218893Sdim
3212218893Sdim    if (!PossibleBitfield) {
3213218893Sdim      SourceRange Range;
3214218893Sdim      BaseType = ParseTypeName(&Range);
3215239462Sdim
3216234353Sdim      if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2)
3217219077Sdim        Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
3218219077Sdim          << Range;
3219234353Sdim      if (getLangOpts().CPlusPlus0x)
3220234353Sdim        Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
3221218893Sdim    }
3222218893Sdim  }
3223218893Sdim
3224234353Sdim  // There are four options here.  If we have 'friend enum foo;' then this is a
3225234353Sdim  // friend declaration, and cannot have an accompanying definition. If we have
3226234353Sdim  // 'enum foo;', then this is a forward declaration.  If we have
3227234353Sdim  // 'enum foo {...' then this is a definition. Otherwise we have something
3228234353Sdim  // like 'enum foo xyz', a reference.
3229193326Sed  //
3230193326Sed  // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3231193326Sed  // enum foo {..};  void bar() { enum foo; }    <- new foo in bar.
3232193326Sed  // enum foo {..};  void bar() { enum foo x; }  <- use of old foo.
3233193326Sed  //
3234212904Sdim  Sema::TagUseKind TUK;
3235239462Sdim  if (!AllowDeclaration) {
3236234353Sdim    TUK = Sema::TUK_Reference;
3237239462Sdim  } else if (Tok.is(tok::l_brace)) {
3238239462Sdim    if (DS.isFriendSpecified()) {
3239239462Sdim      Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3240239462Sdim        << SourceRange(DS.getFriendSpecLoc());
3241239462Sdim      ConsumeBrace();
3242239462Sdim      SkipUntil(tok::r_brace);
3243239462Sdim      TUK = Sema::TUK_Friend;
3244239462Sdim    } else {
3245239462Sdim      TUK = Sema::TUK_Definition;
3246239462Sdim    }
3247239462Sdim  } else if (DSC != DSC_type_specifier &&
3248239462Sdim             (Tok.is(tok::semi) ||
3249239462Sdim              (Tok.isAtStartOfLine() &&
3250239462Sdim               !isValidAfterTypeSpecifier(CanBeBitfield)))) {
3251239462Sdim    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3252239462Sdim    if (Tok.isNot(tok::semi)) {
3253239462Sdim      // A semicolon was missing after this declaration. Diagnose and recover.
3254239462Sdim      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3255239462Sdim                       "enum");
3256239462Sdim      PP.EnterToken(Tok);
3257239462Sdim      Tok.setKind(tok::semi);
3258239462Sdim    }
3259239462Sdim  } else {
3260212904Sdim    TUK = Sema::TUK_Reference;
3261239462Sdim  }
3262234353Sdim
3263239462Sdim  // If this is an elaborated type specifier, and we delayed
3264239462Sdim  // diagnostics before, just merge them into the current pool.
3265239462Sdim  if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3266239462Sdim    diagsFromTag.redelay();
3267239462Sdim  }
3268239462Sdim
3269234353Sdim  MultiTemplateParamsArg TParams;
3270207619Srdivacky  if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
3271212904Sdim      TUK != Sema::TUK_Reference) {
3272234353Sdim    if (!getLangOpts().CPlusPlus0x || !SS.isSet()) {
3273234353Sdim      // Skip the rest of this declarator, up until the comma or semicolon.
3274234353Sdim      Diag(Tok, diag::err_enum_template);
3275234353Sdim      SkipUntil(tok::comma, true);
3276234353Sdim      return;
3277234353Sdim    }
3278234353Sdim
3279234353Sdim    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3280234353Sdim      // Enumerations can't be explicitly instantiated.
3281234353Sdim      DS.SetTypeSpecError();
3282234353Sdim      Diag(StartLoc, diag::err_explicit_instantiation_enum);
3283234353Sdim      return;
3284234353Sdim    }
3285234353Sdim
3286234353Sdim    assert(TemplateInfo.TemplateParams && "no template parameters");
3287234353Sdim    TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3288234353Sdim                                     TemplateInfo.TemplateParams->size());
3289207619Srdivacky  }
3290234353Sdim
3291239462Sdim  if (TUK == Sema::TUK_Reference)
3292239462Sdim    ProhibitAttributes(attrs);
3293239462Sdim
3294219077Sdim  if (!Name && TUK != Sema::TUK_Definition) {
3295219077Sdim    Diag(Tok, diag::err_enumerator_unnamed_no_def);
3296234353Sdim
3297219077Sdim    // Skip the rest of this declarator, up until the comma or semicolon.
3298219077Sdim    SkipUntil(tok::comma, true);
3299219077Sdim    return;
3300219077Sdim  }
3301234353Sdim
3302193326Sed  bool Owned = false;
3303198092Srdivacky  bool IsDependent = false;
3304207619Srdivacky  const char *PrevSpec = 0;
3305207619Srdivacky  unsigned DiagID;
3306212904Sdim  Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
3307218893Sdim                                   StartLoc, SS, Name, NameLoc, attrs.getList(),
3308234353Sdim                                   AS, DS.getModulePrivateSpecLoc(), TParams,
3309234353Sdim                                   Owned, IsDependent, ScopedEnumKWLoc,
3310218893Sdim                                   IsScopedUsingClassTag, BaseType);
3311218893Sdim
3312207619Srdivacky  if (IsDependent) {
3313239462Sdim    // This enum has a dependent nested-name-specifier. Handle it as a
3314207619Srdivacky    // dependent tag.
3315207619Srdivacky    if (!Name) {
3316207619Srdivacky      DS.SetTypeSpecError();
3317207619Srdivacky      Diag(Tok, diag::err_expected_type_name_after_typename);
3318207619Srdivacky      return;
3319207619Srdivacky    }
3320239462Sdim
3321210299Sed    TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
3322239462Sdim                                                TUK, SS, Name, StartLoc,
3323207619Srdivacky                                                NameLoc);
3324207619Srdivacky    if (Type.isInvalid()) {
3325207619Srdivacky      DS.SetTypeSpecError();
3326207619Srdivacky      return;
3327207619Srdivacky    }
3328239462Sdim
3329221345Sdim    if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3330221345Sdim                           NameLoc.isValid() ? NameLoc : StartLoc,
3331221345Sdim                           PrevSpec, DiagID, Type.get()))
3332207619Srdivacky      Diag(StartLoc, DiagID) << PrevSpec;
3333239462Sdim
3334207619Srdivacky    return;
3335207619Srdivacky  }
3336198092Srdivacky
3337212904Sdim  if (!TagDecl) {
3338239462Sdim    // The action failed to produce an enumeration tag. If this is a
3339207619Srdivacky    // definition, consume the entire definition.
3340234353Sdim    if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
3341207619Srdivacky      ConsumeBrace();
3342207619Srdivacky      SkipUntil(tok::r_brace);
3343207619Srdivacky    }
3344239462Sdim
3345207619Srdivacky    DS.SetTypeSpecError();
3346207619Srdivacky    return;
3347207619Srdivacky  }
3348198092Srdivacky
3349239462Sdim  if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
3350239462Sdim    ParseEnumBody(StartLoc, TagDecl);
3351234353Sdim
3352221345Sdim  if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3353221345Sdim                         NameLoc.isValid() ? NameLoc : StartLoc,
3354221345Sdim                         PrevSpec, DiagID, TagDecl, Owned))
3355198092Srdivacky    Diag(StartLoc, DiagID) << PrevSpec;
3356193326Sed}
3357193326Sed
3358193326Sed/// ParseEnumBody - Parse a {} enclosed enumerator-list.
3359193326Sed///       enumerator-list:
3360193326Sed///         enumerator
3361193326Sed///         enumerator-list ',' enumerator
3362193326Sed///       enumerator:
3363193326Sed///         enumeration-constant
3364193326Sed///         enumeration-constant '=' constant-expression
3365193326Sed///       enumeration-constant:
3366193326Sed///         identifier
3367193326Sed///
3368212904Sdimvoid Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
3369193326Sed  // Enter the scope of the enum body and start the definition.
3370193326Sed  ParseScope EnumScope(this, Scope::DeclScope);
3371210299Sed  Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
3372193326Sed
3373226633Sdim  BalancedDelimiterTracker T(*this, tok::l_brace);
3374226633Sdim  T.consumeOpen();
3375198092Srdivacky
3376193326Sed  // C does not allow an empty enumerator-list, C++ does [dcl.enum].
3377234353Sdim  if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
3378210299Sed    Diag(Tok, diag::error_empty_enum);
3379198092Srdivacky
3380226633Sdim  SmallVector<Decl *, 32> EnumConstantDecls;
3381193326Sed
3382212904Sdim  Decl *LastEnumConstDecl = 0;
3383198092Srdivacky
3384193326Sed  // Parse the enumerator-list.
3385193326Sed  while (Tok.is(tok::identifier)) {
3386193326Sed    IdentifierInfo *Ident = Tok.getIdentifierInfo();
3387193326Sed    SourceLocation IdentLoc = ConsumeToken();
3388198092Srdivacky
3389218893Sdim    // If attributes exist after the enumerator, parse them.
3390239462Sdim    ParsedAttributesWithRange attrs(AttrFactory);
3391218893Sdim    MaybeParseGNUAttributes(attrs);
3392239462Sdim    MaybeParseCXX0XAttributes(attrs);
3393239462Sdim    ProhibitAttributes(attrs);
3394218893Sdim
3395193326Sed    SourceLocation EqualLoc;
3396212904Sdim    ExprResult AssignedVal;
3397239462Sdim    ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
3398239462Sdim
3399193326Sed    if (Tok.is(tok::equal)) {
3400193326Sed      EqualLoc = ConsumeToken();
3401193326Sed      AssignedVal = ParseConstantExpression();
3402193326Sed      if (AssignedVal.isInvalid())
3403193326Sed        SkipUntil(tok::comma, tok::r_brace, true, true);
3404193326Sed    }
3405198092Srdivacky
3406193326Sed    // Install the enumerator constant into EnumDecl.
3407212904Sdim    Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3408212904Sdim                                                    LastEnumConstDecl,
3409212904Sdim                                                    IdentLoc, Ident,
3410218893Sdim                                                    attrs.getList(), EqualLoc,
3411212904Sdim                                                    AssignedVal.release());
3412234353Sdim    PD.complete(EnumConstDecl);
3413239462Sdim
3414193326Sed    EnumConstantDecls.push_back(EnumConstDecl);
3415193326Sed    LastEnumConstDecl = EnumConstDecl;
3416198092Srdivacky
3417218893Sdim    if (Tok.is(tok::identifier)) {
3418218893Sdim      // We're missing a comma between enumerators.
3419218893Sdim      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
3420239462Sdim      Diag(Loc, diag::err_enumerator_list_missing_comma)
3421218893Sdim        << FixItHint::CreateInsertion(Loc, ", ");
3422218893Sdim      continue;
3423218893Sdim    }
3424239462Sdim
3425193326Sed    if (Tok.isNot(tok::comma))
3426193326Sed      break;
3427193326Sed    SourceLocation CommaLoc = ConsumeToken();
3428198092Srdivacky
3429234353Sdim    if (Tok.isNot(tok::identifier)) {
3430234353Sdim      if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x)
3431239462Sdim        Diag(CommaLoc, getLangOpts().CPlusPlus ?
3432239462Sdim               diag::ext_enumerator_list_comma_cxx :
3433239462Sdim               diag::ext_enumerator_list_comma_c)
3434234353Sdim          << FixItHint::CreateRemoval(CommaLoc);
3435234353Sdim      else if (getLangOpts().CPlusPlus0x)
3436234353Sdim        Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3437234353Sdim          << FixItHint::CreateRemoval(CommaLoc);
3438234353Sdim    }
3439193326Sed  }
3440198092Srdivacky
3441193326Sed  // Eat the }.
3442226633Sdim  T.consumeClose();
3443193326Sed
3444193326Sed  // If attributes exist after the identifier list, parse them.
3445221345Sdim  ParsedAttributes attrs(AttrFactory);
3446218893Sdim  MaybeParseGNUAttributes(attrs);
3447193326Sed
3448226633Sdim  Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
3449226633Sdim                        EnumDecl, EnumConstantDecls.data(),
3450226633Sdim                        EnumConstantDecls.size(), getCurScope(),
3451226633Sdim                        attrs.getList());
3452198092Srdivacky
3453193326Sed  EnumScope.Exit();
3454226633Sdim  Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3455226633Sdim                                   T.getCloseLocation());
3456239462Sdim
3457239462Sdim  // The next token must be valid after an enum definition. If not, a ';'
3458239462Sdim  // was probably forgotten.
3459239462Sdim  bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3460239462Sdim  if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
3461239462Sdim    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3462239462Sdim    // Push this token back into the preprocessor and change our current token
3463239462Sdim    // to ';' so that the rest of the code recovers as though there were an
3464239462Sdim    // ';' after the definition.
3465239462Sdim    PP.EnterToken(Tok);
3466239462Sdim    Tok.setKind(tok::semi);
3467239462Sdim  }
3468193326Sed}
3469193326Sed
3470193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the
3471193326Sed/// start of a type-qualifier-list.
3472193326Sedbool Parser::isTypeQualifier() const {
3473193326Sed  switch (Tok.getKind()) {
3474193326Sed  default: return false;
3475221345Sdim
3476221345Sdim    // type-qualifier only in OpenCL
3477221345Sdim  case tok::kw_private:
3478234353Sdim    return getLangOpts().OpenCL;
3479221345Sdim
3480193326Sed    // type-qualifier
3481193326Sed  case tok::kw_const:
3482193326Sed  case tok::kw_volatile:
3483193326Sed  case tok::kw_restrict:
3484221345Sdim  case tok::kw___private:
3485221345Sdim  case tok::kw___local:
3486221345Sdim  case tok::kw___global:
3487221345Sdim  case tok::kw___constant:
3488221345Sdim  case tok::kw___read_only:
3489221345Sdim  case tok::kw___read_write:
3490221345Sdim  case tok::kw___write_only:
3491193326Sed    return true;
3492193326Sed  }
3493193326Sed}
3494193326Sed
3495204643Srdivacky/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3496204643Srdivacky/// is definitely a type-specifier.  Return false if it isn't part of a type
3497204643Srdivacky/// specifier or if we're not sure.
3498204643Srdivackybool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3499204643Srdivacky  switch (Tok.getKind()) {
3500204643Srdivacky  default: return false;
3501204643Srdivacky    // type-specifiers
3502204643Srdivacky  case tok::kw_short:
3503204643Srdivacky  case tok::kw_long:
3504221345Sdim  case tok::kw___int64:
3505234353Sdim  case tok::kw___int128:
3506204643Srdivacky  case tok::kw_signed:
3507204643Srdivacky  case tok::kw_unsigned:
3508204643Srdivacky  case tok::kw__Complex:
3509204643Srdivacky  case tok::kw__Imaginary:
3510204643Srdivacky  case tok::kw_void:
3511204643Srdivacky  case tok::kw_char:
3512204643Srdivacky  case tok::kw_wchar_t:
3513204643Srdivacky  case tok::kw_char16_t:
3514204643Srdivacky  case tok::kw_char32_t:
3515204643Srdivacky  case tok::kw_int:
3516226633Sdim  case tok::kw_half:
3517204643Srdivacky  case tok::kw_float:
3518204643Srdivacky  case tok::kw_double:
3519204643Srdivacky  case tok::kw_bool:
3520204643Srdivacky  case tok::kw__Bool:
3521204643Srdivacky  case tok::kw__Decimal32:
3522204643Srdivacky  case tok::kw__Decimal64:
3523204643Srdivacky  case tok::kw__Decimal128:
3524204643Srdivacky  case tok::kw___vector:
3525239462Sdim
3526204643Srdivacky    // struct-or-union-specifier (C99) or class-specifier (C++)
3527204643Srdivacky  case tok::kw_class:
3528204643Srdivacky  case tok::kw_struct:
3529204643Srdivacky  case tok::kw_union:
3530204643Srdivacky    // enum-specifier
3531204643Srdivacky  case tok::kw_enum:
3532239462Sdim
3533204643Srdivacky    // typedef-name
3534204643Srdivacky  case tok::annot_typename:
3535204643Srdivacky    return true;
3536204643Srdivacky  }
3537204643Srdivacky}
3538204643Srdivacky
3539193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the
3540193326Sed/// start of a specifier-qualifier-list.
3541193326Sedbool Parser::isTypeSpecifierQualifier() {
3542193326Sed  switch (Tok.getKind()) {
3543193326Sed  default: return false;
3544198092Srdivacky
3545193326Sed  case tok::identifier:   // foo::bar
3546203955Srdivacky    if (TryAltiVecVectorToken())
3547203955Srdivacky      return true;
3548203955Srdivacky    // Fall through.
3549193326Sed  case tok::kw_typename:  // typename T::type
3550193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
3551193326Sed    // recurse to handle whatever we get.
3552193326Sed    if (TryAnnotateTypeOrScopeToken())
3553204643Srdivacky      return true;
3554204643Srdivacky    if (Tok.is(tok::identifier))
3555204643Srdivacky      return false;
3556204643Srdivacky    return isTypeSpecifierQualifier();
3557193326Sed
3558193326Sed  case tok::coloncolon:   // ::foo::bar
3559193326Sed    if (NextToken().is(tok::kw_new) ||    // ::new
3560193326Sed        NextToken().is(tok::kw_delete))   // ::delete
3561193326Sed      return false;
3562193326Sed
3563193326Sed    if (TryAnnotateTypeOrScopeToken())
3564204643Srdivacky      return true;
3565204643Srdivacky    return isTypeSpecifierQualifier();
3566198092Srdivacky
3567193326Sed    // GNU attributes support.
3568193326Sed  case tok::kw___attribute:
3569193326Sed    // GNU typeof support.
3570193326Sed  case tok::kw_typeof:
3571198092Srdivacky
3572193326Sed    // type-specifiers
3573193326Sed  case tok::kw_short:
3574193326Sed  case tok::kw_long:
3575221345Sdim  case tok::kw___int64:
3576234353Sdim  case tok::kw___int128:
3577193326Sed  case tok::kw_signed:
3578193326Sed  case tok::kw_unsigned:
3579193326Sed  case tok::kw__Complex:
3580193326Sed  case tok::kw__Imaginary:
3581193326Sed  case tok::kw_void:
3582193326Sed  case tok::kw_char:
3583193326Sed  case tok::kw_wchar_t:
3584198092Srdivacky  case tok::kw_char16_t:
3585198092Srdivacky  case tok::kw_char32_t:
3586193326Sed  case tok::kw_int:
3587226633Sdim  case tok::kw_half:
3588193326Sed  case tok::kw_float:
3589193326Sed  case tok::kw_double:
3590193326Sed  case tok::kw_bool:
3591193326Sed  case tok::kw__Bool:
3592193326Sed  case tok::kw__Decimal32:
3593193326Sed  case tok::kw__Decimal64:
3594193326Sed  case tok::kw__Decimal128:
3595203955Srdivacky  case tok::kw___vector:
3596198092Srdivacky
3597193326Sed    // struct-or-union-specifier (C99) or class-specifier (C++)
3598193326Sed  case tok::kw_class:
3599193326Sed  case tok::kw_struct:
3600193326Sed  case tok::kw_union:
3601193326Sed    // enum-specifier
3602193326Sed  case tok::kw_enum:
3603198092Srdivacky
3604193326Sed    // type-qualifier
3605193326Sed  case tok::kw_const:
3606193326Sed  case tok::kw_volatile:
3607193326Sed  case tok::kw_restrict:
3608193326Sed
3609193326Sed    // typedef-name
3610193326Sed  case tok::annot_typename:
3611193326Sed    return true;
3612198092Srdivacky
3613193326Sed    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3614193326Sed  case tok::less:
3615234353Sdim    return getLangOpts().ObjC1;
3616198092Srdivacky
3617193326Sed  case tok::kw___cdecl:
3618193326Sed  case tok::kw___stdcall:
3619193326Sed  case tok::kw___fastcall:
3620208600Srdivacky  case tok::kw___thiscall:
3621194179Sed  case tok::kw___w64:
3622194179Sed  case tok::kw___ptr64:
3623226633Sdim  case tok::kw___ptr32:
3624212904Sdim  case tok::kw___pascal:
3625226633Sdim  case tok::kw___unaligned:
3626221345Sdim
3627221345Sdim  case tok::kw___private:
3628221345Sdim  case tok::kw___local:
3629221345Sdim  case tok::kw___global:
3630221345Sdim  case tok::kw___constant:
3631221345Sdim  case tok::kw___read_only:
3632221345Sdim  case tok::kw___read_write:
3633221345Sdim  case tok::kw___write_only:
3634221345Sdim
3635194179Sed    return true;
3636221345Sdim
3637221345Sdim  case tok::kw_private:
3638234353Sdim    return getLangOpts().OpenCL;
3639226633Sdim
3640234353Sdim  // C11 _Atomic()
3641226633Sdim  case tok::kw__Atomic:
3642226633Sdim    return true;
3643193326Sed  }
3644193326Sed}
3645193326Sed
3646193326Sed/// isDeclarationSpecifier() - Return true if the current token is part of a
3647193326Sed/// declaration specifier.
3648218893Sdim///
3649218893Sdim/// \param DisambiguatingWithExpression True to indicate that the purpose of
3650218893Sdim/// this check is to disambiguate between an expression and a declaration.
3651218893Sdimbool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
3652193326Sed  switch (Tok.getKind()) {
3653193326Sed  default: return false;
3654198092Srdivacky
3655221345Sdim  case tok::kw_private:
3656234353Sdim    return getLangOpts().OpenCL;
3657221345Sdim
3658193326Sed  case tok::identifier:   // foo::bar
3659193326Sed    // Unfortunate hack to support "Class.factoryMethod" notation.
3660234353Sdim    if (getLangOpts().ObjC1 && NextToken().is(tok::period))
3661193326Sed      return false;
3662203955Srdivacky    if (TryAltiVecVectorToken())
3663203955Srdivacky      return true;
3664203955Srdivacky    // Fall through.
3665234353Sdim  case tok::kw_decltype: // decltype(T())::type
3666193326Sed  case tok::kw_typename: // typename T::type
3667193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
3668193326Sed    // recurse to handle whatever we get.
3669193326Sed    if (TryAnnotateTypeOrScopeToken())
3670204643Srdivacky      return true;
3671204643Srdivacky    if (Tok.is(tok::identifier))
3672204643Srdivacky      return false;
3673239462Sdim
3674218893Sdim    // If we're in Objective-C and we have an Objective-C class type followed
3675239462Sdim    // by an identifier and then either ':' or ']', in a place where an
3676218893Sdim    // expression is permitted, then this is probably a class message send
3677218893Sdim    // missing the initial '['. In this case, we won't consider this to be
3678218893Sdim    // the start of a declaration.
3679239462Sdim    if (DisambiguatingWithExpression &&
3680218893Sdim        isStartOfObjCClassMessageMissingOpenBracket())
3681218893Sdim      return false;
3682239462Sdim
3683204643Srdivacky    return isDeclarationSpecifier();
3684204643Srdivacky
3685193326Sed  case tok::coloncolon:   // ::foo::bar
3686193326Sed    if (NextToken().is(tok::kw_new) ||    // ::new
3687193326Sed        NextToken().is(tok::kw_delete))   // ::delete
3688193326Sed      return false;
3689198092Srdivacky
3690193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
3691193326Sed    // recurse to handle whatever we get.
3692193326Sed    if (TryAnnotateTypeOrScopeToken())
3693204643Srdivacky      return true;
3694204643Srdivacky    return isDeclarationSpecifier();
3695198092Srdivacky
3696193326Sed    // storage-class-specifier
3697193326Sed  case tok::kw_typedef:
3698193326Sed  case tok::kw_extern:
3699193326Sed  case tok::kw___private_extern__:
3700193326Sed  case tok::kw_static:
3701193326Sed  case tok::kw_auto:
3702193326Sed  case tok::kw_register:
3703193326Sed  case tok::kw___thread:
3704198092Srdivacky
3705226633Sdim    // Modules
3706226633Sdim  case tok::kw___module_private__:
3707239462Sdim
3708193326Sed    // type-specifiers
3709193326Sed  case tok::kw_short:
3710193326Sed  case tok::kw_long:
3711221345Sdim  case tok::kw___int64:
3712234353Sdim  case tok::kw___int128:
3713193326Sed  case tok::kw_signed:
3714193326Sed  case tok::kw_unsigned:
3715193326Sed  case tok::kw__Complex:
3716193326Sed  case tok::kw__Imaginary:
3717193326Sed  case tok::kw_void:
3718193326Sed  case tok::kw_char:
3719193326Sed  case tok::kw_wchar_t:
3720198092Srdivacky  case tok::kw_char16_t:
3721198092Srdivacky  case tok::kw_char32_t:
3722198092Srdivacky
3723193326Sed  case tok::kw_int:
3724226633Sdim  case tok::kw_half:
3725193326Sed  case tok::kw_float:
3726193326Sed  case tok::kw_double:
3727193326Sed  case tok::kw_bool:
3728193326Sed  case tok::kw__Bool:
3729193326Sed  case tok::kw__Decimal32:
3730193326Sed  case tok::kw__Decimal64:
3731193326Sed  case tok::kw__Decimal128:
3732203955Srdivacky  case tok::kw___vector:
3733198092Srdivacky
3734193326Sed    // struct-or-union-specifier (C99) or class-specifier (C++)
3735193326Sed  case tok::kw_class:
3736193326Sed  case tok::kw_struct:
3737193326Sed  case tok::kw_union:
3738193326Sed    // enum-specifier
3739193326Sed  case tok::kw_enum:
3740198092Srdivacky
3741193326Sed    // type-qualifier
3742193326Sed  case tok::kw_const:
3743193326Sed  case tok::kw_volatile:
3744193326Sed  case tok::kw_restrict:
3745193326Sed
3746193326Sed    // function-specifier
3747193326Sed  case tok::kw_inline:
3748193326Sed  case tok::kw_virtual:
3749193326Sed  case tok::kw_explicit:
3750193326Sed
3751221345Sdim    // static_assert-declaration
3752221345Sdim  case tok::kw__Static_assert:
3753193326Sed
3754193326Sed    // GNU typeof support.
3755193326Sed  case tok::kw_typeof:
3756198092Srdivacky
3757193326Sed    // GNU attributes.
3758193326Sed  case tok::kw___attribute:
3759193326Sed    return true;
3760198092Srdivacky
3761224145Sdim    // C++0x decltype.
3762234353Sdim  case tok::annot_decltype:
3763224145Sdim    return true;
3764224145Sdim
3765234353Sdim    // C11 _Atomic()
3766226633Sdim  case tok::kw__Atomic:
3767226633Sdim    return true;
3768226633Sdim
3769193326Sed    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
3770193326Sed  case tok::less:
3771234353Sdim    return getLangOpts().ObjC1;
3772198092Srdivacky
3773221345Sdim    // typedef-name
3774221345Sdim  case tok::annot_typename:
3775221345Sdim    return !DisambiguatingWithExpression ||
3776221345Sdim           !isStartOfObjCClassMessageMissingOpenBracket();
3777239462Sdim
3778193326Sed  case tok::kw___declspec:
3779193326Sed  case tok::kw___cdecl:
3780193326Sed  case tok::kw___stdcall:
3781193326Sed  case tok::kw___fastcall:
3782208600Srdivacky  case tok::kw___thiscall:
3783194179Sed  case tok::kw___w64:
3784194179Sed  case tok::kw___ptr64:
3785226633Sdim  case tok::kw___ptr32:
3786194179Sed  case tok::kw___forceinline:
3787212904Sdim  case tok::kw___pascal:
3788226633Sdim  case tok::kw___unaligned:
3789221345Sdim
3790221345Sdim  case tok::kw___private:
3791221345Sdim  case tok::kw___local:
3792221345Sdim  case tok::kw___global:
3793221345Sdim  case tok::kw___constant:
3794221345Sdim  case tok::kw___read_only:
3795221345Sdim  case tok::kw___read_write:
3796221345Sdim  case tok::kw___write_only:
3797221345Sdim
3798194179Sed    return true;
3799193326Sed  }
3800193326Sed}
3801193326Sed
3802202379Srdivackybool Parser::isConstructorDeclarator() {
3803202379Srdivacky  TentativeParsingAction TPA(*this);
3804193326Sed
3805202379Srdivacky  // Parse the C++ scope specifier.
3806202379Srdivacky  CXXScopeSpec SS;
3807239462Sdim  if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
3808234353Sdim                                     /*EnteringContext=*/true)) {
3809204643Srdivacky    TPA.Revert();
3810204643Srdivacky    return false;
3811204643Srdivacky  }
3812202379Srdivacky
3813202379Srdivacky  // Parse the constructor name.
3814202379Srdivacky  if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
3815202379Srdivacky    // We already know that we have a constructor name; just consume
3816202379Srdivacky    // the token.
3817202379Srdivacky    ConsumeToken();
3818202379Srdivacky  } else {
3819202379Srdivacky    TPA.Revert();
3820202379Srdivacky    return false;
3821202379Srdivacky  }
3822202379Srdivacky
3823234353Sdim  // Current class name must be followed by a left parenthesis.
3824202379Srdivacky  if (Tok.isNot(tok::l_paren)) {
3825202379Srdivacky    TPA.Revert();
3826202379Srdivacky    return false;
3827202379Srdivacky  }
3828202379Srdivacky  ConsumeParen();
3829202379Srdivacky
3830234353Sdim  // A right parenthesis, or ellipsis followed by a right parenthesis signals
3831234353Sdim  // that we have a constructor.
3832234353Sdim  if (Tok.is(tok::r_paren) ||
3833234353Sdim      (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
3834202379Srdivacky    TPA.Revert();
3835202379Srdivacky    return true;
3836202379Srdivacky  }
3837202379Srdivacky
3838202379Srdivacky  // If we need to, enter the specified scope.
3839202379Srdivacky  DeclaratorScopeObj DeclScopeObj(*this, SS);
3840210299Sed  if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
3841202379Srdivacky    DeclScopeObj.EnterDeclaratorScope();
3842202379Srdivacky
3843218893Sdim  // Optionally skip Microsoft attributes.
3844221345Sdim  ParsedAttributes Attrs(AttrFactory);
3845218893Sdim  MaybeParseMicrosoftAttributes(Attrs);
3846218893Sdim
3847202379Srdivacky  // Check whether the next token(s) are part of a declaration
3848202379Srdivacky  // specifier, in which case we have the start of a parameter and,
3849202379Srdivacky  // therefore, we know that this is a constructor.
3850234353Sdim  bool IsConstructor = false;
3851234353Sdim  if (isDeclarationSpecifier())
3852234353Sdim    IsConstructor = true;
3853234353Sdim  else if (Tok.is(tok::identifier) ||
3854234353Sdim           (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
3855234353Sdim    // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
3856234353Sdim    // This might be a parenthesized member name, but is more likely to
3857234353Sdim    // be a constructor declaration with an invalid argument type. Keep
3858234353Sdim    // looking.
3859234353Sdim    if (Tok.is(tok::annot_cxxscope))
3860234353Sdim      ConsumeToken();
3861234353Sdim    ConsumeToken();
3862234353Sdim
3863234353Sdim    // If this is not a constructor, we must be parsing a declarator,
3864234353Sdim    // which must have one of the following syntactic forms (see the
3865234353Sdim    // grammar extract at the start of ParseDirectDeclarator):
3866234353Sdim    switch (Tok.getKind()) {
3867234353Sdim    case tok::l_paren:
3868234353Sdim      // C(X   (   int));
3869234353Sdim    case tok::l_square:
3870234353Sdim      // C(X   [   5]);
3871234353Sdim      // C(X   [   [attribute]]);
3872234353Sdim    case tok::coloncolon:
3873234353Sdim      // C(X   ::   Y);
3874234353Sdim      // C(X   ::   *p);
3875234353Sdim    case tok::r_paren:
3876234353Sdim      // C(X   )
3877234353Sdim      // Assume this isn't a constructor, rather than assuming it's a
3878234353Sdim      // constructor with an unnamed parameter of an ill-formed type.
3879234353Sdim      break;
3880234353Sdim
3881234353Sdim    default:
3882234353Sdim      IsConstructor = true;
3883234353Sdim      break;
3884234353Sdim    }
3885234353Sdim  }
3886234353Sdim
3887202379Srdivacky  TPA.Revert();
3888202379Srdivacky  return IsConstructor;
3889202379Srdivacky}
3890202379Srdivacky
3891193326Sed/// ParseTypeQualifierListOpt
3892212904Sdim///          type-qualifier-list: [C99 6.7.5]
3893212904Sdim///            type-qualifier
3894239462Sdim/// [vendor]   attributes
3895212904Sdim///              [ only if VendorAttributesAllowed=true ]
3896212904Sdim///            type-qualifier-list type-qualifier
3897239462Sdim/// [vendor]   type-qualifier-list attributes
3898212904Sdim///              [ only if VendorAttributesAllowed=true ]
3899212904Sdim/// [C++0x]    attribute-specifier[opt] is allowed before cv-qualifier-seq
3900212904Sdim///              [ only if CXX0XAttributesAllowed=true ]
3901212904Sdim/// Note: vendor can be GNU, MS, etc.
3902193326Sed///
3903212904Sdimvoid Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
3904212904Sdim                                       bool VendorAttributesAllowed,
3905234353Sdim                                       bool CXX11AttributesAllowed) {
3906234353Sdim  if (getLangOpts().CPlusPlus0x && CXX11AttributesAllowed &&
3907234353Sdim      isCXX11AttributeSpecifier()) {
3908221345Sdim    ParsedAttributesWithRange attrs(AttrFactory);
3909234353Sdim    ParseCXX11Attributes(attrs);
3910234353Sdim    DS.takeAttributesFrom(attrs);
3911199990Srdivacky  }
3912221345Sdim
3913221345Sdim  SourceLocation EndLoc;
3914221345Sdim
3915193326Sed  while (1) {
3916198092Srdivacky    bool isInvalid = false;
3917193326Sed    const char *PrevSpec = 0;
3918198092Srdivacky    unsigned DiagID = 0;
3919193326Sed    SourceLocation Loc = Tok.getLocation();
3920193326Sed
3921193326Sed    switch (Tok.getKind()) {
3922212904Sdim    case tok::code_completion:
3923212904Sdim      Actions.CodeCompleteTypeQualifiers(DS);
3924226633Sdim      return cutOffParsing();
3925239462Sdim
3926193326Sed    case tok::kw_const:
3927198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,
3928239462Sdim                                 getLangOpts(), /*IsTypeSpec*/false);
3929193326Sed      break;
3930193326Sed    case tok::kw_volatile:
3931198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
3932239462Sdim                                 getLangOpts(), /*IsTypeSpec*/false);
3933193326Sed      break;
3934193326Sed    case tok::kw_restrict:
3935198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
3936239462Sdim                                 getLangOpts(), /*IsTypeSpec*/false);
3937193326Sed      break;
3938221345Sdim
3939221345Sdim    // OpenCL qualifiers:
3940239462Sdim    case tok::kw_private:
3941234353Sdim      if (!getLangOpts().OpenCL)
3942221345Sdim        goto DoneWithTypeQuals;
3943221345Sdim    case tok::kw___private:
3944221345Sdim    case tok::kw___global:
3945221345Sdim    case tok::kw___local:
3946221345Sdim    case tok::kw___constant:
3947221345Sdim    case tok::kw___read_only:
3948221345Sdim    case tok::kw___write_only:
3949221345Sdim    case tok::kw___read_write:
3950221345Sdim      ParseOpenCLQualifiers(DS);
3951221345Sdim      break;
3952221345Sdim
3953194179Sed    case tok::kw___w64:
3954193326Sed    case tok::kw___ptr64:
3955226633Sdim    case tok::kw___ptr32:
3956193326Sed    case tok::kw___cdecl:
3957193326Sed    case tok::kw___stdcall:
3958193326Sed    case tok::kw___fastcall:
3959208600Srdivacky    case tok::kw___thiscall:
3960226633Sdim    case tok::kw___unaligned:
3961212904Sdim      if (VendorAttributesAllowed) {
3962218893Sdim        ParseMicrosoftTypeAttributes(DS.getAttributes());
3963194179Sed        continue;
3964194179Sed      }
3965194179Sed      goto DoneWithTypeQuals;
3966212904Sdim    case tok::kw___pascal:
3967212904Sdim      if (VendorAttributesAllowed) {
3968218893Sdim        ParseBorlandTypeAttributes(DS.getAttributes());
3969212904Sdim        continue;
3970212904Sdim      }
3971212904Sdim      goto DoneWithTypeQuals;
3972193326Sed    case tok::kw___attribute:
3973212904Sdim      if (VendorAttributesAllowed) {
3974218893Sdim        ParseGNUAttributes(DS.getAttributes());
3975193326Sed        continue; // do *not* consume the next token!
3976193326Sed      }
3977193326Sed      // otherwise, FALL THROUGH!
3978193326Sed    default:
3979193326Sed      DoneWithTypeQuals:
3980193326Sed      // If this is not a type-qualifier token, we're done reading type
3981193326Sed      // qualifiers.  First verify that DeclSpec's are consistent.
3982193326Sed      DS.Finish(Diags, PP);
3983221345Sdim      if (EndLoc.isValid())
3984221345Sdim        DS.SetRangeEnd(EndLoc);
3985193326Sed      return;
3986193326Sed    }
3987193326Sed
3988193326Sed    // If the specifier combination wasn't legal, issue a diagnostic.
3989193326Sed    if (isInvalid) {
3990193326Sed      assert(PrevSpec && "Method did not return previous specifier!");
3991193326Sed      Diag(Tok, DiagID) << PrevSpec;
3992193326Sed    }
3993221345Sdim    EndLoc = ConsumeToken();
3994193326Sed  }
3995193326Sed}
3996193326Sed
3997193326Sed
3998193326Sed/// ParseDeclarator - Parse and verify a newly-initialized declarator.
3999193326Sed///
4000193326Sedvoid Parser::ParseDeclarator(Declarator &D) {
4001193326Sed  /// This implements the 'declarator' production in the C grammar, then checks
4002193326Sed  /// for well-formedness and issues diagnostics.
4003193326Sed  ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
4004193326Sed}
4005193326Sed
4006234353Sdimstatic bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
4007234353Sdim  if (Kind == tok::star || Kind == tok::caret)
4008234353Sdim    return true;
4009234353Sdim
4010234353Sdim  // We parse rvalue refs in C++03, because otherwise the errors are scary.
4011234353Sdim  if (!Lang.CPlusPlus)
4012234353Sdim    return false;
4013234353Sdim
4014234353Sdim  return Kind == tok::amp || Kind == tok::ampamp;
4015234353Sdim}
4016234353Sdim
4017193326Sed/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
4018193326Sed/// is parsed by the function passed to it. Pass null, and the direct-declarator
4019193326Sed/// isn't parsed at all, making this function effectively parse the C++
4020193326Sed/// ptr-operator production.
4021193326Sed///
4022234353Sdim/// If the grammar of this construct is extended, matching changes must also be
4023234353Sdim/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
4024234353Sdim/// isConstructorDeclarator.
4025234353Sdim///
4026193326Sed///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
4027193326Sed/// [C]     pointer[opt] direct-declarator
4028193326Sed/// [C++]   direct-declarator
4029193326Sed/// [C++]   ptr-operator declarator
4030193326Sed///
4031193326Sed///       pointer: [C99 6.7.5]
4032193326Sed///         '*' type-qualifier-list[opt]
4033193326Sed///         '*' type-qualifier-list[opt] pointer
4034193326Sed///
4035193326Sed///       ptr-operator:
4036193326Sed///         '*' cv-qualifier-seq[opt]
4037193326Sed///         '&'
4038193326Sed/// [C++0x] '&&'
4039193326Sed/// [GNU]   '&' restrict[opt] attributes[opt]
4040193326Sed/// [GNU?]  '&&' restrict[opt] attributes[opt]
4041193326Sed///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
4042193326Sedvoid Parser::ParseDeclaratorInternal(Declarator &D,
4043193326Sed                                     DirectDeclParseFunction DirectDeclParser) {
4044198092Srdivacky  if (Diags.hasAllExtensionsSilenced())
4045198092Srdivacky    D.setExtension();
4046239462Sdim
4047193326Sed  // C++ member pointers start with a '::' or a nested-name.
4048193326Sed  // Member pointers get special handling, since there's no place for the
4049193326Sed  // scope spec in the generic path below.
4050234353Sdim  if (getLangOpts().CPlusPlus &&
4051193326Sed      (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
4052193326Sed       Tok.is(tok::annot_cxxscope))) {
4053234353Sdim    bool EnteringContext = D.getContext() == Declarator::FileContext ||
4054234353Sdim                           D.getContext() == Declarator::MemberContext;
4055193326Sed    CXXScopeSpec SS;
4056234353Sdim    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
4057204643Srdivacky
4058207619Srdivacky    if (SS.isNotEmpty()) {
4059198092Srdivacky      if (Tok.isNot(tok::star)) {
4060193326Sed        // The scope spec really belongs to the direct-declarator.
4061193326Sed        D.getCXXScopeSpec() = SS;
4062193326Sed        if (DirectDeclParser)
4063193326Sed          (this->*DirectDeclParser)(D);
4064193326Sed        return;
4065193326Sed      }
4066193326Sed
4067193326Sed      SourceLocation Loc = ConsumeToken();
4068193326Sed      D.SetRangeEnd(Loc);
4069221345Sdim      DeclSpec DS(AttrFactory);
4070193326Sed      ParseTypeQualifierListOpt(DS);
4071193326Sed      D.ExtendWithDeclSpec(DS);
4072193326Sed
4073193326Sed      // Recurse to parse whatever is left.
4074193326Sed      ParseDeclaratorInternal(D, DirectDeclParser);
4075193326Sed
4076193326Sed      // Sema will have to catch (syntactically invalid) pointers into global
4077193326Sed      // scope. It has to catch pointers into namespace scope anyway.
4078193326Sed      D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
4079221345Sdim                                                      Loc),
4080221345Sdim                    DS.getAttributes(),
4081193326Sed                    /* Don't replace range end. */SourceLocation());
4082193326Sed      return;
4083193326Sed    }
4084193326Sed  }
4085193326Sed
4086193326Sed  tok::TokenKind Kind = Tok.getKind();
4087193326Sed  // Not a pointer, C++ reference, or block.
4088234353Sdim  if (!isPtrOperatorToken(Kind, getLangOpts())) {
4089193326Sed    if (DirectDeclParser)
4090193326Sed      (this->*DirectDeclParser)(D);
4091193326Sed    return;
4092193326Sed  }
4093193326Sed
4094193326Sed  // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4095193326Sed  // '&&' -> rvalue reference
4096193326Sed  SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.
4097193326Sed  D.SetRangeEnd(Loc);
4098193326Sed
4099193326Sed  if (Kind == tok::star || Kind == tok::caret) {
4100193326Sed    // Is a pointer.
4101221345Sdim    DeclSpec DS(AttrFactory);
4102193326Sed
4103234353Sdim    // FIXME: GNU attributes are not allowed here in a new-type-id.
4104193326Sed    ParseTypeQualifierListOpt(DS);
4105193326Sed    D.ExtendWithDeclSpec(DS);
4106193326Sed
4107193326Sed    // Recursively parse the declarator.
4108193326Sed    ParseDeclaratorInternal(D, DirectDeclParser);
4109193326Sed    if (Kind == tok::star)
4110193326Sed      // Remember that we parsed a pointer type, and remember the type-quals.
4111193326Sed      D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
4112219077Sdim                                                DS.getConstSpecLoc(),
4113219077Sdim                                                DS.getVolatileSpecLoc(),
4114221345Sdim                                                DS.getRestrictSpecLoc()),
4115221345Sdim                    DS.getAttributes(),
4116193326Sed                    SourceLocation());
4117193326Sed    else
4118193326Sed      // Remember that we parsed a Block type, and remember the type-quals.
4119198092Srdivacky      D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
4120221345Sdim                                                     Loc),
4121221345Sdim                    DS.getAttributes(),
4122193326Sed                    SourceLocation());
4123193326Sed  } else {
4124193326Sed    // Is a reference
4125221345Sdim    DeclSpec DS(AttrFactory);
4126193326Sed
4127193326Sed    // Complain about rvalue references in C++03, but then go on and build
4128193326Sed    // the declarator.
4129234353Sdim    if (Kind == tok::ampamp)
4130234353Sdim      Diag(Loc, getLangOpts().CPlusPlus0x ?
4131234353Sdim           diag::warn_cxx98_compat_rvalue_reference :
4132234353Sdim           diag::ext_rvalue_reference);
4133193326Sed
4134234353Sdim    // GNU-style and C++11 attributes are allowed here, as is restrict.
4135234353Sdim    ParseTypeQualifierListOpt(DS);
4136234353Sdim    D.ExtendWithDeclSpec(DS);
4137234353Sdim
4138193326Sed    // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4139193326Sed    // cv-qualifiers are introduced through the use of a typedef or of a
4140193326Sed    // template type argument, in which case the cv-qualifiers are ignored.
4141193326Sed    if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4142193326Sed      if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4143193326Sed        Diag(DS.getConstSpecLoc(),
4144193326Sed             diag::err_invalid_reference_qualifier_application) << "const";
4145193326Sed      if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4146193326Sed        Diag(DS.getVolatileSpecLoc(),
4147193326Sed             diag::err_invalid_reference_qualifier_application) << "volatile";
4148193326Sed    }
4149193326Sed
4150193326Sed    // Recursively parse the declarator.
4151193326Sed    ParseDeclaratorInternal(D, DirectDeclParser);
4152193326Sed
4153193326Sed    if (D.getNumTypeObjects() > 0) {
4154193326Sed      // C++ [dcl.ref]p4: There shall be no references to references.
4155193326Sed      DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4156193326Sed      if (InnerChunk.Kind == DeclaratorChunk::Reference) {
4157193326Sed        if (const IdentifierInfo *II = D.getIdentifier())
4158193326Sed          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4159193326Sed           << II;
4160193326Sed        else
4161193326Sed          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4162193326Sed            << "type name";
4163193326Sed
4164193326Sed        // Once we've complained about the reference-to-reference, we
4165193326Sed        // can go ahead and build the (technically ill-formed)
4166193326Sed        // declarator: reference collapsing will take care of it.
4167193326Sed      }
4168193326Sed    }
4169193326Sed
4170193326Sed    // Remember that we parsed a reference type. It doesn't have type-quals.
4171193326Sed    D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
4172193326Sed                                                Kind == tok::amp),
4173221345Sdim                  DS.getAttributes(),
4174193326Sed                  SourceLocation());
4175193326Sed  }
4176193326Sed}
4177193326Sed
4178234353Sdimstatic void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4179234353Sdim                                      SourceLocation EllipsisLoc) {
4180234353Sdim  if (EllipsisLoc.isValid()) {
4181234353Sdim    FixItHint Insertion;
4182234353Sdim    if (!D.getEllipsisLoc().isValid()) {
4183234353Sdim      Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4184234353Sdim      D.setEllipsisLoc(EllipsisLoc);
4185234353Sdim    }
4186234353Sdim    P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4187234353Sdim      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4188234353Sdim  }
4189234353Sdim}
4190234353Sdim
4191193326Sed/// ParseDirectDeclarator
4192193326Sed///       direct-declarator: [C99 6.7.5]
4193193326Sed/// [C99]   identifier
4194193326Sed///         '(' declarator ')'
4195193326Sed/// [GNU]   '(' attributes declarator ')'
4196193326Sed/// [C90]   direct-declarator '[' constant-expression[opt] ']'
4197193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4198193326Sed/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4199193326Sed/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4200193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
4201234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4202234353Sdim///                    attribute-specifier-seq[opt]
4203193326Sed///         direct-declarator '(' parameter-type-list ')'
4204193326Sed///         direct-declarator '(' identifier-list[opt] ')'
4205193326Sed/// [GNU]   direct-declarator '(' parameter-forward-declarations
4206193326Sed///                    parameter-type-list[opt] ')'
4207193326Sed/// [C++]   direct-declarator '(' parameter-declaration-clause ')'
4208193326Sed///                    cv-qualifier-seq[opt] exception-specification[opt]
4209234353Sdim/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4210234353Sdim///                    attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4211234353Sdim///                    ref-qualifier[opt] exception-specification[opt]
4212193326Sed/// [C++]   declarator-id
4213234353Sdim/// [C++11] declarator-id attribute-specifier-seq[opt]
4214193326Sed///
4215193326Sed///       declarator-id: [C++ 8]
4216218893Sdim///         '...'[opt] id-expression
4217193326Sed///         '::'[opt] nested-name-specifier[opt] type-name
4218193326Sed///
4219193326Sed///       id-expression: [C++ 5.1]
4220193326Sed///         unqualified-id
4221198092Srdivacky///         qualified-id
4222193326Sed///
4223193326Sed///       unqualified-id: [C++ 5.1]
4224198092Srdivacky///         identifier
4225193326Sed///         operator-function-id
4226198092Srdivacky///         conversion-function-id
4227198092Srdivacky///          '~' class-name
4228193326Sed///         template-id
4229193326Sed///
4230234353Sdim/// Note, any additional constructs added here may need corresponding changes
4231234353Sdim/// in isConstructorDeclarator.
4232193326Sedvoid Parser::ParseDirectDeclarator(Declarator &D) {
4233193326Sed  DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
4234193326Sed
4235234353Sdim  if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
4236198893Srdivacky    // ParseDeclaratorInternal might already have parsed the scope.
4237207619Srdivacky    if (D.getCXXScopeSpec().isEmpty()) {
4238234353Sdim      bool EnteringContext = D.getContext() == Declarator::FileContext ||
4239234353Sdim                             D.getContext() == Declarator::MemberContext;
4240239462Sdim      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
4241234353Sdim                                     EnteringContext);
4242204643Srdivacky    }
4243204643Srdivacky
4244207619Srdivacky    if (D.getCXXScopeSpec().isValid()) {
4245210299Sed      if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
4246200583Srdivacky        // Change the declaration context for name lookup, until this function
4247200583Srdivacky        // is exited (and the declarator has been parsed).
4248200583Srdivacky        DeclScopeObj.EnterDeclaratorScope();
4249207619Srdivacky    }
4250207619Srdivacky
4251218893Sdim    // C++0x [dcl.fct]p14:
4252218893Sdim    //   There is a syntactic ambiguity when an ellipsis occurs at the end
4253239462Sdim    //   of a parameter-declaration-clause without a preceding comma. In
4254239462Sdim    //   this case, the ellipsis is parsed as part of the
4255239462Sdim    //   abstract-declarator if the type of the parameter names a template
4256218893Sdim    //   parameter pack that has not been expanded; otherwise, it is parsed
4257218893Sdim    //   as part of the parameter-declaration-clause.
4258234353Sdim    if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
4259218893Sdim        !((D.getContext() == Declarator::PrototypeContext ||
4260218893Sdim           D.getContext() == Declarator::BlockLiteralContext) &&
4261218893Sdim          NextToken().is(tok::r_paren) &&
4262234353Sdim          !Actions.containsUnexpandedParameterPacks(D))) {
4263234353Sdim      SourceLocation EllipsisLoc = ConsumeToken();
4264234353Sdim      if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4265234353Sdim        // The ellipsis was put in the wrong place. Recover, and explain to
4266234353Sdim        // the user what they should have done.
4267234353Sdim        ParseDeclarator(D);
4268234353Sdim        diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4269234353Sdim        return;
4270234353Sdim      } else
4271234353Sdim        D.setEllipsisLoc(EllipsisLoc);
4272234353Sdim
4273234353Sdim      // The ellipsis can't be followed by a parenthesized declarator. We
4274234353Sdim      // check for that in ParseParenDeclarator, after we have disambiguated
4275234353Sdim      // the l_paren token.
4276234353Sdim    }
4277234353Sdim
4278198893Srdivacky    if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4279198893Srdivacky        Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4280198893Srdivacky      // We found something that indicates the start of an unqualified-id.
4281198893Srdivacky      // Parse that unqualified-id.
4282207619Srdivacky      bool AllowConstructorName;
4283207619Srdivacky      if (D.getDeclSpec().hasTypeSpecifier())
4284207619Srdivacky        AllowConstructorName = false;
4285207619Srdivacky      else if (D.getCXXScopeSpec().isSet())
4286207619Srdivacky        AllowConstructorName =
4287207619Srdivacky          (D.getContext() == Declarator::FileContext ||
4288207619Srdivacky           (D.getContext() == Declarator::MemberContext &&
4289207619Srdivacky            D.getDeclSpec().isFriendSpecified()));
4290207619Srdivacky      else
4291207619Srdivacky        AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4292207619Srdivacky
4293234353Sdim      SourceLocation TemplateKWLoc;
4294239462Sdim      if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4295239462Sdim                             /*EnteringContext=*/true,
4296239462Sdim                             /*AllowDestructorName=*/true,
4297202379Srdivacky                             AllowConstructorName,
4298212904Sdim                             ParsedType(),
4299234353Sdim                             TemplateKWLoc,
4300207619Srdivacky                             D.getName()) ||
4301207619Srdivacky          // Once we're past the identifier, if the scope was bad, mark the
4302207619Srdivacky          // whole declarator bad.
4303207619Srdivacky          D.getCXXScopeSpec().isInvalid()) {
4304193326Sed        D.SetIdentifier(0, Tok.getLocation());
4305193326Sed        D.setInvalidType(true);
4306198893Srdivacky      } else {
4307198893Srdivacky        // Parsed the unqualified-id; update range information and move along.
4308198893Srdivacky        if (D.getSourceRange().getBegin().isInvalid())
4309198893Srdivacky          D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4310198893Srdivacky        D.SetRangeEnd(D.getName().getSourceRange().getEnd());
4311193326Sed      }
4312198893Srdivacky      goto PastIdentifier;
4313193326Sed    }
4314198893Srdivacky  } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
4315234353Sdim    assert(!getLangOpts().CPlusPlus &&
4316193326Sed           "There's a C++-specific check for tok::identifier above");
4317193326Sed    assert(Tok.getIdentifierInfo() && "Not an identifier?");
4318193326Sed    D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4319193326Sed    ConsumeToken();
4320198893Srdivacky    goto PastIdentifier;
4321198893Srdivacky  }
4322234353Sdim
4323198893Srdivacky  if (Tok.is(tok::l_paren)) {
4324193326Sed    // direct-declarator: '(' declarator ')'
4325193326Sed    // direct-declarator: '(' attributes declarator ')'
4326193326Sed    // Example: 'char (*X)'   or 'int (*XX)(void)'
4327193326Sed    ParseParenDeclarator(D);
4328202379Srdivacky
4329202379Srdivacky    // If the declarator was parenthesized, we entered the declarator
4330202379Srdivacky    // scope when parsing the parenthesized declarator, then exited
4331202379Srdivacky    // the scope already. Re-enter the scope, if we need to.
4332202379Srdivacky    if (D.getCXXScopeSpec().isSet()) {
4333212904Sdim      // If there was an error parsing parenthesized declarator, declarator
4334234353Sdim      // scope may have been entered before. Don't do it again.
4335212904Sdim      if (!D.isInvalidType() &&
4336212904Sdim          Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
4337202379Srdivacky        // Change the declaration context for name lookup, until this function
4338202379Srdivacky        // is exited (and the declarator has been parsed).
4339202379Srdivacky        DeclScopeObj.EnterDeclaratorScope();
4340202379Srdivacky    }
4341193326Sed  } else if (D.mayOmitIdentifier()) {
4342193326Sed    // This could be something simple like "int" (in which case the declarator
4343193326Sed    // portion is empty), if an abstract-declarator is allowed.
4344193326Sed    D.SetIdentifier(0, Tok.getLocation());
4345193326Sed  } else {
4346239462Sdim    if (Tok.getKind() == tok::annot_pragma_parser_crash)
4347239462Sdim      *(volatile int*) 0x11 = 0;
4348193326Sed    if (D.getContext() == Declarator::MemberContext)
4349193326Sed      Diag(Tok, diag::err_expected_member_name_or_semi)
4350193326Sed        << D.getDeclSpec().getSourceRange();
4351234353Sdim    else if (getLangOpts().CPlusPlus)
4352234353Sdim      Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
4353193326Sed    else
4354193326Sed      Diag(Tok, diag::err_expected_ident_lparen);
4355193326Sed    D.SetIdentifier(0, Tok.getLocation());
4356193326Sed    D.setInvalidType(true);
4357193326Sed  }
4358198092Srdivacky
4359193326Sed PastIdentifier:
4360193326Sed  assert(D.isPastIdentifier() &&
4361193326Sed         "Haven't past the location of the identifier yet?");
4362198092Srdivacky
4363234353Sdim  // Don't parse attributes unless we have parsed an unparenthesized name.
4364234353Sdim  if (D.hasName() && !D.getNumTypeObjects())
4365218893Sdim    MaybeParseCXX0XAttributes(D);
4366199990Srdivacky
4367193326Sed  while (1) {
4368193326Sed    if (Tok.is(tok::l_paren)) {
4369234353Sdim      // Enter function-declaration scope, limiting any declarators to the
4370234353Sdim      // function prototype scope, including parameter declarators.
4371234353Sdim      ParseScope PrototypeScope(this,
4372234353Sdim                                Scope::FunctionPrototypeScope|Scope::DeclScope);
4373193326Sed      // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4374193326Sed      // In such a case, check if we actually have a function declarator; if it
4375193326Sed      // is not, the declarator has been fully parsed.
4376239462Sdim      bool IsAmbiguous = false;
4377239462Sdim      if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit() &&
4378239462Sdim          !isCXXFunctionDeclarator(&IsAmbiguous))
4379239462Sdim        break;
4380221345Sdim      ParsedAttributes attrs(AttrFactory);
4381226633Sdim      BalancedDelimiterTracker T(*this, tok::l_paren);
4382226633Sdim      T.consumeOpen();
4383239462Sdim      ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
4384234353Sdim      PrototypeScope.Exit();
4385193326Sed    } else if (Tok.is(tok::l_square)) {
4386193326Sed      ParseBracketDeclarator(D);
4387193326Sed    } else {
4388193326Sed      break;
4389193326Sed    }
4390193326Sed  }
4391239462Sdim}
4392193326Sed
4393193326Sed/// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
4394193326Sed/// only called before the identifier, so these are most likely just grouping
4395198092Srdivacky/// parens for precedence.  If we find that these are actually function
4396193326Sed/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4397193326Sed///
4398193326Sed///       direct-declarator:
4399193326Sed///         '(' declarator ')'
4400193326Sed/// [GNU]   '(' attributes declarator ')'
4401193326Sed///         direct-declarator '(' parameter-type-list ')'
4402193326Sed///         direct-declarator '(' identifier-list[opt] ')'
4403193326Sed/// [GNU]   direct-declarator '(' parameter-forward-declarations
4404193326Sed///                    parameter-type-list[opt] ')'
4405193326Sed///
4406193326Sedvoid Parser::ParseParenDeclarator(Declarator &D) {
4407226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
4408226633Sdim  T.consumeOpen();
4409226633Sdim
4410193326Sed  assert(!D.isPastIdentifier() && "Should be called before passing identifier");
4411198092Srdivacky
4412193326Sed  // Eat any attributes before we look at whether this is a grouping or function
4413193326Sed  // declarator paren.  If this is a grouping paren, the attribute applies to
4414193326Sed  // the type being built up, for example:
4415193326Sed  //     int (__attribute__(()) *x)(long y)
4416193326Sed  // If this ends up not being a grouping paren, the attribute applies to the
4417193326Sed  // first argument, for example:
4418193326Sed  //     int (__attribute__(()) int x)
4419193326Sed  // In either case, we need to eat any attributes to be able to determine what
4420193326Sed  // sort of paren this is.
4421193326Sed  //
4422221345Sdim  ParsedAttributes attrs(AttrFactory);
4423193326Sed  bool RequiresArg = false;
4424193326Sed  if (Tok.is(tok::kw___attribute)) {
4425218893Sdim    ParseGNUAttributes(attrs);
4426198092Srdivacky
4427193326Sed    // We require that the argument list (if this is a non-grouping paren) be
4428193326Sed    // present even if the attribute list was empty.
4429193326Sed    RequiresArg = true;
4430193326Sed  }
4431193326Sed  // Eat any Microsoft extensions.
4432194179Sed  if  (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
4433208600Srdivacky       Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
4434226633Sdim       Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64) ||
4435226633Sdim       Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned)) {
4436218893Sdim    ParseMicrosoftTypeAttributes(attrs);
4437194179Sed  }
4438212904Sdim  // Eat any Borland extensions.
4439218893Sdim  if  (Tok.is(tok::kw___pascal))
4440218893Sdim    ParseBorlandTypeAttributes(attrs);
4441198092Srdivacky
4442193326Sed  // If we haven't past the identifier yet (or where the identifier would be
4443193326Sed  // stored, if this is an abstract declarator), then this is probably just
4444193326Sed  // grouping parens. However, if this could be an abstract-declarator, then
4445193326Sed  // this could also be the start of function arguments (consider 'void()').
4446193326Sed  bool isGrouping;
4447198092Srdivacky
4448193326Sed  if (!D.mayOmitIdentifier()) {
4449193326Sed    // If this can't be an abstract-declarator, this *must* be a grouping
4450193326Sed    // paren, because we haven't seen the identifier yet.
4451193326Sed    isGrouping = true;
4452193326Sed  } else if (Tok.is(tok::r_paren) ||           // 'int()' is a function.
4453234353Sdim             (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
4454234353Sdim              NextToken().is(tok::r_paren)) || // C++ int(...)
4455234353Sdim             isDeclarationSpecifier() ||       // 'int(int)' is a function.
4456234353Sdim             isCXX11AttributeSpecifier()) {    // 'int([[]]int)' is a function.
4457193326Sed    // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
4458193326Sed    // considered to be a type, not a K&R identifier-list.
4459193326Sed    isGrouping = false;
4460193326Sed  } else {
4461193326Sed    // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
4462193326Sed    isGrouping = true;
4463193326Sed  }
4464198092Srdivacky
4465193326Sed  // If this is a grouping paren, handle:
4466193326Sed  // direct-declarator: '(' declarator ')'
4467193326Sed  // direct-declarator: '(' attributes declarator ')'
4468193326Sed  if (isGrouping) {
4469234353Sdim    SourceLocation EllipsisLoc = D.getEllipsisLoc();
4470234353Sdim    D.setEllipsisLoc(SourceLocation());
4471234353Sdim
4472193326Sed    bool hadGroupingParens = D.hasGroupingParens();
4473193326Sed    D.setGroupingParens(true);
4474193326Sed    ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
4475193326Sed    // Match the ')'.
4476226633Sdim    T.consumeClose();
4477239462Sdim    D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
4478226633Sdim                                            T.getCloseLocation()),
4479226633Sdim                  attrs, T.getCloseLocation());
4480193326Sed
4481193326Sed    D.setGroupingParens(hadGroupingParens);
4482234353Sdim
4483234353Sdim    // An ellipsis cannot be placed outside parentheses.
4484234353Sdim    if (EllipsisLoc.isValid())
4485234353Sdim      diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4486234353Sdim
4487193326Sed    return;
4488193326Sed  }
4489198092Srdivacky
4490193326Sed  // Okay, if this wasn't a grouping paren, it must be the start of a function
4491193326Sed  // argument list.  Recognize that this declarator will never have an
4492193326Sed  // identifier (and remember where it would have been), then call into
4493193326Sed  // ParseFunctionDeclarator to handle of argument list.
4494193326Sed  D.SetIdentifier(0, Tok.getLocation());
4495193326Sed
4496234353Sdim  // Enter function-declaration scope, limiting any declarators to the
4497234353Sdim  // function prototype scope, including parameter declarators.
4498234353Sdim  ParseScope PrototypeScope(this,
4499234353Sdim                            Scope::FunctionPrototypeScope|Scope::DeclScope);
4500239462Sdim  ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
4501234353Sdim  PrototypeScope.Exit();
4502193326Sed}
4503193326Sed
4504193326Sed/// ParseFunctionDeclarator - We are after the identifier and have parsed the
4505193326Sed/// declarator D up to a paren, which indicates that we are parsing function
4506193326Sed/// arguments.
4507193326Sed///
4508234353Sdim/// If FirstArgAttrs is non-null, then the caller parsed those arguments
4509234353Sdim/// immediately after the open paren - they should be considered to be the
4510234353Sdim/// first argument of a parameter.
4511193326Sed///
4512234353Sdim/// If RequiresArg is true, then the first argument of the function is required
4513234353Sdim/// to be present and required to not be an identifier list.
4514193326Sed///
4515234353Sdim/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
4516234353Sdim/// (C++11) ref-qualifier[opt], exception-specification[opt],
4517234353Sdim/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
4518234353Sdim///
4519234353Sdim/// [C++11] exception-specification:
4520221345Sdim///           dynamic-exception-specification
4521221345Sdim///           noexcept-specification
4522221345Sdim///
4523226633Sdimvoid Parser::ParseFunctionDeclarator(Declarator &D,
4524234353Sdim                                     ParsedAttributes &FirstArgAttrs,
4525226633Sdim                                     BalancedDelimiterTracker &Tracker,
4526239462Sdim                                     bool IsAmbiguous,
4527193326Sed                                     bool RequiresArg) {
4528239462Sdim  assert(getCurScope()->isFunctionPrototypeScope() &&
4529234353Sdim         "Should call from a Function scope");
4530193326Sed  // lparen is already consumed!
4531193326Sed  assert(D.isPastIdentifier() && "Should not call before identifier!");
4532198092Srdivacky
4533224145Sdim  // This should be true when the function has typed arguments.
4534224145Sdim  // Otherwise, it is treated as a K&R-style function.
4535224145Sdim  bool HasProto = false;
4536224145Sdim  // Build up an array of information about the parsed arguments.
4537226633Sdim  SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
4538224145Sdim  // Remember where we see an ellipsis, if any.
4539224145Sdim  SourceLocation EllipsisLoc;
4540224145Sdim
4541224145Sdim  DeclSpec DS(AttrFactory);
4542224145Sdim  bool RefQualifierIsLValueRef = true;
4543224145Sdim  SourceLocation RefQualifierLoc;
4544234353Sdim  SourceLocation ConstQualifierLoc;
4545234353Sdim  SourceLocation VolatileQualifierLoc;
4546224145Sdim  ExceptionSpecificationType ESpecType = EST_None;
4547224145Sdim  SourceRange ESpecRange;
4548226633Sdim  SmallVector<ParsedType, 2> DynamicExceptions;
4549226633Sdim  SmallVector<SourceRange, 2> DynamicExceptionRanges;
4550224145Sdim  ExprResult NoexceptExpr;
4551234353Sdim  ParsedAttributes FnAttrs(AttrFactory);
4552239462Sdim  TypeResult TrailingReturnType;
4553234353Sdim
4554234353Sdim  Actions.ActOnStartFunctionDeclarator();
4555234353Sdim
4556224145Sdim  SourceLocation EndLoc;
4557224145Sdim  if (isFunctionDeclaratorIdentifierList()) {
4558218893Sdim    if (RequiresArg)
4559193326Sed      Diag(Tok, diag::err_argument_required_after_attribute);
4560193326Sed
4561224145Sdim    ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
4562193326Sed
4563226633Sdim    Tracker.consumeClose();
4564226633Sdim    EndLoc = Tracker.getCloseLocation();
4565224145Sdim  } else {
4566224145Sdim    if (Tok.isNot(tok::r_paren))
4567234353Sdim      ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
4568224145Sdim    else if (RequiresArg)
4569224145Sdim      Diag(Tok, diag::err_argument_required_after_attribute);
4570224145Sdim
4571234353Sdim    HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
4572224145Sdim
4573224145Sdim    // If we have the closing ')', eat it.
4574226633Sdim    Tracker.consumeClose();
4575226633Sdim    EndLoc = Tracker.getCloseLocation();
4576224145Sdim
4577234353Sdim    if (getLangOpts().CPlusPlus) {
4578234353Sdim      // FIXME: Accept these components in any order, and produce fixits to
4579234353Sdim      // correct the order if the user gets it wrong. Ideally we should deal
4580234353Sdim      // with the virt-specifier-seq and pure-specifier in the same way.
4581218893Sdim
4582224145Sdim      // Parse cv-qualifier-seq[opt].
4583234353Sdim      ParseTypeQualifierListOpt(DS, false /*no attributes*/, false);
4584234353Sdim      if (!DS.getSourceRange().getEnd().isInvalid()) {
4585234353Sdim        EndLoc = DS.getSourceRange().getEnd();
4586234353Sdim        ConstQualifierLoc = DS.getConstSpecLoc();
4587234353Sdim        VolatileQualifierLoc = DS.getVolatileSpecLoc();
4588234353Sdim      }
4589193326Sed
4590224145Sdim      // Parse ref-qualifier[opt].
4591218893Sdim      if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
4592234353Sdim        Diag(Tok, getLangOpts().CPlusPlus0x ?
4593234353Sdim             diag::warn_cxx98_compat_ref_qualifier :
4594234353Sdim             diag::ext_ref_qualifier);
4595234353Sdim
4596218893Sdim        RefQualifierIsLValueRef = Tok.is(tok::amp);
4597218893Sdim        RefQualifierLoc = ConsumeToken();
4598218893Sdim        EndLoc = RefQualifierLoc;
4599218893Sdim      }
4600221345Sdim
4601234982Sdim      // C++11 [expr.prim.general]p3:
4602239462Sdim      //   If a declaration declares a member function or member function
4603239462Sdim      //   template of a class X, the expression this is a prvalue of type
4604234982Sdim      //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
4605239462Sdim      //   and the end of the function-definition, member-declarator, or
4606234982Sdim      //   declarator.
4607239462Sdim      bool IsCXX11MemberFunction =
4608234982Sdim        getLangOpts().CPlusPlus0x &&
4609234982Sdim        (D.getContext() == Declarator::MemberContext ||
4610234982Sdim         (D.getContext() == Declarator::FileContext &&
4611239462Sdim          D.getCXXScopeSpec().isValid() &&
4612234982Sdim          Actions.CurContext->isRecord()));
4613234982Sdim      Sema::CXXThisScopeRAII ThisScope(Actions,
4614234982Sdim                               dyn_cast<CXXRecordDecl>(Actions.CurContext),
4615234982Sdim                               DS.getTypeQualifiers(),
4616234982Sdim                               IsCXX11MemberFunction);
4617235864Sdim
4618193326Sed      // Parse exception-specification[opt].
4619235864Sdim      ESpecType = tryParseExceptionSpecification(ESpecRange,
4620234982Sdim                                                 DynamicExceptions,
4621234982Sdim                                                 DynamicExceptionRanges,
4622235864Sdim                                                 NoexceptExpr);
4623221345Sdim      if (ESpecType != EST_None)
4624221345Sdim        EndLoc = ESpecRange.getEnd();
4625218893Sdim
4626234353Sdim      // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
4627234353Sdim      // after the exception-specification.
4628234353Sdim      MaybeParseCXX0XAttributes(FnAttrs);
4629234353Sdim
4630224145Sdim      // Parse trailing-return-type[opt].
4631234353Sdim      if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) {
4632234353Sdim        Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
4633226633Sdim        SourceRange Range;
4634239462Sdim        TrailingReturnType = ParseTrailingReturnType(Range);
4635226633Sdim        if (Range.getEnd().isValid())
4636226633Sdim          EndLoc = Range.getEnd();
4637218893Sdim      }
4638193326Sed    }
4639193326Sed  }
4640193326Sed
4641224145Sdim  // Remember that we parsed a function type, and remember the attributes.
4642224145Sdim  D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
4643224145Sdim                                             /*isVariadic=*/EllipsisLoc.isValid(),
4644239462Sdim                                             IsAmbiguous, EllipsisLoc,
4645224145Sdim                                             ParamInfo.data(), ParamInfo.size(),
4646224145Sdim                                             DS.getTypeQualifiers(),
4647224145Sdim                                             RefQualifierIsLValueRef,
4648234353Sdim                                             RefQualifierLoc, ConstQualifierLoc,
4649234353Sdim                                             VolatileQualifierLoc,
4650224145Sdim                                             /*MutableLoc=*/SourceLocation(),
4651224145Sdim                                             ESpecType, ESpecRange.getBegin(),
4652224145Sdim                                             DynamicExceptions.data(),
4653224145Sdim                                             DynamicExceptionRanges.data(),
4654224145Sdim                                             DynamicExceptions.size(),
4655224145Sdim                                             NoexceptExpr.isUsable() ?
4656224145Sdim                                               NoexceptExpr.get() : 0,
4657239462Sdim                                             Tracker.getOpenLocation(),
4658226633Sdim                                             EndLoc, D,
4659224145Sdim                                             TrailingReturnType),
4660234353Sdim                FnAttrs, EndLoc);
4661234353Sdim
4662234353Sdim  Actions.ActOnEndFunctionDeclarator();
4663224145Sdim}
4664224145Sdim
4665224145Sdim/// isFunctionDeclaratorIdentifierList - This parameter list may have an
4666224145Sdim/// identifier list form for a K&R-style function:  void foo(a,b,c)
4667224145Sdim///
4668224145Sdim/// Note that identifier-lists are only allowed for normal declarators, not for
4669224145Sdim/// abstract-declarators.
4670224145Sdimbool Parser::isFunctionDeclaratorIdentifierList() {
4671234353Sdim  return !getLangOpts().CPlusPlus
4672224145Sdim         && Tok.is(tok::identifier)
4673224145Sdim         && !TryAltiVecVectorToken()
4674224145Sdim         // K&R identifier lists can't have typedefs as identifiers, per C99
4675224145Sdim         // 6.7.5.3p11.
4676224145Sdim         && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
4677224145Sdim         // Identifier lists follow a really simple grammar: the identifiers can
4678224145Sdim         // be followed *only* by a ", identifier" or ")".  However, K&R
4679224145Sdim         // identifier lists are really rare in the brave new modern world, and
4680224145Sdim         // it is very common for someone to typo a type in a non-K&R style
4681224145Sdim         // list.  If we are presented with something like: "void foo(intptr x,
4682224145Sdim         // float y)", we don't want to start parsing the function declarator as
4683224145Sdim         // though it is a K&R style declarator just because intptr is an
4684224145Sdim         // invalid type.
4685224145Sdim         //
4686224145Sdim         // To handle this, we check to see if the token after the first
4687224145Sdim         // identifier is a "," or ")".  Only then do we parse it as an
4688224145Sdim         // identifier list.
4689224145Sdim         && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
4690224145Sdim}
4691224145Sdim
4692224145Sdim/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
4693224145Sdim/// we found a K&R-style identifier list instead of a typed parameter list.
4694224145Sdim///
4695224145Sdim/// After returning, ParamInfo will hold the parsed parameters.
4696224145Sdim///
4697224145Sdim///       identifier-list: [C99 6.7.5]
4698224145Sdim///         identifier
4699224145Sdim///         identifier-list ',' identifier
4700224145Sdim///
4701224145Sdimvoid Parser::ParseFunctionDeclaratorIdentifierList(
4702224145Sdim       Declarator &D,
4703226633Sdim       SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo) {
4704224145Sdim  // If there was no identifier specified for the declarator, either we are in
4705224145Sdim  // an abstract-declarator, or we are in a parameter declarator which was found
4706224145Sdim  // to be abstract.  In abstract-declarators, identifier lists are not valid:
4707224145Sdim  // diagnose this.
4708224145Sdim  if (!D.getIdentifier())
4709224145Sdim    Diag(Tok, diag::ext_ident_list_in_param);
4710224145Sdim
4711224145Sdim  // Maintain an efficient lookup of params we have seen so far.
4712224145Sdim  llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
4713224145Sdim
4714224145Sdim  while (1) {
4715224145Sdim    // If this isn't an identifier, report the error and skip until ')'.
4716224145Sdim    if (Tok.isNot(tok::identifier)) {
4717224145Sdim      Diag(Tok, diag::err_expected_ident);
4718224145Sdim      SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true);
4719224145Sdim      // Forget we parsed anything.
4720224145Sdim      ParamInfo.clear();
4721224145Sdim      return;
4722193326Sed    }
4723198092Srdivacky
4724224145Sdim    IdentifierInfo *ParmII = Tok.getIdentifierInfo();
4725198092Srdivacky
4726224145Sdim    // Reject 'typedef int y; int test(x, y)', but continue parsing.
4727224145Sdim    if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
4728224145Sdim      Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
4729193326Sed
4730224145Sdim    // Verify that the argument identifier has not already been mentioned.
4731224145Sdim    if (!ParamsSoFar.insert(ParmII)) {
4732224145Sdim      Diag(Tok, diag::err_param_redefinition) << ParmII;
4733224145Sdim    } else {
4734224145Sdim      // Remember this identifier in ParamInfo.
4735224145Sdim      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4736224145Sdim                                                     Tok.getLocation(),
4737224145Sdim                                                     0));
4738224145Sdim    }
4739198092Srdivacky
4740224145Sdim    // Eat the identifier.
4741224145Sdim    ConsumeToken();
4742224145Sdim
4743224145Sdim    // The list continues if we see a comma.
4744224145Sdim    if (Tok.isNot(tok::comma))
4745224145Sdim      break;
4746224145Sdim    ConsumeToken();
4747224145Sdim  }
4748224145Sdim}
4749224145Sdim
4750224145Sdim/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
4751224145Sdim/// after the opening parenthesis. This function will not parse a K&R-style
4752224145Sdim/// identifier list.
4753224145Sdim///
4754234353Sdim/// D is the declarator being parsed.  If FirstArgAttrs is non-null, then the
4755234353Sdim/// caller parsed those arguments immediately after the open paren - they should
4756234353Sdim/// be considered to be part of the first parameter.
4757224145Sdim///
4758224145Sdim/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
4759224145Sdim/// be the location of the ellipsis, if any was parsed.
4760224145Sdim///
4761224145Sdim///       parameter-type-list: [C99 6.7.5]
4762224145Sdim///         parameter-list
4763224145Sdim///         parameter-list ',' '...'
4764224145Sdim/// [C++]   parameter-list '...'
4765224145Sdim///
4766224145Sdim///       parameter-list: [C99 6.7.5]
4767224145Sdim///         parameter-declaration
4768224145Sdim///         parameter-list ',' parameter-declaration
4769224145Sdim///
4770224145Sdim///       parameter-declaration: [C99 6.7.5]
4771224145Sdim///         declaration-specifiers declarator
4772224145Sdim/// [C++]   declaration-specifiers declarator '=' assignment-expression
4773234353Sdim/// [C++11]                                       initializer-clause
4774224145Sdim/// [GNU]   declaration-specifiers declarator attributes
4775224145Sdim///         declaration-specifiers abstract-declarator[opt]
4776224145Sdim/// [C++]   declaration-specifiers abstract-declarator[opt]
4777224145Sdim///           '=' assignment-expression
4778224145Sdim/// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
4779234353Sdim/// [C++11] attribute-specifier-seq parameter-declaration
4780224145Sdim///
4781224145Sdimvoid Parser::ParseParameterDeclarationClause(
4782224145Sdim       Declarator &D,
4783234353Sdim       ParsedAttributes &FirstArgAttrs,
4784226633Sdim       SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo,
4785224145Sdim       SourceLocation &EllipsisLoc) {
4786224145Sdim
4787193326Sed  while (1) {
4788193326Sed    if (Tok.is(tok::ellipsis)) {
4789234353Sdim      // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
4790234353Sdim      // before deciding this was a parameter-declaration-clause.
4791193326Sed      EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
4792193326Sed      break;
4793193326Sed    }
4794198092Srdivacky
4795193326Sed    // Parse the declaration-specifiers.
4796198893Srdivacky    // Just use the ParsingDeclaration "scope" of the declarator.
4797221345Sdim    DeclSpec DS(AttrFactory);
4798226633Sdim
4799234353Sdim    // Parse any C++11 attributes.
4800234353Sdim    MaybeParseCXX0XAttributes(DS.getAttributes());
4801234353Sdim
4802218893Sdim    // Skip any Microsoft attributes before a param.
4803234353Sdim    if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
4804218893Sdim      ParseMicrosoftAttributes(DS.getAttributes());
4805193326Sed
4806218893Sdim    SourceLocation DSStart = Tok.getLocation();
4807218893Sdim
4808193326Sed    // If the caller parsed attributes for the first argument, add them now.
4809218893Sdim    // Take them so that we only apply the attributes to the first parameter.
4810224145Sdim    // FIXME: If we can leave the attributes in the token stream somehow, we can
4811234353Sdim    // get rid of a parameter (FirstArgAttrs) and this statement. It might be
4812234353Sdim    // too much hassle.
4813234353Sdim    DS.takeAttributesFrom(FirstArgAttrs);
4814218893Sdim
4815193326Sed    ParseDeclarationSpecifiers(DS);
4816198092Srdivacky
4817193326Sed    // Parse the declarator.  This is "PrototypeContext", because we must
4818193326Sed    // accept either 'declarator' or 'abstract-declarator' here.
4819193326Sed    Declarator ParmDecl(DS, Declarator::PrototypeContext);
4820193326Sed    ParseDeclarator(ParmDecl);
4821193326Sed
4822193326Sed    // Parse GNU attributes, if present.
4823218893Sdim    MaybeParseGNUAttributes(ParmDecl);
4824198092Srdivacky
4825193326Sed    // Remember this parsed parameter in ParamInfo.
4826193326Sed    IdentifierInfo *ParmII = ParmDecl.getIdentifier();
4827198092Srdivacky
4828193326Sed    // DefArgToks is used when the parsing of default arguments needs
4829193326Sed    // to be delayed.
4830193326Sed    CachedTokens *DefArgToks = 0;
4831193326Sed
4832193326Sed    // If no parameter was specified, verify that *something* was specified,
4833193326Sed    // otherwise we have a missing type and identifier.
4834193326Sed    if (DS.isEmpty() && ParmDecl.getIdentifier() == 0 &&
4835193326Sed        ParmDecl.getNumTypeObjects() == 0) {
4836193326Sed      // Completely missing, emit error.
4837193326Sed      Diag(DSStart, diag::err_missing_param);
4838193326Sed    } else {
4839193326Sed      // Otherwise, we have something.  Add it and let semantic analysis try
4840193326Sed      // to grok it and add the result to the ParamInfo we are building.
4841198092Srdivacky
4842193326Sed      // Inform the actions module about the parameter declarator, so it gets
4843193326Sed      // added to the current scope.
4844212904Sdim      Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
4845193326Sed
4846193326Sed      // Parse the default argument, if any. We parse the default
4847193326Sed      // arguments in all dialects; the semantic analysis in
4848193326Sed      // ActOnParamDefaultArgument will reject the default argument in
4849193326Sed      // C.
4850193326Sed      if (Tok.is(tok::equal)) {
4851193326Sed        SourceLocation EqualLoc = Tok.getLocation();
4852193326Sed
4853193326Sed        // Parse the default argument
4854193326Sed        if (D.getContext() == Declarator::MemberContext) {
4855193326Sed          // If we're inside a class definition, cache the tokens
4856193326Sed          // corresponding to the default argument. We'll actually parse
4857193326Sed          // them when we see the end of the class definition.
4858193326Sed          // FIXME: Can we use a smart pointer for Toks?
4859193326Sed          DefArgToks = new CachedTokens;
4860193326Sed
4861198092Srdivacky          if (!ConsumeAndStoreUntil(tok::comma, tok::r_paren, *DefArgToks,
4862207619Srdivacky                                    /*StopAtSemi=*/true,
4863207619Srdivacky                                    /*ConsumeFinalToken=*/false)) {
4864193326Sed            delete DefArgToks;
4865193326Sed            DefArgToks = 0;
4866193326Sed            Actions.ActOnParamDefaultArgumentError(Param);
4867212904Sdim          } else {
4868212904Sdim            // Mark the end of the default argument so that we know when to
4869212904Sdim            // stop when we parse it later on.
4870212904Sdim            Token DefArgEnd;
4871212904Sdim            DefArgEnd.startToken();
4872212904Sdim            DefArgEnd.setKind(tok::cxx_defaultarg_end);
4873212904Sdim            DefArgEnd.setLocation(Tok.getLocation());
4874212904Sdim            DefArgToks->push_back(DefArgEnd);
4875198092Srdivacky            Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
4876194179Sed                                                (*DefArgToks)[1].getLocation());
4877212904Sdim          }
4878193326Sed        } else {
4879193326Sed          // Consume the '='.
4880193326Sed          ConsumeToken();
4881198092Srdivacky
4882239462Sdim          // The argument isn't actually potentially evaluated unless it is
4883218893Sdim          // used.
4884218893Sdim          EnterExpressionEvaluationContext Eval(Actions,
4885234353Sdim                                              Sema::PotentiallyEvaluatedIfUsed,
4886234353Sdim                                                Param);
4887218893Sdim
4888234353Sdim          ExprResult DefArgResult;
4889234353Sdim          if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
4890234353Sdim            Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
4891234353Sdim            DefArgResult = ParseBraceInitializer();
4892234353Sdim          } else
4893234353Sdim            DefArgResult = ParseAssignmentExpression();
4894193326Sed          if (DefArgResult.isInvalid()) {
4895193326Sed            Actions.ActOnParamDefaultArgumentError(Param);
4896193326Sed            SkipUntil(tok::comma, tok::r_paren, true, true);
4897193326Sed          } else {
4898193326Sed            // Inform the actions module about the default argument
4899193326Sed            Actions.ActOnParamDefaultArgument(Param, EqualLoc,
4900212904Sdim                                              DefArgResult.take());
4901193326Sed          }
4902193326Sed        }
4903193326Sed      }
4904198092Srdivacky
4905198092Srdivacky      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
4906198092Srdivacky                                          ParmDecl.getIdentifierLoc(), Param,
4907193326Sed                                          DefArgToks));
4908193326Sed    }
4909193326Sed
4910193326Sed    // If the next token is a comma, consume it and keep reading arguments.
4911198092Srdivacky    if (Tok.isNot(tok::comma)) {
4912198092Srdivacky      if (Tok.is(tok::ellipsis)) {
4913198092Srdivacky        EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
4914239462Sdim
4915234353Sdim        if (!getLangOpts().CPlusPlus) {
4916198092Srdivacky          // We have ellipsis without a preceding ',', which is ill-formed
4917198092Srdivacky          // in C. Complain and provide the fix.
4918198092Srdivacky          Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
4919206084Srdivacky            << FixItHint::CreateInsertion(EllipsisLoc, ", ");
4920198092Srdivacky        }
4921198092Srdivacky      }
4922239462Sdim
4923198092Srdivacky      break;
4924198092Srdivacky    }
4925198092Srdivacky
4926193326Sed    // Consume the comma.
4927193326Sed    ConsumeToken();
4928193326Sed  }
4929198092Srdivacky
4930193326Sed}
4931193326Sed
4932193326Sed/// [C90]   direct-declarator '[' constant-expression[opt] ']'
4933193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4934193326Sed/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4935193326Sed/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4936193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
4937234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4938234353Sdim///                           attribute-specifier-seq[opt]
4939193326Sedvoid Parser::ParseBracketDeclarator(Declarator &D) {
4940234353Sdim  if (CheckProhibitedCXX11Attribute())
4941234353Sdim    return;
4942234353Sdim
4943226633Sdim  BalancedDelimiterTracker T(*this, tok::l_square);
4944226633Sdim  T.consumeOpen();
4945198092Srdivacky
4946193326Sed  // C array syntax has many features, but by-far the most common is [] and [4].
4947193326Sed  // This code does a fast path to handle some of the most obvious cases.
4948193326Sed  if (Tok.getKind() == tok::r_square) {
4949226633Sdim    T.consumeClose();
4950221345Sdim    ParsedAttributes attrs(AttrFactory);
4951218893Sdim    MaybeParseCXX0XAttributes(attrs);
4952239462Sdim
4953193326Sed    // Remember that we parsed the empty array type.
4954212904Sdim    ExprResult NumElements;
4955221345Sdim    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
4956226633Sdim                                            T.getOpenLocation(),
4957226633Sdim                                            T.getCloseLocation()),
4958226633Sdim                  attrs, T.getCloseLocation());
4959193326Sed    return;
4960193326Sed  } else if (Tok.getKind() == tok::numeric_constant &&
4961193326Sed             GetLookAheadToken(1).is(tok::r_square)) {
4962193326Sed    // [4] is very common.  Parse the numeric constant expression.
4963234353Sdim    ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
4964193326Sed    ConsumeToken();
4965193326Sed
4966226633Sdim    T.consumeClose();
4967221345Sdim    ParsedAttributes attrs(AttrFactory);
4968218893Sdim    MaybeParseCXX0XAttributes(attrs);
4969193326Sed
4970193326Sed    // Remember that we parsed a array type, and remember its features.
4971221345Sdim    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
4972218893Sdim                                            ExprRes.release(),
4973226633Sdim                                            T.getOpenLocation(),
4974226633Sdim                                            T.getCloseLocation()),
4975226633Sdim                  attrs, T.getCloseLocation());
4976193326Sed    return;
4977193326Sed  }
4978198092Srdivacky
4979193326Sed  // If valid, this location is the position where we read the 'static' keyword.
4980193326Sed  SourceLocation StaticLoc;
4981193326Sed  if (Tok.is(tok::kw_static))
4982193326Sed    StaticLoc = ConsumeToken();
4983198092Srdivacky
4984193326Sed  // If there is a type-qualifier-list, read it now.
4985193326Sed  // Type qualifiers in an array subscript are a C99 feature.
4986221345Sdim  DeclSpec DS(AttrFactory);
4987193326Sed  ParseTypeQualifierListOpt(DS, false /*no attributes*/);
4988198092Srdivacky
4989193326Sed  // If we haven't already read 'static', check to see if there is one after the
4990193326Sed  // type-qualifier-list.
4991193326Sed  if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
4992193326Sed    StaticLoc = ConsumeToken();
4993198092Srdivacky
4994193326Sed  // Handle "direct-declarator [ type-qual-list[opt] * ]".
4995193326Sed  bool isStar = false;
4996212904Sdim  ExprResult NumElements;
4997198092Srdivacky
4998193326Sed  // Handle the case where we have '[*]' as the array size.  However, a leading
4999193326Sed  // star could be the start of an expression, for example 'X[*p + 4]'.  Verify
5000239462Sdim  // the token after the star is a ']'.  Since stars in arrays are
5001193326Sed  // infrequent, use of lookahead is not costly here.
5002193326Sed  if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
5003193326Sed    ConsumeToken();  // Eat the '*'.
5004193326Sed
5005193326Sed    if (StaticLoc.isValid()) {
5006193326Sed      Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
5007193326Sed      StaticLoc = SourceLocation();  // Drop the static.
5008193326Sed    }
5009193326Sed    isStar = true;
5010193326Sed  } else if (Tok.isNot(tok::r_square)) {
5011193326Sed    // Note, in C89, this production uses the constant-expr production instead
5012193326Sed    // of assignment-expr.  The only difference is that assignment-expr allows
5013193326Sed    // things like '=' and '*='.  Sema rejects these in C89 mode because they
5014193326Sed    // are not i-c-e's, so we don't need to distinguish between the two here.
5015198092Srdivacky
5016194613Sed    // Parse the constant-expression or assignment-expression now (depending
5017194613Sed    // on dialect).
5018234353Sdim    if (getLangOpts().CPlusPlus) {
5019194613Sed      NumElements = ParseConstantExpression();
5020234353Sdim    } else {
5021234353Sdim      EnterExpressionEvaluationContext Unevaluated(Actions,
5022234353Sdim                                                   Sema::ConstantEvaluated);
5023194613Sed      NumElements = ParseAssignmentExpression();
5024234353Sdim    }
5025193326Sed  }
5026198092Srdivacky
5027193326Sed  // If there was an error parsing the assignment-expression, recover.
5028193326Sed  if (NumElements.isInvalid()) {
5029193326Sed    D.setInvalidType(true);
5030193326Sed    // If the expression was invalid, skip it.
5031193326Sed    SkipUntil(tok::r_square);
5032193326Sed    return;
5033193326Sed  }
5034193326Sed
5035226633Sdim  T.consumeClose();
5036193326Sed
5037221345Sdim  ParsedAttributes attrs(AttrFactory);
5038218893Sdim  MaybeParseCXX0XAttributes(attrs);
5039199990Srdivacky
5040193326Sed  // Remember that we parsed a array type, and remember its features.
5041221345Sdim  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
5042193326Sed                                          StaticLoc.isValid(), isStar,
5043198092Srdivacky                                          NumElements.release(),
5044226633Sdim                                          T.getOpenLocation(),
5045226633Sdim                                          T.getCloseLocation()),
5046226633Sdim                attrs, T.getCloseLocation());
5047193326Sed}
5048193326Sed
5049193326Sed/// [GNU]   typeof-specifier:
5050193326Sed///           typeof ( expressions )
5051193326Sed///           typeof ( type-name )
5052193326Sed/// [GNU/C++] typeof unary-expression
5053193326Sed///
5054193326Sedvoid Parser::ParseTypeofSpecifier(DeclSpec &DS) {
5055193326Sed  assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
5056193326Sed  Token OpTok = Tok;
5057193326Sed  SourceLocation StartLoc = ConsumeToken();
5058193326Sed
5059202379Srdivacky  const bool hasParens = Tok.is(tok::l_paren);
5060202379Srdivacky
5061234353Sdim  EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
5062234353Sdim
5063193326Sed  bool isCastExpr;
5064212904Sdim  ParsedType CastTy;
5065193326Sed  SourceRange CastRange;
5066221345Sdim  ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
5067221345Sdim                                                          CastTy, CastRange);
5068202379Srdivacky  if (hasParens)
5069202379Srdivacky    DS.setTypeofParensRange(CastRange);
5070193326Sed
5071193326Sed  if (CastRange.getEnd().isInvalid())
5072193326Sed    // FIXME: Not accurate, the range gets one token more than it should.
5073193326Sed    DS.SetRangeEnd(Tok.getLocation());
5074193326Sed  else
5075193326Sed    DS.SetRangeEnd(CastRange.getEnd());
5076198092Srdivacky
5077193326Sed  if (isCastExpr) {
5078193326Sed    if (!CastTy) {
5079193326Sed      DS.SetTypeSpecError();
5080193326Sed      return;
5081193326Sed    }
5082193326Sed
5083193326Sed    const char *PrevSpec = 0;
5084198092Srdivacky    unsigned DiagID;
5085193326Sed    // Check for duplicate type specifiers (e.g. "int typeof(int)").
5086193326Sed    if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
5087198092Srdivacky                           DiagID, CastTy))
5088198092Srdivacky      Diag(StartLoc, DiagID) << PrevSpec;
5089193326Sed    return;
5090193326Sed  }
5091193326Sed
5092193326Sed  // If we get here, the operand to the typeof was an expresion.
5093193326Sed  if (Operand.isInvalid()) {
5094193326Sed    DS.SetTypeSpecError();
5095193326Sed    return;
5096193326Sed  }
5097193326Sed
5098234353Sdim  // We might need to transform the operand if it is potentially evaluated.
5099234353Sdim  Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5100234353Sdim  if (Operand.isInvalid()) {
5101234353Sdim    DS.SetTypeSpecError();
5102234353Sdim    return;
5103234353Sdim  }
5104234353Sdim
5105193326Sed  const char *PrevSpec = 0;
5106198092Srdivacky  unsigned DiagID;
5107193326Sed  // Check for duplicate type specifiers (e.g. "int typeof(int)").
5108193326Sed  if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
5109212904Sdim                         DiagID, Operand.get()))
5110198092Srdivacky    Diag(StartLoc, DiagID) << PrevSpec;
5111193326Sed}
5112204643Srdivacky
5113234353Sdim/// [C11]   atomic-specifier:
5114226633Sdim///           _Atomic ( type-name )
5115226633Sdim///
5116226633Sdimvoid Parser::ParseAtomicSpecifier(DeclSpec &DS) {
5117226633Sdim  assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier");
5118204643Srdivacky
5119226633Sdim  SourceLocation StartLoc = ConsumeToken();
5120226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
5121226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) {
5122226633Sdim    SkipUntil(tok::r_paren);
5123226633Sdim    return;
5124226633Sdim  }
5125226633Sdim
5126226633Sdim  TypeResult Result = ParseTypeName();
5127226633Sdim  if (Result.isInvalid()) {
5128226633Sdim    SkipUntil(tok::r_paren);
5129226633Sdim    return;
5130226633Sdim  }
5131226633Sdim
5132226633Sdim  // Match the ')'
5133226633Sdim  T.consumeClose();
5134226633Sdim
5135226633Sdim  if (T.getCloseLocation().isInvalid())
5136226633Sdim    return;
5137226633Sdim
5138226633Sdim  DS.setTypeofParensRange(T.getRange());
5139226633Sdim  DS.SetRangeEnd(T.getCloseLocation());
5140226633Sdim
5141226633Sdim  const char *PrevSpec = 0;
5142226633Sdim  unsigned DiagID;
5143226633Sdim  if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5144226633Sdim                         DiagID, Result.release()))
5145226633Sdim    Diag(StartLoc, DiagID) << PrevSpec;
5146226633Sdim}
5147226633Sdim
5148226633Sdim
5149204643Srdivacky/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5150204643Srdivacky/// from TryAltiVecVectorToken.
5151204643Srdivackybool Parser::TryAltiVecVectorTokenOutOfLine() {
5152204643Srdivacky  Token Next = NextToken();
5153204643Srdivacky  switch (Next.getKind()) {
5154204643Srdivacky  default: return false;
5155204643Srdivacky  case tok::kw_short:
5156204643Srdivacky  case tok::kw_long:
5157204643Srdivacky  case tok::kw_signed:
5158204643Srdivacky  case tok::kw_unsigned:
5159204643Srdivacky  case tok::kw_void:
5160204643Srdivacky  case tok::kw_char:
5161204643Srdivacky  case tok::kw_int:
5162204643Srdivacky  case tok::kw_float:
5163204643Srdivacky  case tok::kw_double:
5164204643Srdivacky  case tok::kw_bool:
5165204643Srdivacky  case tok::kw___pixel:
5166204643Srdivacky    Tok.setKind(tok::kw___vector);
5167204643Srdivacky    return true;
5168204643Srdivacky  case tok::identifier:
5169204643Srdivacky    if (Next.getIdentifierInfo() == Ident_pixel) {
5170204643Srdivacky      Tok.setKind(tok::kw___vector);
5171204643Srdivacky      return true;
5172204643Srdivacky    }
5173204643Srdivacky    return false;
5174204643Srdivacky  }
5175204643Srdivacky}
5176204643Srdivacky
5177204643Srdivackybool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5178204643Srdivacky                                      const char *&PrevSpec, unsigned &DiagID,
5179204643Srdivacky                                      bool &isInvalid) {
5180204643Srdivacky  if (Tok.getIdentifierInfo() == Ident_vector) {
5181204643Srdivacky    Token Next = NextToken();
5182204643Srdivacky    switch (Next.getKind()) {
5183204643Srdivacky    case tok::kw_short:
5184204643Srdivacky    case tok::kw_long:
5185204643Srdivacky    case tok::kw_signed:
5186204643Srdivacky    case tok::kw_unsigned:
5187204643Srdivacky    case tok::kw_void:
5188204643Srdivacky    case tok::kw_char:
5189204643Srdivacky    case tok::kw_int:
5190204643Srdivacky    case tok::kw_float:
5191204643Srdivacky    case tok::kw_double:
5192204643Srdivacky    case tok::kw_bool:
5193204643Srdivacky    case tok::kw___pixel:
5194204643Srdivacky      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5195204643Srdivacky      return true;
5196204643Srdivacky    case tok::identifier:
5197204643Srdivacky      if (Next.getIdentifierInfo() == Ident_pixel) {
5198204643Srdivacky        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5199204643Srdivacky        return true;
5200204643Srdivacky      }
5201204643Srdivacky      break;
5202204643Srdivacky    default:
5203204643Srdivacky      break;
5204204643Srdivacky    }
5205210299Sed  } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
5206204643Srdivacky             DS.isTypeAltiVecVector()) {
5207204643Srdivacky    isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5208204643Srdivacky    return true;
5209204643Srdivacky  }
5210204643Srdivacky  return false;
5211204643Srdivacky}
5212