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"
15249423Sdim#include "RAIIObjectsForParser.h"
16263508Sdim#include "clang/AST/DeclTemplate.h"
17249423Sdim#include "clang/Basic/AddressSpaces.h"
18249423Sdim#include "clang/Basic/CharInfo.h"
19249423Sdim#include "clang/Basic/OpenCL.h"
20193326Sed#include "clang/Parse/ParseDiagnostic.h"
21239462Sdim#include "clang/Sema/Lookup.h"
22212904Sdim#include "clang/Sema/ParsedTemplate.h"
23212904Sdim#include "clang/Sema/PrettyDeclStackTrace.h"
24249423Sdim#include "clang/Sema/Scope.h"
25193326Sed#include "llvm/ADT/SmallSet.h"
26234353Sdim#include "llvm/ADT/SmallString.h"
27226633Sdim#include "llvm/ADT/StringSwitch.h"
28193326Sedusing namespace clang;
29193326Sed
30193326Sed//===----------------------------------------------------------------------===//
31193326Sed// C99 6.7: Declarations.
32193326Sed//===----------------------------------------------------------------------===//
33193326Sed
34193326Sed/// ParseTypeName
35193326Sed///       type-name: [C99 6.7.6]
36193326Sed///         specifier-qualifier-list abstract-declarator[opt]
37193326Sed///
38193326Sed/// Called type-id in C++.
39218893SdimTypeResult Parser::ParseTypeName(SourceRange *Range,
40224145Sdim                                 Declarator::TheContext Context,
41224145Sdim                                 AccessSpecifier AS,
42249423Sdim                                 Decl **OwnedType,
43249423Sdim                                 ParsedAttributes *Attrs) {
44234353Sdim  DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
45239462Sdim  if (DSC == DSC_normal)
46239462Sdim    DSC = DSC_type_specifier;
47234353Sdim
48193326Sed  // Parse the common declaration-specifiers piece.
49221345Sdim  DeclSpec DS(AttrFactory);
50249423Sdim  if (Attrs)
51249423Sdim    DS.addAttributes(Attrs->getList());
52234353Sdim  ParseSpecifierQualifierList(DS, AS, DSC);
53224145Sdim  if (OwnedType)
54224145Sdim    *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
55193326Sed
56193326Sed  // Parse the abstract-declarator, if present.
57218893Sdim  Declarator DeclaratorInfo(DS, Context);
58193326Sed  ParseDeclarator(DeclaratorInfo);
59193326Sed  if (Range)
60193326Sed    *Range = DeclaratorInfo.getSourceRange();
61193326Sed
62193326Sed  if (DeclaratorInfo.isInvalidType())
63193326Sed    return true;
64193326Sed
65210299Sed  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
66193326Sed}
67193326Sed
68226633Sdim
69226633Sdim/// isAttributeLateParsed - Return true if the attribute has arguments that
70226633Sdim/// require late parsing.
71226633Sdimstatic bool isAttributeLateParsed(const IdentifierInfo &II) {
72226633Sdim    return llvm::StringSwitch<bool>(II.getName())
73226633Sdim#include "clang/Parse/AttrLateParsed.inc"
74226633Sdim        .Default(false);
75226633Sdim}
76226633Sdim
77199990Srdivacky/// ParseGNUAttributes - Parse a non-empty attributes list.
78193326Sed///
79193326Sed/// [GNU] attributes:
80193326Sed///         attribute
81193326Sed///         attributes attribute
82193326Sed///
83193326Sed/// [GNU]  attribute:
84193326Sed///          '__attribute__' '(' '(' attribute-list ')' ')'
85193326Sed///
86193326Sed/// [GNU]  attribute-list:
87193326Sed///          attrib
88193326Sed///          attribute_list ',' attrib
89193326Sed///
90193326Sed/// [GNU]  attrib:
91193326Sed///          empty
92193326Sed///          attrib-name
93193326Sed///          attrib-name '(' identifier ')'
94193326Sed///          attrib-name '(' identifier ',' nonempty-expr-list ')'
95193326Sed///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
96193326Sed///
97193326Sed/// [GNU]  attrib-name:
98193326Sed///          identifier
99193326Sed///          typespec
100193326Sed///          typequal
101193326Sed///          storageclass
102198092Srdivacky///
103263508Sdim/// Whether an attribute takes an 'identifier' is determined by the
104263508Sdim/// attrib-name. GCC's behavior here is not worth imitating:
105193326Sed///
106263508Sdim///  * In C mode, if the attribute argument list starts with an identifier
107263508Sdim///    followed by a ',' or an ')', and the identifier doesn't resolve to
108263508Sdim///    a type, it is parsed as an identifier. If the attribute actually
109263508Sdim///    wanted an expression, it's out of luck (but it turns out that no
110263508Sdim///    attributes work that way, because C constant expressions are very
111263508Sdim///    limited).
112263508Sdim///  * In C++ mode, if the attribute argument list starts with an identifier,
113263508Sdim///    and the attribute *wants* an identifier, it is parsed as an identifier.
114263508Sdim///    At block scope, any additional tokens between the identifier and the
115263508Sdim///    ',' or ')' are ignored, otherwise they produce a parse error.
116234353Sdim///
117263508Sdim/// We follow the C++ model, but don't allow junk after the identifier.
118218893Sdimvoid Parser::ParseGNUAttributes(ParsedAttributes &attrs,
119226633Sdim                                SourceLocation *endLoc,
120226633Sdim                                LateParsedAttrList *LateAttrs) {
121199990Srdivacky  assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
122198092Srdivacky
123193326Sed  while (Tok.is(tok::kw___attribute)) {
124193326Sed    ConsumeToken();
125193326Sed    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
126193326Sed                         "attribute")) {
127263508Sdim      SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
128218893Sdim      return;
129193326Sed    }
130193326Sed    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
131263508Sdim      SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
132218893Sdim      return;
133193326Sed    }
134193326Sed    // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
135193326Sed    while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
136193326Sed           Tok.is(tok::comma)) {
137198092Srdivacky      if (Tok.is(tok::comma)) {
138193326Sed        // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
139193326Sed        ConsumeToken();
140193326Sed        continue;
141193326Sed      }
142193326Sed      // we have an identifier or declaration specifier (const, int, etc.)
143193326Sed      IdentifierInfo *AttrName = Tok.getIdentifierInfo();
144193326Sed      SourceLocation AttrNameLoc = ConsumeToken();
145198092Srdivacky
146226633Sdim      if (Tok.is(tok::l_paren)) {
147226633Sdim        // handle "parameterized" attributes
148234353Sdim        if (LateAttrs && isAttributeLateParsed(*AttrName)) {
149226633Sdim          LateParsedAttribute *LA =
150226633Sdim            new LateParsedAttribute(this, *AttrName, AttrNameLoc);
151226633Sdim          LateAttrs->push_back(LA);
152198092Srdivacky
153234353Sdim          // Attributes in a class are parsed at the end of the class, along
154234353Sdim          // with other late-parsed declarations.
155243830Sdim          if (!ClassStack.empty() && !LateAttrs->parseSoon())
156234353Sdim            getCurrentClass().LateParsedDeclarations.push_back(LA);
157234353Sdim
158226633Sdim          // consume everything up to and including the matching right parens
159226633Sdim          ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
160198092Srdivacky
161226633Sdim          Token Eof;
162226633Sdim          Eof.startToken();
163226633Sdim          Eof.setLocation(Tok.getLocation());
164226633Sdim          LA->Toks.push_back(Eof);
165226633Sdim        } else {
166243830Sdim          ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
167243830Sdim                                0, SourceLocation(), AttributeList::AS_GNU);
168193326Sed        }
169193326Sed      } else {
170263508Sdim        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
171263508Sdim                     AttributeList::AS_GNU);
172193326Sed      }
173193326Sed    }
174193326Sed    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
175263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
176199990Srdivacky    SourceLocation Loc = Tok.getLocation();
177263508Sdim    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
178263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
179218893Sdim    if (endLoc)
180218893Sdim      *endLoc = Loc;
181193326Sed  }
182193326Sed}
183193326Sed
184263508Sdim/// \brief Normalizes an attribute name by dropping prefixed and suffixed __.
185263508Sdimstatic StringRef normalizeAttrName(StringRef Name) {
186263508Sdim  if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
187263508Sdim    Name = Name.drop_front(2).drop_back(2);
188263508Sdim  return Name;
189263508Sdim}
190263508Sdim
191263508Sdim/// \brief Determine whether the given attribute has an identifier argument.
192263508Sdimstatic bool attributeHasIdentifierArg(const IdentifierInfo &II) {
193263508Sdim  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
194263508Sdim#include "clang/Parse/AttrIdentifierArg.inc"
195251662Sdim           .Default(false);
196251662Sdim}
197226633Sdim
198263508Sdim/// \brief Determine whether the given attribute parses a type argument.
199263508Sdimstatic bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
200263508Sdim  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
201263508Sdim#include "clang/Parse/AttrTypeArg.inc"
202263508Sdim           .Default(false);
203263508Sdim}
204263508Sdim
205263508SdimIdentifierLoc *Parser::ParseIdentifierLoc() {
206263508Sdim  assert(Tok.is(tok::identifier) && "expected an identifier");
207263508Sdim  IdentifierLoc *IL = IdentifierLoc::create(Actions.Context,
208263508Sdim                                            Tok.getLocation(),
209263508Sdim                                            Tok.getIdentifierInfo());
210263508Sdim  ConsumeToken();
211263508Sdim  return IL;
212263508Sdim}
213263508Sdim
214263508Sdimvoid Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
215263508Sdim                                       SourceLocation AttrNameLoc,
216263508Sdim                                       ParsedAttributes &Attrs,
217263508Sdim                                       SourceLocation *EndLoc) {
218263508Sdim  BalancedDelimiterTracker Parens(*this, tok::l_paren);
219263508Sdim  Parens.consumeOpen();
220263508Sdim
221263508Sdim  TypeResult T;
222263508Sdim  if (Tok.isNot(tok::r_paren))
223263508Sdim    T = ParseTypeName();
224263508Sdim
225263508Sdim  if (Parens.consumeClose())
226263508Sdim    return;
227263508Sdim
228263508Sdim  if (T.isInvalid())
229263508Sdim    return;
230263508Sdim
231263508Sdim  if (T.isUsable())
232263508Sdim    Attrs.addNewTypeAttr(&AttrName,
233263508Sdim                         SourceRange(AttrNameLoc, Parens.getCloseLocation()), 0,
234263508Sdim                         AttrNameLoc, T.get(), AttributeList::AS_GNU);
235263508Sdim  else
236263508Sdim    Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),
237263508Sdim                 0, AttrNameLoc, 0, 0, AttributeList::AS_GNU);
238263508Sdim}
239263508Sdim
240243830Sdim/// Parse the arguments to a parameterized GNU attribute or
241243830Sdim/// a C++11 attribute in "gnu" namespace.
242226633Sdimvoid Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
243226633Sdim                                   SourceLocation AttrNameLoc,
244226633Sdim                                   ParsedAttributes &Attrs,
245243830Sdim                                   SourceLocation *EndLoc,
246243830Sdim                                   IdentifierInfo *ScopeName,
247243830Sdim                                   SourceLocation ScopeLoc,
248243830Sdim                                   AttributeList::Syntax Syntax) {
249226633Sdim
250226633Sdim  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
251226633Sdim
252263508Sdim  AttributeList::Kind AttrKind =
253263508Sdim      AttributeList::getKind(AttrName, ScopeName, Syntax);
254263508Sdim
255226633Sdim  // Availability attributes have their own grammar.
256263508Sdim  // FIXME: All these cases fail to pass in the syntax and scope, and might be
257263508Sdim  // written as C++11 gnu:: attributes.
258263508Sdim  if (AttrKind == AttributeList::AT_Availability) {
259226633Sdim    ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
260226633Sdim    return;
261226633Sdim  }
262263508Sdim  // Thread safety attributes are parsed in an unevaluated context.
263263508Sdim  // FIXME: Share the bulk of the parsing code here and just pull out
264263508Sdim  // the unevaluated context.
265226633Sdim  if (IsThreadSafetyAttribute(AttrName->getName())) {
266226633Sdim    ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
267226633Sdim    return;
268226633Sdim  }
269239462Sdim  // Type safety attributes have their own grammar.
270263508Sdim  if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
271239462Sdim    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
272239462Sdim    return;
273239462Sdim  }
274263508Sdim  // Some attributes expect solely a type parameter.
275263508Sdim  if (attributeIsTypeArgAttr(*AttrName)) {
276263508Sdim    ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc);
277263508Sdim    return;
278263508Sdim  }
279226633Sdim
280263508Sdim  // Ignore the left paren location for now.
281263508Sdim  ConsumeParen();
282226633Sdim
283263508Sdim  ArgsVector ArgExprs;
284226633Sdim
285263508Sdim  if (Tok.is(tok::identifier)) {
286263508Sdim    // If this attribute wants an 'identifier' argument, make it so.
287263508Sdim    bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName);
288249423Sdim
289263508Sdim    // If we don't know how to parse this attribute, but this is the only
290263508Sdim    // token in this argument, assume it's meant to be an identifier.
291263508Sdim    if (AttrKind == AttributeList::UnknownAttribute ||
292263508Sdim        AttrKind == AttributeList::IgnoredAttribute) {
293263508Sdim      const Token &Next = NextToken();
294263508Sdim      IsIdentifierArg = Next.is(tok::r_paren) || Next.is(tok::comma);
295249423Sdim    }
296234353Sdim
297263508Sdim    if (IsIdentifierArg)
298263508Sdim      ArgExprs.push_back(ParseIdentifierLoc());
299234353Sdim  }
300234353Sdim
301263508Sdim  if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
302234353Sdim    // Eat the comma.
303263508Sdim    if (!ArgExprs.empty())
304226633Sdim      ConsumeToken();
305226633Sdim
306234353Sdim    // Parse the non-empty comma-separated list of expressions.
307234353Sdim    while (1) {
308234353Sdim      ExprResult ArgExpr(ParseAssignmentExpression());
309234353Sdim      if (ArgExpr.isInvalid()) {
310263508Sdim        SkipUntil(tok::r_paren, StopAtSemi);
311234353Sdim        return;
312226633Sdim      }
313234353Sdim      ArgExprs.push_back(ArgExpr.release());
314234353Sdim      if (Tok.isNot(tok::comma))
315234353Sdim        break;
316234353Sdim      ConsumeToken(); // Eat the comma, move to the next argument
317226633Sdim    }
318234353Sdim  }
319234353Sdim
320234353Sdim  SourceLocation RParen = Tok.getLocation();
321263508Sdim  if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
322243830Sdim    SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
323263508Sdim    Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
324263508Sdim                 ArgExprs.data(), ArgExprs.size(), Syntax);
325234353Sdim  }
326226633Sdim}
327226633Sdim
328239462Sdim/// \brief Parses a single argument for a declspec, including the
329239462Sdim/// surrounding parens.
330239462Sdimvoid Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
331239462Sdim                                                 SourceLocation AttrNameLoc,
332239462Sdim                                                 ParsedAttributes &Attrs)
333239462Sdim{
334239462Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
335239462Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after,
336239462Sdim                         AttrName->getNameStart(), tok::r_paren))
337239462Sdim    return;
338226633Sdim
339239462Sdim  ExprResult ArgExpr(ParseConstantExpression());
340239462Sdim  if (ArgExpr.isInvalid()) {
341239462Sdim    T.skipToEnd();
342239462Sdim    return;
343239462Sdim  }
344263508Sdim  ArgsUnion ExprList = ArgExpr.take();
345263508Sdim  Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, &ExprList, 1,
346263508Sdim               AttributeList::AS_Declspec);
347239462Sdim
348239462Sdim  T.consumeClose();
349239462Sdim}
350239462Sdim
351239462Sdim/// \brief Determines whether a declspec is a "simple" one requiring no
352239462Sdim/// arguments.
353239462Sdimbool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) {
354239462Sdim  return llvm::StringSwitch<bool>(Ident->getName())
355239462Sdim    .Case("dllimport", true)
356239462Sdim    .Case("dllexport", true)
357239462Sdim    .Case("noreturn", true)
358239462Sdim    .Case("nothrow", true)
359239462Sdim    .Case("noinline", true)
360239462Sdim    .Case("naked", true)
361239462Sdim    .Case("appdomain", true)
362239462Sdim    .Case("process", true)
363239462Sdim    .Case("jitintrinsic", true)
364239462Sdim    .Case("noalias", true)
365239462Sdim    .Case("restrict", true)
366239462Sdim    .Case("novtable", true)
367239462Sdim    .Case("selectany", true)
368239462Sdim    .Case("thread", true)
369251662Sdim    .Case("safebuffers", true )
370239462Sdim    .Default(false);
371239462Sdim}
372239462Sdim
373239462Sdim/// \brief Attempts to parse a declspec which is not simple (one that takes
374239462Sdim/// parameters).  Will return false if we properly handled the declspec, or
375239462Sdim/// true if it is an unknown declspec.
376239462Sdimvoid Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
377239462Sdim                                           SourceLocation Loc,
378239462Sdim                                           ParsedAttributes &Attrs) {
379239462Sdim  // Try to handle the easy case first -- these declspecs all take a single
380239462Sdim  // parameter as their argument.
381239462Sdim  if (llvm::StringSwitch<bool>(Ident->getName())
382239462Sdim      .Case("uuid", true)
383239462Sdim      .Case("align", true)
384239462Sdim      .Case("allocate", true)
385239462Sdim      .Default(false)) {
386239462Sdim    ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
387239462Sdim  } else if (Ident->getName() == "deprecated") {
388239462Sdim    // The deprecated declspec has an optional single argument, so we will
389239462Sdim    // check for a l-paren to decide whether we should parse an argument or
390239462Sdim    // not.
391239462Sdim    if (Tok.getKind() == tok::l_paren)
392239462Sdim      ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
393239462Sdim    else
394263508Sdim      Attrs.addNew(Ident, Loc, 0, Loc, 0, 0, AttributeList::AS_Declspec);
395239462Sdim  } else if (Ident->getName() == "property") {
396239462Sdim    // The property declspec is more complex in that it can take one or two
397239462Sdim    // assignment expressions as a parameter, but the lhs of the assignment
398239462Sdim    // must be named get or put.
399251662Sdim    if (Tok.isNot(tok::l_paren)) {
400251662Sdim      Diag(Tok.getLocation(), diag::err_expected_lparen_after)
401251662Sdim        << Ident->getNameStart();
402251662Sdim      return;
403251662Sdim    }
404239462Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
405251662Sdim    T.expectAndConsume(diag::err_expected_lparen_after,
406251662Sdim                       Ident->getNameStart(), tok::r_paren);
407251662Sdim
408251662Sdim    enum AccessorKind {
409251662Sdim      AK_Invalid = -1,
410251662Sdim      AK_Put = 0, AK_Get = 1 // indices into AccessorNames
411251662Sdim    };
412251662Sdim    IdentifierInfo *AccessorNames[] = { 0, 0 };
413251662Sdim    bool HasInvalidAccessor = false;
414251662Sdim
415251662Sdim    // Parse the accessor specifications.
416251662Sdim    while (true) {
417251662Sdim      // Stop if this doesn't look like an accessor spec.
418251662Sdim      if (!Tok.is(tok::identifier)) {
419251662Sdim        // If the user wrote a completely empty list, use a special diagnostic.
420251662Sdim        if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
421251662Sdim            AccessorNames[AK_Put] == 0 && AccessorNames[AK_Get] == 0) {
422251662Sdim          Diag(Loc, diag::err_ms_property_no_getter_or_putter);
423251662Sdim          break;
424251662Sdim        }
425251662Sdim
426251662Sdim        Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
427251662Sdim        break;
428251662Sdim      }
429251662Sdim
430251662Sdim      AccessorKind Kind;
431251662Sdim      SourceLocation KindLoc = Tok.getLocation();
432251662Sdim      StringRef KindStr = Tok.getIdentifierInfo()->getName();
433251662Sdim      if (KindStr == "get") {
434251662Sdim        Kind = AK_Get;
435251662Sdim      } else if (KindStr == "put") {
436251662Sdim        Kind = AK_Put;
437251662Sdim
438251662Sdim      // Recover from the common mistake of using 'set' instead of 'put'.
439251662Sdim      } else if (KindStr == "set") {
440251662Sdim        Diag(KindLoc, diag::err_ms_property_has_set_accessor)
441251662Sdim          << FixItHint::CreateReplacement(KindLoc, "put");
442251662Sdim        Kind = AK_Put;
443251662Sdim
444251662Sdim      // Handle the mistake of forgetting the accessor kind by skipping
445251662Sdim      // this accessor.
446251662Sdim      } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) {
447251662Sdim        Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
448251662Sdim        ConsumeToken();
449251662Sdim        HasInvalidAccessor = true;
450251662Sdim        goto next_property_accessor;
451251662Sdim
452251662Sdim      // Otherwise, complain about the unknown accessor kind.
453251662Sdim      } else {
454251662Sdim        Diag(KindLoc, diag::err_ms_property_unknown_accessor);
455251662Sdim        HasInvalidAccessor = true;
456251662Sdim        Kind = AK_Invalid;
457251662Sdim
458251662Sdim        // Try to keep parsing unless it doesn't look like an accessor spec.
459251662Sdim        if (!NextToken().is(tok::equal)) break;
460251662Sdim      }
461251662Sdim
462251662Sdim      // Consume the identifier.
463251662Sdim      ConsumeToken();
464251662Sdim
465251662Sdim      // Consume the '='.
466251662Sdim      if (Tok.is(tok::equal)) {
467251662Sdim        ConsumeToken();
468251662Sdim      } else {
469251662Sdim        Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
470251662Sdim          << KindStr;
471251662Sdim        break;
472251662Sdim      }
473251662Sdim
474251662Sdim      // Expect the method name.
475251662Sdim      if (!Tok.is(tok::identifier)) {
476251662Sdim        Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
477251662Sdim        break;
478251662Sdim      }
479251662Sdim
480251662Sdim      if (Kind == AK_Invalid) {
481251662Sdim        // Just drop invalid accessors.
482251662Sdim      } else if (AccessorNames[Kind] != NULL) {
483251662Sdim        // Complain about the repeated accessor, ignore it, and keep parsing.
484251662Sdim        Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
485251662Sdim      } else {
486251662Sdim        AccessorNames[Kind] = Tok.getIdentifierInfo();
487251662Sdim      }
488251662Sdim      ConsumeToken();
489251662Sdim
490251662Sdim    next_property_accessor:
491251662Sdim      // Keep processing accessors until we run out.
492251662Sdim      if (Tok.is(tok::comma)) {
493251662Sdim        ConsumeAnyToken();
494251662Sdim        continue;
495251662Sdim
496251662Sdim      // If we run into the ')', stop without consuming it.
497251662Sdim      } else if (Tok.is(tok::r_paren)) {
498251662Sdim        break;
499251662Sdim      } else {
500251662Sdim        Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
501251662Sdim        break;
502251662Sdim      }
503251662Sdim    }
504251662Sdim
505251662Sdim    // Only add the property attribute if it was well-formed.
506251662Sdim    if (!HasInvalidAccessor) {
507263508Sdim      Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(),
508251662Sdim                               AccessorNames[AK_Get], AccessorNames[AK_Put],
509251662Sdim                               AttributeList::AS_Declspec);
510251662Sdim    }
511239462Sdim    T.skipToEnd();
512239462Sdim  } else {
513239462Sdim    // We don't recognize this as a valid declspec, but instead of creating the
514239462Sdim    // attribute and allowing sema to warn about it, we will warn here instead.
515239462Sdim    // This is because some attributes have multiple spellings, but we need to
516239462Sdim    // disallow that for declspecs (such as align vs aligned).  If we made the
517239462Sdim    // attribute, we'd have to split the valid declspec spelling logic into
518239462Sdim    // both locations.
519239462Sdim    Diag(Loc, diag::warn_ms_declspec_unknown) << Ident;
520239462Sdim
521239462Sdim    // If there's an open paren, we should eat the open and close parens under
522239462Sdim    // the assumption that this unknown declspec has parameters.
523239462Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
524239462Sdim    if (!T.consumeOpen())
525239462Sdim      T.skipToEnd();
526239462Sdim  }
527239462Sdim}
528239462Sdim
529193725Sed/// [MS] decl-specifier:
530193725Sed///             __declspec ( extended-decl-modifier-seq )
531193725Sed///
532193725Sed/// [MS] extended-decl-modifier-seq:
533193725Sed///             extended-decl-modifier[opt]
534193725Sed///             extended-decl-modifier extended-decl-modifier-seq
535239462Sdimvoid Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
536193326Sed  assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
537193725Sed
538193326Sed  ConsumeToken();
539239462Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
540239462Sdim  if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
541239462Sdim                         tok::r_paren))
542218893Sdim    return;
543223017Sdim
544239462Sdim  // An empty declspec is perfectly legal and should not warn.  Additionally,
545239462Sdim  // you can specify multiple attributes per declspec.
546239462Sdim  while (Tok.getKind() != tok::r_paren) {
547239462Sdim    // We expect either a well-known identifier or a generic string.  Anything
548239462Sdim    // else is a malformed declspec.
549239462Sdim    bool IsString = Tok.getKind() == tok::string_literal ? true : false;
550239462Sdim    if (!IsString && Tok.getKind() != tok::identifier &&
551239462Sdim        Tok.getKind() != tok::kw_restrict) {
552239462Sdim      Diag(Tok, diag::err_ms_declspec_type);
553239462Sdim      T.skipToEnd();
554239462Sdim      return;
555223017Sdim    }
556239462Sdim
557239462Sdim    IdentifierInfo *AttrName;
558239462Sdim    SourceLocation AttrNameLoc;
559239462Sdim    if (IsString) {
560239462Sdim      SmallString<8> StrBuffer;
561239462Sdim      bool Invalid = false;
562239462Sdim      StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
563239462Sdim      if (Invalid) {
564239462Sdim        T.skipToEnd();
565239462Sdim        return;
566193725Sed      }
567239462Sdim      AttrName = PP.getIdentifierInfo(Str);
568239462Sdim      AttrNameLoc = ConsumeStringToken();
569193725Sed    } else {
570239462Sdim      AttrName = Tok.getIdentifierInfo();
571239462Sdim      AttrNameLoc = ConsumeToken();
572193725Sed    }
573239462Sdim
574239462Sdim    if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
575239462Sdim      // If we have a generic string, we will allow it because there is no
576239462Sdim      // documented list of allowable string declspecs, but we know they exist
577239462Sdim      // (for instance, SAL declspecs in older versions of MSVC).
578239462Sdim      //
579239462Sdim      // Alternatively, if the identifier is a simple one, then it requires no
580239462Sdim      // arguments and can be turned into an attribute directly.
581263508Sdim      Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
582263508Sdim                   AttributeList::AS_Declspec);
583239462Sdim    else
584239462Sdim      ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
585193725Sed  }
586239462Sdim  T.consumeClose();
587193326Sed}
588193326Sed
589218893Sdimvoid Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
590194179Sed  // Treat these like attributes
591194179Sed  while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
592208600Srdivacky         Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl)   ||
593226633Sdim         Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
594263508Sdim         Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned) ||
595263508Sdim         Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) {
596194179Sed    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
597194179Sed    SourceLocation AttrNameLoc = ConsumeToken();
598263508Sdim    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
599263508Sdim                 AttributeList::AS_Keyword);
600194179Sed  }
601194179Sed}
602194179Sed
603218893Sdimvoid Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
604212904Sdim  // Treat these like attributes
605212904Sdim  while (Tok.is(tok::kw___pascal)) {
606212904Sdim    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
607212904Sdim    SourceLocation AttrNameLoc = ConsumeToken();
608263508Sdim    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
609263508Sdim                 AttributeList::AS_Keyword);
610212904Sdim  }
611212904Sdim}
612212904Sdim
613218893Sdimvoid Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
614218893Sdim  // Treat these like attributes
615218893Sdim  while (Tok.is(tok::kw___kernel)) {
616249423Sdim    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
617218893Sdim    SourceLocation AttrNameLoc = ConsumeToken();
618263508Sdim    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
619263508Sdim                 AttributeList::AS_Keyword);
620218893Sdim  }
621218893Sdim}
622218893Sdim
623221345Sdimvoid Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
624249423Sdim  // FIXME: The mapping from attribute spelling to semantics should be
625249423Sdim  //        performed in Sema, not here.
626221345Sdim  SourceLocation Loc = Tok.getLocation();
627221345Sdim  switch(Tok.getKind()) {
628221345Sdim    // OpenCL qualifiers:
629221345Sdim    case tok::kw___private:
630239462Sdim    case tok::kw_private:
631221345Sdim      DS.getAttributes().addNewInteger(
632239462Sdim          Actions.getASTContext(),
633221345Sdim          PP.getIdentifierInfo("address_space"), Loc, 0);
634221345Sdim      break;
635239462Sdim
636221345Sdim    case tok::kw___global:
637221345Sdim      DS.getAttributes().addNewInteger(
638221345Sdim          Actions.getASTContext(),
639221345Sdim          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
640221345Sdim      break;
641239462Sdim
642221345Sdim    case tok::kw___local:
643221345Sdim      DS.getAttributes().addNewInteger(
644221345Sdim          Actions.getASTContext(),
645221345Sdim          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
646221345Sdim      break;
647239462Sdim
648221345Sdim    case tok::kw___constant:
649221345Sdim      DS.getAttributes().addNewInteger(
650221345Sdim          Actions.getASTContext(),
651221345Sdim          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
652221345Sdim      break;
653239462Sdim
654221345Sdim    case tok::kw___read_only:
655221345Sdim      DS.getAttributes().addNewInteger(
656239462Sdim          Actions.getASTContext(),
657221345Sdim          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
658221345Sdim      break;
659239462Sdim
660221345Sdim    case tok::kw___write_only:
661221345Sdim      DS.getAttributes().addNewInteger(
662239462Sdim          Actions.getASTContext(),
663221345Sdim          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
664221345Sdim      break;
665239462Sdim
666221345Sdim    case tok::kw___read_write:
667221345Sdim      DS.getAttributes().addNewInteger(
668221345Sdim          Actions.getASTContext(),
669221345Sdim          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
670221345Sdim      break;
671221345Sdim    default: break;
672221345Sdim  }
673221345Sdim}
674221345Sdim
675221345Sdim/// \brief Parse a version number.
676221345Sdim///
677221345Sdim/// version:
678221345Sdim///   simple-integer
679221345Sdim///   simple-integer ',' simple-integer
680221345Sdim///   simple-integer ',' simple-integer ',' simple-integer
681221345SdimVersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
682221345Sdim  Range = Tok.getLocation();
683221345Sdim
684221345Sdim  if (!Tok.is(tok::numeric_constant)) {
685221345Sdim    Diag(Tok, diag::err_expected_version);
686263508Sdim    SkipUntil(tok::comma, tok::r_paren,
687263508Sdim              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
688221345Sdim    return VersionTuple();
689221345Sdim  }
690221345Sdim
691221345Sdim  // Parse the major (and possibly minor and subminor) versions, which
692221345Sdim  // are stored in the numeric constant. We utilize a quirk of the
693221345Sdim  // lexer, which is that it handles something like 1.2.3 as a single
694221345Sdim  // numeric constant, rather than two separate tokens.
695234353Sdim  SmallString<512> Buffer;
696221345Sdim  Buffer.resize(Tok.getLength()+1);
697221345Sdim  const char *ThisTokBegin = &Buffer[0];
698221345Sdim
699221345Sdim  // Get the spelling of the token, which eliminates trigraphs, etc.
700221345Sdim  bool Invalid = false;
701221345Sdim  unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
702221345Sdim  if (Invalid)
703221345Sdim    return VersionTuple();
704221345Sdim
705221345Sdim  // Parse the major version.
706221345Sdim  unsigned AfterMajor = 0;
707221345Sdim  unsigned Major = 0;
708249423Sdim  while (AfterMajor < ActualLength && isDigit(ThisTokBegin[AfterMajor])) {
709221345Sdim    Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';
710221345Sdim    ++AfterMajor;
711221345Sdim  }
712221345Sdim
713221345Sdim  if (AfterMajor == 0) {
714221345Sdim    Diag(Tok, diag::err_expected_version);
715263508Sdim    SkipUntil(tok::comma, tok::r_paren,
716263508Sdim              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
717221345Sdim    return VersionTuple();
718221345Sdim  }
719221345Sdim
720221345Sdim  if (AfterMajor == ActualLength) {
721221345Sdim    ConsumeToken();
722221345Sdim
723221345Sdim    // We only had a single version component.
724221345Sdim    if (Major == 0) {
725221345Sdim      Diag(Tok, diag::err_zero_version);
726221345Sdim      return VersionTuple();
727221345Sdim    }
728221345Sdim
729221345Sdim    return VersionTuple(Major);
730221345Sdim  }
731221345Sdim
732221345Sdim  if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) {
733221345Sdim    Diag(Tok, diag::err_expected_version);
734263508Sdim    SkipUntil(tok::comma, tok::r_paren,
735263508Sdim              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
736221345Sdim    return VersionTuple();
737221345Sdim  }
738221345Sdim
739221345Sdim  // Parse the minor version.
740221345Sdim  unsigned AfterMinor = AfterMajor + 1;
741221345Sdim  unsigned Minor = 0;
742249423Sdim  while (AfterMinor < ActualLength && isDigit(ThisTokBegin[AfterMinor])) {
743221345Sdim    Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';
744221345Sdim    ++AfterMinor;
745221345Sdim  }
746221345Sdim
747221345Sdim  if (AfterMinor == ActualLength) {
748221345Sdim    ConsumeToken();
749239462Sdim
750221345Sdim    // We had major.minor.
751221345Sdim    if (Major == 0 && Minor == 0) {
752221345Sdim      Diag(Tok, diag::err_zero_version);
753221345Sdim      return VersionTuple();
754221345Sdim    }
755221345Sdim
756239462Sdim    return VersionTuple(Major, Minor);
757221345Sdim  }
758221345Sdim
759221345Sdim  // If what follows is not a '.', we have a problem.
760221345Sdim  if (ThisTokBegin[AfterMinor] != '.') {
761221345Sdim    Diag(Tok, diag::err_expected_version);
762263508Sdim    SkipUntil(tok::comma, tok::r_paren,
763263508Sdim              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
764239462Sdim    return VersionTuple();
765221345Sdim  }
766221345Sdim
767221345Sdim  // Parse the subminor version.
768221345Sdim  unsigned AfterSubminor = AfterMinor + 1;
769221345Sdim  unsigned Subminor = 0;
770249423Sdim  while (AfterSubminor < ActualLength && isDigit(ThisTokBegin[AfterSubminor])) {
771221345Sdim    Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';
772221345Sdim    ++AfterSubminor;
773221345Sdim  }
774221345Sdim
775221345Sdim  if (AfterSubminor != ActualLength) {
776221345Sdim    Diag(Tok, diag::err_expected_version);
777263508Sdim    SkipUntil(tok::comma, tok::r_paren,
778263508Sdim              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
779221345Sdim    return VersionTuple();
780221345Sdim  }
781221345Sdim  ConsumeToken();
782221345Sdim  return VersionTuple(Major, Minor, Subminor);
783221345Sdim}
784221345Sdim
785221345Sdim/// \brief Parse the contents of the "availability" attribute.
786221345Sdim///
787221345Sdim/// availability-attribute:
788234353Sdim///   'availability' '(' platform ',' version-arg-list, opt-message')'
789221345Sdim///
790221345Sdim/// platform:
791221345Sdim///   identifier
792221345Sdim///
793221345Sdim/// version-arg-list:
794221345Sdim///   version-arg
795221345Sdim///   version-arg ',' version-arg-list
796221345Sdim///
797221345Sdim/// version-arg:
798221345Sdim///   'introduced' '=' version
799221345Sdim///   'deprecated' '=' version
800234353Sdim///   'obsoleted' = version
801221345Sdim///   'unavailable'
802234353Sdim/// opt-message:
803234353Sdim///   'message' '=' <string>
804221345Sdimvoid Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
805221345Sdim                                        SourceLocation AvailabilityLoc,
806221345Sdim                                        ParsedAttributes &attrs,
807221345Sdim                                        SourceLocation *endLoc) {
808221345Sdim  enum { Introduced, Deprecated, Obsoleted, Unknown };
809221345Sdim  AvailabilityChange Changes[Unknown];
810234353Sdim  ExprResult MessageExpr;
811221345Sdim
812221345Sdim  // Opening '('.
813226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
814226633Sdim  if (T.consumeOpen()) {
815221345Sdim    Diag(Tok, diag::err_expected_lparen);
816221345Sdim    return;
817221345Sdim  }
818221345Sdim
819221345Sdim  // Parse the platform name,
820221345Sdim  if (Tok.isNot(tok::identifier)) {
821221345Sdim    Diag(Tok, diag::err_availability_expected_platform);
822263508Sdim    SkipUntil(tok::r_paren, StopAtSemi);
823221345Sdim    return;
824221345Sdim  }
825263508Sdim  IdentifierLoc *Platform = ParseIdentifierLoc();
826221345Sdim
827221345Sdim  // Parse the ',' following the platform name.
828221345Sdim  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
829221345Sdim    return;
830221345Sdim
831221345Sdim  // If we haven't grabbed the pointers for the identifiers
832221345Sdim  // "introduced", "deprecated", and "obsoleted", do so now.
833221345Sdim  if (!Ident_introduced) {
834221345Sdim    Ident_introduced = PP.getIdentifierInfo("introduced");
835221345Sdim    Ident_deprecated = PP.getIdentifierInfo("deprecated");
836221345Sdim    Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
837221345Sdim    Ident_unavailable = PP.getIdentifierInfo("unavailable");
838234353Sdim    Ident_message = PP.getIdentifierInfo("message");
839221345Sdim  }
840221345Sdim
841221345Sdim  // Parse the set of introductions/deprecations/removals.
842221345Sdim  SourceLocation UnavailableLoc;
843221345Sdim  do {
844221345Sdim    if (Tok.isNot(tok::identifier)) {
845221345Sdim      Diag(Tok, diag::err_availability_expected_change);
846263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
847221345Sdim      return;
848221345Sdim    }
849221345Sdim    IdentifierInfo *Keyword = Tok.getIdentifierInfo();
850221345Sdim    SourceLocation KeywordLoc = ConsumeToken();
851221345Sdim
852221345Sdim    if (Keyword == Ident_unavailable) {
853221345Sdim      if (UnavailableLoc.isValid()) {
854221345Sdim        Diag(KeywordLoc, diag::err_availability_redundant)
855221345Sdim          << Keyword << SourceRange(UnavailableLoc);
856239462Sdim      }
857221345Sdim      UnavailableLoc = KeywordLoc;
858221345Sdim
859221345Sdim      if (Tok.isNot(tok::comma))
860221345Sdim        break;
861221345Sdim
862221345Sdim      ConsumeToken();
863221345Sdim      continue;
864239462Sdim    }
865239462Sdim
866221345Sdim    if (Tok.isNot(tok::equal)) {
867221345Sdim      Diag(Tok, diag::err_expected_equal_after)
868221345Sdim        << Keyword;
869263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
870221345Sdim      return;
871221345Sdim    }
872221345Sdim    ConsumeToken();
873234353Sdim    if (Keyword == Ident_message) {
874263508Sdim      if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals.
875249423Sdim        Diag(Tok, diag::err_expected_string_literal)
876249423Sdim          << /*Source='availability attribute'*/2;
877263508Sdim        SkipUntil(tok::r_paren, StopAtSemi);
878234353Sdim        return;
879234353Sdim      }
880234353Sdim      MessageExpr = ParseStringLiteralExpression();
881234353Sdim      break;
882234353Sdim    }
883239462Sdim
884221345Sdim    SourceRange VersionRange;
885221345Sdim    VersionTuple Version = ParseVersionTuple(VersionRange);
886239462Sdim
887221345Sdim    if (Version.empty()) {
888263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
889221345Sdim      return;
890221345Sdim    }
891221345Sdim
892221345Sdim    unsigned Index;
893221345Sdim    if (Keyword == Ident_introduced)
894221345Sdim      Index = Introduced;
895221345Sdim    else if (Keyword == Ident_deprecated)
896221345Sdim      Index = Deprecated;
897221345Sdim    else if (Keyword == Ident_obsoleted)
898221345Sdim      Index = Obsoleted;
899239462Sdim    else
900221345Sdim      Index = Unknown;
901221345Sdim
902221345Sdim    if (Index < Unknown) {
903221345Sdim      if (!Changes[Index].KeywordLoc.isInvalid()) {
904221345Sdim        Diag(KeywordLoc, diag::err_availability_redundant)
905239462Sdim          << Keyword
906221345Sdim          << SourceRange(Changes[Index].KeywordLoc,
907221345Sdim                         Changes[Index].VersionRange.getEnd());
908221345Sdim      }
909221345Sdim
910221345Sdim      Changes[Index].KeywordLoc = KeywordLoc;
911221345Sdim      Changes[Index].Version = Version;
912221345Sdim      Changes[Index].VersionRange = VersionRange;
913221345Sdim    } else {
914221345Sdim      Diag(KeywordLoc, diag::err_availability_unknown_change)
915221345Sdim        << Keyword << VersionRange;
916221345Sdim    }
917221345Sdim
918221345Sdim    if (Tok.isNot(tok::comma))
919221345Sdim      break;
920221345Sdim
921221345Sdim    ConsumeToken();
922221345Sdim  } while (true);
923221345Sdim
924221345Sdim  // Closing ')'.
925226633Sdim  if (T.consumeClose())
926221345Sdim    return;
927221345Sdim
928221345Sdim  if (endLoc)
929226633Sdim    *endLoc = T.getCloseLocation();
930221345Sdim
931221345Sdim  // The 'unavailable' availability cannot be combined with any other
932221345Sdim  // availability changes. Make sure that hasn't happened.
933221345Sdim  if (UnavailableLoc.isValid()) {
934221345Sdim    bool Complained = false;
935221345Sdim    for (unsigned Index = Introduced; Index != Unknown; ++Index) {
936221345Sdim      if (Changes[Index].KeywordLoc.isValid()) {
937221345Sdim        if (!Complained) {
938221345Sdim          Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
939221345Sdim            << SourceRange(Changes[Index].KeywordLoc,
940221345Sdim                           Changes[Index].VersionRange.getEnd());
941221345Sdim          Complained = true;
942221345Sdim        }
943221345Sdim
944221345Sdim        // Clear out the availability.
945221345Sdim        Changes[Index] = AvailabilityChange();
946221345Sdim      }
947221345Sdim    }
948221345Sdim  }
949221345Sdim
950221345Sdim  // Record this attribute
951239462Sdim  attrs.addNew(&Availability,
952239462Sdim               SourceRange(AvailabilityLoc, T.getCloseLocation()),
953234353Sdim               0, AvailabilityLoc,
954263508Sdim               Platform,
955221345Sdim               Changes[Introduced],
956221345Sdim               Changes[Deprecated],
957239462Sdim               Changes[Obsoleted],
958234353Sdim               UnavailableLoc, MessageExpr.take(),
959239462Sdim               AttributeList::AS_GNU);
960221345Sdim}
961221345Sdim
962226633Sdim
963226633Sdim// Late Parsed Attributes:
964226633Sdim// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
965226633Sdim
966226633Sdimvoid Parser::LateParsedDeclaration::ParseLexedAttributes() {}
967226633Sdim
968226633Sdimvoid Parser::LateParsedClass::ParseLexedAttributes() {
969226633Sdim  Self->ParseLexedAttributes(*Class);
970226633Sdim}
971226633Sdim
972226633Sdimvoid Parser::LateParsedAttribute::ParseLexedAttributes() {
973234353Sdim  Self->ParseLexedAttribute(*this, true, false);
974226633Sdim}
975226633Sdim
976226633Sdim/// Wrapper class which calls ParseLexedAttribute, after setting up the
977226633Sdim/// scope appropriately.
978226633Sdimvoid Parser::ParseLexedAttributes(ParsingClass &Class) {
979226633Sdim  // Deal with templates
980226633Sdim  // FIXME: Test cases to make sure this does the right thing for templates.
981226633Sdim  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
982226633Sdim  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
983226633Sdim                                HasTemplateScope);
984226633Sdim  if (HasTemplateScope)
985226633Sdim    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
986226633Sdim
987234982Sdim  // Set or update the scope flags.
988226633Sdim  bool AlreadyHasClassScope = Class.TopLevelClass;
989234982Sdim  unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
990226633Sdim  ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
991226633Sdim  ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
992226633Sdim
993234353Sdim  // Enter the scope of nested classes
994234353Sdim  if (!AlreadyHasClassScope)
995234353Sdim    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
996234353Sdim                                                Class.TagOrTemplate);
997239462Sdim  if (!Class.LateParsedDeclarations.empty()) {
998234982Sdim    for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
999234982Sdim      Class.LateParsedDeclarations[i]->ParseLexedAttributes();
1000234982Sdim    }
1001226633Sdim  }
1002239462Sdim
1003234353Sdim  if (!AlreadyHasClassScope)
1004234353Sdim    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
1005234353Sdim                                                 Class.TagOrTemplate);
1006226633Sdim}
1007226633Sdim
1008234353Sdim
1009234353Sdim/// \brief Parse all attributes in LAs, and attach them to Decl D.
1010234353Sdimvoid Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
1011234353Sdim                                     bool EnterScope, bool OnDefinition) {
1012243830Sdim  assert(LAs.parseSoon() &&
1013243830Sdim         "Attribute list should be marked for immediate parsing.");
1014234353Sdim  for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
1015239462Sdim    if (D)
1016239462Sdim      LAs[i]->addDecl(D);
1017234353Sdim    ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
1018234982Sdim    delete LAs[i];
1019234353Sdim  }
1020234353Sdim  LAs.clear();
1021234353Sdim}
1022234353Sdim
1023234353Sdim
1024226633Sdim/// \brief Finish parsing an attribute for which parsing was delayed.
1025226633Sdim/// This will be called at the end of parsing a class declaration
1026226633Sdim/// for each LateParsedAttribute. We consume the saved tokens and
1027239462Sdim/// create an attribute with the arguments filled in. We add this
1028226633Sdim/// to the Attribute list for the decl.
1029234353Sdimvoid Parser::ParseLexedAttribute(LateParsedAttribute &LA,
1030234353Sdim                                 bool EnterScope, bool OnDefinition) {
1031226633Sdim  // Save the current token position.
1032226633Sdim  SourceLocation OrigLoc = Tok.getLocation();
1033226633Sdim
1034226633Sdim  // Append the current token at the end of the new token stream so that it
1035226633Sdim  // doesn't get lost.
1036226633Sdim  LA.Toks.push_back(Tok);
1037226633Sdim  PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
1038226633Sdim  // Consume the previously pushed token.
1039249423Sdim  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1040226633Sdim
1041234353Sdim  if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
1042249423Sdim    // FIXME: Do not warn on C++11 attributes, once we start supporting
1043249423Sdim    // them here.
1044234353Sdim    Diag(Tok, diag::warn_attribute_on_function_definition)
1045234353Sdim      << LA.AttrName.getName();
1046234353Sdim  }
1047234353Sdim
1048226633Sdim  ParsedAttributes Attrs(AttrFactory);
1049226633Sdim  SourceLocation endLoc;
1050226633Sdim
1051243830Sdim  if (LA.Decls.size() > 0) {
1052234353Sdim    Decl *D = LA.Decls[0];
1053243830Sdim    NamedDecl *ND  = dyn_cast<NamedDecl>(D);
1054243830Sdim    RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
1055226633Sdim
1056243830Sdim    // Allow 'this' within late-parsed attributes.
1057263508Sdim    Sema::CXXThisScopeRAII ThisScope(Actions, RD, /*TypeQuals=*/0,
1058263508Sdim                                     ND && ND->isCXXInstanceMember());
1059226633Sdim
1060243830Sdim    if (LA.Decls.size() == 1) {
1061243830Sdim      // If the Decl is templatized, add template parameters to scope.
1062243830Sdim      bool HasTemplateScope = EnterScope && D->isTemplateDecl();
1063243830Sdim      ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
1064243830Sdim      if (HasTemplateScope)
1065243830Sdim        Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
1066226633Sdim
1067243830Sdim      // If the Decl is on a function, add function parameters to the scope.
1068243830Sdim      bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
1069243830Sdim      ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope);
1070243830Sdim      if (HasFunScope)
1071243830Sdim        Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
1072234353Sdim
1073243830Sdim      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1074243830Sdim                            0, SourceLocation(), AttributeList::AS_GNU);
1075243830Sdim
1076243830Sdim      if (HasFunScope) {
1077243830Sdim        Actions.ActOnExitFunctionContext();
1078243830Sdim        FnScope.Exit();  // Pop scope, and remove Decls from IdResolver
1079243830Sdim      }
1080243830Sdim      if (HasTemplateScope) {
1081243830Sdim        TempScope.Exit();
1082243830Sdim      }
1083243830Sdim    } else {
1084243830Sdim      // If there are multiple decls, then the decl cannot be within the
1085243830Sdim      // function scope.
1086243830Sdim      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1087243830Sdim                            0, SourceLocation(), AttributeList::AS_GNU);
1088234353Sdim    }
1089234353Sdim  } else {
1090234353Sdim    Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
1091226633Sdim  }
1092234353Sdim
1093234353Sdim  for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
1094234353Sdim    Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
1095226633Sdim  }
1096226633Sdim
1097226633Sdim  if (Tok.getLocation() != OrigLoc) {
1098226633Sdim    // Due to a parsing error, we either went over the cached tokens or
1099226633Sdim    // there are still cached tokens left, so we skip the leftover tokens.
1100226633Sdim    // Since this is an uncommon situation that should be avoided, use the
1101226633Sdim    // expensive isBeforeInTranslationUnit call.
1102226633Sdim    if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
1103226633Sdim                                                        OrigLoc))
1104226633Sdim    while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
1105234353Sdim      ConsumeAnyToken();
1106226633Sdim  }
1107226633Sdim}
1108226633Sdim
1109226633Sdim/// \brief Wrapper around a case statement checking if AttrName is
1110226633Sdim/// one of the thread safety attributes
1111249423Sdimbool Parser::IsThreadSafetyAttribute(StringRef AttrName) {
1112226633Sdim  return llvm::StringSwitch<bool>(AttrName)
1113226633Sdim      .Case("guarded_by", true)
1114226633Sdim      .Case("guarded_var", true)
1115226633Sdim      .Case("pt_guarded_by", true)
1116226633Sdim      .Case("pt_guarded_var", true)
1117226633Sdim      .Case("lockable", true)
1118226633Sdim      .Case("scoped_lockable", true)
1119226633Sdim      .Case("no_thread_safety_analysis", true)
1120226633Sdim      .Case("acquired_after", true)
1121226633Sdim      .Case("acquired_before", true)
1122226633Sdim      .Case("exclusive_lock_function", true)
1123226633Sdim      .Case("shared_lock_function", true)
1124226633Sdim      .Case("exclusive_trylock_function", true)
1125226633Sdim      .Case("shared_trylock_function", true)
1126226633Sdim      .Case("unlock_function", true)
1127226633Sdim      .Case("lock_returned", true)
1128226633Sdim      .Case("locks_excluded", true)
1129226633Sdim      .Case("exclusive_locks_required", true)
1130226633Sdim      .Case("shared_locks_required", true)
1131226633Sdim      .Default(false);
1132226633Sdim}
1133226633Sdim
1134226633Sdim/// \brief Parse the contents of thread safety attributes. These
1135226633Sdim/// should always be parsed as an expression list.
1136226633Sdim///
1137226633Sdim/// We need to special case the parsing due to the fact that if the first token
1138226633Sdim/// of the first argument is an identifier, the main parse loop will store
1139226633Sdim/// that token as a "parameter" and the rest of
1140226633Sdim/// the arguments will be added to a list of "arguments". However,
1141226633Sdim/// subsequent tokens in the first argument are lost. We instead parse each
1142226633Sdim/// argument as an expression and add all arguments to the list of "arguments".
1143226633Sdim/// In future, we will take advantage of this special case to also
1144226633Sdim/// deal with some argument scoping issues here (for example, referring to a
1145226633Sdim/// function parameter in the attribute on that function).
1146226633Sdimvoid Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
1147226633Sdim                                        SourceLocation AttrNameLoc,
1148226633Sdim                                        ParsedAttributes &Attrs,
1149226633Sdim                                        SourceLocation *EndLoc) {
1150226633Sdim  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1151226633Sdim
1152226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
1153226633Sdim  T.consumeOpen();
1154239462Sdim
1155263508Sdim  ArgsVector ArgExprs;
1156226633Sdim  bool ArgExprsOk = true;
1157239462Sdim
1158226633Sdim  // now parse the list of expressions
1159234353Sdim  while (Tok.isNot(tok::r_paren)) {
1160249423Sdim    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
1161226633Sdim    ExprResult ArgExpr(ParseAssignmentExpression());
1162226633Sdim    if (ArgExpr.isInvalid()) {
1163226633Sdim      ArgExprsOk = false;
1164226633Sdim      T.consumeClose();
1165226633Sdim      break;
1166226633Sdim    } else {
1167226633Sdim      ArgExprs.push_back(ArgExpr.release());
1168226633Sdim    }
1169226633Sdim    if (Tok.isNot(tok::comma))
1170226633Sdim      break;
1171226633Sdim    ConsumeToken(); // Eat the comma, move to the next argument
1172226633Sdim  }
1173226633Sdim  // Match the ')'.
1174226633Sdim  if (ArgExprsOk && !T.consumeClose()) {
1175263508Sdim    Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(),
1176263508Sdim                 ArgExprs.size(), AttributeList::AS_GNU);
1177226633Sdim  }
1178226633Sdim  if (EndLoc)
1179226633Sdim    *EndLoc = T.getCloseLocation();
1180226633Sdim}
1181226633Sdim
1182239462Sdimvoid Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
1183239462Sdim                                              SourceLocation AttrNameLoc,
1184239462Sdim                                              ParsedAttributes &Attrs,
1185239462Sdim                                              SourceLocation *EndLoc) {
1186239462Sdim  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1187239462Sdim
1188239462Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
1189239462Sdim  T.consumeOpen();
1190239462Sdim
1191239462Sdim  if (Tok.isNot(tok::identifier)) {
1192239462Sdim    Diag(Tok, diag::err_expected_ident);
1193239462Sdim    T.skipToEnd();
1194239462Sdim    return;
1195239462Sdim  }
1196263508Sdim  IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1197239462Sdim
1198239462Sdim  if (Tok.isNot(tok::comma)) {
1199239462Sdim    Diag(Tok, diag::err_expected_comma);
1200239462Sdim    T.skipToEnd();
1201239462Sdim    return;
1202239462Sdim  }
1203239462Sdim  ConsumeToken();
1204239462Sdim
1205239462Sdim  SourceRange MatchingCTypeRange;
1206239462Sdim  TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);
1207239462Sdim  if (MatchingCType.isInvalid()) {
1208239462Sdim    T.skipToEnd();
1209239462Sdim    return;
1210239462Sdim  }
1211239462Sdim
1212239462Sdim  bool LayoutCompatible = false;
1213239462Sdim  bool MustBeNull = false;
1214239462Sdim  while (Tok.is(tok::comma)) {
1215239462Sdim    ConsumeToken();
1216239462Sdim    if (Tok.isNot(tok::identifier)) {
1217239462Sdim      Diag(Tok, diag::err_expected_ident);
1218239462Sdim      T.skipToEnd();
1219239462Sdim      return;
1220239462Sdim    }
1221239462Sdim    IdentifierInfo *Flag = Tok.getIdentifierInfo();
1222239462Sdim    if (Flag->isStr("layout_compatible"))
1223239462Sdim      LayoutCompatible = true;
1224239462Sdim    else if (Flag->isStr("must_be_null"))
1225239462Sdim      MustBeNull = true;
1226239462Sdim    else {
1227239462Sdim      Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1228239462Sdim      T.skipToEnd();
1229239462Sdim      return;
1230239462Sdim    }
1231239462Sdim    ConsumeToken(); // consume flag
1232239462Sdim  }
1233239462Sdim
1234239462Sdim  if (!T.consumeClose()) {
1235239462Sdim    Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
1236263508Sdim                                   ArgumentKind, MatchingCType.release(),
1237263508Sdim                                   LayoutCompatible, MustBeNull,
1238263508Sdim                                   AttributeList::AS_GNU);
1239239462Sdim  }
1240239462Sdim
1241239462Sdim  if (EndLoc)
1242239462Sdim    *EndLoc = T.getCloseLocation();
1243239462Sdim}
1244239462Sdim
1245234353Sdim/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
1246234353Sdim/// of a C++11 attribute-specifier in a location where an attribute is not
1247234353Sdim/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
1248234353Sdim/// situation.
1249234353Sdim///
1250234353Sdim/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
1251234353Sdim/// this doesn't appear to actually be an attribute-specifier, and the caller
1252234353Sdim/// should try to parse it.
1253234353Sdimbool Parser::DiagnoseProhibitedCXX11Attribute() {
1254234353Sdim  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1255234353Sdim
1256234353Sdim  switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1257234353Sdim  case CAK_NotAttributeSpecifier:
1258234353Sdim    // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1259234353Sdim    return false;
1260234353Sdim
1261234353Sdim  case CAK_InvalidAttributeSpecifier:
1262234353Sdim    Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1263234353Sdim    return false;
1264234353Sdim
1265234353Sdim  case CAK_AttributeSpecifier:
1266234353Sdim    // Parse and discard the attributes.
1267234353Sdim    SourceLocation BeginLoc = ConsumeBracket();
1268234353Sdim    ConsumeBracket();
1269263508Sdim    SkipUntil(tok::r_square);
1270234353Sdim    assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1271234353Sdim    SourceLocation EndLoc = ConsumeBracket();
1272234353Sdim    Diag(BeginLoc, diag::err_attributes_not_allowed)
1273234353Sdim      << SourceRange(BeginLoc, EndLoc);
1274234353Sdim    return true;
1275234353Sdim  }
1276234353Sdim  llvm_unreachable("All cases handled above.");
1277234353Sdim}
1278234353Sdim
1279249423Sdim/// \brief We have found the opening square brackets of a C++11
1280249423Sdim/// attribute-specifier in a location where an attribute is not permitted, but
1281249423Sdim/// we know where the attributes ought to be written. Parse them anyway, and
1282249423Sdim/// provide a fixit moving them to the right place.
1283249423Sdimvoid Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
1284249423Sdim                                             SourceLocation CorrectLocation) {
1285249423Sdim  assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||
1286249423Sdim         Tok.is(tok::kw_alignas));
1287249423Sdim
1288249423Sdim  // Consume the attributes.
1289249423Sdim  SourceLocation Loc = Tok.getLocation();
1290249423Sdim  ParseCXX11Attributes(Attrs);
1291249423Sdim  CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true);
1292249423Sdim
1293249423Sdim  Diag(Loc, diag::err_attributes_not_allowed)
1294249423Sdim    << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
1295249423Sdim    << FixItHint::CreateRemoval(AttrRange);
1296249423Sdim}
1297249423Sdim
1298218893Sdimvoid Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1299218893Sdim  Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1300218893Sdim    << attrs.Range;
1301218893Sdim}
1302218893Sdim
1303243830Sdimvoid Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) {
1304243830Sdim  AttributeList *AttrList = attrs.getList();
1305243830Sdim  while (AttrList) {
1306249423Sdim    if (AttrList->isCXX11Attribute()) {
1307249423Sdim      Diag(AttrList->getLoc(), diag::err_attribute_not_type_attr)
1308243830Sdim        << AttrList->getName();
1309243830Sdim      AttrList->setInvalid();
1310243830Sdim    }
1311243830Sdim    AttrList = AttrList->getNext();
1312243830Sdim  }
1313243830Sdim}
1314243830Sdim
1315193326Sed/// ParseDeclaration - Parse a full 'declaration', which consists of
1316193326Sed/// declaration-specifiers, some number of declarators, and a semicolon.
1317193326Sed/// 'Context' should be a Declarator::TheContext value.  This returns the
1318193326Sed/// location of the semicolon in DeclEnd.
1319193326Sed///
1320193326Sed///       declaration: [C99 6.7]
1321193326Sed///         block-declaration ->
1322193326Sed///           simple-declaration
1323193326Sed///           others                   [FIXME]
1324193326Sed/// [C++]   template-declaration
1325193326Sed/// [C++]   namespace-definition
1326193326Sed/// [C++]   using-directive
1327194711Sed/// [C++]   using-declaration
1328234982Sdim/// [C++11/C11] static_assert-declaration
1329193326Sed///         others... [FIXME]
1330193326Sed///
1331218893SdimParser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1332218893Sdim                                                unsigned Context,
1333199990Srdivacky                                                SourceLocation &DeclEnd,
1334218893Sdim                                          ParsedAttributesWithRange &attrs) {
1335210299Sed  ParenBraceBracketBalancer BalancerRAIIObj(*this);
1336226633Sdim  // Must temporarily exit the objective-c container scope for
1337226633Sdim  // parsing c none objective-c decls.
1338226633Sdim  ObjCDeclContextSwitch ObjCDC(*this);
1339239462Sdim
1340212904Sdim  Decl *SingleDecl = 0;
1341224145Sdim  Decl *OwnedType = 0;
1342193326Sed  switch (Tok.getKind()) {
1343193326Sed  case tok::kw_template:
1344193326Sed  case tok::kw_export:
1345218893Sdim    ProhibitAttributes(attrs);
1346193326Sed    SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
1347193326Sed    break;
1348212904Sdim  case tok::kw_inline:
1349212904Sdim    // Could be the start of an inline namespace. Allowed as an ext in C++03.
1350234353Sdim    if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
1351218893Sdim      ProhibitAttributes(attrs);
1352212904Sdim      SourceLocation InlineLoc = ConsumeToken();
1353212904Sdim      SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1354212904Sdim      break;
1355212904Sdim    }
1356239462Sdim    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
1357218893Sdim                                  true);
1358193326Sed  case tok::kw_namespace:
1359218893Sdim    ProhibitAttributes(attrs);
1360193326Sed    SingleDecl = ParseNamespace(Context, DeclEnd);
1361193326Sed    break;
1362193326Sed  case tok::kw_using:
1363218893Sdim    SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1364224145Sdim                                                  DeclEnd, attrs, &OwnedType);
1365193326Sed    break;
1366193326Sed  case tok::kw_static_assert:
1367221345Sdim  case tok::kw__Static_assert:
1368218893Sdim    ProhibitAttributes(attrs);
1369193326Sed    SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1370193326Sed    break;
1371193326Sed  default:
1372218893Sdim    return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
1373193326Sed  }
1374239462Sdim
1375193326Sed  // This routine returns a DeclGroup, if the thing we parsed only contains a
1376224145Sdim  // single decl, convert it now. Alias declarations can also declare a type;
1377224145Sdim  // include that too if it is present.
1378224145Sdim  return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
1379193326Sed}
1380193326Sed
1381193326Sed///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
1382193326Sed///         declaration-specifiers init-declarator-list[opt] ';'
1383239462Sdim/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1384239462Sdim///             init-declarator-list ';'
1385193326Sed///[C90/C++]init-declarator-list ';'                             [TODO]
1386193326Sed/// [OMP]   threadprivate-directive                              [TODO]
1387193326Sed///
1388239462Sdim///       for-range-declaration: [C++11 6.5p1: stmt.ranged]
1389221345Sdim///         attribute-specifier-seq[opt] type-specifier-seq declarator
1390221345Sdim///
1391193326Sed/// If RequireSemi is false, this does not check for a ';' at the end of the
1392206275Srdivacky/// declaration.  If it is true, it checks for and eats it.
1393221345Sdim///
1394221345Sdim/// If FRI is non-null, we might be parsing a for-range-declaration instead
1395221345Sdim/// of a simple-declaration. If we find that we are, we also parse the
1396221345Sdim/// for-range-initializer, and place it here.
1397239462SdimParser::DeclGroupPtrTy
1398239462SdimParser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1399239462Sdim                               SourceLocation &DeclEnd,
1400249423Sdim                               ParsedAttributesWithRange &Attrs,
1401239462Sdim                               bool RequireSemi, ForRangeInit *FRI) {
1402193326Sed  // Parse the common declaration-specifiers piece.
1403198893Srdivacky  ParsingDeclSpec DS(*this);
1404221345Sdim
1405263508Sdim  DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1406263508Sdim  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext);
1407234353Sdim
1408263508Sdim  // If we had a free-standing type definition with a missing semicolon, we
1409263508Sdim  // may get this far before the problem becomes obvious.
1410263508Sdim  if (DS.hasTagDefinition() &&
1411263508Sdim      DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext))
1412263508Sdim    return DeclGroupPtrTy();
1413263508Sdim
1414193326Sed  // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1415193326Sed  // declaration-specifiers init-declarator-list[opt] ';'
1416193326Sed  if (Tok.is(tok::semi)) {
1417249423Sdim    ProhibitAttributes(Attrs);
1418239462Sdim    DeclEnd = Tok.getLocation();
1419206275Srdivacky    if (RequireSemi) ConsumeToken();
1420212904Sdim    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
1421221345Sdim                                                       DS);
1422198893Srdivacky    DS.complete(TheDecl);
1423193326Sed    return Actions.ConvertDeclToDeclGroup(TheDecl);
1424193326Sed  }
1425239462Sdim
1426249423Sdim  DS.takeAttributesFrom(Attrs);
1427239462Sdim  return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
1428198893Srdivacky}
1429198092Srdivacky
1430234353Sdim/// Returns true if this might be the start of a declarator, or a common typo
1431234353Sdim/// for a declarator.
1432234353Sdimbool Parser::MightBeDeclarator(unsigned Context) {
1433234353Sdim  switch (Tok.getKind()) {
1434234353Sdim  case tok::annot_cxxscope:
1435234353Sdim  case tok::annot_template_id:
1436234353Sdim  case tok::caret:
1437234353Sdim  case tok::code_completion:
1438234353Sdim  case tok::coloncolon:
1439234353Sdim  case tok::ellipsis:
1440234353Sdim  case tok::kw___attribute:
1441234353Sdim  case tok::kw_operator:
1442234353Sdim  case tok::l_paren:
1443234353Sdim  case tok::star:
1444234353Sdim    return true;
1445234353Sdim
1446234353Sdim  case tok::amp:
1447234353Sdim  case tok::ampamp:
1448234353Sdim    return getLangOpts().CPlusPlus;
1449234353Sdim
1450234353Sdim  case tok::l_square: // Might be an attribute on an unnamed bit-field.
1451249423Sdim    return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 &&
1452234353Sdim           NextToken().is(tok::l_square);
1453234353Sdim
1454234353Sdim  case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
1455234353Sdim    return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
1456234353Sdim
1457234353Sdim  case tok::identifier:
1458234353Sdim    switch (NextToken().getKind()) {
1459234353Sdim    case tok::code_completion:
1460234353Sdim    case tok::coloncolon:
1461234353Sdim    case tok::comma:
1462234353Sdim    case tok::equal:
1463234353Sdim    case tok::equalequal: // Might be a typo for '='.
1464234353Sdim    case tok::kw_alignas:
1465234353Sdim    case tok::kw_asm:
1466234353Sdim    case tok::kw___attribute:
1467234353Sdim    case tok::l_brace:
1468234353Sdim    case tok::l_paren:
1469234353Sdim    case tok::l_square:
1470234353Sdim    case tok::less:
1471234353Sdim    case tok::r_brace:
1472234353Sdim    case tok::r_paren:
1473234353Sdim    case tok::r_square:
1474234353Sdim    case tok::semi:
1475234353Sdim      return true;
1476234353Sdim
1477234353Sdim    case tok::colon:
1478234353Sdim      // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
1479234353Sdim      // and in block scope it's probably a label. Inside a class definition,
1480234353Sdim      // this is a bit-field.
1481234353Sdim      return Context == Declarator::MemberContext ||
1482234353Sdim             (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
1483234353Sdim
1484234353Sdim    case tok::identifier: // Possible virt-specifier.
1485249423Sdim      return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken());
1486234353Sdim
1487234353Sdim    default:
1488234353Sdim      return false;
1489234353Sdim    }
1490234353Sdim
1491234353Sdim  default:
1492234353Sdim    return false;
1493234353Sdim  }
1494234353Sdim}
1495234353Sdim
1496234353Sdim/// Skip until we reach something which seems like a sensible place to pick
1497234353Sdim/// up parsing after a malformed declaration. This will sometimes stop sooner
1498234353Sdim/// than SkipUntil(tok::r_brace) would, but will never stop later.
1499234353Sdimvoid Parser::SkipMalformedDecl() {
1500234353Sdim  while (true) {
1501234353Sdim    switch (Tok.getKind()) {
1502234353Sdim    case tok::l_brace:
1503234353Sdim      // Skip until matching }, then stop. We've probably skipped over
1504234353Sdim      // a malformed class or function definition or similar.
1505234353Sdim      ConsumeBrace();
1506263508Sdim      SkipUntil(tok::r_brace);
1507234353Sdim      if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
1508234353Sdim        // This declaration isn't over yet. Keep skipping.
1509234353Sdim        continue;
1510234353Sdim      }
1511234353Sdim      if (Tok.is(tok::semi))
1512234353Sdim        ConsumeToken();
1513234353Sdim      return;
1514234353Sdim
1515234353Sdim    case tok::l_square:
1516234353Sdim      ConsumeBracket();
1517263508Sdim      SkipUntil(tok::r_square);
1518234353Sdim      continue;
1519234353Sdim
1520234353Sdim    case tok::l_paren:
1521234353Sdim      ConsumeParen();
1522263508Sdim      SkipUntil(tok::r_paren);
1523234353Sdim      continue;
1524234353Sdim
1525234353Sdim    case tok::r_brace:
1526234353Sdim      return;
1527234353Sdim
1528234353Sdim    case tok::semi:
1529234353Sdim      ConsumeToken();
1530234353Sdim      return;
1531234353Sdim
1532234353Sdim    case tok::kw_inline:
1533234353Sdim      // 'inline namespace' at the start of a line is almost certainly
1534239462Sdim      // a good place to pick back up parsing, except in an Objective-C
1535239462Sdim      // @interface context.
1536239462Sdim      if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&
1537239462Sdim          (!ParsingInObjCContainer || CurParsedObjCImpl))
1538234353Sdim        return;
1539234353Sdim      break;
1540234353Sdim
1541234353Sdim    case tok::kw_namespace:
1542234353Sdim      // 'namespace' at the start of a line is almost certainly a good
1543239462Sdim      // place to pick back up parsing, except in an Objective-C
1544239462Sdim      // @interface context.
1545239462Sdim      if (Tok.isAtStartOfLine() &&
1546239462Sdim          (!ParsingInObjCContainer || CurParsedObjCImpl))
1547234353Sdim        return;
1548234353Sdim      break;
1549234353Sdim
1550239462Sdim    case tok::at:
1551239462Sdim      // @end is very much like } in Objective-C contexts.
1552239462Sdim      if (NextToken().isObjCAtKeyword(tok::objc_end) &&
1553239462Sdim          ParsingInObjCContainer)
1554239462Sdim        return;
1555239462Sdim      break;
1556239462Sdim
1557239462Sdim    case tok::minus:
1558239462Sdim    case tok::plus:
1559239462Sdim      // - and + probably start new method declarations in Objective-C contexts.
1560239462Sdim      if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
1561239462Sdim        return;
1562239462Sdim      break;
1563239462Sdim
1564234353Sdim    case tok::eof:
1565234353Sdim      return;
1566234353Sdim
1567234353Sdim    default:
1568234353Sdim      break;
1569234353Sdim    }
1570234353Sdim
1571234353Sdim    ConsumeAnyToken();
1572234353Sdim  }
1573234353Sdim}
1574234353Sdim
1575198893Srdivacky/// ParseDeclGroup - Having concluded that this is either a function
1576198893Srdivacky/// definition or a group of object declarations, actually parse the
1577198893Srdivacky/// result.
1578198893SrdivackyParser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1579198893Srdivacky                                              unsigned Context,
1580198893Srdivacky                                              bool AllowFunctionDefinitions,
1581221345Sdim                                              SourceLocation *DeclEnd,
1582221345Sdim                                              ForRangeInit *FRI) {
1583198893Srdivacky  // Parse the first declarator.
1584198893Srdivacky  ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
1585198893Srdivacky  ParseDeclarator(D);
1586193326Sed
1587198893Srdivacky  // Bail out if the first declarator didn't seem well-formed.
1588198893Srdivacky  if (!D.hasName() && !D.mayOmitIdentifier()) {
1589234353Sdim    SkipMalformedDecl();
1590198893Srdivacky    return DeclGroupPtrTy();
1591198893Srdivacky  }
1592198092Srdivacky
1593234353Sdim  // Save late-parsed attributes for now; they need to be parsed in the
1594234353Sdim  // appropriate function scope after the function Decl has been constructed.
1595243830Sdim  // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList.
1596243830Sdim  LateParsedAttrList LateParsedAttrs(true);
1597234353Sdim  if (D.isFunctionDeclarator())
1598234353Sdim    MaybeParseGNUAttributes(D, &LateParsedAttrs);
1599234353Sdim
1600210299Sed  // Check to see if we have a function *definition* which must have a body.
1601251662Sdim  if (D.isFunctionDeclarator() &&
1602210299Sed      // Look at the next token to make sure that this isn't a function
1603210299Sed      // declaration.  We have to check this because __attribute__ might be the
1604210299Sed      // start of a function definition in GCC-extended K&R C.
1605210299Sed      !isDeclarationAfterDeclarator()) {
1606239462Sdim
1607251662Sdim    if (AllowFunctionDefinitions) {
1608251662Sdim      if (isStartOfFunctionDefinition(D)) {
1609251662Sdim        if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
1610251662Sdim          Diag(Tok, diag::err_function_declared_typedef);
1611198092Srdivacky
1612251662Sdim          // Recover by treating the 'typedef' as spurious.
1613251662Sdim          DS.ClearStorageClassSpecs();
1614251662Sdim        }
1615251662Sdim
1616251662Sdim        Decl *TheDecl =
1617251662Sdim          ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
1618251662Sdim        return Actions.ConvertDeclToDeclGroup(TheDecl);
1619198893Srdivacky      }
1620198893Srdivacky
1621251662Sdim      if (isDeclarationSpecifier()) {
1622251662Sdim        // If there is an invalid declaration specifier right after the function
1623251662Sdim        // prototype, then we must be in a missing semicolon case where this isn't
1624251662Sdim        // actually a body.  Just fall through into the code that handles it as a
1625251662Sdim        // prototype, and let the top-level code handle the erroneous declspec
1626251662Sdim        // where it would otherwise expect a comma or semicolon.
1627251662Sdim      } else {
1628251662Sdim        Diag(Tok, diag::err_expected_fn_body);
1629251662Sdim        SkipUntil(tok::semi);
1630251662Sdim        return DeclGroupPtrTy();
1631251662Sdim      }
1632198893Srdivacky    } else {
1633251662Sdim      if (Tok.is(tok::l_brace)) {
1634251662Sdim        Diag(Tok, diag::err_function_definition_not_allowed);
1635263508Sdim        SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
1636251662Sdim      }
1637198893Srdivacky    }
1638198893Srdivacky  }
1639198893Srdivacky
1640234353Sdim  if (ParseAsmAttributesAfterDeclarator(D))
1641221345Sdim    return DeclGroupPtrTy();
1642221345Sdim
1643221345Sdim  // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
1644221345Sdim  // must parse and analyze the for-range-initializer before the declaration is
1645221345Sdim  // analyzed.
1646251662Sdim  //
1647251662Sdim  // Handle the Objective-C for-in loop variable similarly, although we
1648251662Sdim  // don't need to parse the container in advance.
1649251662Sdim  if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
1650251662Sdim    bool IsForRangeLoop = false;
1651251662Sdim    if (Tok.is(tok::colon)) {
1652251662Sdim      IsForRangeLoop = true;
1653251662Sdim      FRI->ColonLoc = ConsumeToken();
1654251662Sdim      if (Tok.is(tok::l_brace))
1655251662Sdim        FRI->RangeExpr = ParseBraceInitializer();
1656251662Sdim      else
1657251662Sdim        FRI->RangeExpr = ParseExpression();
1658251662Sdim    }
1659251662Sdim
1660221345Sdim    Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1661251662Sdim    if (IsForRangeLoop)
1662251662Sdim      Actions.ActOnCXXForRangeDecl(ThisDecl);
1663221345Sdim    Actions.FinalizeDeclaration(ThisDecl);
1664234353Sdim    D.complete(ThisDecl);
1665263508Sdim    return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl);
1666221345Sdim  }
1667221345Sdim
1668226633Sdim  SmallVector<Decl *, 8> DeclsInGroup;
1669221345Sdim  Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
1670234353Sdim  if (LateParsedAttrs.size() > 0)
1671234353Sdim    ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
1672198893Srdivacky  D.complete(FirstDecl);
1673212904Sdim  if (FirstDecl)
1674198893Srdivacky    DeclsInGroup.push_back(FirstDecl);
1675198893Srdivacky
1676234353Sdim  bool ExpectSemi = Context != Declarator::ForContext;
1677239462Sdim
1678198893Srdivacky  // If we don't have a comma, it is either the end of the list (a ';') or an
1679198893Srdivacky  // error, bail out.
1680198893Srdivacky  while (Tok.is(tok::comma)) {
1681234353Sdim    SourceLocation CommaLoc = ConsumeToken();
1682198893Srdivacky
1683234353Sdim    if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1684234353Sdim      // This comma was followed by a line-break and something which can't be
1685234353Sdim      // the start of a declarator. The comma was probably a typo for a
1686234353Sdim      // semicolon.
1687234353Sdim      Diag(CommaLoc, diag::err_expected_semi_declaration)
1688234353Sdim        << FixItHint::CreateReplacement(CommaLoc, ";");
1689234353Sdim      ExpectSemi = false;
1690234353Sdim      break;
1691234353Sdim    }
1692234353Sdim
1693198893Srdivacky    // Parse the next declarator.
1694198893Srdivacky    D.clear();
1695234353Sdim    D.setCommaLoc(CommaLoc);
1696198893Srdivacky
1697198893Srdivacky    // Accept attributes in an init-declarator.  In the first declarator in a
1698198893Srdivacky    // declaration, these would be part of the declspec.  In subsequent
1699198893Srdivacky    // declarators, they become part of the declarator itself, so that they
1700198893Srdivacky    // don't apply to declarators after *this* one.  Examples:
1701198893Srdivacky    //    short __attribute__((common)) var;    -> declspec
1702198893Srdivacky    //    short var __attribute__((common));    -> declarator
1703198893Srdivacky    //    short x, __attribute__((common)) var;    -> declarator
1704218893Sdim    MaybeParseGNUAttributes(D);
1705198893Srdivacky
1706198893Srdivacky    ParseDeclarator(D);
1707234353Sdim    if (!D.isInvalidType()) {
1708234353Sdim      Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1709234353Sdim      D.complete(ThisDecl);
1710234353Sdim      if (ThisDecl)
1711239462Sdim        DeclsInGroup.push_back(ThisDecl);
1712234353Sdim    }
1713193326Sed  }
1714198092Srdivacky
1715198893Srdivacky  if (DeclEnd)
1716198893Srdivacky    *DeclEnd = Tok.getLocation();
1717198893Srdivacky
1718234353Sdim  if (ExpectSemi &&
1719239462Sdim      ExpectAndConsumeSemi(Context == Declarator::FileContext
1720239462Sdim                           ? diag::err_invalid_token_after_toplevel_declarator
1721239462Sdim                           : diag::err_expected_semi_declaration)) {
1722210299Sed    // Okay, there was no semicolon and one was expected.  If we see a
1723210299Sed    // declaration specifier, just assume it was missing and continue parsing.
1724210299Sed    // Otherwise things are very confused and we skip to recover.
1725210299Sed    if (!isDeclarationSpecifier()) {
1726263508Sdim      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
1727210299Sed      if (Tok.is(tok::semi))
1728210299Sed        ConsumeToken();
1729210299Sed    }
1730198893Srdivacky  }
1731198893Srdivacky
1732263508Sdim  return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
1733193326Sed}
1734193326Sed
1735221345Sdim/// Parse an optional simple-asm-expr and attributes, and attach them to a
1736221345Sdim/// declarator. Returns true on an error.
1737234353Sdimbool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
1738221345Sdim  // If a simple-asm-expr is present, parse it.
1739221345Sdim  if (Tok.is(tok::kw_asm)) {
1740221345Sdim    SourceLocation Loc;
1741221345Sdim    ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1742221345Sdim    if (AsmLabel.isInvalid()) {
1743263508Sdim      SkipUntil(tok::semi, StopBeforeMatch);
1744221345Sdim      return true;
1745221345Sdim    }
1746221345Sdim
1747221345Sdim    D.setAsmLabel(AsmLabel.release());
1748221345Sdim    D.SetRangeEnd(Loc);
1749221345Sdim  }
1750221345Sdim
1751221345Sdim  MaybeParseGNUAttributes(D);
1752221345Sdim  return false;
1753221345Sdim}
1754221345Sdim
1755193326Sed/// \brief Parse 'declaration' after parsing 'declaration-specifiers
1756193326Sed/// declarator'. This method parses the remainder of the declaration
1757193326Sed/// (including any attributes or initializer, among other things) and
1758193326Sed/// finalizes the declaration.
1759193326Sed///
1760193326Sed///       init-declarator: [C99 6.7]
1761193326Sed///         declarator
1762193326Sed///         declarator '=' initializer
1763193326Sed/// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
1764193326Sed/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
1765193326Sed/// [C++]   declarator initializer[opt]
1766193326Sed///
1767193326Sed/// [C++] initializer:
1768193326Sed/// [C++]   '=' initializer-clause
1769193326Sed/// [C++]   '(' expression-list ')'
1770193326Sed/// [C++0x] '=' 'default'                                                [TODO]
1771193326Sed/// [C++0x] '=' 'delete'
1772223017Sdim/// [C++0x] braced-init-list
1773193326Sed///
1774193326Sed/// According to the standard grammar, =default and =delete are function
1775193326Sed/// definitions, but that definitely doesn't fit with the parser here.
1776193326Sed///
1777212904SdimDecl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
1778195099Sed                                     const ParsedTemplateInfo &TemplateInfo) {
1779234353Sdim  if (ParseAsmAttributesAfterDeclarator(D))
1780221345Sdim    return 0;
1781198092Srdivacky
1782221345Sdim  return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1783221345Sdim}
1784198092Srdivacky
1785221345SdimDecl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1786221345Sdim                                     const ParsedTemplateInfo &TemplateInfo) {
1787193326Sed  // Inform the current actions module that we just parsed this declarator.
1788212904Sdim  Decl *ThisDecl = 0;
1789198092Srdivacky  switch (TemplateInfo.Kind) {
1790198092Srdivacky  case ParsedTemplateInfo::NonTemplate:
1791210299Sed    ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1792198092Srdivacky    break;
1793239462Sdim
1794198092Srdivacky  case ParsedTemplateInfo::Template:
1795263508Sdim  case ParsedTemplateInfo::ExplicitSpecialization: {
1796210299Sed    ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
1797243830Sdim                                               *TemplateInfo.TemplateParams,
1798198092Srdivacky                                               D);
1799263508Sdim    if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl))
1800263508Sdim      // Re-direct this decl to refer to the templated decl so that we can
1801263508Sdim      // initialize it.
1802263508Sdim      ThisDecl = VT->getTemplatedDecl();
1803198092Srdivacky    break;
1804263508Sdim  }
1805263508Sdim  case ParsedTemplateInfo::ExplicitInstantiation: {
1806263508Sdim    if (Tok.is(tok::semi)) {
1807263508Sdim      DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
1808263508Sdim          getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
1809263508Sdim      if (ThisRes.isInvalid()) {
1810263508Sdim        SkipUntil(tok::semi, StopBeforeMatch);
1811263508Sdim        return 0;
1812263508Sdim      }
1813263508Sdim      ThisDecl = ThisRes.get();
1814263508Sdim    } else {
1815263508Sdim      // FIXME: This check should be for a variable template instantiation only.
1816239462Sdim
1817263508Sdim      // Check that this is a valid instantiation
1818263508Sdim      if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
1819263508Sdim        // If the declarator-id is not a template-id, issue a diagnostic and
1820263508Sdim        // recover by ignoring the 'template' keyword.
1821263508Sdim        Diag(Tok, diag::err_template_defn_explicit_instantiation)
1822263508Sdim            << 2 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
1823263508Sdim        ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1824263508Sdim      } else {
1825263508Sdim        SourceLocation LAngleLoc =
1826263508Sdim            PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
1827263508Sdim        Diag(D.getIdentifierLoc(),
1828263508Sdim             diag::err_explicit_instantiation_with_definition)
1829263508Sdim            << SourceRange(TemplateInfo.TemplateLoc)
1830263508Sdim            << FixItHint::CreateInsertion(LAngleLoc, "<>");
1831263508Sdim
1832263508Sdim        // Recover as if it were an explicit specialization.
1833263508Sdim        TemplateParameterLists FakedParamLists;
1834263508Sdim        FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
1835263508Sdim            0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0,
1836263508Sdim            LAngleLoc));
1837263508Sdim
1838263508Sdim        ThisDecl =
1839263508Sdim            Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
1840263508Sdim      }
1841198092Srdivacky    }
1842198092Srdivacky    break;
1843198092Srdivacky    }
1844198092Srdivacky  }
1845198092Srdivacky
1846251662Sdim  bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
1847218893Sdim
1848193326Sed  // Parse declarator '=' initializer.
1849234353Sdim  // If a '==' or '+=' is found, suggest a fixit to '='.
1850234353Sdim  if (isTokenEqualOrEqualTypo()) {
1851193326Sed    ConsumeToken();
1852263508Sdim
1853218893Sdim    if (Tok.is(tok::kw_delete)) {
1854223017Sdim      if (D.isFunctionDeclarator())
1855223017Sdim        Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1856223017Sdim          << 1 /* delete */;
1857223017Sdim      else
1858223017Sdim        Diag(ConsumeToken(), diag::err_deleted_non_function);
1859223017Sdim    } else if (Tok.is(tok::kw_default)) {
1860223017Sdim      if (D.isFunctionDeclarator())
1861234353Sdim        Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1862234353Sdim          << 0 /* default */;
1863223017Sdim      else
1864223017Sdim        Diag(ConsumeToken(), diag::err_default_special_members);
1865193326Sed    } else {
1866234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1867201361Srdivacky        EnterScope(0);
1868210299Sed        Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1869201361Srdivacky      }
1870194613Sed
1871210299Sed      if (Tok.is(tok::code_completion)) {
1872210299Sed        Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
1873239462Sdim        Actions.FinalizeDeclaration(ThisDecl);
1874226633Sdim        cutOffParsing();
1875226633Sdim        return 0;
1876210299Sed      }
1877239462Sdim
1878212904Sdim      ExprResult Init(ParseInitializer());
1879194613Sed
1880234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1881210299Sed        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1882201361Srdivacky        ExitScope();
1883201361Srdivacky      }
1884194613Sed
1885193326Sed      if (Init.isInvalid()) {
1886263508Sdim        SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
1887204643Srdivacky        Actions.ActOnInitializerError(ThisDecl);
1888204643Srdivacky      } else
1889218893Sdim        Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1890218893Sdim                                     /*DirectInit=*/false, TypeContainsAuto);
1891193326Sed    }
1892193326Sed  } else if (Tok.is(tok::l_paren)) {
1893193326Sed    // Parse C++ direct initializer: '(' expression-list ')'
1894226633Sdim    BalancedDelimiterTracker T(*this, tok::l_paren);
1895226633Sdim    T.consumeOpen();
1896226633Sdim
1897243830Sdim    ExprVector Exprs;
1898193326Sed    CommaLocsTy CommaLocs;
1899193326Sed
1900234353Sdim    if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1901201361Srdivacky      EnterScope(0);
1902210299Sed      Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1903201361Srdivacky    }
1904201361Srdivacky
1905193326Sed    if (ParseExpressionList(Exprs, CommaLocs)) {
1906243830Sdim      Actions.ActOnInitializerError(ThisDecl);
1907263508Sdim      SkipUntil(tok::r_paren, StopAtSemi);
1908201361Srdivacky
1909234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1910210299Sed        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1911201361Srdivacky        ExitScope();
1912201361Srdivacky      }
1913193326Sed    } else {
1914193326Sed      // Match the ')'.
1915226633Sdim      T.consumeClose();
1916193326Sed
1917193326Sed      assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1918193326Sed             "Unexpected number of commas!");
1919201361Srdivacky
1920234353Sdim      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1921210299Sed        Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1922201361Srdivacky        ExitScope();
1923201361Srdivacky      }
1924201361Srdivacky
1925234353Sdim      ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
1926234353Sdim                                                          T.getCloseLocation(),
1927243830Sdim                                                          Exprs);
1928234353Sdim      Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
1929234353Sdim                                   /*DirectInit=*/true, TypeContainsAuto);
1930193326Sed    }
1931249423Sdim  } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
1932239462Sdim             (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
1933223017Sdim    // Parse C++0x braced-init-list.
1934234353Sdim    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1935234353Sdim
1936223017Sdim    if (D.getCXXScopeSpec().isSet()) {
1937223017Sdim      EnterScope(0);
1938223017Sdim      Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1939223017Sdim    }
1940223017Sdim
1941223017Sdim    ExprResult Init(ParseBraceInitializer());
1942223017Sdim
1943223017Sdim    if (D.getCXXScopeSpec().isSet()) {
1944223017Sdim      Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1945223017Sdim      ExitScope();
1946223017Sdim    }
1947223017Sdim
1948223017Sdim    if (Init.isInvalid()) {
1949223017Sdim      Actions.ActOnInitializerError(ThisDecl);
1950223017Sdim    } else
1951223017Sdim      Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1952223017Sdim                                   /*DirectInit=*/true, TypeContainsAuto);
1953223017Sdim
1954193326Sed  } else {
1955218893Sdim    Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
1956193326Sed  }
1957193326Sed
1958219077Sdim  Actions.FinalizeDeclaration(ThisDecl);
1959219077Sdim
1960193326Sed  return ThisDecl;
1961193326Sed}
1962193326Sed
1963193326Sed/// ParseSpecifierQualifierList
1964193326Sed///        specifier-qualifier-list:
1965193326Sed///          type-specifier specifier-qualifier-list[opt]
1966193326Sed///          type-qualifier specifier-qualifier-list[opt]
1967193326Sed/// [GNU]    attributes     specifier-qualifier-list[opt]
1968193326Sed///
1969234353Sdimvoid Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1970234353Sdim                                         DeclSpecContext DSC) {
1971193326Sed  /// specifier-qualifier-list is a subset of declaration-specifiers.  Just
1972193326Sed  /// parse declaration-specifiers and complain about extra stuff.
1973226633Sdim  /// TODO: diagnose attribute-specifiers and alignment-specifiers.
1974234353Sdim  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
1975198092Srdivacky
1976193326Sed  // Validate declspec for type-name.
1977193326Sed  unsigned Specs = DS.getParsedSpecifiers();
1978239462Sdim  if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1979239462Sdim      !DS.hasTypeSpecifier()) {
1980234353Sdim    Diag(Tok, diag::err_expected_type);
1981234353Sdim    DS.SetTypeSpecError();
1982234353Sdim  } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
1983234353Sdim             !DS.hasAttributes()) {
1984193326Sed    Diag(Tok, diag::err_typename_requires_specqual);
1985234353Sdim    if (!DS.hasTypeSpecifier())
1986234353Sdim      DS.SetTypeSpecError();
1987234353Sdim  }
1988198092Srdivacky
1989193326Sed  // Issue diagnostic and remove storage class if present.
1990193326Sed  if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
1991193326Sed    if (DS.getStorageClassSpecLoc().isValid())
1992193326Sed      Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1993193326Sed    else
1994251662Sdim      Diag(DS.getThreadStorageClassSpecLoc(),
1995251662Sdim           diag::err_typename_invalid_storageclass);
1996193326Sed    DS.ClearStorageClassSpecs();
1997193326Sed  }
1998198092Srdivacky
1999193326Sed  // Issue diagnostic and remove function specfier if present.
2000193326Sed  if (Specs & DeclSpec::PQ_FunctionSpecifier) {
2001193326Sed    if (DS.isInlineSpecified())
2002193326Sed      Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
2003193326Sed    if (DS.isVirtualSpecified())
2004193326Sed      Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
2005193326Sed    if (DS.isExplicitSpecified())
2006193326Sed      Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
2007193326Sed    DS.ClearFunctionSpecs();
2008193326Sed  }
2009234353Sdim
2010234353Sdim  // Issue diagnostic and remove constexpr specfier if present.
2011234353Sdim  if (DS.isConstexprSpecified()) {
2012234353Sdim    Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
2013234353Sdim    DS.ClearConstexprSpec();
2014234353Sdim  }
2015193326Sed}
2016193326Sed
2017193326Sed/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
2018193326Sed/// specified token is valid after the identifier in a declarator which
2019193326Sed/// immediately follows the declspec.  For example, these things are valid:
2020193326Sed///
2021193326Sed///      int x   [             4];         // direct-declarator
2022193326Sed///      int x   (             int y);     // direct-declarator
2023193326Sed///  int(int x   )                         // direct-declarator
2024193326Sed///      int x   ;                         // simple-declaration
2025193326Sed///      int x   =             17;         // init-declarator-list
2026193326Sed///      int x   ,             y;          // init-declarator-list
2027193326Sed///      int x   __asm__       ("foo");    // init-declarator-list
2028193326Sed///      int x   :             4;          // struct-declarator
2029193326Sed///      int x   {             5};         // C++'0x unified initializers
2030193326Sed///
2031193326Sed/// This is not, because 'x' does not immediately follow the declspec (though
2032193326Sed/// ')' happens to be valid anyway).
2033193326Sed///    int (x)
2034193326Sed///
2035193326Sedstatic bool isValidAfterIdentifierInDeclarator(const Token &T) {
2036193326Sed  return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
2037193326Sed         T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
2038193326Sed         T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
2039193326Sed}
2040193326Sed
2041193326Sed
2042193326Sed/// ParseImplicitInt - This method is called when we have an non-typename
2043193326Sed/// identifier in a declspec (which normally terminates the decl spec) when
2044193326Sed/// the declspec has no type specifier.  In this case, the declspec is either
2045193326Sed/// malformed or is "implicit int" (in K&R and C89).
2046193326Sed///
2047193326Sed/// This method handles diagnosing this prettily and returns false if the
2048193326Sed/// declspec is done being processed.  If it recovers and thinks there may be
2049193326Sed/// other pieces of declspec after it, it returns true.
2050193326Sed///
2051193326Sedbool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
2052193326Sed                              const ParsedTemplateInfo &TemplateInfo,
2053249423Sdim                              AccessSpecifier AS, DeclSpecContext DSC,
2054249423Sdim                              ParsedAttributesWithRange &Attrs) {
2055193326Sed  assert(Tok.is(tok::identifier) && "should have identifier");
2056198092Srdivacky
2057193326Sed  SourceLocation Loc = Tok.getLocation();
2058193326Sed  // If we see an identifier that is not a type name, we normally would
2059193326Sed  // parse it as the identifer being declared.  However, when a typename
2060193326Sed  // is typo'd or the definition is not included, this will incorrectly
2061193326Sed  // parse the typename as the identifier name and fall over misparsing
2062193326Sed  // later parts of the diagnostic.
2063193326Sed  //
2064193326Sed  // As such, we try to do some look-ahead in cases where this would
2065193326Sed  // otherwise be an "implicit-int" case to see if this is invalid.  For
2066193326Sed  // example: "static foo_t x = 4;"  In this case, if we parsed foo_t as
2067193326Sed  // an identifier with implicit int, we'd get a parse error because the
2068193326Sed  // next token is obviously invalid for a type.  Parse these as a case
2069193326Sed  // with an invalid type specifier.
2070193326Sed  assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
2071198092Srdivacky
2072193326Sed  // Since we know that this either implicit int (which is rare) or an
2073239462Sdim  // error, do lookahead to try to do better recovery. This never applies
2074239462Sdim  // within a type specifier. Outside of C++, we allow this even if the
2075239462Sdim  // language doesn't "officially" support implicit int -- we support
2076251662Sdim  // implicit int as an extension in C99 and C11.
2077239462Sdim  if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
2078251662Sdim      !getLangOpts().CPlusPlus &&
2079234353Sdim      isValidAfterIdentifierInDeclarator(NextToken())) {
2080193326Sed    // If this token is valid for implicit int, e.g. "static x = 4", then
2081193326Sed    // we just avoid eating the identifier, so it will be parsed as the
2082193326Sed    // identifier in the declarator.
2083193326Sed    return false;
2084193326Sed  }
2085198092Srdivacky
2086239462Sdim  if (getLangOpts().CPlusPlus &&
2087239462Sdim      DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
2088239462Sdim    // Don't require a type specifier if we have the 'auto' storage class
2089239462Sdim    // specifier in C++98 -- we'll promote it to a type specifier.
2090263508Sdim    if (SS)
2091263508Sdim      AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);
2092239462Sdim    return false;
2093239462Sdim  }
2094239462Sdim
2095193326Sed  // Otherwise, if we don't consume this token, we are going to emit an
2096193326Sed  // error anyway.  Try to recover from various common problems.  Check
2097193326Sed  // to see if this was a reference to a tag name without a tag specified.
2098193326Sed  // This is a common problem in C (saying 'foo' instead of 'struct foo').
2099193326Sed  //
2100193326Sed  // C++ doesn't need this, and isTagName doesn't take SS.
2101193326Sed  if (SS == 0) {
2102221345Sdim    const char *TagName = 0, *FixitTagName = 0;
2103193326Sed    tok::TokenKind TagKind = tok::unknown;
2104198092Srdivacky
2105210299Sed    switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
2106193326Sed      default: break;
2107221345Sdim      case DeclSpec::TST_enum:
2108221345Sdim        TagName="enum"  ; FixitTagName = "enum "  ; TagKind=tok::kw_enum ;break;
2109221345Sdim      case DeclSpec::TST_union:
2110221345Sdim        TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
2111221345Sdim      case DeclSpec::TST_struct:
2112221345Sdim        TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
2113243830Sdim      case DeclSpec::TST_interface:
2114243830Sdim        TagName="__interface"; FixitTagName = "__interface ";
2115243830Sdim        TagKind=tok::kw___interface;break;
2116221345Sdim      case DeclSpec::TST_class:
2117221345Sdim        TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
2118193326Sed    }
2119198092Srdivacky
2120193326Sed    if (TagName) {
2121239462Sdim      IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2122239462Sdim      LookupResult R(Actions, TokenName, SourceLocation(),
2123239462Sdim                     Sema::LookupOrdinaryName);
2124239462Sdim
2125193326Sed      Diag(Loc, diag::err_use_of_tag_name_without_tag)
2126239462Sdim        << TokenName << TagName << getLangOpts().CPlusPlus
2127239462Sdim        << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
2128198092Srdivacky
2129239462Sdim      if (Actions.LookupParsedName(R, getCurScope(), SS)) {
2130239462Sdim        for (LookupResult::iterator I = R.begin(), IEnd = R.end();
2131239462Sdim             I != IEnd; ++I)
2132239462Sdim          Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2133239462Sdim            << TokenName << TagName;
2134239462Sdim      }
2135239462Sdim
2136193326Sed      // Parse this as a tag as if the missing tag were present.
2137193326Sed      if (TagKind == tok::kw_enum)
2138234353Sdim        ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
2139193326Sed      else
2140234353Sdim        ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2141249423Sdim                            /*EnteringContext*/ false, DSC_normal, Attrs);
2142193326Sed      return true;
2143193326Sed    }
2144193326Sed  }
2145198092Srdivacky
2146239462Sdim  // Determine whether this identifier could plausibly be the name of something
2147239462Sdim  // being declared (with a missing type).
2148239462Sdim  if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
2149239462Sdim      (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
2150239462Sdim    // Look ahead to the next token to try to figure out what this declaration
2151239462Sdim    // was supposed to be.
2152239462Sdim    switch (NextToken().getKind()) {
2153239462Sdim    case tok::l_paren: {
2154239462Sdim      // static x(4); // 'x' is not a type
2155239462Sdim      // x(int n);    // 'x' is not a type
2156239462Sdim      // x (*p)[];    // 'x' is a type
2157239462Sdim      //
2158239462Sdim      // Since we're in an error case (or the rare 'implicit int in C++' MS
2159239462Sdim      // extension), we can afford to perform a tentative parse to determine
2160239462Sdim      // which case we're in.
2161239462Sdim      TentativeParsingAction PA(*this);
2162239462Sdim      ConsumeToken();
2163239462Sdim      TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
2164239462Sdim      PA.Revert();
2165263508Sdim
2166263508Sdim      if (TPR != TPResult::False()) {
2167263508Sdim        // The identifier is followed by a parenthesized declarator.
2168263508Sdim        // It's supposed to be a type.
2169263508Sdim        break;
2170263508Sdim      }
2171263508Sdim
2172263508Sdim      // If we're in a context where we could be declaring a constructor,
2173263508Sdim      // check whether this is a constructor declaration with a bogus name.
2174263508Sdim      if (DSC == DSC_class || (DSC == DSC_top_level && SS)) {
2175263508Sdim        IdentifierInfo *II = Tok.getIdentifierInfo();
2176263508Sdim        if (Actions.isCurrentClassNameTypo(II, SS)) {
2177263508Sdim          Diag(Loc, diag::err_constructor_bad_name)
2178263508Sdim            << Tok.getIdentifierInfo() << II
2179263508Sdim            << FixItHint::CreateReplacement(Tok.getLocation(), II->getName());
2180263508Sdim          Tok.setIdentifierInfo(II);
2181263508Sdim        }
2182263508Sdim      }
2183263508Sdim      // Fall through.
2184239462Sdim    }
2185263508Sdim    case tok::comma:
2186263508Sdim    case tok::equal:
2187263508Sdim    case tok::kw_asm:
2188263508Sdim    case tok::l_brace:
2189263508Sdim    case tok::l_square:
2190263508Sdim    case tok::semi:
2191263508Sdim      // This looks like a variable or function declaration. The type is
2192263508Sdim      // probably missing. We're done parsing decl-specifiers.
2193263508Sdim      if (SS)
2194263508Sdim        AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);
2195263508Sdim      return false;
2196239462Sdim
2197239462Sdim    default:
2198239462Sdim      // This is probably supposed to be a type. This includes cases like:
2199239462Sdim      //   int f(itn);
2200239462Sdim      //   struct S { unsinged : 4; };
2201239462Sdim      break;
2202239462Sdim    }
2203239462Sdim  }
2204239462Sdim
2205239462Sdim  // This is almost certainly an invalid type name. Let the action emit a
2206198092Srdivacky  // diagnostic and attempt to recover.
2207212904Sdim  ParsedType T;
2208239462Sdim  IdentifierInfo *II = Tok.getIdentifierInfo();
2209239462Sdim  if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
2210198092Srdivacky    // The action emitted a diagnostic, so we don't have to.
2211198092Srdivacky    if (T) {
2212198092Srdivacky      // The action has suggested that the type T could be used. Set that as
2213198092Srdivacky      // the type in the declaration specifiers, consume the would-be type
2214198092Srdivacky      // name token, and we're done.
2215198092Srdivacky      const char *PrevSpec;
2216198092Srdivacky      unsigned DiagID;
2217212904Sdim      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
2218198092Srdivacky      DS.SetRangeEnd(Tok.getLocation());
2219198092Srdivacky      ConsumeToken();
2220198092Srdivacky      // There may be other declaration specifiers after this.
2221198092Srdivacky      return true;
2222239462Sdim    } else if (II != Tok.getIdentifierInfo()) {
2223239462Sdim      // If no type was suggested, the correction is to a keyword
2224239462Sdim      Tok.setKind(II->getTokenID());
2225239462Sdim      // There may be other declaration specifiers after this.
2226239462Sdim      return true;
2227198092Srdivacky    }
2228239462Sdim
2229198092Srdivacky    // Fall through; the action had no suggestion for us.
2230198092Srdivacky  } else {
2231198092Srdivacky    // The action did not emit a diagnostic, so emit one now.
2232198092Srdivacky    SourceRange R;
2233198092Srdivacky    if (SS) R = SS->getRange();
2234198092Srdivacky    Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
2235198092Srdivacky  }
2236198092Srdivacky
2237198092Srdivacky  // Mark this as an error.
2238234353Sdim  DS.SetTypeSpecError();
2239193326Sed  DS.SetRangeEnd(Tok.getLocation());
2240193326Sed  ConsumeToken();
2241198092Srdivacky
2242193326Sed  // TODO: Could inject an invalid typedef decl in an enclosing scope to
2243193326Sed  // avoid rippling error messages on subsequent uses of the same type,
2244193326Sed  // could be useful if #include was forgotten.
2245193326Sed  return false;
2246193326Sed}
2247193326Sed
2248202379Srdivacky/// \brief Determine the declaration specifier context from the declarator
2249202379Srdivacky/// context.
2250202379Srdivacky///
2251202379Srdivacky/// \param Context the declarator context, which is one of the
2252202379Srdivacky/// Declarator::TheContext enumerator values.
2253239462SdimParser::DeclSpecContext
2254202379SrdivackyParser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
2255202379Srdivacky  if (Context == Declarator::MemberContext)
2256202379Srdivacky    return DSC_class;
2257202379Srdivacky  if (Context == Declarator::FileContext)
2258202379Srdivacky    return DSC_top_level;
2259234353Sdim  if (Context == Declarator::TrailingReturnContext)
2260234353Sdim    return DSC_trailing;
2261202379Srdivacky  return DSC_normal;
2262202379Srdivacky}
2263202379Srdivacky
2264226633Sdim/// ParseAlignArgument - Parse the argument to an alignment-specifier.
2265226633Sdim///
2266226633Sdim/// FIXME: Simply returns an alignof() expression if the argument is a
2267226633Sdim/// type. Ideally, the type should be propagated directly into Sema.
2268226633Sdim///
2269234353Sdim/// [C11]   type-id
2270234353Sdim/// [C11]   constant-expression
2271234353Sdim/// [C++0x] type-id ...[opt]
2272234353Sdim/// [C++0x] assignment-expression ...[opt]
2273234353SdimExprResult Parser::ParseAlignArgument(SourceLocation Start,
2274234353Sdim                                      SourceLocation &EllipsisLoc) {
2275234353Sdim  ExprResult ER;
2276226633Sdim  if (isTypeIdInParens()) {
2277226633Sdim    SourceLocation TypeLoc = Tok.getLocation();
2278226633Sdim    ParsedType Ty = ParseTypeName().get();
2279226633Sdim    SourceRange TypeRange(Start, Tok.getLocation());
2280234353Sdim    ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
2281234353Sdim                                               Ty.getAsOpaquePtr(), TypeRange);
2282226633Sdim  } else
2283234353Sdim    ER = ParseConstantExpression();
2284234353Sdim
2285249423Sdim  if (getLangOpts().CPlusPlus11 && Tok.is(tok::ellipsis))
2286234353Sdim    EllipsisLoc = ConsumeToken();
2287234353Sdim
2288234353Sdim  return ER;
2289226633Sdim}
2290226633Sdim
2291226633Sdim/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
2292226633Sdim/// attribute to Attrs.
2293226633Sdim///
2294226633Sdim/// alignment-specifier:
2295234353Sdim/// [C11]   '_Alignas' '(' type-id ')'
2296234353Sdim/// [C11]   '_Alignas' '(' constant-expression ')'
2297249423Sdim/// [C++11] 'alignas' '(' type-id ...[opt] ')'
2298249423Sdim/// [C++11] 'alignas' '(' assignment-expression ...[opt] ')'
2299226633Sdimvoid Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
2300249423Sdim                                     SourceLocation *EndLoc) {
2301226633Sdim  assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
2302226633Sdim         "Not an alignment-specifier!");
2303226633Sdim
2304249423Sdim  IdentifierInfo *KWName = Tok.getIdentifierInfo();
2305249423Sdim  SourceLocation KWLoc = ConsumeToken();
2306226633Sdim
2307226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
2308226633Sdim  if (T.expectAndConsume(diag::err_expected_lparen))
2309226633Sdim    return;
2310226633Sdim
2311234353Sdim  SourceLocation EllipsisLoc;
2312234353Sdim  ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
2313226633Sdim  if (ArgExpr.isInvalid()) {
2314263508Sdim    T.skipToEnd();
2315226633Sdim    return;
2316226633Sdim  }
2317226633Sdim
2318226633Sdim  T.consumeClose();
2319249423Sdim  if (EndLoc)
2320249423Sdim    *EndLoc = T.getCloseLocation();
2321226633Sdim
2322263508Sdim  ArgsVector ArgExprs;
2323226633Sdim  ArgExprs.push_back(ArgExpr.release());
2324263508Sdim  Attrs.addNew(KWName, KWLoc, 0, KWLoc, ArgExprs.data(), 1,
2325263508Sdim               AttributeList::AS_Keyword, EllipsisLoc);
2326226633Sdim}
2327226633Sdim
2328263508Sdim/// Determine whether we're looking at something that might be a declarator
2329263508Sdim/// in a simple-declaration. If it can't possibly be a declarator, maybe
2330263508Sdim/// diagnose a missing semicolon after a prior tag definition in the decl
2331263508Sdim/// specifier.
2332263508Sdim///
2333263508Sdim/// \return \c true if an error occurred and this can't be any kind of
2334263508Sdim/// declaration.
2335263508Sdimbool
2336263508SdimParser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
2337263508Sdim                                              DeclSpecContext DSContext,
2338263508Sdim                                              LateParsedAttrList *LateAttrs) {
2339263508Sdim  assert(DS.hasTagDefinition() && "shouldn't call this");
2340263508Sdim
2341263508Sdim  bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2342263508Sdim  bool HasMissingSemi = false;
2343263508Sdim
2344263508Sdim  if (getLangOpts().CPlusPlus &&
2345263508Sdim      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
2346263508Sdim       Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) &&
2347263508Sdim      TryAnnotateCXXScopeToken(EnteringContext)) {
2348263508Sdim    SkipMalformedDecl();
2349263508Sdim    return true;
2350263508Sdim  }
2351263508Sdim
2352263508Sdim  // Determine whether the following tokens could possibly be a
2353263508Sdim  // declarator.
2354263508Sdim  if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
2355263508Sdim    const Token &Next = NextToken();
2356263508Sdim    // These tokens cannot come after the declarator-id in a
2357263508Sdim    // simple-declaration, and are likely to come after a type-specifier.
2358263508Sdim    HasMissingSemi = Next.is(tok::star) || Next.is(tok::amp) ||
2359263508Sdim                     Next.is(tok::ampamp) || Next.is(tok::identifier) ||
2360263508Sdim                     Next.is(tok::annot_cxxscope) ||
2361263508Sdim                     Next.is(tok::coloncolon);
2362263508Sdim  } else if (Tok.is(tok::annot_cxxscope) &&
2363263508Sdim             NextToken().is(tok::identifier) &&
2364263508Sdim             DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
2365263508Sdim    // We almost certainly have a missing semicolon. Look up the name and
2366263508Sdim    // check; if it names a type, we're missing a semicolon.
2367263508Sdim    CXXScopeSpec SS;
2368263508Sdim    Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2369263508Sdim                                                 Tok.getAnnotationRange(), SS);
2370263508Sdim    const Token &Next = NextToken();
2371263508Sdim    IdentifierInfo *Name = Next.getIdentifierInfo();
2372263508Sdim    Sema::NameClassification Classification =
2373263508Sdim        Actions.ClassifyName(getCurScope(), SS, Name, Next.getLocation(),
2374263508Sdim                             NextToken(), /*IsAddressOfOperand*/false);
2375263508Sdim    switch (Classification.getKind()) {
2376263508Sdim    case Sema::NC_Error:
2377263508Sdim      SkipMalformedDecl();
2378263508Sdim      return true;
2379263508Sdim
2380263508Sdim    case Sema::NC_Keyword:
2381263508Sdim    case Sema::NC_NestedNameSpecifier:
2382263508Sdim      llvm_unreachable("typo correction and nested name specifiers not "
2383263508Sdim                       "possible here");
2384263508Sdim
2385263508Sdim    case Sema::NC_Type:
2386263508Sdim    case Sema::NC_TypeTemplate:
2387263508Sdim      // Not a previously-declared non-type entity.
2388263508Sdim      HasMissingSemi = true;
2389263508Sdim      break;
2390263508Sdim
2391263508Sdim    case Sema::NC_Unknown:
2392263508Sdim    case Sema::NC_Expression:
2393263508Sdim    case Sema::NC_VarTemplate:
2394263508Sdim    case Sema::NC_FunctionTemplate:
2395263508Sdim      // Might be a redeclaration of a prior entity.
2396263508Sdim      HasMissingSemi = false;
2397263508Sdim      break;
2398263508Sdim    }
2399263508Sdim  } else if (Tok.is(tok::kw_typename) || Tok.is(tok::annot_typename)) {
2400263508Sdim    HasMissingSemi = true;
2401263508Sdim  }
2402263508Sdim
2403263508Sdim  if (!HasMissingSemi)
2404263508Sdim    return false;
2405263508Sdim
2406263508Sdim  Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getLocEnd()),
2407263508Sdim       diag::err_expected_semi_after_tagdecl)
2408263508Sdim    << DeclSpec::getSpecifierName(DS.getTypeSpecType());
2409263508Sdim
2410263508Sdim  // Try to recover from the typo, by dropping the tag definition and parsing
2411263508Sdim  // the problematic tokens as a type.
2412263508Sdim  //
2413263508Sdim  // FIXME: Split the DeclSpec into pieces for the standalone
2414263508Sdim  // declaration and pieces for the following declaration, instead
2415263508Sdim  // of assuming that all the other pieces attach to new declaration,
2416263508Sdim  // and call ParsedFreeStandingDeclSpec as appropriate.
2417263508Sdim  DS.ClearTypeSpecType();
2418263508Sdim  ParsedTemplateInfo NotATemplate;
2419263508Sdim  ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
2420263508Sdim  return false;
2421263508Sdim}
2422263508Sdim
2423193326Sed/// ParseDeclarationSpecifiers
2424193326Sed///       declaration-specifiers: [C99 6.7]
2425193326Sed///         storage-class-specifier declaration-specifiers[opt]
2426193326Sed///         type-specifier declaration-specifiers[opt]
2427193326Sed/// [C99]   function-specifier declaration-specifiers[opt]
2428234353Sdim/// [C11]   alignment-specifier declaration-specifiers[opt]
2429193326Sed/// [GNU]   attributes declaration-specifiers[opt]
2430226633Sdim/// [Clang] '__module_private__' declaration-specifiers[opt]
2431193326Sed///
2432193326Sed///       storage-class-specifier: [C99 6.7.1]
2433193326Sed///         'typedef'
2434193326Sed///         'extern'
2435193326Sed///         'static'
2436193326Sed///         'auto'
2437193326Sed///         'register'
2438193326Sed/// [C++]   'mutable'
2439251662Sdim/// [C++11] 'thread_local'
2440251662Sdim/// [C11]   '_Thread_local'
2441193326Sed/// [GNU]   '__thread'
2442193326Sed///       function-specifier: [C99 6.7.4]
2443193326Sed/// [C99]   'inline'
2444193326Sed/// [C++]   'virtual'
2445193326Sed/// [C++]   'explicit'
2446218893Sdim/// [OpenCL] '__kernel'
2447193326Sed///       'friend': [C++ dcl.friend]
2448198954Srdivacky///       'constexpr': [C++0x dcl.constexpr]
2449193326Sed
2450193326Sed///
2451193326Sedvoid Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
2452193326Sed                                        const ParsedTemplateInfo &TemplateInfo,
2453198092Srdivacky                                        AccessSpecifier AS,
2454234353Sdim                                        DeclSpecContext DSContext,
2455234353Sdim                                        LateParsedAttrList *LateAttrs) {
2456221345Sdim  if (DS.getSourceRange().isInvalid()) {
2457221345Sdim    DS.SetRangeStart(Tok.getLocation());
2458221345Sdim    DS.SetRangeEnd(Tok.getLocation());
2459221345Sdim  }
2460239462Sdim
2461234353Sdim  bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2462239462Sdim  bool AttrsLastTime = false;
2463239462Sdim  ParsedAttributesWithRange attrs(AttrFactory);
2464193326Sed  while (1) {
2465198092Srdivacky    bool isInvalid = false;
2466193326Sed    const char *PrevSpec = 0;
2467198092Srdivacky    unsigned DiagID = 0;
2468198092Srdivacky
2469193326Sed    SourceLocation Loc = Tok.getLocation();
2470193326Sed
2471193326Sed    switch (Tok.getKind()) {
2472198092Srdivacky    default:
2473193326Sed    DoneWithDeclSpec:
2474239462Sdim      if (!AttrsLastTime)
2475239462Sdim        ProhibitAttributes(attrs);
2476243830Sdim      else {
2477243830Sdim        // Reject C++11 attributes that appertain to decl specifiers as
2478243830Sdim        // we don't support any C++11 attributes that appertain to decl
2479243830Sdim        // specifiers. This also conforms to what g++ 4.8 is doing.
2480243830Sdim        ProhibitCXX11Attributes(attrs);
2481243830Sdim
2482239462Sdim        DS.takeAttributesFrom(attrs);
2483243830Sdim      }
2484226633Sdim
2485193326Sed      // If this is not a declaration specifier token, we're done reading decl
2486193326Sed      // specifiers.  First verify that DeclSpec's are consistent.
2487193326Sed      DS.Finish(Diags, PP);
2488193326Sed      return;
2489198092Srdivacky
2490239462Sdim    case tok::l_square:
2491239462Sdim    case tok::kw_alignas:
2492249423Sdim      if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier())
2493239462Sdim        goto DoneWithDeclSpec;
2494239462Sdim
2495239462Sdim      ProhibitAttributes(attrs);
2496239462Sdim      // FIXME: It would be good to recover by accepting the attributes,
2497239462Sdim      //        but attempting to do that now would cause serious
2498239462Sdim      //        madness in terms of diagnostics.
2499239462Sdim      attrs.clear();
2500239462Sdim      attrs.Range = SourceRange();
2501239462Sdim
2502239462Sdim      ParseCXX11Attributes(attrs);
2503239462Sdim      AttrsLastTime = true;
2504239462Sdim      continue;
2505239462Sdim
2506212904Sdim    case tok::code_completion: {
2507212904Sdim      Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
2508212904Sdim      if (DS.hasTypeSpecifier()) {
2509212904Sdim        bool AllowNonIdentifiers
2510212904Sdim          = (getCurScope()->getFlags() & (Scope::ControlScope |
2511212904Sdim                                          Scope::BlockScope |
2512212904Sdim                                          Scope::TemplateParamScope |
2513212904Sdim                                          Scope::FunctionPrototypeScope |
2514212904Sdim                                          Scope::AtCatchScope)) == 0;
2515212904Sdim        bool AllowNestedNameSpecifiers
2516239462Sdim          = DSContext == DSC_top_level ||
2517212904Sdim            (DSContext == DSC_class && DS.isFriendSpecified());
2518212904Sdim
2519218893Sdim        Actions.CodeCompleteDeclSpec(getCurScope(), DS,
2520239462Sdim                                     AllowNonIdentifiers,
2521218893Sdim                                     AllowNestedNameSpecifiers);
2522226633Sdim        return cutOffParsing();
2523239462Sdim      }
2524239462Sdim
2525218893Sdim      if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2526218893Sdim        CCC = Sema::PCC_LocalDeclarationSpecifiers;
2527218893Sdim      else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
2528239462Sdim        CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
2529212904Sdim                                    : Sema::PCC_Template;
2530212904Sdim      else if (DSContext == DSC_class)
2531212904Sdim        CCC = Sema::PCC_Class;
2532234353Sdim      else if (CurParsedObjCImpl)
2533212904Sdim        CCC = Sema::PCC_ObjCImplementation;
2534239462Sdim
2535212904Sdim      Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
2536226633Sdim      return cutOffParsing();
2537212904Sdim    }
2538212904Sdim
2539193326Sed    case tok::coloncolon: // ::foo::bar
2540204643Srdivacky      // C++ scope specifier.  Annotate and loop, or bail out on error.
2541263508Sdim      if (TryAnnotateCXXScopeToken(EnteringContext)) {
2542204643Srdivacky        if (!DS.hasTypeSpecifier())
2543204643Srdivacky          DS.SetTypeSpecError();
2544204643Srdivacky        goto DoneWithDeclSpec;
2545204643Srdivacky      }
2546204643Srdivacky      if (Tok.is(tok::coloncolon)) // ::new or ::delete
2547204643Srdivacky        goto DoneWithDeclSpec;
2548204643Srdivacky      continue;
2549193326Sed
2550193326Sed    case tok::annot_cxxscope: {
2551239462Sdim      if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
2552193326Sed        goto DoneWithDeclSpec;
2553193326Sed
2554200583Srdivacky      CXXScopeSpec SS;
2555219077Sdim      Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2556219077Sdim                                                   Tok.getAnnotationRange(),
2557219077Sdim                                                   SS);
2558200583Srdivacky
2559193326Sed      // We are looking for a qualified typename.
2560193326Sed      Token Next = NextToken();
2561198092Srdivacky      if (Next.is(tok::annot_template_id) &&
2562193326Sed          static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
2563193326Sed            ->Kind == TNK_Type_template) {
2564193326Sed        // We have a qualified template-id, e.g., N::A<int>
2565202379Srdivacky
2566202379Srdivacky        // C++ [class.qual]p2:
2567202379Srdivacky        //   In a lookup in which the constructor is an acceptable lookup
2568202379Srdivacky        //   result and the nested-name-specifier nominates a class C:
2569202379Srdivacky        //
2570202379Srdivacky        //     - if the name specified after the
2571202379Srdivacky        //       nested-name-specifier, when looked up in C, is the
2572202379Srdivacky        //       injected-class-name of C (Clause 9), or
2573202379Srdivacky        //
2574202379Srdivacky        //     - if the name specified after the nested-name-specifier
2575202379Srdivacky        //       is the same as the identifier or the
2576202379Srdivacky        //       simple-template-id's template-name in the last
2577202379Srdivacky        //       component of the nested-name-specifier,
2578202379Srdivacky        //
2579202379Srdivacky        //   the name is instead considered to name the constructor of
2580202379Srdivacky        //   class C.
2581239462Sdim        //
2582202379Srdivacky        // Thus, if the template-name is actually the constructor
2583202379Srdivacky        // name, then the code is ill-formed; this interpretation is
2584239462Sdim        // reinforced by the NAD status of core issue 635.
2585224145Sdim        TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
2586249423Sdim        if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
2587207619Srdivacky            TemplateId->Name &&
2588210299Sed            Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
2589202379Srdivacky          if (isConstructorDeclarator()) {
2590202379Srdivacky            // The user meant this to be an out-of-line constructor
2591202379Srdivacky            // definition, but template arguments are not allowed
2592202379Srdivacky            // there.  Just allow this as a constructor; we'll
2593202379Srdivacky            // complain about it later.
2594202379Srdivacky            goto DoneWithDeclSpec;
2595202379Srdivacky          }
2596202379Srdivacky
2597202379Srdivacky          // The user meant this to name a type, but it actually names
2598202379Srdivacky          // a constructor with some extraneous template
2599202379Srdivacky          // arguments. Complain, then parse it as a type as the user
2600202379Srdivacky          // intended.
2601202379Srdivacky          Diag(TemplateId->TemplateNameLoc,
2602202379Srdivacky               diag::err_out_of_line_template_id_names_constructor)
2603202379Srdivacky            << TemplateId->Name;
2604202379Srdivacky        }
2605202379Srdivacky
2606200583Srdivacky        DS.getTypeSpecScope() = SS;
2607200583Srdivacky        ConsumeToken(); // The C++ scope.
2608198092Srdivacky        assert(Tok.is(tok::annot_template_id) &&
2609193326Sed               "ParseOptionalCXXScopeSpecifier not working");
2610221345Sdim        AnnotateTemplateIdTokenAsType();
2611193326Sed        continue;
2612193326Sed      }
2613193326Sed
2614198092Srdivacky      if (Next.is(tok::annot_typename)) {
2615200583Srdivacky        DS.getTypeSpecScope() = SS;
2616200583Srdivacky        ConsumeToken(); // The C++ scope.
2617212904Sdim        if (Tok.getAnnotationValue()) {
2618212904Sdim          ParsedType T = getTypeAnnotation(Tok);
2619218893Sdim          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
2620239462Sdim                                         Tok.getAnnotationEndLoc(),
2621212904Sdim                                         PrevSpec, DiagID, T);
2622243830Sdim          if (isInvalid)
2623243830Sdim            break;
2624212904Sdim        }
2625198092Srdivacky        else
2626198092Srdivacky          DS.SetTypeSpecError();
2627198092Srdivacky        DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2628198092Srdivacky        ConsumeToken(); // The typename
2629198092Srdivacky      }
2630198092Srdivacky
2631193326Sed      if (Next.isNot(tok::identifier))
2632193326Sed        goto DoneWithDeclSpec;
2633193326Sed
2634202379Srdivacky      // If we're in a context where the identifier could be a class name,
2635202379Srdivacky      // check whether this is a constructor declaration.
2636249423Sdim      if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
2637239462Sdim          Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
2638202379Srdivacky                                     &SS)) {
2639202379Srdivacky        if (isConstructorDeclarator())
2640202379Srdivacky          goto DoneWithDeclSpec;
2641193326Sed
2642202379Srdivacky        // As noted in C++ [class.qual]p2 (cited above), when the name
2643202379Srdivacky        // of the class is qualified in a context where it could name
2644202379Srdivacky        // a constructor, its a constructor name. However, we've
2645202379Srdivacky        // looked at the declarator, and the user probably meant this
2646202379Srdivacky        // to be a type. Complain that it isn't supposed to be treated
2647202379Srdivacky        // as a type, then proceed to parse it as a type.
2648202379Srdivacky        Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
2649202379Srdivacky          << Next.getIdentifierInfo();
2650202379Srdivacky      }
2651202379Srdivacky
2652212904Sdim      ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2653212904Sdim                                               Next.getLocation(),
2654221345Sdim                                               getCurScope(), &SS,
2655221345Sdim                                               false, false, ParsedType(),
2656234353Sdim                                               /*IsCtorOrDtorName=*/false,
2657221345Sdim                                               /*NonTrivialSourceInfo=*/true);
2658193326Sed
2659193326Sed      // If the referenced identifier is not a type, then this declspec is
2660193326Sed      // erroneous: We already checked about that it has no type specifier, and
2661193326Sed      // C++ doesn't have implicit int.  Diagnose it as a typo w.r.t. to the
2662198092Srdivacky      // typename.
2663263508Sdim      if (!TypeRep) {
2664193326Sed        ConsumeToken();   // Eat the scope spec so the identifier is current.
2665249423Sdim        ParsedAttributesWithRange Attrs(AttrFactory);
2666249423Sdim        if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
2667249423Sdim          if (!Attrs.empty()) {
2668249423Sdim            AttrsLastTime = true;
2669249423Sdim            attrs.takeAllFrom(Attrs);
2670249423Sdim          }
2671249423Sdim          continue;
2672249423Sdim        }
2673193326Sed        goto DoneWithDeclSpec;
2674193326Sed      }
2675198092Srdivacky
2676200583Srdivacky      DS.getTypeSpecScope() = SS;
2677193326Sed      ConsumeToken(); // The C++ scope.
2678193326Sed
2679193326Sed      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2680198092Srdivacky                                     DiagID, TypeRep);
2681193326Sed      if (isInvalid)
2682193326Sed        break;
2683198092Srdivacky
2684193326Sed      DS.SetRangeEnd(Tok.getLocation());
2685193326Sed      ConsumeToken(); // The typename.
2686193326Sed
2687193326Sed      continue;
2688193326Sed    }
2689198092Srdivacky
2690193326Sed    case tok::annot_typename: {
2691263508Sdim      // If we've previously seen a tag definition, we were almost surely
2692263508Sdim      // missing a semicolon after it.
2693263508Sdim      if (DS.hasTypeSpecifier() && DS.hasTagDefinition())
2694263508Sdim        goto DoneWithDeclSpec;
2695263508Sdim
2696212904Sdim      if (Tok.getAnnotationValue()) {
2697212904Sdim        ParsedType T = getTypeAnnotation(Tok);
2698193326Sed        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2699212904Sdim                                       DiagID, T);
2700212904Sdim      } else
2701193326Sed        DS.SetTypeSpecError();
2702239462Sdim
2703206275Srdivacky      if (isInvalid)
2704206275Srdivacky        break;
2705206275Srdivacky
2706193326Sed      DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2707193326Sed      ConsumeToken(); // The typename
2708198092Srdivacky
2709193326Sed      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2710193326Sed      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
2711239462Sdim      // Objective-C interface.
2712234353Sdim      if (Tok.is(tok::less) && getLangOpts().ObjC1)
2713218893Sdim        ParseObjCProtocolQualifiers(DS);
2714239462Sdim
2715193326Sed      continue;
2716193326Sed    }
2717198092Srdivacky
2718221345Sdim    case tok::kw___is_signed:
2719221345Sdim      // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
2720221345Sdim      // typically treats it as a trait. If we see __is_signed as it appears
2721221345Sdim      // in libstdc++, e.g.,
2722221345Sdim      //
2723221345Sdim      //   static const bool __is_signed;
2724221345Sdim      //
2725221345Sdim      // then treat __is_signed as an identifier rather than as a keyword.
2726221345Sdim      if (DS.getTypeSpecType() == TST_bool &&
2727221345Sdim          DS.getTypeQualifiers() == DeclSpec::TQ_const &&
2728263508Sdim          DS.getStorageClassSpec() == DeclSpec::SCS_static)
2729263508Sdim        TryKeywordIdentFallback(true);
2730221345Sdim
2731221345Sdim      // We're done with the declaration-specifiers.
2732221345Sdim      goto DoneWithDeclSpec;
2733239462Sdim
2734193326Sed      // typedef-name
2735234353Sdim    case tok::kw_decltype:
2736193326Sed    case tok::identifier: {
2737193326Sed      // In C++, check to see if this is a scope specifier like foo::bar::, if
2738193326Sed      // so handle it as such.  This is important for ctor parsing.
2739234353Sdim      if (getLangOpts().CPlusPlus) {
2740263508Sdim        if (TryAnnotateCXXScopeToken(EnteringContext)) {
2741204643Srdivacky          if (!DS.hasTypeSpecifier())
2742204643Srdivacky            DS.SetTypeSpecError();
2743204643Srdivacky          goto DoneWithDeclSpec;
2744204643Srdivacky        }
2745204643Srdivacky        if (!Tok.is(tok::identifier))
2746204643Srdivacky          continue;
2747204643Srdivacky      }
2748198092Srdivacky
2749193326Sed      // This identifier can only be a typedef name if we haven't already seen
2750193326Sed      // a type-specifier.  Without this check we misparse:
2751193326Sed      //  typedef int X; struct Y { short X; };  as 'short int'.
2752193326Sed      if (DS.hasTypeSpecifier())
2753193326Sed        goto DoneWithDeclSpec;
2754198092Srdivacky
2755203955Srdivacky      // Check for need to substitute AltiVec keyword tokens.
2756203955Srdivacky      if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2757203955Srdivacky        break;
2758203955Srdivacky
2759239462Sdim      // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2760239462Sdim      //                allow the use of a typedef name as a type specifier.
2761239462Sdim      if (DS.isTypeAltiVecVector())
2762239462Sdim        goto DoneWithDeclSpec;
2763239462Sdim
2764212904Sdim      ParsedType TypeRep =
2765212904Sdim        Actions.getTypeName(*Tok.getIdentifierInfo(),
2766212904Sdim                            Tok.getLocation(), getCurScope());
2767193326Sed
2768193326Sed      // If this is not a typedef name, don't parse it as part of the declspec,
2769193326Sed      // it must be an implicit int or an error.
2770212904Sdim      if (!TypeRep) {
2771249423Sdim        ParsedAttributesWithRange Attrs(AttrFactory);
2772249423Sdim        if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) {
2773249423Sdim          if (!Attrs.empty()) {
2774249423Sdim            AttrsLastTime = true;
2775249423Sdim            attrs.takeAllFrom(Attrs);
2776249423Sdim          }
2777249423Sdim          continue;
2778249423Sdim        }
2779193326Sed        goto DoneWithDeclSpec;
2780193326Sed      }
2781193326Sed
2782202379Srdivacky      // If we're in a context where the identifier could be a class name,
2783202379Srdivacky      // check whether this is a constructor declaration.
2784234353Sdim      if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
2785210299Sed          Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
2786202379Srdivacky          isConstructorDeclarator())
2787193326Sed        goto DoneWithDeclSpec;
2788193326Sed
2789193326Sed      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2790198092Srdivacky                                     DiagID, TypeRep);
2791193326Sed      if (isInvalid)
2792193326Sed        break;
2793198092Srdivacky
2794193326Sed      DS.SetRangeEnd(Tok.getLocation());
2795193326Sed      ConsumeToken(); // The identifier
2796193326Sed
2797193326Sed      // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2798193326Sed      // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
2799239462Sdim      // Objective-C interface.
2800234353Sdim      if (Tok.is(tok::less) && getLangOpts().ObjC1)
2801218893Sdim        ParseObjCProtocolQualifiers(DS);
2802239462Sdim
2803193326Sed      // Need to support trailing type qualifiers (e.g. "id<p> const").
2804193326Sed      // If a type specifier follows, it will be diagnosed elsewhere.
2805193326Sed      continue;
2806193326Sed    }
2807193326Sed
2808193326Sed      // type-name
2809193326Sed    case tok::annot_template_id: {
2810224145Sdim      TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2811193326Sed      if (TemplateId->Kind != TNK_Type_template) {
2812193326Sed        // This template-id does not refer to a type name, so we're
2813193326Sed        // done with the type-specifiers.
2814193326Sed        goto DoneWithDeclSpec;
2815193326Sed      }
2816193326Sed
2817202379Srdivacky      // If we're in a context where the template-id could be a
2818202379Srdivacky      // constructor name or specialization, check whether this is a
2819202379Srdivacky      // constructor declaration.
2820234353Sdim      if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
2821210299Sed          Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
2822202379Srdivacky          isConstructorDeclarator())
2823202379Srdivacky        goto DoneWithDeclSpec;
2824202379Srdivacky
2825193326Sed      // Turn the template-id annotation token into a type annotation
2826193326Sed      // token, then try again to parse it as a type-specifier.
2827193326Sed      AnnotateTemplateIdTokenAsType();
2828193326Sed      continue;
2829193326Sed    }
2830193326Sed
2831193326Sed    // GNU attributes support.
2832193326Sed    case tok::kw___attribute:
2833234353Sdim      ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
2834193326Sed      continue;
2835193326Sed
2836193326Sed    // Microsoft declspec support.
2837193326Sed    case tok::kw___declspec:
2838218893Sdim      ParseMicrosoftDeclSpec(DS.getAttributes());
2839193326Sed      continue;
2840198092Srdivacky
2841193326Sed    // Microsoft single token adornments.
2842239462Sdim    case tok::kw___forceinline: {
2843263508Sdim      isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID);
2844239462Sdim      IdentifierInfo *AttrName = Tok.getIdentifierInfo();
2845243830Sdim      SourceLocation AttrNameLoc = Tok.getLocation();
2846239462Sdim      // FIXME: This does not work correctly if it is set to be a declspec
2847239462Sdim      //        attribute, and a GNU attribute is simply incorrect.
2848263508Sdim      DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
2849263508Sdim                                AttributeList::AS_GNU);
2850243830Sdim      break;
2851239462Sdim    }
2852194179Sed
2853263508Sdim    case tok::kw___sptr:
2854263508Sdim    case tok::kw___uptr:
2855194179Sed    case tok::kw___ptr64:
2856226633Sdim    case tok::kw___ptr32:
2857193326Sed    case tok::kw___w64:
2858193326Sed    case tok::kw___cdecl:
2859193326Sed    case tok::kw___stdcall:
2860193326Sed    case tok::kw___fastcall:
2861208600Srdivacky    case tok::kw___thiscall:
2862226633Sdim    case tok::kw___unaligned:
2863218893Sdim      ParseMicrosoftTypeAttributes(DS.getAttributes());
2864194179Sed      continue;
2865194179Sed
2866212904Sdim    // Borland single token adornments.
2867212904Sdim    case tok::kw___pascal:
2868218893Sdim      ParseBorlandTypeAttributes(DS.getAttributes());
2869212904Sdim      continue;
2870212904Sdim
2871218893Sdim    // OpenCL single token adornments.
2872218893Sdim    case tok::kw___kernel:
2873218893Sdim      ParseOpenCLAttributes(DS.getAttributes());
2874218893Sdim      continue;
2875218893Sdim
2876193326Sed    // storage-class-specifier
2877193326Sed    case tok::kw_typedef:
2878226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2879226633Sdim                                         PrevSpec, DiagID);
2880193326Sed      break;
2881193326Sed    case tok::kw_extern:
2882251662Sdim      if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
2883193326Sed        Diag(Tok, diag::ext_thread_before) << "extern";
2884226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2885226633Sdim                                         PrevSpec, DiagID);
2886193326Sed      break;
2887193326Sed    case tok::kw___private_extern__:
2888226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2889226633Sdim                                         Loc, PrevSpec, DiagID);
2890193326Sed      break;
2891193326Sed    case tok::kw_static:
2892251662Sdim      if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
2893193326Sed        Diag(Tok, diag::ext_thread_before) << "static";
2894226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2895226633Sdim                                         PrevSpec, DiagID);
2896193326Sed      break;
2897193326Sed    case tok::kw_auto:
2898249423Sdim      if (getLangOpts().CPlusPlus11) {
2899219077Sdim        if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
2900226633Sdim          isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2901226633Sdim                                             PrevSpec, DiagID);
2902219077Sdim          if (!isInvalid)
2903226633Sdim            Diag(Tok, diag::ext_auto_storage_class)
2904219077Sdim              << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
2905226633Sdim        } else
2906219077Sdim          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2907219077Sdim                                         DiagID);
2908226633Sdim      } else
2909226633Sdim        isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2910226633Sdim                                           PrevSpec, DiagID);
2911193326Sed      break;
2912193326Sed    case tok::kw_register:
2913226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2914226633Sdim                                         PrevSpec, DiagID);
2915193326Sed      break;
2916193326Sed    case tok::kw_mutable:
2917226633Sdim      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2918226633Sdim                                         PrevSpec, DiagID);
2919193326Sed      break;
2920193326Sed    case tok::kw___thread:
2921251662Sdim      isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,
2922251662Sdim                                               PrevSpec, DiagID);
2923193326Sed      break;
2924251662Sdim    case tok::kw_thread_local:
2925251662Sdim      isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc,
2926251662Sdim                                               PrevSpec, DiagID);
2927251662Sdim      break;
2928251662Sdim    case tok::kw__Thread_local:
2929251662Sdim      isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
2930251662Sdim                                               Loc, PrevSpec, DiagID);
2931251662Sdim      break;
2932198092Srdivacky
2933193326Sed    // function-specifier
2934193326Sed    case tok::kw_inline:
2935263508Sdim      isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);
2936193326Sed      break;
2937193326Sed    case tok::kw_virtual:
2938263508Sdim      isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
2939193326Sed      break;
2940193326Sed    case tok::kw_explicit:
2941263508Sdim      isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID);
2942193326Sed      break;
2943249423Sdim    case tok::kw__Noreturn:
2944249423Sdim      if (!getLangOpts().C11)
2945249423Sdim        Diag(Loc, diag::ext_c11_noreturn);
2946263508Sdim      isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);
2947249423Sdim      break;
2948193326Sed
2949226633Sdim    // alignment-specifier
2950226633Sdim    case tok::kw__Alignas:
2951234353Sdim      if (!getLangOpts().C11)
2952239462Sdim        Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
2953226633Sdim      ParseAlignmentSpecifier(DS.getAttributes());
2954226633Sdim      continue;
2955226633Sdim
2956193326Sed    // friend
2957193326Sed    case tok::kw_friend:
2958198092Srdivacky      if (DSContext == DSC_class)
2959198092Srdivacky        isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2960198092Srdivacky      else {
2961198092Srdivacky        PrevSpec = ""; // not actually used by the diagnostic
2962198092Srdivacky        DiagID = diag::err_friend_invalid_in_context;
2963198092Srdivacky        isInvalid = true;
2964198092Srdivacky      }
2965193326Sed      break;
2966198092Srdivacky
2967226633Sdim    // Modules
2968226633Sdim    case tok::kw___module_private__:
2969226633Sdim      isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2970226633Sdim      break;
2971239462Sdim
2972198954Srdivacky    // constexpr
2973198954Srdivacky    case tok::kw_constexpr:
2974198954Srdivacky      isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2975198954Srdivacky      break;
2976198954Srdivacky
2977193326Sed    // type-specifier
2978193326Sed    case tok::kw_short:
2979198092Srdivacky      isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2980198092Srdivacky                                      DiagID);
2981193326Sed      break;
2982193326Sed    case tok::kw_long:
2983193326Sed      if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
2984198092Srdivacky        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2985198092Srdivacky                                        DiagID);
2986193326Sed      else
2987198092Srdivacky        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2988198092Srdivacky                                        DiagID);
2989193326Sed      break;
2990221345Sdim    case tok::kw___int64:
2991221345Sdim        isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2992221345Sdim                                        DiagID);
2993221345Sdim      break;
2994193326Sed    case tok::kw_signed:
2995198092Srdivacky      isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2996198092Srdivacky                                     DiagID);
2997193326Sed      break;
2998193326Sed    case tok::kw_unsigned:
2999198092Srdivacky      isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
3000198092Srdivacky                                     DiagID);
3001193326Sed      break;
3002193326Sed    case tok::kw__Complex:
3003198092Srdivacky      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
3004198092Srdivacky                                        DiagID);
3005193326Sed      break;
3006193326Sed    case tok::kw__Imaginary:
3007198092Srdivacky      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
3008198092Srdivacky                                        DiagID);
3009193326Sed      break;
3010193326Sed    case tok::kw_void:
3011198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
3012198092Srdivacky                                     DiagID);
3013193326Sed      break;
3014193326Sed    case tok::kw_char:
3015198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
3016198092Srdivacky                                     DiagID);
3017193326Sed      break;
3018193326Sed    case tok::kw_int:
3019198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
3020198092Srdivacky                                     DiagID);
3021193326Sed      break;
3022234353Sdim    case tok::kw___int128:
3023234353Sdim      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
3024234353Sdim                                     DiagID);
3025234353Sdim      break;
3026234353Sdim    case tok::kw_half:
3027234353Sdim      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
3028234353Sdim                                     DiagID);
3029234353Sdim      break;
3030193326Sed    case tok::kw_float:
3031198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
3032198092Srdivacky                                     DiagID);
3033193326Sed      break;
3034193326Sed    case tok::kw_double:
3035198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
3036198092Srdivacky                                     DiagID);
3037193326Sed      break;
3038193326Sed    case tok::kw_wchar_t:
3039198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
3040198092Srdivacky                                     DiagID);
3041193326Sed      break;
3042198092Srdivacky    case tok::kw_char16_t:
3043198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
3044198092Srdivacky                                     DiagID);
3045198092Srdivacky      break;
3046198092Srdivacky    case tok::kw_char32_t:
3047198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
3048198092Srdivacky                                     DiagID);
3049198092Srdivacky      break;
3050193326Sed    case tok::kw_bool:
3051193326Sed    case tok::kw__Bool:
3052218893Sdim      if (Tok.is(tok::kw_bool) &&
3053218893Sdim          DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
3054218893Sdim          DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
3055218893Sdim        PrevSpec = ""; // Not used by the diagnostic.
3056218893Sdim        DiagID = diag::err_bool_redeclaration;
3057221345Sdim        // For better error recovery.
3058221345Sdim        Tok.setKind(tok::identifier);
3059218893Sdim        isInvalid = true;
3060218893Sdim      } else {
3061218893Sdim        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
3062218893Sdim                                       DiagID);
3063218893Sdim      }
3064193326Sed      break;
3065193326Sed    case tok::kw__Decimal32:
3066198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
3067198092Srdivacky                                     DiagID);
3068193326Sed      break;
3069193326Sed    case tok::kw__Decimal64:
3070198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
3071198092Srdivacky                                     DiagID);
3072193326Sed      break;
3073193326Sed    case tok::kw__Decimal128:
3074198092Srdivacky      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
3075198092Srdivacky                                     DiagID);
3076193326Sed      break;
3077203955Srdivacky    case tok::kw___vector:
3078203955Srdivacky      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
3079203955Srdivacky      break;
3080203955Srdivacky    case tok::kw___pixel:
3081203955Srdivacky      isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
3082203955Srdivacky      break;
3083249423Sdim    case tok::kw_image1d_t:
3084249423Sdim       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc,
3085249423Sdim                                      PrevSpec, DiagID);
3086249423Sdim      break;
3087249423Sdim    case tok::kw_image1d_array_t:
3088249423Sdim       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc,
3089249423Sdim                                      PrevSpec, DiagID);
3090249423Sdim      break;
3091249423Sdim    case tok::kw_image1d_buffer_t:
3092249423Sdim       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc,
3093249423Sdim                                      PrevSpec, DiagID);
3094249423Sdim      break;
3095249423Sdim    case tok::kw_image2d_t:
3096249423Sdim       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc,
3097249423Sdim                                      PrevSpec, DiagID);
3098249423Sdim      break;
3099249423Sdim    case tok::kw_image2d_array_t:
3100249423Sdim       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc,
3101249423Sdim                                      PrevSpec, DiagID);
3102249423Sdim      break;
3103249423Sdim    case tok::kw_image3d_t:
3104249423Sdim      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc,
3105249423Sdim                                     PrevSpec, DiagID);
3106249423Sdim      break;
3107249423Sdim    case tok::kw_sampler_t:
3108249423Sdim      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc,
3109249423Sdim                                     PrevSpec, DiagID);
3110249423Sdim      break;
3111249423Sdim    case tok::kw_event_t:
3112249423Sdim      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc,
3113249423Sdim                                     PrevSpec, DiagID);
3114249423Sdim      break;
3115221345Sdim    case tok::kw___unknown_anytype:
3116221345Sdim      isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
3117221345Sdim                                     PrevSpec, DiagID);
3118221345Sdim      break;
3119193326Sed
3120193326Sed    // class-specifier:
3121193326Sed    case tok::kw_class:
3122193326Sed    case tok::kw_struct:
3123243830Sdim    case tok::kw___interface:
3124193326Sed    case tok::kw_union: {
3125193326Sed      tok::TokenKind Kind = Tok.getKind();
3126193326Sed      ConsumeToken();
3127249423Sdim
3128249423Sdim      // These are attributes following class specifiers.
3129249423Sdim      // To produce better diagnostic, we parse them when
3130249423Sdim      // parsing class specifier.
3131249423Sdim      ParsedAttributesWithRange Attributes(AttrFactory);
3132234353Sdim      ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
3133249423Sdim                          EnteringContext, DSContext, Attributes);
3134249423Sdim
3135249423Sdim      // If there are attributes following class specifier,
3136249423Sdim      // take them over and handle them here.
3137249423Sdim      if (!Attributes.empty()) {
3138249423Sdim        AttrsLastTime = true;
3139249423Sdim        attrs.takeAllFrom(Attributes);
3140249423Sdim      }
3141193326Sed      continue;
3142193326Sed    }
3143193326Sed
3144193326Sed    // enum-specifier:
3145193326Sed    case tok::kw_enum:
3146193326Sed      ConsumeToken();
3147234353Sdim      ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
3148193326Sed      continue;
3149193326Sed
3150193326Sed    // cv-qualifier:
3151193326Sed    case tok::kw_const:
3152198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
3153243830Sdim                                 getLangOpts());
3154193326Sed      break;
3155193326Sed    case tok::kw_volatile:
3156198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
3157243830Sdim                                 getLangOpts());
3158193326Sed      break;
3159193326Sed    case tok::kw_restrict:
3160198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
3161243830Sdim                                 getLangOpts());
3162193326Sed      break;
3163193326Sed
3164193326Sed    // C++ typename-specifier:
3165193326Sed    case tok::kw_typename:
3166204643Srdivacky      if (TryAnnotateTypeOrScopeToken()) {
3167204643Srdivacky        DS.SetTypeSpecError();
3168204643Srdivacky        goto DoneWithDeclSpec;
3169204643Srdivacky      }
3170204643Srdivacky      if (!Tok.is(tok::kw_typename))
3171193326Sed        continue;
3172193326Sed      break;
3173193326Sed
3174193326Sed    // GNU typeof support.
3175193326Sed    case tok::kw_typeof:
3176193326Sed      ParseTypeofSpecifier(DS);
3177193326Sed      continue;
3178193326Sed
3179234353Sdim    case tok::annot_decltype:
3180195099Sed      ParseDecltypeSpecifier(DS);
3181195099Sed      continue;
3182195099Sed
3183223017Sdim    case tok::kw___underlying_type:
3184223017Sdim      ParseUnderlyingTypeSpecifier(DS);
3185226633Sdim      continue;
3186223017Sdim
3187226633Sdim    case tok::kw__Atomic:
3188249423Sdim      // C11 6.7.2.4/4:
3189249423Sdim      //   If the _Atomic keyword is immediately followed by a left parenthesis,
3190249423Sdim      //   it is interpreted as a type specifier (with a type name), not as a
3191249423Sdim      //   type qualifier.
3192249423Sdim      if (NextToken().is(tok::l_paren)) {
3193249423Sdim        ParseAtomicSpecifier(DS);
3194249423Sdim        continue;
3195249423Sdim      }
3196249423Sdim      isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
3197249423Sdim                                 getLangOpts());
3198249423Sdim      break;
3199226633Sdim
3200221345Sdim    // OpenCL qualifiers:
3201239462Sdim    case tok::kw_private:
3202234353Sdim      if (!getLangOpts().OpenCL)
3203221345Sdim        goto DoneWithDeclSpec;
3204221345Sdim    case tok::kw___private:
3205221345Sdim    case tok::kw___global:
3206221345Sdim    case tok::kw___local:
3207221345Sdim    case tok::kw___constant:
3208221345Sdim    case tok::kw___read_only:
3209221345Sdim    case tok::kw___write_only:
3210221345Sdim    case tok::kw___read_write:
3211221345Sdim      ParseOpenCLQualifiers(DS);
3212221345Sdim      break;
3213239462Sdim
3214193326Sed    case tok::less:
3215193326Sed      // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
3216193326Sed      // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,
3217193326Sed      // but we support it.
3218234353Sdim      if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
3219193326Sed        goto DoneWithDeclSpec;
3220198092Srdivacky
3221218893Sdim      if (!ParseObjCProtocolQualifiers(DS))
3222193326Sed        Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
3223206084Srdivacky          << FixItHint::CreateInsertion(Loc, "id")
3224218893Sdim          << SourceRange(Loc, DS.getSourceRange().getEnd());
3225239462Sdim
3226218893Sdim      // Need to support trailing type qualifiers (e.g. "id<p> const").
3227218893Sdim      // If a type specifier follows, it will be diagnosed elsewhere.
3228218893Sdim      continue;
3229193326Sed    }
3230198092Srdivacky    // If the specifier wasn't legal, issue a diagnostic.
3231193326Sed    if (isInvalid) {
3232193326Sed      assert(PrevSpec && "Method did not return previous specifier!");
3233198092Srdivacky      assert(DiagID);
3234239462Sdim
3235212904Sdim      if (DiagID == diag::ext_duplicate_declspec)
3236212904Sdim        Diag(Tok, DiagID)
3237212904Sdim          << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
3238212904Sdim      else
3239212904Sdim        Diag(Tok, DiagID) << PrevSpec;
3240193326Sed    }
3241219077Sdim
3242193326Sed    DS.SetRangeEnd(Tok.getLocation());
3243221345Sdim    if (DiagID != diag::err_bool_redeclaration)
3244221345Sdim      ConsumeToken();
3245239462Sdim
3246239462Sdim    AttrsLastTime = false;
3247193326Sed  }
3248193326Sed}
3249193326Sed
3250193326Sed/// ParseStructDeclaration - Parse a struct declaration without the terminating
3251193326Sed/// semicolon.
3252193326Sed///
3253193326Sed///       struct-declaration:
3254193326Sed///         specifier-qualifier-list struct-declarator-list
3255193326Sed/// [GNU]   __extension__ struct-declaration
3256193326Sed/// [GNU]   specifier-qualifier-list
3257193326Sed///       struct-declarator-list:
3258193326Sed///         struct-declarator
3259193326Sed///         struct-declarator-list ',' struct-declarator
3260193326Sed/// [GNU]   struct-declarator-list ',' attributes[opt] struct-declarator
3261193326Sed///       struct-declarator:
3262193326Sed///         declarator
3263193326Sed/// [GNU]   declarator attributes[opt]
3264193326Sed///         declarator[opt] ':' constant-expression
3265193326Sed/// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
3266193326Sed///
3267193326Sedvoid Parser::
3268239462SdimParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
3269239462Sdim
3270193326Sed  if (Tok.is(tok::kw___extension__)) {
3271193326Sed    // __extension__ silences extension warnings in the subexpression.
3272193326Sed    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
3273193326Sed    ConsumeToken();
3274193326Sed    return ParseStructDeclaration(DS, Fields);
3275193326Sed  }
3276198092Srdivacky
3277193326Sed  // Parse the common specifier-qualifiers-list piece.
3278193326Sed  ParseSpecifierQualifierList(DS);
3279198092Srdivacky
3280193326Sed  // If there are no declarators, this is a free-standing declaration
3281193326Sed  // specifier. Let the actions module cope with it.
3282193326Sed  if (Tok.is(tok::semi)) {
3283239462Sdim    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
3284239462Sdim                                                       DS);
3285239462Sdim    DS.complete(TheDecl);
3286193326Sed    return;
3287193326Sed  }
3288193326Sed
3289193326Sed  // Read struct-declarators until we find the semicolon.
3290198893Srdivacky  bool FirstDeclarator = true;
3291234353Sdim  SourceLocation CommaLoc;
3292193326Sed  while (1) {
3293239462Sdim    ParsingFieldDeclarator DeclaratorInfo(*this, DS);
3294234353Sdim    DeclaratorInfo.D.setCommaLoc(CommaLoc);
3295198092Srdivacky
3296198893Srdivacky    // Attributes are only allowed here on successive declarators.
3297218893Sdim    if (!FirstDeclarator)
3298218893Sdim      MaybeParseGNUAttributes(DeclaratorInfo.D);
3299198893Srdivacky
3300193326Sed    /// struct-declarator: declarator
3301193326Sed    /// struct-declarator: declarator[opt] ':' constant-expression
3302200583Srdivacky    if (Tok.isNot(tok::colon)) {
3303200583Srdivacky      // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
3304200583Srdivacky      ColonProtectionRAIIObject X(*this);
3305193326Sed      ParseDeclarator(DeclaratorInfo.D);
3306200583Srdivacky    }
3307198092Srdivacky
3308193326Sed    if (Tok.is(tok::colon)) {
3309193326Sed      ConsumeToken();
3310212904Sdim      ExprResult Res(ParseConstantExpression());
3311193326Sed      if (Res.isInvalid())
3312263508Sdim        SkipUntil(tok::semi, StopBeforeMatch);
3313193326Sed      else
3314193326Sed        DeclaratorInfo.BitfieldSize = Res.release();
3315193326Sed    }
3316193326Sed
3317193326Sed    // If attributes exist after the declarator, parse them.
3318218893Sdim    MaybeParseGNUAttributes(DeclaratorInfo.D);
3319193326Sed
3320198893Srdivacky    // We're done with this declarator;  invoke the callback.
3321239462Sdim    Fields.invoke(DeclaratorInfo);
3322198893Srdivacky
3323193326Sed    // If we don't have a comma, it is either the end of the list (a ';')
3324193326Sed    // or an error, bail out.
3325193326Sed    if (Tok.isNot(tok::comma))
3326193326Sed      return;
3327193326Sed
3328193326Sed    // Consume the comma.
3329234353Sdim    CommaLoc = ConsumeToken();
3330193326Sed
3331198893Srdivacky    FirstDeclarator = false;
3332193326Sed  }
3333193326Sed}
3334193326Sed
3335193326Sed/// ParseStructUnionBody
3336193326Sed///       struct-contents:
3337193326Sed///         struct-declaration-list
3338193326Sed/// [EXT]   empty
3339193326Sed/// [GNU]   "struct-declaration-list" without terminatoring ';'
3340193326Sed///       struct-declaration-list:
3341193326Sed///         struct-declaration
3342193326Sed///         struct-declaration-list struct-declaration
3343193326Sed/// [OBC]   '@' 'defs' '(' class-name ')'
3344193326Sed///
3345193326Sedvoid Parser::ParseStructUnionBody(SourceLocation RecordLoc,
3346212904Sdim                                  unsigned TagType, Decl *TagDecl) {
3347212904Sdim  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
3348212904Sdim                                      "parsing struct/union body");
3349249423Sdim  assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");
3350198092Srdivacky
3351226633Sdim  BalancedDelimiterTracker T(*this, tok::l_brace);
3352226633Sdim  if (T.consumeOpen())
3353226633Sdim    return;
3354198092Srdivacky
3355193326Sed  ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
3356210299Sed  Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
3357193326Sed
3358226633Sdim  SmallVector<Decl *, 32> FieldDecls;
3359193326Sed
3360193326Sed  // While we still have something to read, read the declarations in the struct.
3361193326Sed  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3362193326Sed    // Each iteration of this loop reads one struct-declaration.
3363198092Srdivacky
3364193326Sed    // Check for extraneous top-level semicolon.
3365193326Sed    if (Tok.is(tok::semi)) {
3366239462Sdim      ConsumeExtraSemi(InsideStruct, TagType);
3367193326Sed      continue;
3368193326Sed    }
3369193326Sed
3370249423Sdim    // Parse _Static_assert declaration.
3371249423Sdim    if (Tok.is(tok::kw__Static_assert)) {
3372249423Sdim      SourceLocation DeclEnd;
3373249423Sdim      ParseStaticAssertDeclaration(DeclEnd);
3374249423Sdim      continue;
3375249423Sdim    }
3376249423Sdim
3377251662Sdim    if (Tok.is(tok::annot_pragma_pack)) {
3378251662Sdim      HandlePragmaPack();
3379251662Sdim      continue;
3380251662Sdim    }
3381251662Sdim
3382251662Sdim    if (Tok.is(tok::annot_pragma_align)) {
3383251662Sdim      HandlePragmaAlign();
3384251662Sdim      continue;
3385251662Sdim    }
3386251662Sdim
3387193326Sed    if (!Tok.is(tok::at)) {
3388198893Srdivacky      struct CFieldCallback : FieldCallback {
3389198893Srdivacky        Parser &P;
3390212904Sdim        Decl *TagDecl;
3391226633Sdim        SmallVectorImpl<Decl *> &FieldDecls;
3392198092Srdivacky
3393212904Sdim        CFieldCallback(Parser &P, Decl *TagDecl,
3394226633Sdim                       SmallVectorImpl<Decl *> &FieldDecls) :
3395198893Srdivacky          P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
3396198893Srdivacky
3397239462Sdim        void invoke(ParsingFieldDeclarator &FD) {
3398198893Srdivacky          // Install the declarator into the current TagDecl.
3399212904Sdim          Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
3400198893Srdivacky                              FD.D.getDeclSpec().getSourceRange().getBegin(),
3401198893Srdivacky                                                 FD.D, FD.BitfieldSize);
3402198893Srdivacky          FieldDecls.push_back(Field);
3403239462Sdim          FD.complete(Field);
3404198092Srdivacky        }
3405198893Srdivacky      } Callback(*this, TagDecl, FieldDecls);
3406198893Srdivacky
3407239462Sdim      // Parse all the comma separated declarators.
3408239462Sdim      ParsingDeclSpec DS(*this);
3409198893Srdivacky      ParseStructDeclaration(DS, Callback);
3410193326Sed    } else { // Handle @defs
3411193326Sed      ConsumeToken();
3412193326Sed      if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
3413193326Sed        Diag(Tok, diag::err_unexpected_at);
3414263508Sdim        SkipUntil(tok::semi);
3415193326Sed        continue;
3416193326Sed      }
3417193326Sed      ConsumeToken();
3418193326Sed      ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
3419193326Sed      if (!Tok.is(tok::identifier)) {
3420193326Sed        Diag(Tok, diag::err_expected_ident);
3421263508Sdim        SkipUntil(tok::semi);
3422193326Sed        continue;
3423193326Sed      }
3424226633Sdim      SmallVector<Decl *, 16> Fields;
3425210299Sed      Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
3426193326Sed                        Tok.getIdentifierInfo(), Fields);
3427193326Sed      FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
3428193326Sed      ConsumeToken();
3429193326Sed      ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
3430198092Srdivacky    }
3431193326Sed
3432193326Sed    if (Tok.is(tok::semi)) {
3433193326Sed      ConsumeToken();
3434193326Sed    } else if (Tok.is(tok::r_brace)) {
3435203955Srdivacky      ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
3436193326Sed      break;
3437193326Sed    } else {
3438203955Srdivacky      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
3439203955Srdivacky      // Skip to end of block or statement to avoid ext-warning on extra ';'.
3440263508Sdim      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
3441203955Srdivacky      // If we stopped at a ';', eat it.
3442203955Srdivacky      if (Tok.is(tok::semi)) ConsumeToken();
3443193326Sed    }
3444193326Sed  }
3445198092Srdivacky
3446226633Sdim  T.consumeClose();
3447198092Srdivacky
3448221345Sdim  ParsedAttributes attrs(AttrFactory);
3449193326Sed  // If attributes exist after struct contents, parse them.
3450218893Sdim  MaybeParseGNUAttributes(attrs);
3451193326Sed
3452210299Sed  Actions.ActOnFields(getCurScope(),
3453226633Sdim                      RecordLoc, TagDecl, FieldDecls,
3454226633Sdim                      T.getOpenLocation(), T.getCloseLocation(),
3455218893Sdim                      attrs.getList());
3456193326Sed  StructScope.Exit();
3457226633Sdim  Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
3458226633Sdim                                   T.getCloseLocation());
3459193326Sed}
3460193326Sed
3461193326Sed/// ParseEnumSpecifier
3462193326Sed///       enum-specifier: [C99 6.7.2.2]
3463193326Sed///         'enum' identifier[opt] '{' enumerator-list '}'
3464193326Sed///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
3465193326Sed/// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
3466193326Sed///                                                 '}' attributes[opt]
3467234353Sdim/// [MS]    'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
3468234353Sdim///                                                 '}'
3469193326Sed///         'enum' identifier
3470193326Sed/// [GNU]   'enum' attributes[opt] identifier
3471193326Sed///
3472234353Sdim/// [C++11] enum-head '{' enumerator-list[opt] '}'
3473234353Sdim/// [C++11] enum-head '{' enumerator-list ','  '}'
3474218893Sdim///
3475234353Sdim///       enum-head: [C++11]
3476234353Sdim///         enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
3477234353Sdim///         enum-key attribute-specifier-seq[opt] nested-name-specifier
3478234353Sdim///             identifier enum-base[opt]
3479218893Sdim///
3480234353Sdim///       enum-key: [C++11]
3481218893Sdim///         'enum'
3482218893Sdim///         'enum' 'class'
3483218893Sdim///         'enum' 'struct'
3484218893Sdim///
3485234353Sdim///       enum-base: [C++11]
3486218893Sdim///         ':' type-specifier-seq
3487218893Sdim///
3488193326Sed/// [C++] elaborated-type-specifier:
3489193326Sed/// [C++]   'enum' '::'[opt] nested-name-specifier[opt] identifier
3490193326Sed///
3491193326Sedvoid Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
3492204643Srdivacky                                const ParsedTemplateInfo &TemplateInfo,
3493234353Sdim                                AccessSpecifier AS, DeclSpecContext DSC) {
3494193326Sed  // Parse the tag portion of this.
3495198092Srdivacky  if (Tok.is(tok::code_completion)) {
3496198092Srdivacky    // Code completion for an enum name.
3497210299Sed    Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
3498226633Sdim    return cutOffParsing();
3499198092Srdivacky  }
3500224145Sdim
3501239462Sdim  // If attributes exist after tag, parse them.
3502239462Sdim  ParsedAttributesWithRange attrs(AttrFactory);
3503239462Sdim  MaybeParseGNUAttributes(attrs);
3504249423Sdim  MaybeParseCXX11Attributes(attrs);
3505239462Sdim
3506239462Sdim  // If declspecs exist after tag, parse them.
3507239462Sdim  while (Tok.is(tok::kw___declspec))
3508239462Sdim    ParseMicrosoftDeclSpec(attrs);
3509239462Sdim
3510234353Sdim  SourceLocation ScopedEnumKWLoc;
3511224145Sdim  bool IsScopedUsingClassTag = false;
3512224145Sdim
3513239462Sdim  // In C++11, recognize 'enum class' and 'enum struct'.
3514251662Sdim  if (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct)) {
3515251662Sdim    Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum
3516251662Sdim                                        : diag::ext_scoped_enum);
3517224145Sdim    IsScopedUsingClassTag = Tok.is(tok::kw_class);
3518234353Sdim    ScopedEnumKWLoc = ConsumeToken();
3519234353Sdim
3520239462Sdim    // Attributes are not allowed between these keywords.  Diagnose,
3521239462Sdim    // but then just treat them like they appeared in the right place.
3522239462Sdim    ProhibitAttributes(attrs);
3523234353Sdim
3524239462Sdim    // They are allowed afterwards, though.
3525239462Sdim    MaybeParseGNUAttributes(attrs);
3526249423Sdim    MaybeParseCXX11Attributes(attrs);
3527239462Sdim    while (Tok.is(tok::kw___declspec))
3528239462Sdim      ParseMicrosoftDeclSpec(attrs);
3529239462Sdim  }
3530193326Sed
3531239462Sdim  // C++11 [temp.explicit]p12:
3532239462Sdim  //   The usual access controls do not apply to names used to specify
3533239462Sdim  //   explicit instantiations.
3534239462Sdim  // We extend this to also cover explicit specializations.  Note that
3535239462Sdim  // we don't suppress if this turns out to be an elaborated type
3536239462Sdim  // specifier.
3537239462Sdim  bool shouldDelayDiagsInTag =
3538239462Sdim    (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3539239462Sdim     TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3540239462Sdim  SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
3541224145Sdim
3542234353Sdim  // Enum definitions should not be parsed in a trailing-return-type.
3543234353Sdim  bool AllowDeclaration = DSC != DSC_trailing;
3544234353Sdim
3545234353Sdim  bool AllowFixedUnderlyingType = AllowDeclaration &&
3546249423Sdim    (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt ||
3547234353Sdim     getLangOpts().ObjC2);
3548234353Sdim
3549208600Srdivacky  CXXScopeSpec &SS = DS.getTypeSpecScope();
3550234353Sdim  if (getLangOpts().CPlusPlus) {
3551224145Sdim    // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3552224145Sdim    // if a fixed underlying type is allowed.
3553224145Sdim    ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
3554239462Sdim
3555239462Sdim    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
3556249423Sdim                                       /*EnteringContext=*/true))
3557204643Srdivacky      return;
3558204643Srdivacky
3559204643Srdivacky    if (SS.isSet() && Tok.isNot(tok::identifier)) {
3560193326Sed      Diag(Tok, diag::err_expected_ident);
3561193326Sed      if (Tok.isNot(tok::l_brace)) {
3562193326Sed        // Has no name and is not a definition.
3563193326Sed        // Skip the rest of this declarator, up until the comma or semicolon.
3564263508Sdim        SkipUntil(tok::comma, StopAtSemi);
3565193326Sed        return;
3566193326Sed      }
3567193326Sed    }
3568193326Sed  }
3569198092Srdivacky
3570193326Sed  // Must have either 'enum name' or 'enum {...}'.
3571219077Sdim  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
3572234353Sdim      !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
3573193326Sed    Diag(Tok, diag::err_expected_ident_lbrace);
3574198092Srdivacky
3575193326Sed    // Skip the rest of this declarator, up until the comma or semicolon.
3576263508Sdim    SkipUntil(tok::comma, StopAtSemi);
3577193326Sed    return;
3578193326Sed  }
3579198092Srdivacky
3580193326Sed  // If an identifier is present, consume and remember it.
3581193326Sed  IdentifierInfo *Name = 0;
3582193326Sed  SourceLocation NameLoc;
3583193326Sed  if (Tok.is(tok::identifier)) {
3584193326Sed    Name = Tok.getIdentifierInfo();
3585193326Sed    NameLoc = ConsumeToken();
3586193326Sed  }
3587198092Srdivacky
3588234353Sdim  if (!Name && ScopedEnumKWLoc.isValid()) {
3589218893Sdim    // C++0x 7.2p2: The optional identifier shall not be omitted in the
3590218893Sdim    // declaration of a scoped enumeration.
3591218893Sdim    Diag(Tok, diag::err_scoped_enum_missing_identifier);
3592234353Sdim    ScopedEnumKWLoc = SourceLocation();
3593218893Sdim    IsScopedUsingClassTag = false;
3594218893Sdim  }
3595218893Sdim
3596239462Sdim  // Okay, end the suppression area.  We'll decide whether to emit the
3597239462Sdim  // diagnostics in a second.
3598239462Sdim  if (shouldDelayDiagsInTag)
3599239462Sdim    diagsFromTag.done();
3600234353Sdim
3601218893Sdim  TypeResult BaseType;
3602218893Sdim
3603218893Sdim  // Parse the fixed underlying type.
3604239462Sdim  bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3605219077Sdim  if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
3606218893Sdim    bool PossibleBitfield = false;
3607239462Sdim    if (CanBeBitfield) {
3608218893Sdim      // If we're in class scope, this can either be an enum declaration with
3609218893Sdim      // an underlying type, or a declaration of a bitfield member. We try to
3610218893Sdim      // use a simple disambiguation scheme first to catch the common cases
3611239462Sdim      // (integer literal, sizeof); if it's still ambiguous, we then consider
3612239462Sdim      // anything that's a simple-type-specifier followed by '(' as an
3613239462Sdim      // expression. This suffices because function types are not valid
3614218893Sdim      // underlying types anyway.
3615243830Sdim      EnterExpressionEvaluationContext Unevaluated(Actions,
3616243830Sdim                                                   Sema::ConstantEvaluated);
3617218893Sdim      TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
3618239462Sdim      // If the next token starts an expression, we know we're parsing a
3619218893Sdim      // bit-field. This is the common case.
3620218893Sdim      if (TPR == TPResult::True())
3621218893Sdim        PossibleBitfield = true;
3622218893Sdim      // If the next token starts a type-specifier-seq, it may be either a
3623218893Sdim      // a fixed underlying type or the start of a function-style cast in C++;
3624239462Sdim      // lookahead one more token to see if it's obvious that we have a
3625218893Sdim      // fixed underlying type.
3626239462Sdim      else if (TPR == TPResult::False() &&
3627218893Sdim               GetLookAheadToken(2).getKind() == tok::semi) {
3628218893Sdim        // Consume the ':'.
3629218893Sdim        ConsumeToken();
3630218893Sdim      } else {
3631218893Sdim        // We have the start of a type-specifier-seq, so we have to perform
3632218893Sdim        // tentative parsing to determine whether we have an expression or a
3633218893Sdim        // type.
3634218893Sdim        TentativeParsingAction TPA(*this);
3635218893Sdim
3636218893Sdim        // Consume the ':'.
3637218893Sdim        ConsumeToken();
3638234353Sdim
3639234353Sdim        // If we see a type specifier followed by an open-brace, we have an
3640234353Sdim        // ambiguity between an underlying type and a C++11 braced
3641234353Sdim        // function-style cast. Resolve this by always treating it as an
3642234353Sdim        // underlying type.
3643234353Sdim        // FIXME: The standard is not entirely clear on how to disambiguate in
3644234353Sdim        // this case.
3645234353Sdim        if ((getLangOpts().CPlusPlus &&
3646234353Sdim             isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
3647234353Sdim            (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
3648218893Sdim          // We'll parse this as a bitfield later.
3649218893Sdim          PossibleBitfield = true;
3650218893Sdim          TPA.Revert();
3651218893Sdim        } else {
3652218893Sdim          // We have a type-specifier-seq.
3653218893Sdim          TPA.Commit();
3654218893Sdim        }
3655218893Sdim      }
3656218893Sdim    } else {
3657218893Sdim      // Consume the ':'.
3658218893Sdim      ConsumeToken();
3659218893Sdim    }
3660218893Sdim
3661218893Sdim    if (!PossibleBitfield) {
3662218893Sdim      SourceRange Range;
3663218893Sdim      BaseType = ParseTypeName(&Range);
3664239462Sdim
3665249423Sdim      if (getLangOpts().CPlusPlus11) {
3666234353Sdim        Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
3667243830Sdim      } else if (!getLangOpts().ObjC2) {
3668243830Sdim        if (getLangOpts().CPlusPlus)
3669243830Sdim          Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range;
3670243830Sdim        else
3671243830Sdim          Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range;
3672243830Sdim      }
3673218893Sdim    }
3674218893Sdim  }
3675218893Sdim
3676234353Sdim  // There are four options here.  If we have 'friend enum foo;' then this is a
3677234353Sdim  // friend declaration, and cannot have an accompanying definition. If we have
3678234353Sdim  // 'enum foo;', then this is a forward declaration.  If we have
3679234353Sdim  // 'enum foo {...' then this is a definition. Otherwise we have something
3680234353Sdim  // like 'enum foo xyz', a reference.
3681193326Sed  //
3682193326Sed  // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3683193326Sed  // enum foo {..};  void bar() { enum foo; }    <- new foo in bar.
3684193326Sed  // enum foo {..};  void bar() { enum foo x; }  <- use of old foo.
3685193326Sed  //
3686212904Sdim  Sema::TagUseKind TUK;
3687239462Sdim  if (!AllowDeclaration) {
3688234353Sdim    TUK = Sema::TUK_Reference;
3689239462Sdim  } else if (Tok.is(tok::l_brace)) {
3690239462Sdim    if (DS.isFriendSpecified()) {
3691239462Sdim      Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3692239462Sdim        << SourceRange(DS.getFriendSpecLoc());
3693239462Sdim      ConsumeBrace();
3694263508Sdim      SkipUntil(tok::r_brace, StopAtSemi);
3695239462Sdim      TUK = Sema::TUK_Friend;
3696239462Sdim    } else {
3697239462Sdim      TUK = Sema::TUK_Definition;
3698239462Sdim    }
3699239462Sdim  } else if (DSC != DSC_type_specifier &&
3700239462Sdim             (Tok.is(tok::semi) ||
3701239462Sdim              (Tok.isAtStartOfLine() &&
3702239462Sdim               !isValidAfterTypeSpecifier(CanBeBitfield)))) {
3703239462Sdim    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3704239462Sdim    if (Tok.isNot(tok::semi)) {
3705239462Sdim      // A semicolon was missing after this declaration. Diagnose and recover.
3706239462Sdim      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3707239462Sdim                       "enum");
3708239462Sdim      PP.EnterToken(Tok);
3709239462Sdim      Tok.setKind(tok::semi);
3710239462Sdim    }
3711239462Sdim  } else {
3712212904Sdim    TUK = Sema::TUK_Reference;
3713239462Sdim  }
3714234353Sdim
3715239462Sdim  // If this is an elaborated type specifier, and we delayed
3716239462Sdim  // diagnostics before, just merge them into the current pool.
3717239462Sdim  if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3718239462Sdim    diagsFromTag.redelay();
3719239462Sdim  }
3720239462Sdim
3721234353Sdim  MultiTemplateParamsArg TParams;
3722207619Srdivacky  if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
3723212904Sdim      TUK != Sema::TUK_Reference) {
3724249423Sdim    if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {
3725234353Sdim      // Skip the rest of this declarator, up until the comma or semicolon.
3726234353Sdim      Diag(Tok, diag::err_enum_template);
3727263508Sdim      SkipUntil(tok::comma, StopAtSemi);
3728234353Sdim      return;
3729234353Sdim    }
3730234353Sdim
3731234353Sdim    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3732234353Sdim      // Enumerations can't be explicitly instantiated.
3733234353Sdim      DS.SetTypeSpecError();
3734234353Sdim      Diag(StartLoc, diag::err_explicit_instantiation_enum);
3735234353Sdim      return;
3736234353Sdim    }
3737234353Sdim
3738234353Sdim    assert(TemplateInfo.TemplateParams && "no template parameters");
3739234353Sdim    TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3740234353Sdim                                     TemplateInfo.TemplateParams->size());
3741207619Srdivacky  }
3742234353Sdim
3743239462Sdim  if (TUK == Sema::TUK_Reference)
3744239462Sdim    ProhibitAttributes(attrs);
3745239462Sdim
3746219077Sdim  if (!Name && TUK != Sema::TUK_Definition) {
3747219077Sdim    Diag(Tok, diag::err_enumerator_unnamed_no_def);
3748234353Sdim
3749219077Sdim    // Skip the rest of this declarator, up until the comma or semicolon.
3750263508Sdim    SkipUntil(tok::comma, StopAtSemi);
3751219077Sdim    return;
3752219077Sdim  }
3753234353Sdim
3754193326Sed  bool Owned = false;
3755198092Srdivacky  bool IsDependent = false;
3756207619Srdivacky  const char *PrevSpec = 0;
3757207619Srdivacky  unsigned DiagID;
3758212904Sdim  Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
3759218893Sdim                                   StartLoc, SS, Name, NameLoc, attrs.getList(),
3760234353Sdim                                   AS, DS.getModulePrivateSpecLoc(), TParams,
3761234353Sdim                                   Owned, IsDependent, ScopedEnumKWLoc,
3762218893Sdim                                   IsScopedUsingClassTag, BaseType);
3763218893Sdim
3764207619Srdivacky  if (IsDependent) {
3765239462Sdim    // This enum has a dependent nested-name-specifier. Handle it as a
3766207619Srdivacky    // dependent tag.
3767207619Srdivacky    if (!Name) {
3768207619Srdivacky      DS.SetTypeSpecError();
3769207619Srdivacky      Diag(Tok, diag::err_expected_type_name_after_typename);
3770207619Srdivacky      return;
3771207619Srdivacky    }
3772239462Sdim
3773210299Sed    TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
3774239462Sdim                                                TUK, SS, Name, StartLoc,
3775207619Srdivacky                                                NameLoc);
3776207619Srdivacky    if (Type.isInvalid()) {
3777207619Srdivacky      DS.SetTypeSpecError();
3778207619Srdivacky      return;
3779207619Srdivacky    }
3780239462Sdim
3781221345Sdim    if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3782221345Sdim                           NameLoc.isValid() ? NameLoc : StartLoc,
3783221345Sdim                           PrevSpec, DiagID, Type.get()))
3784207619Srdivacky      Diag(StartLoc, DiagID) << PrevSpec;
3785239462Sdim
3786207619Srdivacky    return;
3787207619Srdivacky  }
3788198092Srdivacky
3789212904Sdim  if (!TagDecl) {
3790239462Sdim    // The action failed to produce an enumeration tag. If this is a
3791207619Srdivacky    // definition, consume the entire definition.
3792234353Sdim    if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
3793207619Srdivacky      ConsumeBrace();
3794263508Sdim      SkipUntil(tok::r_brace, StopAtSemi);
3795207619Srdivacky    }
3796239462Sdim
3797207619Srdivacky    DS.SetTypeSpecError();
3798207619Srdivacky    return;
3799207619Srdivacky  }
3800198092Srdivacky
3801239462Sdim  if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
3802239462Sdim    ParseEnumBody(StartLoc, TagDecl);
3803234353Sdim
3804221345Sdim  if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3805221345Sdim                         NameLoc.isValid() ? NameLoc : StartLoc,
3806221345Sdim                         PrevSpec, DiagID, TagDecl, Owned))
3807198092Srdivacky    Diag(StartLoc, DiagID) << PrevSpec;
3808193326Sed}
3809193326Sed
3810193326Sed/// ParseEnumBody - Parse a {} enclosed enumerator-list.
3811193326Sed///       enumerator-list:
3812193326Sed///         enumerator
3813193326Sed///         enumerator-list ',' enumerator
3814193326Sed///       enumerator:
3815193326Sed///         enumeration-constant
3816193326Sed///         enumeration-constant '=' constant-expression
3817193326Sed///       enumeration-constant:
3818193326Sed///         identifier
3819193326Sed///
3820212904Sdimvoid Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
3821193326Sed  // Enter the scope of the enum body and start the definition.
3822193326Sed  ParseScope EnumScope(this, Scope::DeclScope);
3823210299Sed  Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
3824193326Sed
3825226633Sdim  BalancedDelimiterTracker T(*this, tok::l_brace);
3826226633Sdim  T.consumeOpen();
3827198092Srdivacky
3828193326Sed  // C does not allow an empty enumerator-list, C++ does [dcl.enum].
3829234353Sdim  if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
3830210299Sed    Diag(Tok, diag::error_empty_enum);
3831198092Srdivacky
3832226633Sdim  SmallVector<Decl *, 32> EnumConstantDecls;
3833193326Sed
3834212904Sdim  Decl *LastEnumConstDecl = 0;
3835198092Srdivacky
3836193326Sed  // Parse the enumerator-list.
3837193326Sed  while (Tok.is(tok::identifier)) {
3838193326Sed    IdentifierInfo *Ident = Tok.getIdentifierInfo();
3839193326Sed    SourceLocation IdentLoc = ConsumeToken();
3840198092Srdivacky
3841218893Sdim    // If attributes exist after the enumerator, parse them.
3842239462Sdim    ParsedAttributesWithRange attrs(AttrFactory);
3843218893Sdim    MaybeParseGNUAttributes(attrs);
3844249423Sdim    MaybeParseCXX11Attributes(attrs);
3845239462Sdim    ProhibitAttributes(attrs);
3846218893Sdim
3847193326Sed    SourceLocation EqualLoc;
3848212904Sdim    ExprResult AssignedVal;
3849239462Sdim    ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
3850239462Sdim
3851193326Sed    if (Tok.is(tok::equal)) {
3852193326Sed      EqualLoc = ConsumeToken();
3853193326Sed      AssignedVal = ParseConstantExpression();
3854193326Sed      if (AssignedVal.isInvalid())
3855263508Sdim        SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
3856193326Sed    }
3857198092Srdivacky
3858193326Sed    // Install the enumerator constant into EnumDecl.
3859212904Sdim    Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3860212904Sdim                                                    LastEnumConstDecl,
3861212904Sdim                                                    IdentLoc, Ident,
3862218893Sdim                                                    attrs.getList(), EqualLoc,
3863212904Sdim                                                    AssignedVal.release());
3864234353Sdim    PD.complete(EnumConstDecl);
3865239462Sdim
3866193326Sed    EnumConstantDecls.push_back(EnumConstDecl);
3867193326Sed    LastEnumConstDecl = EnumConstDecl;
3868198092Srdivacky
3869218893Sdim    if (Tok.is(tok::identifier)) {
3870218893Sdim      // We're missing a comma between enumerators.
3871218893Sdim      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
3872239462Sdim      Diag(Loc, diag::err_enumerator_list_missing_comma)
3873218893Sdim        << FixItHint::CreateInsertion(Loc, ", ");
3874218893Sdim      continue;
3875218893Sdim    }
3876239462Sdim
3877193326Sed    if (Tok.isNot(tok::comma))
3878193326Sed      break;
3879193326Sed    SourceLocation CommaLoc = ConsumeToken();
3880198092Srdivacky
3881234353Sdim    if (Tok.isNot(tok::identifier)) {
3882249423Sdim      if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)
3883239462Sdim        Diag(CommaLoc, getLangOpts().CPlusPlus ?
3884239462Sdim               diag::ext_enumerator_list_comma_cxx :
3885239462Sdim               diag::ext_enumerator_list_comma_c)
3886234353Sdim          << FixItHint::CreateRemoval(CommaLoc);
3887249423Sdim      else if (getLangOpts().CPlusPlus11)
3888234353Sdim        Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3889234353Sdim          << FixItHint::CreateRemoval(CommaLoc);
3890234353Sdim    }
3891193326Sed  }
3892198092Srdivacky
3893193326Sed  // Eat the }.
3894226633Sdim  T.consumeClose();
3895193326Sed
3896193326Sed  // If attributes exist after the identifier list, parse them.
3897221345Sdim  ParsedAttributes attrs(AttrFactory);
3898218893Sdim  MaybeParseGNUAttributes(attrs);
3899193326Sed
3900226633Sdim  Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
3901251662Sdim                        EnumDecl, EnumConstantDecls,
3902251662Sdim                        getCurScope(),
3903226633Sdim                        attrs.getList());
3904198092Srdivacky
3905193326Sed  EnumScope.Exit();
3906226633Sdim  Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3907226633Sdim                                   T.getCloseLocation());
3908239462Sdim
3909239462Sdim  // The next token must be valid after an enum definition. If not, a ';'
3910239462Sdim  // was probably forgotten.
3911239462Sdim  bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3912239462Sdim  if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
3913239462Sdim    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3914239462Sdim    // Push this token back into the preprocessor and change our current token
3915239462Sdim    // to ';' so that the rest of the code recovers as though there were an
3916239462Sdim    // ';' after the definition.
3917239462Sdim    PP.EnterToken(Tok);
3918239462Sdim    Tok.setKind(tok::semi);
3919239462Sdim  }
3920193326Sed}
3921193326Sed
3922193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the
3923193326Sed/// start of a type-qualifier-list.
3924193326Sedbool Parser::isTypeQualifier() const {
3925193326Sed  switch (Tok.getKind()) {
3926193326Sed  default: return false;
3927221345Sdim
3928221345Sdim    // type-qualifier only in OpenCL
3929221345Sdim  case tok::kw_private:
3930234353Sdim    return getLangOpts().OpenCL;
3931221345Sdim
3932193326Sed    // type-qualifier
3933193326Sed  case tok::kw_const:
3934193326Sed  case tok::kw_volatile:
3935193326Sed  case tok::kw_restrict:
3936221345Sdim  case tok::kw___private:
3937221345Sdim  case tok::kw___local:
3938221345Sdim  case tok::kw___global:
3939221345Sdim  case tok::kw___constant:
3940221345Sdim  case tok::kw___read_only:
3941221345Sdim  case tok::kw___read_write:
3942221345Sdim  case tok::kw___write_only:
3943193326Sed    return true;
3944193326Sed  }
3945193326Sed}
3946193326Sed
3947204643Srdivacky/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3948204643Srdivacky/// is definitely a type-specifier.  Return false if it isn't part of a type
3949204643Srdivacky/// specifier or if we're not sure.
3950204643Srdivackybool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3951204643Srdivacky  switch (Tok.getKind()) {
3952204643Srdivacky  default: return false;
3953204643Srdivacky    // type-specifiers
3954204643Srdivacky  case tok::kw_short:
3955204643Srdivacky  case tok::kw_long:
3956221345Sdim  case tok::kw___int64:
3957234353Sdim  case tok::kw___int128:
3958204643Srdivacky  case tok::kw_signed:
3959204643Srdivacky  case tok::kw_unsigned:
3960204643Srdivacky  case tok::kw__Complex:
3961204643Srdivacky  case tok::kw__Imaginary:
3962204643Srdivacky  case tok::kw_void:
3963204643Srdivacky  case tok::kw_char:
3964204643Srdivacky  case tok::kw_wchar_t:
3965204643Srdivacky  case tok::kw_char16_t:
3966204643Srdivacky  case tok::kw_char32_t:
3967204643Srdivacky  case tok::kw_int:
3968226633Sdim  case tok::kw_half:
3969204643Srdivacky  case tok::kw_float:
3970204643Srdivacky  case tok::kw_double:
3971204643Srdivacky  case tok::kw_bool:
3972204643Srdivacky  case tok::kw__Bool:
3973204643Srdivacky  case tok::kw__Decimal32:
3974204643Srdivacky  case tok::kw__Decimal64:
3975204643Srdivacky  case tok::kw__Decimal128:
3976204643Srdivacky  case tok::kw___vector:
3977239462Sdim
3978249423Sdim    // OpenCL specific types:
3979249423Sdim  case tok::kw_image1d_t:
3980249423Sdim  case tok::kw_image1d_array_t:
3981249423Sdim  case tok::kw_image1d_buffer_t:
3982249423Sdim  case tok::kw_image2d_t:
3983249423Sdim  case tok::kw_image2d_array_t:
3984249423Sdim  case tok::kw_image3d_t:
3985249423Sdim  case tok::kw_sampler_t:
3986249423Sdim  case tok::kw_event_t:
3987249423Sdim
3988204643Srdivacky    // struct-or-union-specifier (C99) or class-specifier (C++)
3989204643Srdivacky  case tok::kw_class:
3990204643Srdivacky  case tok::kw_struct:
3991243830Sdim  case tok::kw___interface:
3992204643Srdivacky  case tok::kw_union:
3993204643Srdivacky    // enum-specifier
3994204643Srdivacky  case tok::kw_enum:
3995239462Sdim
3996204643Srdivacky    // typedef-name
3997204643Srdivacky  case tok::annot_typename:
3998204643Srdivacky    return true;
3999204643Srdivacky  }
4000204643Srdivacky}
4001204643Srdivacky
4002193326Sed/// isTypeSpecifierQualifier - Return true if the current token could be the
4003193326Sed/// start of a specifier-qualifier-list.
4004193326Sedbool Parser::isTypeSpecifierQualifier() {
4005193326Sed  switch (Tok.getKind()) {
4006193326Sed  default: return false;
4007198092Srdivacky
4008193326Sed  case tok::identifier:   // foo::bar
4009203955Srdivacky    if (TryAltiVecVectorToken())
4010203955Srdivacky      return true;
4011203955Srdivacky    // Fall through.
4012193326Sed  case tok::kw_typename:  // typename T::type
4013193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
4014193326Sed    // recurse to handle whatever we get.
4015193326Sed    if (TryAnnotateTypeOrScopeToken())
4016204643Srdivacky      return true;
4017204643Srdivacky    if (Tok.is(tok::identifier))
4018204643Srdivacky      return false;
4019204643Srdivacky    return isTypeSpecifierQualifier();
4020193326Sed
4021193326Sed  case tok::coloncolon:   // ::foo::bar
4022193326Sed    if (NextToken().is(tok::kw_new) ||    // ::new
4023193326Sed        NextToken().is(tok::kw_delete))   // ::delete
4024193326Sed      return false;
4025193326Sed
4026193326Sed    if (TryAnnotateTypeOrScopeToken())
4027204643Srdivacky      return true;
4028204643Srdivacky    return isTypeSpecifierQualifier();
4029198092Srdivacky
4030193326Sed    // GNU attributes support.
4031193326Sed  case tok::kw___attribute:
4032193326Sed    // GNU typeof support.
4033193326Sed  case tok::kw_typeof:
4034198092Srdivacky
4035193326Sed    // type-specifiers
4036193326Sed  case tok::kw_short:
4037193326Sed  case tok::kw_long:
4038221345Sdim  case tok::kw___int64:
4039234353Sdim  case tok::kw___int128:
4040193326Sed  case tok::kw_signed:
4041193326Sed  case tok::kw_unsigned:
4042193326Sed  case tok::kw__Complex:
4043193326Sed  case tok::kw__Imaginary:
4044193326Sed  case tok::kw_void:
4045193326Sed  case tok::kw_char:
4046193326Sed  case tok::kw_wchar_t:
4047198092Srdivacky  case tok::kw_char16_t:
4048198092Srdivacky  case tok::kw_char32_t:
4049193326Sed  case tok::kw_int:
4050226633Sdim  case tok::kw_half:
4051193326Sed  case tok::kw_float:
4052193326Sed  case tok::kw_double:
4053193326Sed  case tok::kw_bool:
4054193326Sed  case tok::kw__Bool:
4055193326Sed  case tok::kw__Decimal32:
4056193326Sed  case tok::kw__Decimal64:
4057193326Sed  case tok::kw__Decimal128:
4058203955Srdivacky  case tok::kw___vector:
4059198092Srdivacky
4060249423Sdim    // OpenCL specific types:
4061249423Sdim  case tok::kw_image1d_t:
4062249423Sdim  case tok::kw_image1d_array_t:
4063249423Sdim  case tok::kw_image1d_buffer_t:
4064249423Sdim  case tok::kw_image2d_t:
4065249423Sdim  case tok::kw_image2d_array_t:
4066249423Sdim  case tok::kw_image3d_t:
4067249423Sdim  case tok::kw_sampler_t:
4068249423Sdim  case tok::kw_event_t:
4069249423Sdim
4070193326Sed    // struct-or-union-specifier (C99) or class-specifier (C++)
4071193326Sed  case tok::kw_class:
4072193326Sed  case tok::kw_struct:
4073243830Sdim  case tok::kw___interface:
4074193326Sed  case tok::kw_union:
4075193326Sed    // enum-specifier
4076193326Sed  case tok::kw_enum:
4077198092Srdivacky
4078193326Sed    // type-qualifier
4079193326Sed  case tok::kw_const:
4080193326Sed  case tok::kw_volatile:
4081193326Sed  case tok::kw_restrict:
4082193326Sed
4083249423Sdim    // Debugger support.
4084249423Sdim  case tok::kw___unknown_anytype:
4085249423Sdim
4086193326Sed    // typedef-name
4087193326Sed  case tok::annot_typename:
4088193326Sed    return true;
4089198092Srdivacky
4090193326Sed    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4091193326Sed  case tok::less:
4092234353Sdim    return getLangOpts().ObjC1;
4093198092Srdivacky
4094193326Sed  case tok::kw___cdecl:
4095193326Sed  case tok::kw___stdcall:
4096193326Sed  case tok::kw___fastcall:
4097208600Srdivacky  case tok::kw___thiscall:
4098194179Sed  case tok::kw___w64:
4099194179Sed  case tok::kw___ptr64:
4100226633Sdim  case tok::kw___ptr32:
4101212904Sdim  case tok::kw___pascal:
4102226633Sdim  case tok::kw___unaligned:
4103221345Sdim
4104221345Sdim  case tok::kw___private:
4105221345Sdim  case tok::kw___local:
4106221345Sdim  case tok::kw___global:
4107221345Sdim  case tok::kw___constant:
4108221345Sdim  case tok::kw___read_only:
4109221345Sdim  case tok::kw___read_write:
4110221345Sdim  case tok::kw___write_only:
4111221345Sdim
4112194179Sed    return true;
4113221345Sdim
4114221345Sdim  case tok::kw_private:
4115234353Sdim    return getLangOpts().OpenCL;
4116226633Sdim
4117249423Sdim  // C11 _Atomic
4118226633Sdim  case tok::kw__Atomic:
4119226633Sdim    return true;
4120193326Sed  }
4121193326Sed}
4122193326Sed
4123193326Sed/// isDeclarationSpecifier() - Return true if the current token is part of a
4124193326Sed/// declaration specifier.
4125218893Sdim///
4126218893Sdim/// \param DisambiguatingWithExpression True to indicate that the purpose of
4127218893Sdim/// this check is to disambiguate between an expression and a declaration.
4128218893Sdimbool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
4129193326Sed  switch (Tok.getKind()) {
4130193326Sed  default: return false;
4131198092Srdivacky
4132221345Sdim  case tok::kw_private:
4133234353Sdim    return getLangOpts().OpenCL;
4134221345Sdim
4135193326Sed  case tok::identifier:   // foo::bar
4136193326Sed    // Unfortunate hack to support "Class.factoryMethod" notation.
4137234353Sdim    if (getLangOpts().ObjC1 && NextToken().is(tok::period))
4138193326Sed      return false;
4139203955Srdivacky    if (TryAltiVecVectorToken())
4140203955Srdivacky      return true;
4141203955Srdivacky    // Fall through.
4142234353Sdim  case tok::kw_decltype: // decltype(T())::type
4143193326Sed  case tok::kw_typename: // typename T::type
4144193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
4145193326Sed    // recurse to handle whatever we get.
4146193326Sed    if (TryAnnotateTypeOrScopeToken())
4147204643Srdivacky      return true;
4148204643Srdivacky    if (Tok.is(tok::identifier))
4149204643Srdivacky      return false;
4150239462Sdim
4151218893Sdim    // If we're in Objective-C and we have an Objective-C class type followed
4152239462Sdim    // by an identifier and then either ':' or ']', in a place where an
4153218893Sdim    // expression is permitted, then this is probably a class message send
4154218893Sdim    // missing the initial '['. In this case, we won't consider this to be
4155218893Sdim    // the start of a declaration.
4156239462Sdim    if (DisambiguatingWithExpression &&
4157218893Sdim        isStartOfObjCClassMessageMissingOpenBracket())
4158218893Sdim      return false;
4159239462Sdim
4160204643Srdivacky    return isDeclarationSpecifier();
4161204643Srdivacky
4162193326Sed  case tok::coloncolon:   // ::foo::bar
4163193326Sed    if (NextToken().is(tok::kw_new) ||    // ::new
4164193326Sed        NextToken().is(tok::kw_delete))   // ::delete
4165193326Sed      return false;
4166198092Srdivacky
4167193326Sed    // Annotate typenames and C++ scope specifiers.  If we get one, just
4168193326Sed    // recurse to handle whatever we get.
4169193326Sed    if (TryAnnotateTypeOrScopeToken())
4170204643Srdivacky      return true;
4171204643Srdivacky    return isDeclarationSpecifier();
4172198092Srdivacky
4173193326Sed    // storage-class-specifier
4174193326Sed  case tok::kw_typedef:
4175193326Sed  case tok::kw_extern:
4176193326Sed  case tok::kw___private_extern__:
4177193326Sed  case tok::kw_static:
4178193326Sed  case tok::kw_auto:
4179193326Sed  case tok::kw_register:
4180193326Sed  case tok::kw___thread:
4181251662Sdim  case tok::kw_thread_local:
4182251662Sdim  case tok::kw__Thread_local:
4183198092Srdivacky
4184226633Sdim    // Modules
4185226633Sdim  case tok::kw___module_private__:
4186239462Sdim
4187249423Sdim    // Debugger support
4188249423Sdim  case tok::kw___unknown_anytype:
4189249423Sdim
4190193326Sed    // type-specifiers
4191193326Sed  case tok::kw_short:
4192193326Sed  case tok::kw_long:
4193221345Sdim  case tok::kw___int64:
4194234353Sdim  case tok::kw___int128:
4195193326Sed  case tok::kw_signed:
4196193326Sed  case tok::kw_unsigned:
4197193326Sed  case tok::kw__Complex:
4198193326Sed  case tok::kw__Imaginary:
4199193326Sed  case tok::kw_void:
4200193326Sed  case tok::kw_char:
4201193326Sed  case tok::kw_wchar_t:
4202198092Srdivacky  case tok::kw_char16_t:
4203198092Srdivacky  case tok::kw_char32_t:
4204198092Srdivacky
4205193326Sed  case tok::kw_int:
4206226633Sdim  case tok::kw_half:
4207193326Sed  case tok::kw_float:
4208193326Sed  case tok::kw_double:
4209193326Sed  case tok::kw_bool:
4210193326Sed  case tok::kw__Bool:
4211193326Sed  case tok::kw__Decimal32:
4212193326Sed  case tok::kw__Decimal64:
4213193326Sed  case tok::kw__Decimal128:
4214203955Srdivacky  case tok::kw___vector:
4215198092Srdivacky
4216249423Sdim    // OpenCL specific types:
4217249423Sdim  case tok::kw_image1d_t:
4218249423Sdim  case tok::kw_image1d_array_t:
4219249423Sdim  case tok::kw_image1d_buffer_t:
4220249423Sdim  case tok::kw_image2d_t:
4221249423Sdim  case tok::kw_image2d_array_t:
4222249423Sdim  case tok::kw_image3d_t:
4223249423Sdim  case tok::kw_sampler_t:
4224249423Sdim  case tok::kw_event_t:
4225249423Sdim
4226193326Sed    // struct-or-union-specifier (C99) or class-specifier (C++)
4227193326Sed  case tok::kw_class:
4228193326Sed  case tok::kw_struct:
4229193326Sed  case tok::kw_union:
4230243830Sdim  case tok::kw___interface:
4231193326Sed    // enum-specifier
4232193326Sed  case tok::kw_enum:
4233198092Srdivacky
4234193326Sed    // type-qualifier
4235193326Sed  case tok::kw_const:
4236193326Sed  case tok::kw_volatile:
4237193326Sed  case tok::kw_restrict:
4238193326Sed
4239193326Sed    // function-specifier
4240193326Sed  case tok::kw_inline:
4241193326Sed  case tok::kw_virtual:
4242193326Sed  case tok::kw_explicit:
4243249423Sdim  case tok::kw__Noreturn:
4244193326Sed
4245249423Sdim    // alignment-specifier
4246249423Sdim  case tok::kw__Alignas:
4247249423Sdim
4248243830Sdim    // friend keyword.
4249243830Sdim  case tok::kw_friend:
4250243830Sdim
4251221345Sdim    // static_assert-declaration
4252221345Sdim  case tok::kw__Static_assert:
4253193326Sed
4254193326Sed    // GNU typeof support.
4255193326Sed  case tok::kw_typeof:
4256198092Srdivacky
4257193326Sed    // GNU attributes.
4258193326Sed  case tok::kw___attribute:
4259198092Srdivacky
4260243830Sdim    // C++11 decltype and constexpr.
4261234353Sdim  case tok::annot_decltype:
4262243830Sdim  case tok::kw_constexpr:
4263224145Sdim
4264249423Sdim    // C11 _Atomic
4265226633Sdim  case tok::kw__Atomic:
4266226633Sdim    return true;
4267226633Sdim
4268193326Sed    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4269193326Sed  case tok::less:
4270234353Sdim    return getLangOpts().ObjC1;
4271198092Srdivacky
4272221345Sdim    // typedef-name
4273221345Sdim  case tok::annot_typename:
4274221345Sdim    return !DisambiguatingWithExpression ||
4275221345Sdim           !isStartOfObjCClassMessageMissingOpenBracket();
4276239462Sdim
4277193326Sed  case tok::kw___declspec:
4278193326Sed  case tok::kw___cdecl:
4279193326Sed  case tok::kw___stdcall:
4280193326Sed  case tok::kw___fastcall:
4281208600Srdivacky  case tok::kw___thiscall:
4282194179Sed  case tok::kw___w64:
4283263508Sdim  case tok::kw___sptr:
4284263508Sdim  case tok::kw___uptr:
4285194179Sed  case tok::kw___ptr64:
4286226633Sdim  case tok::kw___ptr32:
4287194179Sed  case tok::kw___forceinline:
4288212904Sdim  case tok::kw___pascal:
4289226633Sdim  case tok::kw___unaligned:
4290221345Sdim
4291221345Sdim  case tok::kw___private:
4292221345Sdim  case tok::kw___local:
4293221345Sdim  case tok::kw___global:
4294221345Sdim  case tok::kw___constant:
4295221345Sdim  case tok::kw___read_only:
4296221345Sdim  case tok::kw___read_write:
4297221345Sdim  case tok::kw___write_only:
4298221345Sdim
4299194179Sed    return true;
4300193326Sed  }
4301193326Sed}
4302193326Sed
4303202379Srdivackybool Parser::isConstructorDeclarator() {
4304202379Srdivacky  TentativeParsingAction TPA(*this);
4305193326Sed
4306202379Srdivacky  // Parse the C++ scope specifier.
4307202379Srdivacky  CXXScopeSpec SS;
4308239462Sdim  if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
4309234353Sdim                                     /*EnteringContext=*/true)) {
4310204643Srdivacky    TPA.Revert();
4311204643Srdivacky    return false;
4312204643Srdivacky  }
4313202379Srdivacky
4314202379Srdivacky  // Parse the constructor name.
4315202379Srdivacky  if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
4316202379Srdivacky    // We already know that we have a constructor name; just consume
4317202379Srdivacky    // the token.
4318202379Srdivacky    ConsumeToken();
4319202379Srdivacky  } else {
4320202379Srdivacky    TPA.Revert();
4321202379Srdivacky    return false;
4322202379Srdivacky  }
4323202379Srdivacky
4324234353Sdim  // Current class name must be followed by a left parenthesis.
4325202379Srdivacky  if (Tok.isNot(tok::l_paren)) {
4326202379Srdivacky    TPA.Revert();
4327202379Srdivacky    return false;
4328202379Srdivacky  }
4329202379Srdivacky  ConsumeParen();
4330202379Srdivacky
4331234353Sdim  // A right parenthesis, or ellipsis followed by a right parenthesis signals
4332234353Sdim  // that we have a constructor.
4333234353Sdim  if (Tok.is(tok::r_paren) ||
4334234353Sdim      (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
4335202379Srdivacky    TPA.Revert();
4336202379Srdivacky    return true;
4337202379Srdivacky  }
4338202379Srdivacky
4339263508Sdim  // A C++11 attribute here signals that we have a constructor, and is an
4340263508Sdim  // attribute on the first constructor parameter.
4341263508Sdim  if (getLangOpts().CPlusPlus11 &&
4342263508Sdim      isCXX11AttributeSpecifier(/*Disambiguate*/ false,
4343263508Sdim                                /*OuterMightBeMessageSend*/ true)) {
4344263508Sdim    TPA.Revert();
4345263508Sdim    return true;
4346263508Sdim  }
4347263508Sdim
4348202379Srdivacky  // If we need to, enter the specified scope.
4349202379Srdivacky  DeclaratorScopeObj DeclScopeObj(*this, SS);
4350210299Sed  if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
4351202379Srdivacky    DeclScopeObj.EnterDeclaratorScope();
4352202379Srdivacky
4353218893Sdim  // Optionally skip Microsoft attributes.
4354221345Sdim  ParsedAttributes Attrs(AttrFactory);
4355218893Sdim  MaybeParseMicrosoftAttributes(Attrs);
4356218893Sdim
4357202379Srdivacky  // Check whether the next token(s) are part of a declaration
4358202379Srdivacky  // specifier, in which case we have the start of a parameter and,
4359202379Srdivacky  // therefore, we know that this is a constructor.
4360234353Sdim  bool IsConstructor = false;
4361234353Sdim  if (isDeclarationSpecifier())
4362234353Sdim    IsConstructor = true;
4363234353Sdim  else if (Tok.is(tok::identifier) ||
4364234353Sdim           (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
4365234353Sdim    // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
4366234353Sdim    // This might be a parenthesized member name, but is more likely to
4367234353Sdim    // be a constructor declaration with an invalid argument type. Keep
4368234353Sdim    // looking.
4369234353Sdim    if (Tok.is(tok::annot_cxxscope))
4370234353Sdim      ConsumeToken();
4371234353Sdim    ConsumeToken();
4372234353Sdim
4373234353Sdim    // If this is not a constructor, we must be parsing a declarator,
4374234353Sdim    // which must have one of the following syntactic forms (see the
4375234353Sdim    // grammar extract at the start of ParseDirectDeclarator):
4376234353Sdim    switch (Tok.getKind()) {
4377234353Sdim    case tok::l_paren:
4378234353Sdim      // C(X   (   int));
4379234353Sdim    case tok::l_square:
4380234353Sdim      // C(X   [   5]);
4381234353Sdim      // C(X   [   [attribute]]);
4382234353Sdim    case tok::coloncolon:
4383234353Sdim      // C(X   ::   Y);
4384234353Sdim      // C(X   ::   *p);
4385234353Sdim    case tok::r_paren:
4386234353Sdim      // C(X   )
4387234353Sdim      // Assume this isn't a constructor, rather than assuming it's a
4388234353Sdim      // constructor with an unnamed parameter of an ill-formed type.
4389234353Sdim      break;
4390234353Sdim
4391234353Sdim    default:
4392234353Sdim      IsConstructor = true;
4393234353Sdim      break;
4394234353Sdim    }
4395234353Sdim  }
4396234353Sdim
4397202379Srdivacky  TPA.Revert();
4398202379Srdivacky  return IsConstructor;
4399202379Srdivacky}
4400202379Srdivacky
4401193326Sed/// ParseTypeQualifierListOpt
4402212904Sdim///          type-qualifier-list: [C99 6.7.5]
4403212904Sdim///            type-qualifier
4404239462Sdim/// [vendor]   attributes
4405212904Sdim///              [ only if VendorAttributesAllowed=true ]
4406212904Sdim///            type-qualifier-list type-qualifier
4407239462Sdim/// [vendor]   type-qualifier-list attributes
4408212904Sdim///              [ only if VendorAttributesAllowed=true ]
4409212904Sdim/// [C++0x]    attribute-specifier[opt] is allowed before cv-qualifier-seq
4410249423Sdim///              [ only if CXX11AttributesAllowed=true ]
4411212904Sdim/// Note: vendor can be GNU, MS, etc.
4412193326Sed///
4413212904Sdimvoid Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
4414212904Sdim                                       bool VendorAttributesAllowed,
4415249423Sdim                                       bool CXX11AttributesAllowed,
4416263508Sdim                                       bool AtomicAllowed,
4417263508Sdim                                       bool IdentifierRequired) {
4418249423Sdim  if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed &&
4419234353Sdim      isCXX11AttributeSpecifier()) {
4420221345Sdim    ParsedAttributesWithRange attrs(AttrFactory);
4421234353Sdim    ParseCXX11Attributes(attrs);
4422234353Sdim    DS.takeAttributesFrom(attrs);
4423199990Srdivacky  }
4424221345Sdim
4425221345Sdim  SourceLocation EndLoc;
4426221345Sdim
4427193326Sed  while (1) {
4428198092Srdivacky    bool isInvalid = false;
4429193326Sed    const char *PrevSpec = 0;
4430198092Srdivacky    unsigned DiagID = 0;
4431193326Sed    SourceLocation Loc = Tok.getLocation();
4432193326Sed
4433193326Sed    switch (Tok.getKind()) {
4434212904Sdim    case tok::code_completion:
4435212904Sdim      Actions.CodeCompleteTypeQualifiers(DS);
4436226633Sdim      return cutOffParsing();
4437239462Sdim
4438193326Sed    case tok::kw_const:
4439198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,
4440243830Sdim                                 getLangOpts());
4441193326Sed      break;
4442193326Sed    case tok::kw_volatile:
4443198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
4444243830Sdim                                 getLangOpts());
4445193326Sed      break;
4446193326Sed    case tok::kw_restrict:
4447198092Srdivacky      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
4448243830Sdim                                 getLangOpts());
4449193326Sed      break;
4450249423Sdim    case tok::kw__Atomic:
4451249423Sdim      if (!AtomicAllowed)
4452249423Sdim        goto DoneWithTypeQuals;
4453249423Sdim      isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
4454249423Sdim                                 getLangOpts());
4455249423Sdim      break;
4456221345Sdim
4457221345Sdim    // OpenCL qualifiers:
4458239462Sdim    case tok::kw_private:
4459234353Sdim      if (!getLangOpts().OpenCL)
4460221345Sdim        goto DoneWithTypeQuals;
4461221345Sdim    case tok::kw___private:
4462221345Sdim    case tok::kw___global:
4463221345Sdim    case tok::kw___local:
4464221345Sdim    case tok::kw___constant:
4465221345Sdim    case tok::kw___read_only:
4466221345Sdim    case tok::kw___write_only:
4467221345Sdim    case tok::kw___read_write:
4468221345Sdim      ParseOpenCLQualifiers(DS);
4469221345Sdim      break;
4470221345Sdim
4471263508Sdim    case tok::kw___uptr:
4472263508Sdim      // GNU libc headers in C mode use '__uptr' as an identifer which conflicts
4473263508Sdim      // with the MS modifier keyword.
4474263508Sdim      if (VendorAttributesAllowed && !getLangOpts().CPlusPlus &&
4475263508Sdim          IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) {
4476263508Sdim        if (TryKeywordIdentFallback(false))
4477263508Sdim          continue;
4478263508Sdim      }
4479263508Sdim    case tok::kw___sptr:
4480194179Sed    case tok::kw___w64:
4481193326Sed    case tok::kw___ptr64:
4482226633Sdim    case tok::kw___ptr32:
4483193326Sed    case tok::kw___cdecl:
4484193326Sed    case tok::kw___stdcall:
4485193326Sed    case tok::kw___fastcall:
4486208600Srdivacky    case tok::kw___thiscall:
4487226633Sdim    case tok::kw___unaligned:
4488212904Sdim      if (VendorAttributesAllowed) {
4489218893Sdim        ParseMicrosoftTypeAttributes(DS.getAttributes());
4490194179Sed        continue;
4491194179Sed      }
4492194179Sed      goto DoneWithTypeQuals;
4493212904Sdim    case tok::kw___pascal:
4494212904Sdim      if (VendorAttributesAllowed) {
4495218893Sdim        ParseBorlandTypeAttributes(DS.getAttributes());
4496212904Sdim        continue;
4497212904Sdim      }
4498212904Sdim      goto DoneWithTypeQuals;
4499193326Sed    case tok::kw___attribute:
4500212904Sdim      if (VendorAttributesAllowed) {
4501218893Sdim        ParseGNUAttributes(DS.getAttributes());
4502193326Sed        continue; // do *not* consume the next token!
4503193326Sed      }
4504193326Sed      // otherwise, FALL THROUGH!
4505193326Sed    default:
4506193326Sed      DoneWithTypeQuals:
4507193326Sed      // If this is not a type-qualifier token, we're done reading type
4508193326Sed      // qualifiers.  First verify that DeclSpec's are consistent.
4509193326Sed      DS.Finish(Diags, PP);
4510221345Sdim      if (EndLoc.isValid())
4511221345Sdim        DS.SetRangeEnd(EndLoc);
4512193326Sed      return;
4513193326Sed    }
4514193326Sed
4515193326Sed    // If the specifier combination wasn't legal, issue a diagnostic.
4516193326Sed    if (isInvalid) {
4517193326Sed      assert(PrevSpec && "Method did not return previous specifier!");
4518193326Sed      Diag(Tok, DiagID) << PrevSpec;
4519193326Sed    }
4520221345Sdim    EndLoc = ConsumeToken();
4521193326Sed  }
4522193326Sed}
4523193326Sed
4524193326Sed
4525193326Sed/// ParseDeclarator - Parse and verify a newly-initialized declarator.
4526193326Sed///
4527193326Sedvoid Parser::ParseDeclarator(Declarator &D) {
4528193326Sed  /// This implements the 'declarator' production in the C grammar, then checks
4529193326Sed  /// for well-formedness and issues diagnostics.
4530193326Sed  ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
4531193326Sed}
4532193326Sed
4533234353Sdimstatic bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
4534234353Sdim  if (Kind == tok::star || Kind == tok::caret)
4535234353Sdim    return true;
4536234353Sdim
4537234353Sdim  // We parse rvalue refs in C++03, because otherwise the errors are scary.
4538234353Sdim  if (!Lang.CPlusPlus)
4539234353Sdim    return false;
4540234353Sdim
4541234353Sdim  return Kind == tok::amp || Kind == tok::ampamp;
4542234353Sdim}
4543234353Sdim
4544193326Sed/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
4545193326Sed/// is parsed by the function passed to it. Pass null, and the direct-declarator
4546193326Sed/// isn't parsed at all, making this function effectively parse the C++
4547193326Sed/// ptr-operator production.
4548193326Sed///
4549234353Sdim/// If the grammar of this construct is extended, matching changes must also be
4550234353Sdim/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
4551234353Sdim/// isConstructorDeclarator.
4552234353Sdim///
4553193326Sed///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
4554193326Sed/// [C]     pointer[opt] direct-declarator
4555193326Sed/// [C++]   direct-declarator
4556193326Sed/// [C++]   ptr-operator declarator
4557193326Sed///
4558193326Sed///       pointer: [C99 6.7.5]
4559193326Sed///         '*' type-qualifier-list[opt]
4560193326Sed///         '*' type-qualifier-list[opt] pointer
4561193326Sed///
4562193326Sed///       ptr-operator:
4563193326Sed///         '*' cv-qualifier-seq[opt]
4564193326Sed///         '&'
4565193326Sed/// [C++0x] '&&'
4566193326Sed/// [GNU]   '&' restrict[opt] attributes[opt]
4567193326Sed/// [GNU?]  '&&' restrict[opt] attributes[opt]
4568193326Sed///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
4569193326Sedvoid Parser::ParseDeclaratorInternal(Declarator &D,
4570193326Sed                                     DirectDeclParseFunction DirectDeclParser) {
4571198092Srdivacky  if (Diags.hasAllExtensionsSilenced())
4572198092Srdivacky    D.setExtension();
4573239462Sdim
4574193326Sed  // C++ member pointers start with a '::' or a nested-name.
4575193326Sed  // Member pointers get special handling, since there's no place for the
4576193326Sed  // scope spec in the generic path below.
4577234353Sdim  if (getLangOpts().CPlusPlus &&
4578193326Sed      (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
4579193326Sed       Tok.is(tok::annot_cxxscope))) {
4580234353Sdim    bool EnteringContext = D.getContext() == Declarator::FileContext ||
4581234353Sdim                           D.getContext() == Declarator::MemberContext;
4582193326Sed    CXXScopeSpec SS;
4583234353Sdim    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
4584204643Srdivacky
4585207619Srdivacky    if (SS.isNotEmpty()) {
4586198092Srdivacky      if (Tok.isNot(tok::star)) {
4587193326Sed        // The scope spec really belongs to the direct-declarator.
4588249423Sdim        if (D.mayHaveIdentifier())
4589249423Sdim          D.getCXXScopeSpec() = SS;
4590249423Sdim        else
4591249423Sdim          AnnotateScopeToken(SS, true);
4592249423Sdim
4593193326Sed        if (DirectDeclParser)
4594193326Sed          (this->*DirectDeclParser)(D);
4595193326Sed        return;
4596193326Sed      }
4597193326Sed
4598193326Sed      SourceLocation Loc = ConsumeToken();
4599193326Sed      D.SetRangeEnd(Loc);
4600221345Sdim      DeclSpec DS(AttrFactory);
4601193326Sed      ParseTypeQualifierListOpt(DS);
4602193326Sed      D.ExtendWithDeclSpec(DS);
4603193326Sed
4604193326Sed      // Recurse to parse whatever is left.
4605193326Sed      ParseDeclaratorInternal(D, DirectDeclParser);
4606193326Sed
4607193326Sed      // Sema will have to catch (syntactically invalid) pointers into global
4608193326Sed      // scope. It has to catch pointers into namespace scope anyway.
4609193326Sed      D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
4610221345Sdim                                                      Loc),
4611221345Sdim                    DS.getAttributes(),
4612193326Sed                    /* Don't replace range end. */SourceLocation());
4613193326Sed      return;
4614193326Sed    }
4615193326Sed  }
4616193326Sed
4617193326Sed  tok::TokenKind Kind = Tok.getKind();
4618193326Sed  // Not a pointer, C++ reference, or block.
4619234353Sdim  if (!isPtrOperatorToken(Kind, getLangOpts())) {
4620193326Sed    if (DirectDeclParser)
4621193326Sed      (this->*DirectDeclParser)(D);
4622193326Sed    return;
4623193326Sed  }
4624193326Sed
4625193326Sed  // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4626193326Sed  // '&&' -> rvalue reference
4627193326Sed  SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.
4628193326Sed  D.SetRangeEnd(Loc);
4629193326Sed
4630193326Sed  if (Kind == tok::star || Kind == tok::caret) {
4631193326Sed    // Is a pointer.
4632221345Sdim    DeclSpec DS(AttrFactory);
4633193326Sed
4634234353Sdim    // FIXME: GNU attributes are not allowed here in a new-type-id.
4635263508Sdim    ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier());
4636193326Sed    D.ExtendWithDeclSpec(DS);
4637193326Sed
4638193326Sed    // Recursively parse the declarator.
4639193326Sed    ParseDeclaratorInternal(D, DirectDeclParser);
4640193326Sed    if (Kind == tok::star)
4641193326Sed      // Remember that we parsed a pointer type, and remember the type-quals.
4642193326Sed      D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
4643219077Sdim                                                DS.getConstSpecLoc(),
4644219077Sdim                                                DS.getVolatileSpecLoc(),
4645221345Sdim                                                DS.getRestrictSpecLoc()),
4646221345Sdim                    DS.getAttributes(),
4647193326Sed                    SourceLocation());
4648193326Sed    else
4649193326Sed      // Remember that we parsed a Block type, and remember the type-quals.
4650198092Srdivacky      D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
4651221345Sdim                                                     Loc),
4652221345Sdim                    DS.getAttributes(),
4653193326Sed                    SourceLocation());
4654193326Sed  } else {
4655193326Sed    // Is a reference
4656221345Sdim    DeclSpec DS(AttrFactory);
4657193326Sed
4658193326Sed    // Complain about rvalue references in C++03, but then go on and build
4659193326Sed    // the declarator.
4660234353Sdim    if (Kind == tok::ampamp)
4661249423Sdim      Diag(Loc, getLangOpts().CPlusPlus11 ?
4662234353Sdim           diag::warn_cxx98_compat_rvalue_reference :
4663234353Sdim           diag::ext_rvalue_reference);
4664193326Sed
4665234353Sdim    // GNU-style and C++11 attributes are allowed here, as is restrict.
4666234353Sdim    ParseTypeQualifierListOpt(DS);
4667234353Sdim    D.ExtendWithDeclSpec(DS);
4668234353Sdim
4669193326Sed    // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4670193326Sed    // cv-qualifiers are introduced through the use of a typedef or of a
4671193326Sed    // template type argument, in which case the cv-qualifiers are ignored.
4672193326Sed    if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4673193326Sed      if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4674193326Sed        Diag(DS.getConstSpecLoc(),
4675193326Sed             diag::err_invalid_reference_qualifier_application) << "const";
4676193326Sed      if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4677193326Sed        Diag(DS.getVolatileSpecLoc(),
4678193326Sed             diag::err_invalid_reference_qualifier_application) << "volatile";
4679249423Sdim      // 'restrict' is permitted as an extension.
4680249423Sdim      if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
4681249423Sdim        Diag(DS.getAtomicSpecLoc(),
4682249423Sdim             diag::err_invalid_reference_qualifier_application) << "_Atomic";
4683193326Sed    }
4684193326Sed
4685193326Sed    // Recursively parse the declarator.
4686193326Sed    ParseDeclaratorInternal(D, DirectDeclParser);
4687193326Sed
4688193326Sed    if (D.getNumTypeObjects() > 0) {
4689193326Sed      // C++ [dcl.ref]p4: There shall be no references to references.
4690193326Sed      DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4691193326Sed      if (InnerChunk.Kind == DeclaratorChunk::Reference) {
4692193326Sed        if (const IdentifierInfo *II = D.getIdentifier())
4693193326Sed          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4694193326Sed           << II;
4695193326Sed        else
4696193326Sed          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4697193326Sed            << "type name";
4698193326Sed
4699193326Sed        // Once we've complained about the reference-to-reference, we
4700193326Sed        // can go ahead and build the (technically ill-formed)
4701193326Sed        // declarator: reference collapsing will take care of it.
4702193326Sed      }
4703193326Sed    }
4704193326Sed
4705249423Sdim    // Remember that we parsed a reference type.
4706193326Sed    D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
4707193326Sed                                                Kind == tok::amp),
4708221345Sdim                  DS.getAttributes(),
4709193326Sed                  SourceLocation());
4710193326Sed  }
4711193326Sed}
4712193326Sed
4713234353Sdimstatic void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4714234353Sdim                                      SourceLocation EllipsisLoc) {
4715234353Sdim  if (EllipsisLoc.isValid()) {
4716234353Sdim    FixItHint Insertion;
4717234353Sdim    if (!D.getEllipsisLoc().isValid()) {
4718234353Sdim      Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4719234353Sdim      D.setEllipsisLoc(EllipsisLoc);
4720234353Sdim    }
4721234353Sdim    P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4722234353Sdim      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4723234353Sdim  }
4724234353Sdim}
4725234353Sdim
4726193326Sed/// ParseDirectDeclarator
4727193326Sed///       direct-declarator: [C99 6.7.5]
4728193326Sed/// [C99]   identifier
4729193326Sed///         '(' declarator ')'
4730193326Sed/// [GNU]   '(' attributes declarator ')'
4731193326Sed/// [C90]   direct-declarator '[' constant-expression[opt] ']'
4732193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4733193326Sed/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4734193326Sed/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4735193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
4736234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']'
4737234353Sdim///                    attribute-specifier-seq[opt]
4738193326Sed///         direct-declarator '(' parameter-type-list ')'
4739193326Sed///         direct-declarator '(' identifier-list[opt] ')'
4740193326Sed/// [GNU]   direct-declarator '(' parameter-forward-declarations
4741193326Sed///                    parameter-type-list[opt] ')'
4742193326Sed/// [C++]   direct-declarator '(' parameter-declaration-clause ')'
4743193326Sed///                    cv-qualifier-seq[opt] exception-specification[opt]
4744234353Sdim/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4745234353Sdim///                    attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4746234353Sdim///                    ref-qualifier[opt] exception-specification[opt]
4747193326Sed/// [C++]   declarator-id
4748234353Sdim/// [C++11] declarator-id attribute-specifier-seq[opt]
4749193326Sed///
4750193326Sed///       declarator-id: [C++ 8]
4751218893Sdim///         '...'[opt] id-expression
4752193326Sed///         '::'[opt] nested-name-specifier[opt] type-name
4753193326Sed///
4754193326Sed///       id-expression: [C++ 5.1]
4755193326Sed///         unqualified-id
4756198092Srdivacky///         qualified-id
4757193326Sed///
4758193326Sed///       unqualified-id: [C++ 5.1]
4759198092Srdivacky///         identifier
4760193326Sed///         operator-function-id
4761198092Srdivacky///         conversion-function-id
4762198092Srdivacky///          '~' class-name
4763193326Sed///         template-id
4764193326Sed///
4765234353Sdim/// Note, any additional constructs added here may need corresponding changes
4766234353Sdim/// in isConstructorDeclarator.
4767193326Sedvoid Parser::ParseDirectDeclarator(Declarator &D) {
4768193326Sed  DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
4769193326Sed
4770234353Sdim  if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
4771198893Srdivacky    // ParseDeclaratorInternal might already have parsed the scope.
4772207619Srdivacky    if (D.getCXXScopeSpec().isEmpty()) {
4773234353Sdim      bool EnteringContext = D.getContext() == Declarator::FileContext ||
4774234353Sdim                             D.getContext() == Declarator::MemberContext;
4775239462Sdim      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
4776234353Sdim                                     EnteringContext);
4777204643Srdivacky    }
4778204643Srdivacky
4779207619Srdivacky    if (D.getCXXScopeSpec().isValid()) {
4780210299Sed      if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
4781200583Srdivacky        // Change the declaration context for name lookup, until this function
4782200583Srdivacky        // is exited (and the declarator has been parsed).
4783200583Srdivacky        DeclScopeObj.EnterDeclaratorScope();
4784207619Srdivacky    }
4785207619Srdivacky
4786218893Sdim    // C++0x [dcl.fct]p14:
4787218893Sdim    //   There is a syntactic ambiguity when an ellipsis occurs at the end
4788239462Sdim    //   of a parameter-declaration-clause without a preceding comma. In
4789239462Sdim    //   this case, the ellipsis is parsed as part of the
4790239462Sdim    //   abstract-declarator if the type of the parameter names a template
4791218893Sdim    //   parameter pack that has not been expanded; otherwise, it is parsed
4792218893Sdim    //   as part of the parameter-declaration-clause.
4793234353Sdim    if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
4794218893Sdim        !((D.getContext() == Declarator::PrototypeContext ||
4795263508Sdim           D.getContext() == Declarator::LambdaExprParameterContext ||
4796218893Sdim           D.getContext() == Declarator::BlockLiteralContext) &&
4797218893Sdim          NextToken().is(tok::r_paren) &&
4798249423Sdim          !D.hasGroupingParens() &&
4799234353Sdim          !Actions.containsUnexpandedParameterPacks(D))) {
4800234353Sdim      SourceLocation EllipsisLoc = ConsumeToken();
4801234353Sdim      if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4802234353Sdim        // The ellipsis was put in the wrong place. Recover, and explain to
4803234353Sdim        // the user what they should have done.
4804234353Sdim        ParseDeclarator(D);
4805234353Sdim        diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4806234353Sdim        return;
4807234353Sdim      } else
4808234353Sdim        D.setEllipsisLoc(EllipsisLoc);
4809234353Sdim
4810234353Sdim      // The ellipsis can't be followed by a parenthesized declarator. We
4811234353Sdim      // check for that in ParseParenDeclarator, after we have disambiguated
4812234353Sdim      // the l_paren token.
4813234353Sdim    }
4814234353Sdim
4815198893Srdivacky    if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4816198893Srdivacky        Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4817198893Srdivacky      // We found something that indicates the start of an unqualified-id.
4818198893Srdivacky      // Parse that unqualified-id.
4819207619Srdivacky      bool AllowConstructorName;
4820207619Srdivacky      if (D.getDeclSpec().hasTypeSpecifier())
4821207619Srdivacky        AllowConstructorName = false;
4822207619Srdivacky      else if (D.getCXXScopeSpec().isSet())
4823207619Srdivacky        AllowConstructorName =
4824207619Srdivacky          (D.getContext() == Declarator::FileContext ||
4825249423Sdim           D.getContext() == Declarator::MemberContext);
4826207619Srdivacky      else
4827207619Srdivacky        AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4828207619Srdivacky
4829234353Sdim      SourceLocation TemplateKWLoc;
4830239462Sdim      if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4831239462Sdim                             /*EnteringContext=*/true,
4832239462Sdim                             /*AllowDestructorName=*/true,
4833202379Srdivacky                             AllowConstructorName,
4834212904Sdim                             ParsedType(),
4835234353Sdim                             TemplateKWLoc,
4836207619Srdivacky                             D.getName()) ||
4837207619Srdivacky          // Once we're past the identifier, if the scope was bad, mark the
4838207619Srdivacky          // whole declarator bad.
4839207619Srdivacky          D.getCXXScopeSpec().isInvalid()) {
4840193326Sed        D.SetIdentifier(0, Tok.getLocation());
4841193326Sed        D.setInvalidType(true);
4842198893Srdivacky      } else {
4843198893Srdivacky        // Parsed the unqualified-id; update range information and move along.
4844198893Srdivacky        if (D.getSourceRange().getBegin().isInvalid())
4845198893Srdivacky          D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4846198893Srdivacky        D.SetRangeEnd(D.getName().getSourceRange().getEnd());
4847193326Sed      }
4848198893Srdivacky      goto PastIdentifier;
4849193326Sed    }
4850198893Srdivacky  } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
4851234353Sdim    assert(!getLangOpts().CPlusPlus &&
4852193326Sed           "There's a C++-specific check for tok::identifier above");
4853193326Sed    assert(Tok.getIdentifierInfo() && "Not an identifier?");
4854193326Sed    D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4855193326Sed    ConsumeToken();
4856198893Srdivacky    goto PastIdentifier;
4857263508Sdim  } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
4858263508Sdim    // A virt-specifier isn't treated as an identifier if it appears after a
4859263508Sdim    // trailing-return-type.
4860263508Sdim    if (D.getContext() != Declarator::TrailingReturnContext ||
4861263508Sdim        !isCXX11VirtSpecifier(Tok)) {
4862263508Sdim      Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
4863263508Sdim        << FixItHint::CreateRemoval(Tok.getLocation());
4864263508Sdim      D.SetIdentifier(0, Tok.getLocation());
4865263508Sdim      ConsumeToken();
4866263508Sdim      goto PastIdentifier;
4867263508Sdim    }
4868198893Srdivacky  }
4869234353Sdim
4870198893Srdivacky  if (Tok.is(tok::l_paren)) {
4871193326Sed    // direct-declarator: '(' declarator ')'
4872193326Sed    // direct-declarator: '(' attributes declarator ')'
4873193326Sed    // Example: 'char (*X)'   or 'int (*XX)(void)'
4874193326Sed    ParseParenDeclarator(D);
4875202379Srdivacky
4876202379Srdivacky    // If the declarator was parenthesized, we entered the declarator
4877202379Srdivacky    // scope when parsing the parenthesized declarator, then exited
4878202379Srdivacky    // the scope already. Re-enter the scope, if we need to.
4879202379Srdivacky    if (D.getCXXScopeSpec().isSet()) {
4880212904Sdim      // If there was an error parsing parenthesized declarator, declarator
4881234353Sdim      // scope may have been entered before. Don't do it again.
4882212904Sdim      if (!D.isInvalidType() &&
4883212904Sdim          Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
4884202379Srdivacky        // Change the declaration context for name lookup, until this function
4885202379Srdivacky        // is exited (and the declarator has been parsed).
4886202379Srdivacky        DeclScopeObj.EnterDeclaratorScope();
4887202379Srdivacky    }
4888193326Sed  } else if (D.mayOmitIdentifier()) {
4889193326Sed    // This could be something simple like "int" (in which case the declarator
4890193326Sed    // portion is empty), if an abstract-declarator is allowed.
4891193326Sed    D.SetIdentifier(0, Tok.getLocation());
4892249423Sdim
4893249423Sdim    // The grammar for abstract-pack-declarator does not allow grouping parens.
4894249423Sdim    // FIXME: Revisit this once core issue 1488 is resolved.
4895249423Sdim    if (D.hasEllipsis() && D.hasGroupingParens())
4896249423Sdim      Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()),
4897249423Sdim           diag::ext_abstract_pack_declarator_parens);
4898193326Sed  } else {
4899239462Sdim    if (Tok.getKind() == tok::annot_pragma_parser_crash)
4900243830Sdim      LLVM_BUILTIN_TRAP;
4901193326Sed    if (D.getContext() == Declarator::MemberContext)
4902193326Sed      Diag(Tok, diag::err_expected_member_name_or_semi)
4903193326Sed        << D.getDeclSpec().getSourceRange();
4904249423Sdim    else if (getLangOpts().CPlusPlus) {
4905249423Sdim      if (Tok.is(tok::period) || Tok.is(tok::arrow))
4906249423Sdim        Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
4907263508Sdim      else {
4908263508Sdim        SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();
4909263508Sdim        if (Tok.isAtStartOfLine() && Loc.isValid())
4910263508Sdim          Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
4911263508Sdim              << getLangOpts().CPlusPlus;
4912263508Sdim        else
4913263508Sdim          Diag(Tok, diag::err_expected_unqualified_id)
4914263508Sdim              << getLangOpts().CPlusPlus;
4915263508Sdim      }
4916249423Sdim    } else
4917193326Sed      Diag(Tok, diag::err_expected_ident_lparen);
4918193326Sed    D.SetIdentifier(0, Tok.getLocation());
4919193326Sed    D.setInvalidType(true);
4920193326Sed  }
4921198092Srdivacky
4922193326Sed PastIdentifier:
4923193326Sed  assert(D.isPastIdentifier() &&
4924193326Sed         "Haven't past the location of the identifier yet?");
4925198092Srdivacky
4926234353Sdim  // Don't parse attributes unless we have parsed an unparenthesized name.
4927234353Sdim  if (D.hasName() && !D.getNumTypeObjects())
4928249423Sdim    MaybeParseCXX11Attributes(D);
4929199990Srdivacky
4930193326Sed  while (1) {
4931193326Sed    if (Tok.is(tok::l_paren)) {
4932234353Sdim      // Enter function-declaration scope, limiting any declarators to the
4933234353Sdim      // function prototype scope, including parameter declarators.
4934234353Sdim      ParseScope PrototypeScope(this,
4935249423Sdim                                Scope::FunctionPrototypeScope|Scope::DeclScope|
4936249423Sdim                                (D.isFunctionDeclaratorAFunctionDeclaration()
4937249423Sdim                                   ? Scope::FunctionDeclarationScope : 0));
4938249423Sdim
4939193326Sed      // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4940193326Sed      // In such a case, check if we actually have a function declarator; if it
4941193326Sed      // is not, the declarator has been fully parsed.
4942239462Sdim      bool IsAmbiguous = false;
4943243830Sdim      if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
4944243830Sdim        // The name of the declarator, if any, is tentatively declared within
4945243830Sdim        // a possible direct initializer.
4946243830Sdim        TentativelyDeclaredIdentifiers.push_back(D.getIdentifier());
4947243830Sdim        bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
4948243830Sdim        TentativelyDeclaredIdentifiers.pop_back();
4949243830Sdim        if (!IsFunctionDecl)
4950243830Sdim          break;
4951243830Sdim      }
4952221345Sdim      ParsedAttributes attrs(AttrFactory);
4953226633Sdim      BalancedDelimiterTracker T(*this, tok::l_paren);
4954226633Sdim      T.consumeOpen();
4955239462Sdim      ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
4956234353Sdim      PrototypeScope.Exit();
4957193326Sed    } else if (Tok.is(tok::l_square)) {
4958193326Sed      ParseBracketDeclarator(D);
4959193326Sed    } else {
4960193326Sed      break;
4961193326Sed    }
4962193326Sed  }
4963239462Sdim}
4964193326Sed
4965193326Sed/// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
4966193326Sed/// only called before the identifier, so these are most likely just grouping
4967198092Srdivacky/// parens for precedence.  If we find that these are actually function
4968193326Sed/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4969193326Sed///
4970193326Sed///       direct-declarator:
4971193326Sed///         '(' declarator ')'
4972193326Sed/// [GNU]   '(' attributes declarator ')'
4973193326Sed///         direct-declarator '(' parameter-type-list ')'
4974193326Sed///         direct-declarator '(' identifier-list[opt] ')'
4975193326Sed/// [GNU]   direct-declarator '(' parameter-forward-declarations
4976193326Sed///                    parameter-type-list[opt] ')'
4977193326Sed///
4978193326Sedvoid Parser::ParseParenDeclarator(Declarator &D) {
4979226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
4980226633Sdim  T.consumeOpen();
4981226633Sdim
4982193326Sed  assert(!D.isPastIdentifier() && "Should be called before passing identifier");
4983198092Srdivacky
4984193326Sed  // Eat any attributes before we look at whether this is a grouping or function
4985193326Sed  // declarator paren.  If this is a grouping paren, the attribute applies to
4986193326Sed  // the type being built up, for example:
4987193326Sed  //     int (__attribute__(()) *x)(long y)
4988193326Sed  // If this ends up not being a grouping paren, the attribute applies to the
4989193326Sed  // first argument, for example:
4990193326Sed  //     int (__attribute__(()) int x)
4991193326Sed  // In either case, we need to eat any attributes to be able to determine what
4992193326Sed  // sort of paren this is.
4993193326Sed  //
4994221345Sdim  ParsedAttributes attrs(AttrFactory);
4995193326Sed  bool RequiresArg = false;
4996193326Sed  if (Tok.is(tok::kw___attribute)) {
4997218893Sdim    ParseGNUAttributes(attrs);
4998198092Srdivacky
4999193326Sed    // We require that the argument list (if this is a non-grouping paren) be
5000193326Sed    // present even if the attribute list was empty.
5001193326Sed    RequiresArg = true;
5002193326Sed  }
5003249423Sdim
5004193326Sed  // Eat any Microsoft extensions.
5005249423Sdim  ParseMicrosoftTypeAttributes(attrs);
5006249423Sdim
5007212904Sdim  // Eat any Borland extensions.
5008218893Sdim  if  (Tok.is(tok::kw___pascal))
5009218893Sdim    ParseBorlandTypeAttributes(attrs);
5010198092Srdivacky
5011193326Sed  // If we haven't past the identifier yet (or where the identifier would be
5012193326Sed  // stored, if this is an abstract declarator), then this is probably just
5013193326Sed  // grouping parens. However, if this could be an abstract-declarator, then
5014193326Sed  // this could also be the start of function arguments (consider 'void()').
5015193326Sed  bool isGrouping;
5016198092Srdivacky
5017193326Sed  if (!D.mayOmitIdentifier()) {
5018193326Sed    // If this can't be an abstract-declarator, this *must* be a grouping
5019193326Sed    // paren, because we haven't seen the identifier yet.
5020193326Sed    isGrouping = true;
5021193326Sed  } else if (Tok.is(tok::r_paren) ||           // 'int()' is a function.
5022234353Sdim             (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
5023234353Sdim              NextToken().is(tok::r_paren)) || // C++ int(...)
5024234353Sdim             isDeclarationSpecifier() ||       // 'int(int)' is a function.
5025234353Sdim             isCXX11AttributeSpecifier()) {    // 'int([[]]int)' is a function.
5026193326Sed    // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
5027193326Sed    // considered to be a type, not a K&R identifier-list.
5028193326Sed    isGrouping = false;
5029193326Sed  } else {
5030193326Sed    // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
5031193326Sed    isGrouping = true;
5032193326Sed  }
5033198092Srdivacky
5034193326Sed  // If this is a grouping paren, handle:
5035193326Sed  // direct-declarator: '(' declarator ')'
5036193326Sed  // direct-declarator: '(' attributes declarator ')'
5037193326Sed  if (isGrouping) {
5038234353Sdim    SourceLocation EllipsisLoc = D.getEllipsisLoc();
5039234353Sdim    D.setEllipsisLoc(SourceLocation());
5040234353Sdim
5041193326Sed    bool hadGroupingParens = D.hasGroupingParens();
5042193326Sed    D.setGroupingParens(true);
5043193326Sed    ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
5044193326Sed    // Match the ')'.
5045226633Sdim    T.consumeClose();
5046239462Sdim    D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
5047226633Sdim                                            T.getCloseLocation()),
5048226633Sdim                  attrs, T.getCloseLocation());
5049193326Sed
5050193326Sed    D.setGroupingParens(hadGroupingParens);
5051234353Sdim
5052234353Sdim    // An ellipsis cannot be placed outside parentheses.
5053234353Sdim    if (EllipsisLoc.isValid())
5054234353Sdim      diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
5055234353Sdim
5056193326Sed    return;
5057193326Sed  }
5058198092Srdivacky
5059193326Sed  // Okay, if this wasn't a grouping paren, it must be the start of a function
5060193326Sed  // argument list.  Recognize that this declarator will never have an
5061193326Sed  // identifier (and remember where it would have been), then call into
5062193326Sed  // ParseFunctionDeclarator to handle of argument list.
5063193326Sed  D.SetIdentifier(0, Tok.getLocation());
5064193326Sed
5065234353Sdim  // Enter function-declaration scope, limiting any declarators to the
5066234353Sdim  // function prototype scope, including parameter declarators.
5067234353Sdim  ParseScope PrototypeScope(this,
5068249423Sdim                            Scope::FunctionPrototypeScope | Scope::DeclScope |
5069249423Sdim                            (D.isFunctionDeclaratorAFunctionDeclaration()
5070249423Sdim                               ? Scope::FunctionDeclarationScope : 0));
5071239462Sdim  ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
5072234353Sdim  PrototypeScope.Exit();
5073193326Sed}
5074193326Sed
5075193326Sed/// ParseFunctionDeclarator - We are after the identifier and have parsed the
5076193326Sed/// declarator D up to a paren, which indicates that we are parsing function
5077193326Sed/// arguments.
5078193326Sed///
5079234353Sdim/// If FirstArgAttrs is non-null, then the caller parsed those arguments
5080234353Sdim/// immediately after the open paren - they should be considered to be the
5081234353Sdim/// first argument of a parameter.
5082193326Sed///
5083234353Sdim/// If RequiresArg is true, then the first argument of the function is required
5084234353Sdim/// to be present and required to not be an identifier list.
5085193326Sed///
5086234353Sdim/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
5087234353Sdim/// (C++11) ref-qualifier[opt], exception-specification[opt],
5088234353Sdim/// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
5089234353Sdim///
5090234353Sdim/// [C++11] exception-specification:
5091221345Sdim///           dynamic-exception-specification
5092221345Sdim///           noexcept-specification
5093221345Sdim///
5094226633Sdimvoid Parser::ParseFunctionDeclarator(Declarator &D,
5095234353Sdim                                     ParsedAttributes &FirstArgAttrs,
5096226633Sdim                                     BalancedDelimiterTracker &Tracker,
5097239462Sdim                                     bool IsAmbiguous,
5098193326Sed                                     bool RequiresArg) {
5099239462Sdim  assert(getCurScope()->isFunctionPrototypeScope() &&
5100234353Sdim         "Should call from a Function scope");
5101193326Sed  // lparen is already consumed!
5102193326Sed  assert(D.isPastIdentifier() && "Should not call before identifier!");
5103198092Srdivacky
5104224145Sdim  // This should be true when the function has typed arguments.
5105224145Sdim  // Otherwise, it is treated as a K&R-style function.
5106224145Sdim  bool HasProto = false;
5107224145Sdim  // Build up an array of information about the parsed arguments.
5108226633Sdim  SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
5109224145Sdim  // Remember where we see an ellipsis, if any.
5110224145Sdim  SourceLocation EllipsisLoc;
5111224145Sdim
5112224145Sdim  DeclSpec DS(AttrFactory);
5113224145Sdim  bool RefQualifierIsLValueRef = true;
5114224145Sdim  SourceLocation RefQualifierLoc;
5115234353Sdim  SourceLocation ConstQualifierLoc;
5116234353Sdim  SourceLocation VolatileQualifierLoc;
5117224145Sdim  ExceptionSpecificationType ESpecType = EST_None;
5118224145Sdim  SourceRange ESpecRange;
5119226633Sdim  SmallVector<ParsedType, 2> DynamicExceptions;
5120226633Sdim  SmallVector<SourceRange, 2> DynamicExceptionRanges;
5121224145Sdim  ExprResult NoexceptExpr;
5122234353Sdim  ParsedAttributes FnAttrs(AttrFactory);
5123239462Sdim  TypeResult TrailingReturnType;
5124234353Sdim
5125234353Sdim  Actions.ActOnStartFunctionDeclarator();
5126243830Sdim  /* LocalEndLoc is the end location for the local FunctionTypeLoc.
5127243830Sdim     EndLoc is the end location for the function declarator.
5128243830Sdim     They differ for trailing return types. */
5129243830Sdim  SourceLocation StartLoc, LocalEndLoc, EndLoc;
5130243830Sdim  SourceLocation LParenLoc, RParenLoc;
5131243830Sdim  LParenLoc = Tracker.getOpenLocation();
5132243830Sdim  StartLoc = LParenLoc;
5133243830Sdim
5134224145Sdim  if (isFunctionDeclaratorIdentifierList()) {
5135218893Sdim    if (RequiresArg)
5136193326Sed      Diag(Tok, diag::err_argument_required_after_attribute);
5137193326Sed
5138224145Sdim    ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
5139193326Sed
5140226633Sdim    Tracker.consumeClose();
5141243830Sdim    RParenLoc = Tracker.getCloseLocation();
5142243830Sdim    LocalEndLoc = RParenLoc;
5143243830Sdim    EndLoc = RParenLoc;
5144224145Sdim  } else {
5145224145Sdim    if (Tok.isNot(tok::r_paren))
5146263508Sdim      ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo,
5147263508Sdim                                      EllipsisLoc);
5148224145Sdim    else if (RequiresArg)
5149224145Sdim      Diag(Tok, diag::err_argument_required_after_attribute);
5150224145Sdim
5151234353Sdim    HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
5152224145Sdim
5153224145Sdim    // If we have the closing ')', eat it.
5154226633Sdim    Tracker.consumeClose();
5155243830Sdim    RParenLoc = Tracker.getCloseLocation();
5156243830Sdim    LocalEndLoc = RParenLoc;
5157243830Sdim    EndLoc = RParenLoc;
5158224145Sdim
5159234353Sdim    if (getLangOpts().CPlusPlus) {
5160234353Sdim      // FIXME: Accept these components in any order, and produce fixits to
5161234353Sdim      // correct the order if the user gets it wrong. Ideally we should deal
5162234353Sdim      // with the virt-specifier-seq and pure-specifier in the same way.
5163218893Sdim
5164224145Sdim      // Parse cv-qualifier-seq[opt].
5165249423Sdim      ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false,
5166249423Sdim                                /*CXX11AttributesAllowed*/ false,
5167249423Sdim                                /*AtomicAllowed*/ false);
5168234353Sdim      if (!DS.getSourceRange().getEnd().isInvalid()) {
5169234353Sdim        EndLoc = DS.getSourceRange().getEnd();
5170234353Sdim        ConstQualifierLoc = DS.getConstSpecLoc();
5171234353Sdim        VolatileQualifierLoc = DS.getVolatileSpecLoc();
5172234353Sdim      }
5173193326Sed
5174224145Sdim      // Parse ref-qualifier[opt].
5175218893Sdim      if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
5176249423Sdim        Diag(Tok, getLangOpts().CPlusPlus11 ?
5177234353Sdim             diag::warn_cxx98_compat_ref_qualifier :
5178234353Sdim             diag::ext_ref_qualifier);
5179234353Sdim
5180218893Sdim        RefQualifierIsLValueRef = Tok.is(tok::amp);
5181218893Sdim        RefQualifierLoc = ConsumeToken();
5182218893Sdim        EndLoc = RefQualifierLoc;
5183218893Sdim      }
5184221345Sdim
5185234982Sdim      // C++11 [expr.prim.general]p3:
5186239462Sdim      //   If a declaration declares a member function or member function
5187239462Sdim      //   template of a class X, the expression this is a prvalue of type
5188234982Sdim      //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
5189239462Sdim      //   and the end of the function-definition, member-declarator, or
5190234982Sdim      //   declarator.
5191249423Sdim      // FIXME: currently, "static" case isn't handled correctly.
5192239462Sdim      bool IsCXX11MemberFunction =
5193249423Sdim        getLangOpts().CPlusPlus11 &&
5194249423Sdim        (D.getContext() == Declarator::MemberContext
5195249423Sdim         ? !D.getDeclSpec().isFriendSpecified()
5196249423Sdim         : D.getContext() == Declarator::FileContext &&
5197249423Sdim           D.getCXXScopeSpec().isValid() &&
5198249423Sdim           Actions.CurContext->isRecord());
5199234982Sdim      Sema::CXXThisScopeRAII ThisScope(Actions,
5200234982Sdim                               dyn_cast<CXXRecordDecl>(Actions.CurContext),
5201249423Sdim                               DS.getTypeQualifiers() |
5202251662Sdim                               (D.getDeclSpec().isConstexprSpecified() &&
5203251662Sdim                                !getLangOpts().CPlusPlus1y
5204249423Sdim                                  ? Qualifiers::Const : 0),
5205234982Sdim                               IsCXX11MemberFunction);
5206235864Sdim
5207193326Sed      // Parse exception-specification[opt].
5208235864Sdim      ESpecType = tryParseExceptionSpecification(ESpecRange,
5209234982Sdim                                                 DynamicExceptions,
5210234982Sdim                                                 DynamicExceptionRanges,
5211235864Sdim                                                 NoexceptExpr);
5212221345Sdim      if (ESpecType != EST_None)
5213221345Sdim        EndLoc = ESpecRange.getEnd();
5214218893Sdim
5215234353Sdim      // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
5216234353Sdim      // after the exception-specification.
5217249423Sdim      MaybeParseCXX11Attributes(FnAttrs);
5218234353Sdim
5219224145Sdim      // Parse trailing-return-type[opt].
5220243830Sdim      LocalEndLoc = EndLoc;
5221249423Sdim      if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) {
5222234353Sdim        Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
5223243830Sdim        if (D.getDeclSpec().getTypeSpecType() == TST_auto)
5224243830Sdim          StartLoc = D.getDeclSpec().getTypeSpecTypeLoc();
5225243830Sdim        LocalEndLoc = Tok.getLocation();
5226226633Sdim        SourceRange Range;
5227239462Sdim        TrailingReturnType = ParseTrailingReturnType(Range);
5228243830Sdim        EndLoc = Range.getEnd();
5229218893Sdim      }
5230193326Sed    }
5231193326Sed  }
5232193326Sed
5233224145Sdim  // Remember that we parsed a function type, and remember the attributes.
5234224145Sdim  D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
5235243830Sdim                                             IsAmbiguous,
5236243830Sdim                                             LParenLoc,
5237224145Sdim                                             ParamInfo.data(), ParamInfo.size(),
5238243830Sdim                                             EllipsisLoc, RParenLoc,
5239224145Sdim                                             DS.getTypeQualifiers(),
5240224145Sdim                                             RefQualifierIsLValueRef,
5241234353Sdim                                             RefQualifierLoc, ConstQualifierLoc,
5242234353Sdim                                             VolatileQualifierLoc,
5243224145Sdim                                             /*MutableLoc=*/SourceLocation(),
5244224145Sdim                                             ESpecType, ESpecRange.getBegin(),
5245224145Sdim                                             DynamicExceptions.data(),
5246224145Sdim                                             DynamicExceptionRanges.data(),
5247224145Sdim                                             DynamicExceptions.size(),
5248224145Sdim                                             NoexceptExpr.isUsable() ?
5249224145Sdim                                               NoexceptExpr.get() : 0,
5250243830Sdim                                             StartLoc, LocalEndLoc, D,
5251224145Sdim                                             TrailingReturnType),
5252234353Sdim                FnAttrs, EndLoc);
5253234353Sdim
5254234353Sdim  Actions.ActOnEndFunctionDeclarator();
5255224145Sdim}
5256224145Sdim
5257224145Sdim/// isFunctionDeclaratorIdentifierList - This parameter list may have an
5258224145Sdim/// identifier list form for a K&R-style function:  void foo(a,b,c)
5259224145Sdim///
5260224145Sdim/// Note that identifier-lists are only allowed for normal declarators, not for
5261224145Sdim/// abstract-declarators.
5262224145Sdimbool Parser::isFunctionDeclaratorIdentifierList() {
5263234353Sdim  return !getLangOpts().CPlusPlus
5264224145Sdim         && Tok.is(tok::identifier)
5265224145Sdim         && !TryAltiVecVectorToken()
5266224145Sdim         // K&R identifier lists can't have typedefs as identifiers, per C99
5267224145Sdim         // 6.7.5.3p11.
5268224145Sdim         && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
5269224145Sdim         // Identifier lists follow a really simple grammar: the identifiers can
5270224145Sdim         // be followed *only* by a ", identifier" or ")".  However, K&R
5271224145Sdim         // identifier lists are really rare in the brave new modern world, and
5272224145Sdim         // it is very common for someone to typo a type in a non-K&R style
5273224145Sdim         // list.  If we are presented with something like: "void foo(intptr x,
5274224145Sdim         // float y)", we don't want to start parsing the function declarator as
5275224145Sdim         // though it is a K&R style declarator just because intptr is an
5276224145Sdim         // invalid type.
5277224145Sdim         //
5278224145Sdim         // To handle this, we check to see if the token after the first
5279224145Sdim         // identifier is a "," or ")".  Only then do we parse it as an
5280224145Sdim         // identifier list.
5281224145Sdim         && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
5282224145Sdim}
5283224145Sdim
5284224145Sdim/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
5285224145Sdim/// we found a K&R-style identifier list instead of a typed parameter list.
5286224145Sdim///
5287224145Sdim/// After returning, ParamInfo will hold the parsed parameters.
5288224145Sdim///
5289224145Sdim///       identifier-list: [C99 6.7.5]
5290224145Sdim///         identifier
5291224145Sdim///         identifier-list ',' identifier
5292224145Sdim///
5293224145Sdimvoid Parser::ParseFunctionDeclaratorIdentifierList(
5294224145Sdim       Declarator &D,
5295263508Sdim       SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {
5296224145Sdim  // If there was no identifier specified for the declarator, either we are in
5297224145Sdim  // an abstract-declarator, or we are in a parameter declarator which was found
5298224145Sdim  // to be abstract.  In abstract-declarators, identifier lists are not valid:
5299224145Sdim  // diagnose this.
5300224145Sdim  if (!D.getIdentifier())
5301224145Sdim    Diag(Tok, diag::ext_ident_list_in_param);
5302224145Sdim
5303224145Sdim  // Maintain an efficient lookup of params we have seen so far.
5304224145Sdim  llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
5305224145Sdim
5306224145Sdim  while (1) {
5307224145Sdim    // If this isn't an identifier, report the error and skip until ')'.
5308224145Sdim    if (Tok.isNot(tok::identifier)) {
5309224145Sdim      Diag(Tok, diag::err_expected_ident);
5310263508Sdim      SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
5311224145Sdim      // Forget we parsed anything.
5312224145Sdim      ParamInfo.clear();
5313224145Sdim      return;
5314193326Sed    }
5315198092Srdivacky
5316224145Sdim    IdentifierInfo *ParmII = Tok.getIdentifierInfo();
5317198092Srdivacky
5318224145Sdim    // Reject 'typedef int y; int test(x, y)', but continue parsing.
5319224145Sdim    if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
5320224145Sdim      Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
5321193326Sed
5322224145Sdim    // Verify that the argument identifier has not already been mentioned.
5323224145Sdim    if (!ParamsSoFar.insert(ParmII)) {
5324224145Sdim      Diag(Tok, diag::err_param_redefinition) << ParmII;
5325224145Sdim    } else {
5326224145Sdim      // Remember this identifier in ParamInfo.
5327224145Sdim      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
5328224145Sdim                                                     Tok.getLocation(),
5329224145Sdim                                                     0));
5330224145Sdim    }
5331198092Srdivacky
5332224145Sdim    // Eat the identifier.
5333224145Sdim    ConsumeToken();
5334224145Sdim
5335224145Sdim    // The list continues if we see a comma.
5336224145Sdim    if (Tok.isNot(tok::comma))
5337224145Sdim      break;
5338224145Sdim    ConsumeToken();
5339224145Sdim  }
5340224145Sdim}
5341224145Sdim
5342224145Sdim/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
5343224145Sdim/// after the opening parenthesis. This function will not parse a K&R-style
5344224145Sdim/// identifier list.
5345224145Sdim///
5346234353Sdim/// D is the declarator being parsed.  If FirstArgAttrs is non-null, then the
5347234353Sdim/// caller parsed those arguments immediately after the open paren - they should
5348234353Sdim/// be considered to be part of the first parameter.
5349224145Sdim///
5350224145Sdim/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
5351224145Sdim/// be the location of the ellipsis, if any was parsed.
5352224145Sdim///
5353224145Sdim///       parameter-type-list: [C99 6.7.5]
5354224145Sdim///         parameter-list
5355224145Sdim///         parameter-list ',' '...'
5356224145Sdim/// [C++]   parameter-list '...'
5357224145Sdim///
5358224145Sdim///       parameter-list: [C99 6.7.5]
5359224145Sdim///         parameter-declaration
5360224145Sdim///         parameter-list ',' parameter-declaration
5361224145Sdim///
5362224145Sdim///       parameter-declaration: [C99 6.7.5]
5363224145Sdim///         declaration-specifiers declarator
5364224145Sdim/// [C++]   declaration-specifiers declarator '=' assignment-expression
5365234353Sdim/// [C++11]                                       initializer-clause
5366224145Sdim/// [GNU]   declaration-specifiers declarator attributes
5367224145Sdim///         declaration-specifiers abstract-declarator[opt]
5368224145Sdim/// [C++]   declaration-specifiers abstract-declarator[opt]
5369224145Sdim///           '=' assignment-expression
5370224145Sdim/// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
5371234353Sdim/// [C++11] attribute-specifier-seq parameter-declaration
5372224145Sdim///
5373224145Sdimvoid Parser::ParseParameterDeclarationClause(
5374224145Sdim       Declarator &D,
5375234353Sdim       ParsedAttributes &FirstArgAttrs,
5376263508Sdim       SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
5377224145Sdim       SourceLocation &EllipsisLoc) {
5378193326Sed  while (1) {
5379193326Sed    if (Tok.is(tok::ellipsis)) {
5380234353Sdim      // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
5381234353Sdim      // before deciding this was a parameter-declaration-clause.
5382193326Sed      EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
5383193326Sed      break;
5384193326Sed    }
5385198092Srdivacky
5386193326Sed    // Parse the declaration-specifiers.
5387198893Srdivacky    // Just use the ParsingDeclaration "scope" of the declarator.
5388221345Sdim    DeclSpec DS(AttrFactory);
5389226633Sdim
5390234353Sdim    // Parse any C++11 attributes.
5391249423Sdim    MaybeParseCXX11Attributes(DS.getAttributes());
5392234353Sdim
5393218893Sdim    // Skip any Microsoft attributes before a param.
5394249423Sdim    MaybeParseMicrosoftAttributes(DS.getAttributes());
5395193326Sed
5396218893Sdim    SourceLocation DSStart = Tok.getLocation();
5397218893Sdim
5398193326Sed    // If the caller parsed attributes for the first argument, add them now.
5399218893Sdim    // Take them so that we only apply the attributes to the first parameter.
5400224145Sdim    // FIXME: If we can leave the attributes in the token stream somehow, we can
5401234353Sdim    // get rid of a parameter (FirstArgAttrs) and this statement. It might be
5402234353Sdim    // too much hassle.
5403234353Sdim    DS.takeAttributesFrom(FirstArgAttrs);
5404218893Sdim
5405193326Sed    ParseDeclarationSpecifiers(DS);
5406198092Srdivacky
5407193326Sed
5408263508Sdim    // Parse the declarator.  This is "PrototypeContext" or
5409263508Sdim    // "LambdaExprParameterContext", because we must accept either
5410263508Sdim    // 'declarator' or 'abstract-declarator' here.
5411263508Sdim    Declarator ParmDeclarator(DS,
5412263508Sdim              D.getContext() == Declarator::LambdaExprContext ?
5413263508Sdim                                  Declarator::LambdaExprParameterContext :
5414263508Sdim                                                Declarator::PrototypeContext);
5415263508Sdim    ParseDeclarator(ParmDeclarator);
5416263508Sdim
5417193326Sed    // Parse GNU attributes, if present.
5418263508Sdim    MaybeParseGNUAttributes(ParmDeclarator);
5419198092Srdivacky
5420193326Sed    // Remember this parsed parameter in ParamInfo.
5421263508Sdim    IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
5422198092Srdivacky
5423193326Sed    // DefArgToks is used when the parsing of default arguments needs
5424193326Sed    // to be delayed.
5425193326Sed    CachedTokens *DefArgToks = 0;
5426193326Sed
5427193326Sed    // If no parameter was specified, verify that *something* was specified,
5428193326Sed    // otherwise we have a missing type and identifier.
5429263508Sdim    if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 &&
5430263508Sdim        ParmDeclarator.getNumTypeObjects() == 0) {
5431193326Sed      // Completely missing, emit error.
5432193326Sed      Diag(DSStart, diag::err_missing_param);
5433193326Sed    } else {
5434193326Sed      // Otherwise, we have something.  Add it and let semantic analysis try
5435193326Sed      // to grok it and add the result to the ParamInfo we are building.
5436198092Srdivacky
5437193326Sed      // Inform the actions module about the parameter declarator, so it gets
5438193326Sed      // added to the current scope.
5439263508Sdim      Decl *Param = Actions.ActOnParamDeclarator(getCurScope(),
5440263508Sdim                                                       ParmDeclarator);
5441193326Sed      // Parse the default argument, if any. We parse the default
5442193326Sed      // arguments in all dialects; the semantic analysis in
5443193326Sed      // ActOnParamDefaultArgument will reject the default argument in
5444193326Sed      // C.
5445193326Sed      if (Tok.is(tok::equal)) {
5446193326Sed        SourceLocation EqualLoc = Tok.getLocation();
5447193326Sed
5448193326Sed        // Parse the default argument
5449193326Sed        if (D.getContext() == Declarator::MemberContext) {
5450193326Sed          // If we're inside a class definition, cache the tokens
5451193326Sed          // corresponding to the default argument. We'll actually parse
5452193326Sed          // them when we see the end of the class definition.
5453193326Sed          // FIXME: Can we use a smart pointer for Toks?
5454193326Sed          DefArgToks = new CachedTokens;
5455193326Sed
5456263508Sdim          if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) {
5457193326Sed            delete DefArgToks;
5458193326Sed            DefArgToks = 0;
5459193326Sed            Actions.ActOnParamDefaultArgumentError(Param);
5460212904Sdim          } else {
5461212904Sdim            // Mark the end of the default argument so that we know when to
5462212904Sdim            // stop when we parse it later on.
5463212904Sdim            Token DefArgEnd;
5464212904Sdim            DefArgEnd.startToken();
5465212904Sdim            DefArgEnd.setKind(tok::cxx_defaultarg_end);
5466212904Sdim            DefArgEnd.setLocation(Tok.getLocation());
5467212904Sdim            DefArgToks->push_back(DefArgEnd);
5468198092Srdivacky            Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
5469194179Sed                                                (*DefArgToks)[1].getLocation());
5470212904Sdim          }
5471193326Sed        } else {
5472193326Sed          // Consume the '='.
5473193326Sed          ConsumeToken();
5474198092Srdivacky
5475239462Sdim          // The argument isn't actually potentially evaluated unless it is
5476218893Sdim          // used.
5477218893Sdim          EnterExpressionEvaluationContext Eval(Actions,
5478234353Sdim                                              Sema::PotentiallyEvaluatedIfUsed,
5479234353Sdim                                                Param);
5480218893Sdim
5481234353Sdim          ExprResult DefArgResult;
5482249423Sdim          if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
5483234353Sdim            Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
5484234353Sdim            DefArgResult = ParseBraceInitializer();
5485234353Sdim          } else
5486234353Sdim            DefArgResult = ParseAssignmentExpression();
5487193326Sed          if (DefArgResult.isInvalid()) {
5488193326Sed            Actions.ActOnParamDefaultArgumentError(Param);
5489263508Sdim            SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
5490193326Sed          } else {
5491193326Sed            // Inform the actions module about the default argument
5492193326Sed            Actions.ActOnParamDefaultArgument(Param, EqualLoc,
5493212904Sdim                                              DefArgResult.take());
5494193326Sed          }
5495193326Sed        }
5496193326Sed      }
5497198092Srdivacky
5498198092Srdivacky      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
5499263508Sdim                                          ParmDeclarator.getIdentifierLoc(),
5500263508Sdim                                          Param, DefArgToks));
5501193326Sed    }
5502193326Sed
5503193326Sed    // If the next token is a comma, consume it and keep reading arguments.
5504198092Srdivacky    if (Tok.isNot(tok::comma)) {
5505198092Srdivacky      if (Tok.is(tok::ellipsis)) {
5506198092Srdivacky        EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
5507239462Sdim
5508234353Sdim        if (!getLangOpts().CPlusPlus) {
5509198092Srdivacky          // We have ellipsis without a preceding ',', which is ill-formed
5510198092Srdivacky          // in C. Complain and provide the fix.
5511198092Srdivacky          Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
5512206084Srdivacky            << FixItHint::CreateInsertion(EllipsisLoc, ", ");
5513198092Srdivacky        }
5514198092Srdivacky      }
5515239462Sdim
5516198092Srdivacky      break;
5517198092Srdivacky    }
5518198092Srdivacky
5519193326Sed    // Consume the comma.
5520193326Sed    ConsumeToken();
5521193326Sed  }
5522198092Srdivacky
5523193326Sed}
5524193326Sed
5525193326Sed/// [C90]   direct-declarator '[' constant-expression[opt] ']'
5526193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
5527193326Sed/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
5528193326Sed/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
5529193326Sed/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
5530234353Sdim/// [C++11] direct-declarator '[' constant-expression[opt] ']'
5531234353Sdim///                           attribute-specifier-seq[opt]
5532193326Sedvoid Parser::ParseBracketDeclarator(Declarator &D) {
5533234353Sdim  if (CheckProhibitedCXX11Attribute())
5534234353Sdim    return;
5535234353Sdim
5536226633Sdim  BalancedDelimiterTracker T(*this, tok::l_square);
5537226633Sdim  T.consumeOpen();
5538198092Srdivacky
5539193326Sed  // C array syntax has many features, but by-far the most common is [] and [4].
5540193326Sed  // This code does a fast path to handle some of the most obvious cases.
5541193326Sed  if (Tok.getKind() == tok::r_square) {
5542226633Sdim    T.consumeClose();
5543221345Sdim    ParsedAttributes attrs(AttrFactory);
5544249423Sdim    MaybeParseCXX11Attributes(attrs);
5545239462Sdim
5546193326Sed    // Remember that we parsed the empty array type.
5547212904Sdim    ExprResult NumElements;
5548221345Sdim    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
5549226633Sdim                                            T.getOpenLocation(),
5550226633Sdim                                            T.getCloseLocation()),
5551226633Sdim                  attrs, T.getCloseLocation());
5552193326Sed    return;
5553193326Sed  } else if (Tok.getKind() == tok::numeric_constant &&
5554193326Sed             GetLookAheadToken(1).is(tok::r_square)) {
5555193326Sed    // [4] is very common.  Parse the numeric constant expression.
5556234353Sdim    ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
5557193326Sed    ConsumeToken();
5558193326Sed
5559226633Sdim    T.consumeClose();
5560221345Sdim    ParsedAttributes attrs(AttrFactory);
5561249423Sdim    MaybeParseCXX11Attributes(attrs);
5562193326Sed
5563193326Sed    // Remember that we parsed a array type, and remember its features.
5564249423Sdim    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
5565218893Sdim                                            ExprRes.release(),
5566226633Sdim                                            T.getOpenLocation(),
5567226633Sdim                                            T.getCloseLocation()),
5568226633Sdim                  attrs, T.getCloseLocation());
5569193326Sed    return;
5570193326Sed  }
5571198092Srdivacky
5572193326Sed  // If valid, this location is the position where we read the 'static' keyword.
5573193326Sed  SourceLocation StaticLoc;
5574193326Sed  if (Tok.is(tok::kw_static))
5575193326Sed    StaticLoc = ConsumeToken();
5576198092Srdivacky
5577193326Sed  // If there is a type-qualifier-list, read it now.
5578193326Sed  // Type qualifiers in an array subscript are a C99 feature.
5579221345Sdim  DeclSpec DS(AttrFactory);
5580193326Sed  ParseTypeQualifierListOpt(DS, false /*no attributes*/);
5581198092Srdivacky
5582193326Sed  // If we haven't already read 'static', check to see if there is one after the
5583193326Sed  // type-qualifier-list.
5584193326Sed  if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
5585193326Sed    StaticLoc = ConsumeToken();
5586198092Srdivacky
5587193326Sed  // Handle "direct-declarator [ type-qual-list[opt] * ]".
5588193326Sed  bool isStar = false;
5589212904Sdim  ExprResult NumElements;
5590198092Srdivacky
5591193326Sed  // Handle the case where we have '[*]' as the array size.  However, a leading
5592193326Sed  // star could be the start of an expression, for example 'X[*p + 4]'.  Verify
5593239462Sdim  // the token after the star is a ']'.  Since stars in arrays are
5594193326Sed  // infrequent, use of lookahead is not costly here.
5595193326Sed  if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
5596193326Sed    ConsumeToken();  // Eat the '*'.
5597193326Sed
5598193326Sed    if (StaticLoc.isValid()) {
5599193326Sed      Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
5600193326Sed      StaticLoc = SourceLocation();  // Drop the static.
5601193326Sed    }
5602193326Sed    isStar = true;
5603193326Sed  } else if (Tok.isNot(tok::r_square)) {
5604193326Sed    // Note, in C89, this production uses the constant-expr production instead
5605193326Sed    // of assignment-expr.  The only difference is that assignment-expr allows
5606193326Sed    // things like '=' and '*='.  Sema rejects these in C89 mode because they
5607193326Sed    // are not i-c-e's, so we don't need to distinguish between the two here.
5608198092Srdivacky
5609194613Sed    // Parse the constant-expression or assignment-expression now (depending
5610194613Sed    // on dialect).
5611234353Sdim    if (getLangOpts().CPlusPlus) {
5612194613Sed      NumElements = ParseConstantExpression();
5613234353Sdim    } else {
5614234353Sdim      EnterExpressionEvaluationContext Unevaluated(Actions,
5615234353Sdim                                                   Sema::ConstantEvaluated);
5616194613Sed      NumElements = ParseAssignmentExpression();
5617234353Sdim    }
5618193326Sed  }
5619198092Srdivacky
5620193326Sed  // If there was an error parsing the assignment-expression, recover.
5621193326Sed  if (NumElements.isInvalid()) {
5622193326Sed    D.setInvalidType(true);
5623193326Sed    // If the expression was invalid, skip it.
5624263508Sdim    SkipUntil(tok::r_square, StopAtSemi);
5625193326Sed    return;
5626193326Sed  }
5627193326Sed
5628226633Sdim  T.consumeClose();
5629193326Sed
5630221345Sdim  ParsedAttributes attrs(AttrFactory);
5631249423Sdim  MaybeParseCXX11Attributes(attrs);
5632199990Srdivacky
5633193326Sed  // Remember that we parsed a array type, and remember its features.
5634221345Sdim  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
5635193326Sed                                          StaticLoc.isValid(), isStar,
5636198092Srdivacky                                          NumElements.release(),
5637226633Sdim                                          T.getOpenLocation(),
5638226633Sdim                                          T.getCloseLocation()),
5639226633Sdim                attrs, T.getCloseLocation());
5640193326Sed}
5641193326Sed
5642193326Sed/// [GNU]   typeof-specifier:
5643193326Sed///           typeof ( expressions )
5644193326Sed///           typeof ( type-name )
5645193326Sed/// [GNU/C++] typeof unary-expression
5646193326Sed///
5647193326Sedvoid Parser::ParseTypeofSpecifier(DeclSpec &DS) {
5648193326Sed  assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
5649193326Sed  Token OpTok = Tok;
5650193326Sed  SourceLocation StartLoc = ConsumeToken();
5651193326Sed
5652202379Srdivacky  const bool hasParens = Tok.is(tok::l_paren);
5653202379Srdivacky
5654243830Sdim  EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
5655243830Sdim                                               Sema::ReuseLambdaContextDecl);
5656234353Sdim
5657193326Sed  bool isCastExpr;
5658212904Sdim  ParsedType CastTy;
5659193326Sed  SourceRange CastRange;
5660221345Sdim  ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
5661221345Sdim                                                          CastTy, CastRange);
5662202379Srdivacky  if (hasParens)
5663202379Srdivacky    DS.setTypeofParensRange(CastRange);
5664193326Sed
5665193326Sed  if (CastRange.getEnd().isInvalid())
5666193326Sed    // FIXME: Not accurate, the range gets one token more than it should.
5667193326Sed    DS.SetRangeEnd(Tok.getLocation());
5668193326Sed  else
5669193326Sed    DS.SetRangeEnd(CastRange.getEnd());
5670198092Srdivacky
5671193326Sed  if (isCastExpr) {
5672193326Sed    if (!CastTy) {
5673193326Sed      DS.SetTypeSpecError();
5674193326Sed      return;
5675193326Sed    }
5676193326Sed
5677193326Sed    const char *PrevSpec = 0;
5678198092Srdivacky    unsigned DiagID;
5679193326Sed    // Check for duplicate type specifiers (e.g. "int typeof(int)").
5680193326Sed    if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
5681198092Srdivacky                           DiagID, CastTy))
5682198092Srdivacky      Diag(StartLoc, DiagID) << PrevSpec;
5683193326Sed    return;
5684193326Sed  }
5685193326Sed
5686193326Sed  // If we get here, the operand to the typeof was an expresion.
5687193326Sed  if (Operand.isInvalid()) {
5688193326Sed    DS.SetTypeSpecError();
5689193326Sed    return;
5690193326Sed  }
5691193326Sed
5692234353Sdim  // We might need to transform the operand if it is potentially evaluated.
5693234353Sdim  Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5694234353Sdim  if (Operand.isInvalid()) {
5695234353Sdim    DS.SetTypeSpecError();
5696234353Sdim    return;
5697234353Sdim  }
5698234353Sdim
5699193326Sed  const char *PrevSpec = 0;
5700198092Srdivacky  unsigned DiagID;
5701193326Sed  // Check for duplicate type specifiers (e.g. "int typeof(int)").
5702193326Sed  if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
5703212904Sdim                         DiagID, Operand.get()))
5704198092Srdivacky    Diag(StartLoc, DiagID) << PrevSpec;
5705193326Sed}
5706204643Srdivacky
5707234353Sdim/// [C11]   atomic-specifier:
5708226633Sdim///           _Atomic ( type-name )
5709226633Sdim///
5710226633Sdimvoid Parser::ParseAtomicSpecifier(DeclSpec &DS) {
5711249423Sdim  assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) &&
5712249423Sdim         "Not an atomic specifier");
5713204643Srdivacky
5714226633Sdim  SourceLocation StartLoc = ConsumeToken();
5715226633Sdim  BalancedDelimiterTracker T(*this, tok::l_paren);
5716249423Sdim  if (T.consumeOpen())
5717226633Sdim    return;
5718226633Sdim
5719226633Sdim  TypeResult Result = ParseTypeName();
5720226633Sdim  if (Result.isInvalid()) {
5721263508Sdim    SkipUntil(tok::r_paren, StopAtSemi);
5722226633Sdim    return;
5723226633Sdim  }
5724226633Sdim
5725226633Sdim  // Match the ')'
5726226633Sdim  T.consumeClose();
5727226633Sdim
5728226633Sdim  if (T.getCloseLocation().isInvalid())
5729226633Sdim    return;
5730226633Sdim
5731226633Sdim  DS.setTypeofParensRange(T.getRange());
5732226633Sdim  DS.SetRangeEnd(T.getCloseLocation());
5733226633Sdim
5734226633Sdim  const char *PrevSpec = 0;
5735226633Sdim  unsigned DiagID;
5736226633Sdim  if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5737226633Sdim                         DiagID, Result.release()))
5738226633Sdim    Diag(StartLoc, DiagID) << PrevSpec;
5739226633Sdim}
5740226633Sdim
5741226633Sdim
5742204643Srdivacky/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5743204643Srdivacky/// from TryAltiVecVectorToken.
5744204643Srdivackybool Parser::TryAltiVecVectorTokenOutOfLine() {
5745204643Srdivacky  Token Next = NextToken();
5746204643Srdivacky  switch (Next.getKind()) {
5747204643Srdivacky  default: return false;
5748204643Srdivacky  case tok::kw_short:
5749204643Srdivacky  case tok::kw_long:
5750204643Srdivacky  case tok::kw_signed:
5751204643Srdivacky  case tok::kw_unsigned:
5752204643Srdivacky  case tok::kw_void:
5753204643Srdivacky  case tok::kw_char:
5754204643Srdivacky  case tok::kw_int:
5755204643Srdivacky  case tok::kw_float:
5756204643Srdivacky  case tok::kw_double:
5757204643Srdivacky  case tok::kw_bool:
5758204643Srdivacky  case tok::kw___pixel:
5759204643Srdivacky    Tok.setKind(tok::kw___vector);
5760204643Srdivacky    return true;
5761204643Srdivacky  case tok::identifier:
5762204643Srdivacky    if (Next.getIdentifierInfo() == Ident_pixel) {
5763204643Srdivacky      Tok.setKind(tok::kw___vector);
5764204643Srdivacky      return true;
5765204643Srdivacky    }
5766263508Sdim    if (Next.getIdentifierInfo() == Ident_bool) {
5767263508Sdim      Tok.setKind(tok::kw___vector);
5768263508Sdim      return true;
5769263508Sdim    }
5770204643Srdivacky    return false;
5771204643Srdivacky  }
5772204643Srdivacky}
5773204643Srdivacky
5774204643Srdivackybool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5775204643Srdivacky                                      const char *&PrevSpec, unsigned &DiagID,
5776204643Srdivacky                                      bool &isInvalid) {
5777204643Srdivacky  if (Tok.getIdentifierInfo() == Ident_vector) {
5778204643Srdivacky    Token Next = NextToken();
5779204643Srdivacky    switch (Next.getKind()) {
5780204643Srdivacky    case tok::kw_short:
5781204643Srdivacky    case tok::kw_long:
5782204643Srdivacky    case tok::kw_signed:
5783204643Srdivacky    case tok::kw_unsigned:
5784204643Srdivacky    case tok::kw_void:
5785204643Srdivacky    case tok::kw_char:
5786204643Srdivacky    case tok::kw_int:
5787204643Srdivacky    case tok::kw_float:
5788204643Srdivacky    case tok::kw_double:
5789204643Srdivacky    case tok::kw_bool:
5790204643Srdivacky    case tok::kw___pixel:
5791204643Srdivacky      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5792204643Srdivacky      return true;
5793204643Srdivacky    case tok::identifier:
5794204643Srdivacky      if (Next.getIdentifierInfo() == Ident_pixel) {
5795204643Srdivacky        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5796204643Srdivacky        return true;
5797204643Srdivacky      }
5798263508Sdim      if (Next.getIdentifierInfo() == Ident_bool) {
5799263508Sdim        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5800263508Sdim        return true;
5801263508Sdim      }
5802204643Srdivacky      break;
5803204643Srdivacky    default:
5804204643Srdivacky      break;
5805204643Srdivacky    }
5806210299Sed  } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
5807204643Srdivacky             DS.isTypeAltiVecVector()) {
5808204643Srdivacky    isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5809204643Srdivacky    return true;
5810263508Sdim  } else if ((Tok.getIdentifierInfo() == Ident_bool) &&
5811263508Sdim             DS.isTypeAltiVecVector()) {
5812263508Sdim    isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID);
5813263508Sdim    return true;
5814204643Srdivacky  }
5815204643Srdivacky  return false;
5816204643Srdivacky}
5817