xref: /minix3/external/bsd/llvm/dist/clang/lib/Parse/ParseDecl.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc //  This file implements the Declaration portions of the Parser interfaces.
11*f4a2713aSLionel Sambuc //
12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13*f4a2713aSLionel Sambuc 
14*f4a2713aSLionel Sambuc #include "clang/Parse/Parser.h"
15*f4a2713aSLionel Sambuc #include "RAIIObjectsForParser.h"
16*f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
17*f4a2713aSLionel Sambuc #include "clang/Basic/AddressSpaces.h"
18*f4a2713aSLionel Sambuc #include "clang/Basic/CharInfo.h"
19*f4a2713aSLionel Sambuc #include "clang/Basic/OpenCL.h"
20*f4a2713aSLionel Sambuc #include "clang/Parse/ParseDiagnostic.h"
21*f4a2713aSLionel Sambuc #include "clang/Sema/Lookup.h"
22*f4a2713aSLionel Sambuc #include "clang/Sema/ParsedTemplate.h"
23*f4a2713aSLionel Sambuc #include "clang/Sema/PrettyDeclStackTrace.h"
24*f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
25*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallSet.h"
26*f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
27*f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
28*f4a2713aSLionel Sambuc using namespace clang;
29*f4a2713aSLionel Sambuc 
30*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
31*f4a2713aSLionel Sambuc // C99 6.7: Declarations.
32*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
33*f4a2713aSLionel Sambuc 
34*f4a2713aSLionel Sambuc /// ParseTypeName
35*f4a2713aSLionel Sambuc ///       type-name: [C99 6.7.6]
36*f4a2713aSLionel Sambuc ///         specifier-qualifier-list abstract-declarator[opt]
37*f4a2713aSLionel Sambuc ///
38*f4a2713aSLionel Sambuc /// Called type-id in C++.
39*f4a2713aSLionel Sambuc TypeResult Parser::ParseTypeName(SourceRange *Range,
40*f4a2713aSLionel Sambuc                                  Declarator::TheContext Context,
41*f4a2713aSLionel Sambuc                                  AccessSpecifier AS,
42*f4a2713aSLionel Sambuc                                  Decl **OwnedType,
43*f4a2713aSLionel Sambuc                                  ParsedAttributes *Attrs) {
44*f4a2713aSLionel Sambuc   DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
45*f4a2713aSLionel Sambuc   if (DSC == DSC_normal)
46*f4a2713aSLionel Sambuc     DSC = DSC_type_specifier;
47*f4a2713aSLionel Sambuc 
48*f4a2713aSLionel Sambuc   // Parse the common declaration-specifiers piece.
49*f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
50*f4a2713aSLionel Sambuc   if (Attrs)
51*f4a2713aSLionel Sambuc     DS.addAttributes(Attrs->getList());
52*f4a2713aSLionel Sambuc   ParseSpecifierQualifierList(DS, AS, DSC);
53*f4a2713aSLionel Sambuc   if (OwnedType)
54*f4a2713aSLionel Sambuc     *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
55*f4a2713aSLionel Sambuc 
56*f4a2713aSLionel Sambuc   // Parse the abstract-declarator, if present.
57*f4a2713aSLionel Sambuc   Declarator DeclaratorInfo(DS, Context);
58*f4a2713aSLionel Sambuc   ParseDeclarator(DeclaratorInfo);
59*f4a2713aSLionel Sambuc   if (Range)
60*f4a2713aSLionel Sambuc     *Range = DeclaratorInfo.getSourceRange();
61*f4a2713aSLionel Sambuc 
62*f4a2713aSLionel Sambuc   if (DeclaratorInfo.isInvalidType())
63*f4a2713aSLionel Sambuc     return true;
64*f4a2713aSLionel Sambuc 
65*f4a2713aSLionel Sambuc   return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
66*f4a2713aSLionel Sambuc }
67*f4a2713aSLionel Sambuc 
68*f4a2713aSLionel Sambuc 
69*f4a2713aSLionel Sambuc /// isAttributeLateParsed - Return true if the attribute has arguments that
70*f4a2713aSLionel Sambuc /// require late parsing.
71*f4a2713aSLionel Sambuc static bool isAttributeLateParsed(const IdentifierInfo &II) {
72*f4a2713aSLionel Sambuc     return llvm::StringSwitch<bool>(II.getName())
73*f4a2713aSLionel Sambuc #include "clang/Parse/AttrLateParsed.inc"
74*f4a2713aSLionel Sambuc         .Default(false);
75*f4a2713aSLionel Sambuc }
76*f4a2713aSLionel Sambuc 
77*f4a2713aSLionel Sambuc /// ParseGNUAttributes - Parse a non-empty attributes list.
78*f4a2713aSLionel Sambuc ///
79*f4a2713aSLionel Sambuc /// [GNU] attributes:
80*f4a2713aSLionel Sambuc ///         attribute
81*f4a2713aSLionel Sambuc ///         attributes attribute
82*f4a2713aSLionel Sambuc ///
83*f4a2713aSLionel Sambuc /// [GNU]  attribute:
84*f4a2713aSLionel Sambuc ///          '__attribute__' '(' '(' attribute-list ')' ')'
85*f4a2713aSLionel Sambuc ///
86*f4a2713aSLionel Sambuc /// [GNU]  attribute-list:
87*f4a2713aSLionel Sambuc ///          attrib
88*f4a2713aSLionel Sambuc ///          attribute_list ',' attrib
89*f4a2713aSLionel Sambuc ///
90*f4a2713aSLionel Sambuc /// [GNU]  attrib:
91*f4a2713aSLionel Sambuc ///          empty
92*f4a2713aSLionel Sambuc ///          attrib-name
93*f4a2713aSLionel Sambuc ///          attrib-name '(' identifier ')'
94*f4a2713aSLionel Sambuc ///          attrib-name '(' identifier ',' nonempty-expr-list ')'
95*f4a2713aSLionel Sambuc ///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
96*f4a2713aSLionel Sambuc ///
97*f4a2713aSLionel Sambuc /// [GNU]  attrib-name:
98*f4a2713aSLionel Sambuc ///          identifier
99*f4a2713aSLionel Sambuc ///          typespec
100*f4a2713aSLionel Sambuc ///          typequal
101*f4a2713aSLionel Sambuc ///          storageclass
102*f4a2713aSLionel Sambuc ///
103*f4a2713aSLionel Sambuc /// Whether an attribute takes an 'identifier' is determined by the
104*f4a2713aSLionel Sambuc /// attrib-name. GCC's behavior here is not worth imitating:
105*f4a2713aSLionel Sambuc ///
106*f4a2713aSLionel Sambuc ///  * In C mode, if the attribute argument list starts with an identifier
107*f4a2713aSLionel Sambuc ///    followed by a ',' or an ')', and the identifier doesn't resolve to
108*f4a2713aSLionel Sambuc ///    a type, it is parsed as an identifier. If the attribute actually
109*f4a2713aSLionel Sambuc ///    wanted an expression, it's out of luck (but it turns out that no
110*f4a2713aSLionel Sambuc ///    attributes work that way, because C constant expressions are very
111*f4a2713aSLionel Sambuc ///    limited).
112*f4a2713aSLionel Sambuc ///  * In C++ mode, if the attribute argument list starts with an identifier,
113*f4a2713aSLionel Sambuc ///    and the attribute *wants* an identifier, it is parsed as an identifier.
114*f4a2713aSLionel Sambuc ///    At block scope, any additional tokens between the identifier and the
115*f4a2713aSLionel Sambuc ///    ',' or ')' are ignored, otherwise they produce a parse error.
116*f4a2713aSLionel Sambuc ///
117*f4a2713aSLionel Sambuc /// We follow the C++ model, but don't allow junk after the identifier.
118*f4a2713aSLionel Sambuc void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
119*f4a2713aSLionel Sambuc                                 SourceLocation *endLoc,
120*f4a2713aSLionel Sambuc                                 LateParsedAttrList *LateAttrs) {
121*f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
122*f4a2713aSLionel Sambuc 
123*f4a2713aSLionel Sambuc   while (Tok.is(tok::kw___attribute)) {
124*f4a2713aSLionel Sambuc     ConsumeToken();
125*f4a2713aSLionel Sambuc     if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
126*f4a2713aSLionel Sambuc                          "attribute")) {
127*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
128*f4a2713aSLionel Sambuc       return;
129*f4a2713aSLionel Sambuc     }
130*f4a2713aSLionel Sambuc     if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
131*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
132*f4a2713aSLionel Sambuc       return;
133*f4a2713aSLionel Sambuc     }
134*f4a2713aSLionel Sambuc     // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
135*f4a2713aSLionel Sambuc     while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
136*f4a2713aSLionel Sambuc            Tok.is(tok::comma)) {
137*f4a2713aSLionel Sambuc       if (Tok.is(tok::comma)) {
138*f4a2713aSLionel Sambuc         // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
139*f4a2713aSLionel Sambuc         ConsumeToken();
140*f4a2713aSLionel Sambuc         continue;
141*f4a2713aSLionel Sambuc       }
142*f4a2713aSLionel Sambuc       // we have an identifier or declaration specifier (const, int, etc.)
143*f4a2713aSLionel Sambuc       IdentifierInfo *AttrName = Tok.getIdentifierInfo();
144*f4a2713aSLionel Sambuc       SourceLocation AttrNameLoc = ConsumeToken();
145*f4a2713aSLionel Sambuc 
146*f4a2713aSLionel Sambuc       if (Tok.is(tok::l_paren)) {
147*f4a2713aSLionel Sambuc         // handle "parameterized" attributes
148*f4a2713aSLionel Sambuc         if (LateAttrs && isAttributeLateParsed(*AttrName)) {
149*f4a2713aSLionel Sambuc           LateParsedAttribute *LA =
150*f4a2713aSLionel Sambuc             new LateParsedAttribute(this, *AttrName, AttrNameLoc);
151*f4a2713aSLionel Sambuc           LateAttrs->push_back(LA);
152*f4a2713aSLionel Sambuc 
153*f4a2713aSLionel Sambuc           // Attributes in a class are parsed at the end of the class, along
154*f4a2713aSLionel Sambuc           // with other late-parsed declarations.
155*f4a2713aSLionel Sambuc           if (!ClassStack.empty() && !LateAttrs->parseSoon())
156*f4a2713aSLionel Sambuc             getCurrentClass().LateParsedDeclarations.push_back(LA);
157*f4a2713aSLionel Sambuc 
158*f4a2713aSLionel Sambuc           // consume everything up to and including the matching right parens
159*f4a2713aSLionel Sambuc           ConsumeAndStoreUntil(tok::r_paren, LA->Toks, true, false);
160*f4a2713aSLionel Sambuc 
161*f4a2713aSLionel Sambuc           Token Eof;
162*f4a2713aSLionel Sambuc           Eof.startToken();
163*f4a2713aSLionel Sambuc           Eof.setLocation(Tok.getLocation());
164*f4a2713aSLionel Sambuc           LA->Toks.push_back(Eof);
165*f4a2713aSLionel Sambuc         } else {
166*f4a2713aSLionel Sambuc           ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
167*f4a2713aSLionel Sambuc                                 0, SourceLocation(), AttributeList::AS_GNU);
168*f4a2713aSLionel Sambuc         }
169*f4a2713aSLionel Sambuc       } else {
170*f4a2713aSLionel Sambuc         attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
171*f4a2713aSLionel Sambuc                      AttributeList::AS_GNU);
172*f4a2713aSLionel Sambuc       }
173*f4a2713aSLionel Sambuc     }
174*f4a2713aSLionel Sambuc     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
175*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
176*f4a2713aSLionel Sambuc     SourceLocation Loc = Tok.getLocation();
177*f4a2713aSLionel Sambuc     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
178*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
179*f4a2713aSLionel Sambuc     if (endLoc)
180*f4a2713aSLionel Sambuc       *endLoc = Loc;
181*f4a2713aSLionel Sambuc   }
182*f4a2713aSLionel Sambuc }
183*f4a2713aSLionel Sambuc 
184*f4a2713aSLionel Sambuc /// \brief Normalizes an attribute name by dropping prefixed and suffixed __.
185*f4a2713aSLionel Sambuc static StringRef normalizeAttrName(StringRef Name) {
186*f4a2713aSLionel Sambuc   if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
187*f4a2713aSLionel Sambuc     Name = Name.drop_front(2).drop_back(2);
188*f4a2713aSLionel Sambuc   return Name;
189*f4a2713aSLionel Sambuc }
190*f4a2713aSLionel Sambuc 
191*f4a2713aSLionel Sambuc /// \brief Determine whether the given attribute has an identifier argument.
192*f4a2713aSLionel Sambuc static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
193*f4a2713aSLionel Sambuc   return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
194*f4a2713aSLionel Sambuc #include "clang/Parse/AttrIdentifierArg.inc"
195*f4a2713aSLionel Sambuc            .Default(false);
196*f4a2713aSLionel Sambuc }
197*f4a2713aSLionel Sambuc 
198*f4a2713aSLionel Sambuc /// \brief Determine whether the given attribute parses a type argument.
199*f4a2713aSLionel Sambuc static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
200*f4a2713aSLionel Sambuc   return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
201*f4a2713aSLionel Sambuc #include "clang/Parse/AttrTypeArg.inc"
202*f4a2713aSLionel Sambuc            .Default(false);
203*f4a2713aSLionel Sambuc }
204*f4a2713aSLionel Sambuc 
205*f4a2713aSLionel Sambuc IdentifierLoc *Parser::ParseIdentifierLoc() {
206*f4a2713aSLionel Sambuc   assert(Tok.is(tok::identifier) && "expected an identifier");
207*f4a2713aSLionel Sambuc   IdentifierLoc *IL = IdentifierLoc::create(Actions.Context,
208*f4a2713aSLionel Sambuc                                             Tok.getLocation(),
209*f4a2713aSLionel Sambuc                                             Tok.getIdentifierInfo());
210*f4a2713aSLionel Sambuc   ConsumeToken();
211*f4a2713aSLionel Sambuc   return IL;
212*f4a2713aSLionel Sambuc }
213*f4a2713aSLionel Sambuc 
214*f4a2713aSLionel Sambuc void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
215*f4a2713aSLionel Sambuc                                        SourceLocation AttrNameLoc,
216*f4a2713aSLionel Sambuc                                        ParsedAttributes &Attrs,
217*f4a2713aSLionel Sambuc                                        SourceLocation *EndLoc) {
218*f4a2713aSLionel Sambuc   BalancedDelimiterTracker Parens(*this, tok::l_paren);
219*f4a2713aSLionel Sambuc   Parens.consumeOpen();
220*f4a2713aSLionel Sambuc 
221*f4a2713aSLionel Sambuc   TypeResult T;
222*f4a2713aSLionel Sambuc   if (Tok.isNot(tok::r_paren))
223*f4a2713aSLionel Sambuc     T = ParseTypeName();
224*f4a2713aSLionel Sambuc 
225*f4a2713aSLionel Sambuc   if (Parens.consumeClose())
226*f4a2713aSLionel Sambuc     return;
227*f4a2713aSLionel Sambuc 
228*f4a2713aSLionel Sambuc   if (T.isInvalid())
229*f4a2713aSLionel Sambuc     return;
230*f4a2713aSLionel Sambuc 
231*f4a2713aSLionel Sambuc   if (T.isUsable())
232*f4a2713aSLionel Sambuc     Attrs.addNewTypeAttr(&AttrName,
233*f4a2713aSLionel Sambuc                          SourceRange(AttrNameLoc, Parens.getCloseLocation()), 0,
234*f4a2713aSLionel Sambuc                          AttrNameLoc, T.get(), AttributeList::AS_GNU);
235*f4a2713aSLionel Sambuc   else
236*f4a2713aSLionel Sambuc     Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),
237*f4a2713aSLionel Sambuc                  0, AttrNameLoc, 0, 0, AttributeList::AS_GNU);
238*f4a2713aSLionel Sambuc }
239*f4a2713aSLionel Sambuc 
240*f4a2713aSLionel Sambuc /// Parse the arguments to a parameterized GNU attribute or
241*f4a2713aSLionel Sambuc /// a C++11 attribute in "gnu" namespace.
242*f4a2713aSLionel Sambuc void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
243*f4a2713aSLionel Sambuc                                    SourceLocation AttrNameLoc,
244*f4a2713aSLionel Sambuc                                    ParsedAttributes &Attrs,
245*f4a2713aSLionel Sambuc                                    SourceLocation *EndLoc,
246*f4a2713aSLionel Sambuc                                    IdentifierInfo *ScopeName,
247*f4a2713aSLionel Sambuc                                    SourceLocation ScopeLoc,
248*f4a2713aSLionel Sambuc                                    AttributeList::Syntax Syntax) {
249*f4a2713aSLionel Sambuc 
250*f4a2713aSLionel Sambuc   assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
251*f4a2713aSLionel Sambuc 
252*f4a2713aSLionel Sambuc   AttributeList::Kind AttrKind =
253*f4a2713aSLionel Sambuc       AttributeList::getKind(AttrName, ScopeName, Syntax);
254*f4a2713aSLionel Sambuc 
255*f4a2713aSLionel Sambuc   // Availability attributes have their own grammar.
256*f4a2713aSLionel Sambuc   // FIXME: All these cases fail to pass in the syntax and scope, and might be
257*f4a2713aSLionel Sambuc   // written as C++11 gnu:: attributes.
258*f4a2713aSLionel Sambuc   if (AttrKind == AttributeList::AT_Availability) {
259*f4a2713aSLionel Sambuc     ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
260*f4a2713aSLionel Sambuc     return;
261*f4a2713aSLionel Sambuc   }
262*f4a2713aSLionel Sambuc   // Thread safety attributes are parsed in an unevaluated context.
263*f4a2713aSLionel Sambuc   // FIXME: Share the bulk of the parsing code here and just pull out
264*f4a2713aSLionel Sambuc   // the unevaluated context.
265*f4a2713aSLionel Sambuc   if (IsThreadSafetyAttribute(AttrName->getName())) {
266*f4a2713aSLionel Sambuc     ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
267*f4a2713aSLionel Sambuc     return;
268*f4a2713aSLionel Sambuc   }
269*f4a2713aSLionel Sambuc   // Type safety attributes have their own grammar.
270*f4a2713aSLionel Sambuc   if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
271*f4a2713aSLionel Sambuc     ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
272*f4a2713aSLionel Sambuc     return;
273*f4a2713aSLionel Sambuc   }
274*f4a2713aSLionel Sambuc   // Some attributes expect solely a type parameter.
275*f4a2713aSLionel Sambuc   if (attributeIsTypeArgAttr(*AttrName)) {
276*f4a2713aSLionel Sambuc     ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc);
277*f4a2713aSLionel Sambuc     return;
278*f4a2713aSLionel Sambuc   }
279*f4a2713aSLionel Sambuc 
280*f4a2713aSLionel Sambuc   // Ignore the left paren location for now.
281*f4a2713aSLionel Sambuc   ConsumeParen();
282*f4a2713aSLionel Sambuc 
283*f4a2713aSLionel Sambuc   ArgsVector ArgExprs;
284*f4a2713aSLionel Sambuc 
285*f4a2713aSLionel Sambuc   if (Tok.is(tok::identifier)) {
286*f4a2713aSLionel Sambuc     // If this attribute wants an 'identifier' argument, make it so.
287*f4a2713aSLionel Sambuc     bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName);
288*f4a2713aSLionel Sambuc 
289*f4a2713aSLionel Sambuc     // If we don't know how to parse this attribute, but this is the only
290*f4a2713aSLionel Sambuc     // token in this argument, assume it's meant to be an identifier.
291*f4a2713aSLionel Sambuc     if (AttrKind == AttributeList::UnknownAttribute) {
292*f4a2713aSLionel Sambuc       const Token &Next = NextToken();
293*f4a2713aSLionel Sambuc       IsIdentifierArg = Next.is(tok::r_paren) || Next.is(tok::comma);
294*f4a2713aSLionel Sambuc     }
295*f4a2713aSLionel Sambuc 
296*f4a2713aSLionel Sambuc     if (IsIdentifierArg)
297*f4a2713aSLionel Sambuc       ArgExprs.push_back(ParseIdentifierLoc());
298*f4a2713aSLionel Sambuc   }
299*f4a2713aSLionel Sambuc 
300*f4a2713aSLionel Sambuc   if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
301*f4a2713aSLionel Sambuc     // Eat the comma.
302*f4a2713aSLionel Sambuc     if (!ArgExprs.empty())
303*f4a2713aSLionel Sambuc       ConsumeToken();
304*f4a2713aSLionel Sambuc 
305*f4a2713aSLionel Sambuc     // Parse the non-empty comma-separated list of expressions.
306*f4a2713aSLionel Sambuc     while (1) {
307*f4a2713aSLionel Sambuc       ExprResult ArgExpr(ParseAssignmentExpression());
308*f4a2713aSLionel Sambuc       if (ArgExpr.isInvalid()) {
309*f4a2713aSLionel Sambuc         SkipUntil(tok::r_paren, StopAtSemi);
310*f4a2713aSLionel Sambuc         return;
311*f4a2713aSLionel Sambuc       }
312*f4a2713aSLionel Sambuc       ArgExprs.push_back(ArgExpr.release());
313*f4a2713aSLionel Sambuc       if (Tok.isNot(tok::comma))
314*f4a2713aSLionel Sambuc         break;
315*f4a2713aSLionel Sambuc       ConsumeToken(); // Eat the comma, move to the next argument
316*f4a2713aSLionel Sambuc     }
317*f4a2713aSLionel Sambuc   }
318*f4a2713aSLionel Sambuc 
319*f4a2713aSLionel Sambuc   SourceLocation RParen = Tok.getLocation();
320*f4a2713aSLionel Sambuc   if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
321*f4a2713aSLionel Sambuc     SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
322*f4a2713aSLionel Sambuc     Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
323*f4a2713aSLionel Sambuc                  ArgExprs.data(), ArgExprs.size(), Syntax);
324*f4a2713aSLionel Sambuc   }
325*f4a2713aSLionel Sambuc }
326*f4a2713aSLionel Sambuc 
327*f4a2713aSLionel Sambuc /// \brief Parses a single argument for a declspec, including the
328*f4a2713aSLionel Sambuc /// surrounding parens.
329*f4a2713aSLionel Sambuc void Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
330*f4a2713aSLionel Sambuc                                                  SourceLocation AttrNameLoc,
331*f4a2713aSLionel Sambuc                                                  ParsedAttributes &Attrs)
332*f4a2713aSLionel Sambuc {
333*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
334*f4a2713aSLionel Sambuc   if (T.expectAndConsume(diag::err_expected_lparen_after,
335*f4a2713aSLionel Sambuc                          AttrName->getNameStart(), tok::r_paren))
336*f4a2713aSLionel Sambuc     return;
337*f4a2713aSLionel Sambuc 
338*f4a2713aSLionel Sambuc   ExprResult ArgExpr(ParseConstantExpression());
339*f4a2713aSLionel Sambuc   if (ArgExpr.isInvalid()) {
340*f4a2713aSLionel Sambuc     T.skipToEnd();
341*f4a2713aSLionel Sambuc     return;
342*f4a2713aSLionel Sambuc   }
343*f4a2713aSLionel Sambuc   ArgsUnion ExprList = ArgExpr.take();
344*f4a2713aSLionel Sambuc   Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, &ExprList, 1,
345*f4a2713aSLionel Sambuc                AttributeList::AS_Declspec);
346*f4a2713aSLionel Sambuc 
347*f4a2713aSLionel Sambuc   T.consumeClose();
348*f4a2713aSLionel Sambuc }
349*f4a2713aSLionel Sambuc 
350*f4a2713aSLionel Sambuc /// \brief Determines whether a declspec is a "simple" one requiring no
351*f4a2713aSLionel Sambuc /// arguments.
352*f4a2713aSLionel Sambuc bool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) {
353*f4a2713aSLionel Sambuc   return llvm::StringSwitch<bool>(Ident->getName())
354*f4a2713aSLionel Sambuc     .Case("dllimport", true)
355*f4a2713aSLionel Sambuc     .Case("dllexport", true)
356*f4a2713aSLionel Sambuc     .Case("noreturn", true)
357*f4a2713aSLionel Sambuc     .Case("nothrow", true)
358*f4a2713aSLionel Sambuc     .Case("noinline", true)
359*f4a2713aSLionel Sambuc     .Case("naked", true)
360*f4a2713aSLionel Sambuc     .Case("appdomain", true)
361*f4a2713aSLionel Sambuc     .Case("process", true)
362*f4a2713aSLionel Sambuc     .Case("jitintrinsic", true)
363*f4a2713aSLionel Sambuc     .Case("noalias", true)
364*f4a2713aSLionel Sambuc     .Case("restrict", true)
365*f4a2713aSLionel Sambuc     .Case("novtable", true)
366*f4a2713aSLionel Sambuc     .Case("selectany", true)
367*f4a2713aSLionel Sambuc     .Case("thread", true)
368*f4a2713aSLionel Sambuc     .Case("safebuffers", true )
369*f4a2713aSLionel Sambuc     .Default(false);
370*f4a2713aSLionel Sambuc }
371*f4a2713aSLionel Sambuc 
372*f4a2713aSLionel Sambuc /// \brief Attempts to parse a declspec which is not simple (one that takes
373*f4a2713aSLionel Sambuc /// parameters).  Will return false if we properly handled the declspec, or
374*f4a2713aSLionel Sambuc /// true if it is an unknown declspec.
375*f4a2713aSLionel Sambuc void Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
376*f4a2713aSLionel Sambuc                                            SourceLocation Loc,
377*f4a2713aSLionel Sambuc                                            ParsedAttributes &Attrs) {
378*f4a2713aSLionel Sambuc   // Try to handle the easy case first -- these declspecs all take a single
379*f4a2713aSLionel Sambuc   // parameter as their argument.
380*f4a2713aSLionel Sambuc   if (llvm::StringSwitch<bool>(Ident->getName())
381*f4a2713aSLionel Sambuc       .Case("uuid", true)
382*f4a2713aSLionel Sambuc       .Case("align", true)
383*f4a2713aSLionel Sambuc       .Case("allocate", true)
384*f4a2713aSLionel Sambuc       .Default(false)) {
385*f4a2713aSLionel Sambuc     ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
386*f4a2713aSLionel Sambuc   } else if (Ident->getName() == "deprecated") {
387*f4a2713aSLionel Sambuc     // The deprecated declspec has an optional single argument, so we will
388*f4a2713aSLionel Sambuc     // check for a l-paren to decide whether we should parse an argument or
389*f4a2713aSLionel Sambuc     // not.
390*f4a2713aSLionel Sambuc     if (Tok.getKind() == tok::l_paren)
391*f4a2713aSLionel Sambuc       ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
392*f4a2713aSLionel Sambuc     else
393*f4a2713aSLionel Sambuc       Attrs.addNew(Ident, Loc, 0, Loc, 0, 0, AttributeList::AS_Declspec);
394*f4a2713aSLionel Sambuc   } else if (Ident->getName() == "property") {
395*f4a2713aSLionel Sambuc     // The property declspec is more complex in that it can take one or two
396*f4a2713aSLionel Sambuc     // assignment expressions as a parameter, but the lhs of the assignment
397*f4a2713aSLionel Sambuc     // must be named get or put.
398*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::l_paren)) {
399*f4a2713aSLionel Sambuc       Diag(Tok.getLocation(), diag::err_expected_lparen_after)
400*f4a2713aSLionel Sambuc         << Ident->getNameStart();
401*f4a2713aSLionel Sambuc       return;
402*f4a2713aSLionel Sambuc     }
403*f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_paren);
404*f4a2713aSLionel Sambuc     T.expectAndConsume(diag::err_expected_lparen_after,
405*f4a2713aSLionel Sambuc                        Ident->getNameStart(), tok::r_paren);
406*f4a2713aSLionel Sambuc 
407*f4a2713aSLionel Sambuc     enum AccessorKind {
408*f4a2713aSLionel Sambuc       AK_Invalid = -1,
409*f4a2713aSLionel Sambuc       AK_Put = 0, AK_Get = 1 // indices into AccessorNames
410*f4a2713aSLionel Sambuc     };
411*f4a2713aSLionel Sambuc     IdentifierInfo *AccessorNames[] = { 0, 0 };
412*f4a2713aSLionel Sambuc     bool HasInvalidAccessor = false;
413*f4a2713aSLionel Sambuc 
414*f4a2713aSLionel Sambuc     // Parse the accessor specifications.
415*f4a2713aSLionel Sambuc     while (true) {
416*f4a2713aSLionel Sambuc       // Stop if this doesn't look like an accessor spec.
417*f4a2713aSLionel Sambuc       if (!Tok.is(tok::identifier)) {
418*f4a2713aSLionel Sambuc         // If the user wrote a completely empty list, use a special diagnostic.
419*f4a2713aSLionel Sambuc         if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
420*f4a2713aSLionel Sambuc             AccessorNames[AK_Put] == 0 && AccessorNames[AK_Get] == 0) {
421*f4a2713aSLionel Sambuc           Diag(Loc, diag::err_ms_property_no_getter_or_putter);
422*f4a2713aSLionel Sambuc           break;
423*f4a2713aSLionel Sambuc         }
424*f4a2713aSLionel Sambuc 
425*f4a2713aSLionel Sambuc         Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
426*f4a2713aSLionel Sambuc         break;
427*f4a2713aSLionel Sambuc       }
428*f4a2713aSLionel Sambuc 
429*f4a2713aSLionel Sambuc       AccessorKind Kind;
430*f4a2713aSLionel Sambuc       SourceLocation KindLoc = Tok.getLocation();
431*f4a2713aSLionel Sambuc       StringRef KindStr = Tok.getIdentifierInfo()->getName();
432*f4a2713aSLionel Sambuc       if (KindStr == "get") {
433*f4a2713aSLionel Sambuc         Kind = AK_Get;
434*f4a2713aSLionel Sambuc       } else if (KindStr == "put") {
435*f4a2713aSLionel Sambuc         Kind = AK_Put;
436*f4a2713aSLionel Sambuc 
437*f4a2713aSLionel Sambuc       // Recover from the common mistake of using 'set' instead of 'put'.
438*f4a2713aSLionel Sambuc       } else if (KindStr == "set") {
439*f4a2713aSLionel Sambuc         Diag(KindLoc, diag::err_ms_property_has_set_accessor)
440*f4a2713aSLionel Sambuc           << FixItHint::CreateReplacement(KindLoc, "put");
441*f4a2713aSLionel Sambuc         Kind = AK_Put;
442*f4a2713aSLionel Sambuc 
443*f4a2713aSLionel Sambuc       // Handle the mistake of forgetting the accessor kind by skipping
444*f4a2713aSLionel Sambuc       // this accessor.
445*f4a2713aSLionel Sambuc       } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) {
446*f4a2713aSLionel Sambuc         Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
447*f4a2713aSLionel Sambuc         ConsumeToken();
448*f4a2713aSLionel Sambuc         HasInvalidAccessor = true;
449*f4a2713aSLionel Sambuc         goto next_property_accessor;
450*f4a2713aSLionel Sambuc 
451*f4a2713aSLionel Sambuc       // Otherwise, complain about the unknown accessor kind.
452*f4a2713aSLionel Sambuc       } else {
453*f4a2713aSLionel Sambuc         Diag(KindLoc, diag::err_ms_property_unknown_accessor);
454*f4a2713aSLionel Sambuc         HasInvalidAccessor = true;
455*f4a2713aSLionel Sambuc         Kind = AK_Invalid;
456*f4a2713aSLionel Sambuc 
457*f4a2713aSLionel Sambuc         // Try to keep parsing unless it doesn't look like an accessor spec.
458*f4a2713aSLionel Sambuc         if (!NextToken().is(tok::equal)) break;
459*f4a2713aSLionel Sambuc       }
460*f4a2713aSLionel Sambuc 
461*f4a2713aSLionel Sambuc       // Consume the identifier.
462*f4a2713aSLionel Sambuc       ConsumeToken();
463*f4a2713aSLionel Sambuc 
464*f4a2713aSLionel Sambuc       // Consume the '='.
465*f4a2713aSLionel Sambuc       if (Tok.is(tok::equal)) {
466*f4a2713aSLionel Sambuc         ConsumeToken();
467*f4a2713aSLionel Sambuc       } else {
468*f4a2713aSLionel Sambuc         Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
469*f4a2713aSLionel Sambuc           << KindStr;
470*f4a2713aSLionel Sambuc         break;
471*f4a2713aSLionel Sambuc       }
472*f4a2713aSLionel Sambuc 
473*f4a2713aSLionel Sambuc       // Expect the method name.
474*f4a2713aSLionel Sambuc       if (!Tok.is(tok::identifier)) {
475*f4a2713aSLionel Sambuc         Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
476*f4a2713aSLionel Sambuc         break;
477*f4a2713aSLionel Sambuc       }
478*f4a2713aSLionel Sambuc 
479*f4a2713aSLionel Sambuc       if (Kind == AK_Invalid) {
480*f4a2713aSLionel Sambuc         // Just drop invalid accessors.
481*f4a2713aSLionel Sambuc       } else if (AccessorNames[Kind] != NULL) {
482*f4a2713aSLionel Sambuc         // Complain about the repeated accessor, ignore it, and keep parsing.
483*f4a2713aSLionel Sambuc         Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
484*f4a2713aSLionel Sambuc       } else {
485*f4a2713aSLionel Sambuc         AccessorNames[Kind] = Tok.getIdentifierInfo();
486*f4a2713aSLionel Sambuc       }
487*f4a2713aSLionel Sambuc       ConsumeToken();
488*f4a2713aSLionel Sambuc 
489*f4a2713aSLionel Sambuc     next_property_accessor:
490*f4a2713aSLionel Sambuc       // Keep processing accessors until we run out.
491*f4a2713aSLionel Sambuc       if (Tok.is(tok::comma)) {
492*f4a2713aSLionel Sambuc         ConsumeAnyToken();
493*f4a2713aSLionel Sambuc         continue;
494*f4a2713aSLionel Sambuc 
495*f4a2713aSLionel Sambuc       // If we run into the ')', stop without consuming it.
496*f4a2713aSLionel Sambuc       } else if (Tok.is(tok::r_paren)) {
497*f4a2713aSLionel Sambuc         break;
498*f4a2713aSLionel Sambuc       } else {
499*f4a2713aSLionel Sambuc         Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
500*f4a2713aSLionel Sambuc         break;
501*f4a2713aSLionel Sambuc       }
502*f4a2713aSLionel Sambuc     }
503*f4a2713aSLionel Sambuc 
504*f4a2713aSLionel Sambuc     // Only add the property attribute if it was well-formed.
505*f4a2713aSLionel Sambuc     if (!HasInvalidAccessor) {
506*f4a2713aSLionel Sambuc       Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(),
507*f4a2713aSLionel Sambuc                                AccessorNames[AK_Get], AccessorNames[AK_Put],
508*f4a2713aSLionel Sambuc                                AttributeList::AS_Declspec);
509*f4a2713aSLionel Sambuc     }
510*f4a2713aSLionel Sambuc     T.skipToEnd();
511*f4a2713aSLionel Sambuc   } else {
512*f4a2713aSLionel Sambuc     // We don't recognize this as a valid declspec, but instead of creating the
513*f4a2713aSLionel Sambuc     // attribute and allowing sema to warn about it, we will warn here instead.
514*f4a2713aSLionel Sambuc     // This is because some attributes have multiple spellings, but we need to
515*f4a2713aSLionel Sambuc     // disallow that for declspecs (such as align vs aligned).  If we made the
516*f4a2713aSLionel Sambuc     // attribute, we'd have to split the valid declspec spelling logic into
517*f4a2713aSLionel Sambuc     // both locations.
518*f4a2713aSLionel Sambuc     Diag(Loc, diag::warn_ms_declspec_unknown) << Ident;
519*f4a2713aSLionel Sambuc 
520*f4a2713aSLionel Sambuc     // If there's an open paren, we should eat the open and close parens under
521*f4a2713aSLionel Sambuc     // the assumption that this unknown declspec has parameters.
522*f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_paren);
523*f4a2713aSLionel Sambuc     if (!T.consumeOpen())
524*f4a2713aSLionel Sambuc       T.skipToEnd();
525*f4a2713aSLionel Sambuc   }
526*f4a2713aSLionel Sambuc }
527*f4a2713aSLionel Sambuc 
528*f4a2713aSLionel Sambuc /// [MS] decl-specifier:
529*f4a2713aSLionel Sambuc ///             __declspec ( extended-decl-modifier-seq )
530*f4a2713aSLionel Sambuc ///
531*f4a2713aSLionel Sambuc /// [MS] extended-decl-modifier-seq:
532*f4a2713aSLionel Sambuc ///             extended-decl-modifier[opt]
533*f4a2713aSLionel Sambuc ///             extended-decl-modifier extended-decl-modifier-seq
534*f4a2713aSLionel Sambuc void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &Attrs) {
535*f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
536*f4a2713aSLionel Sambuc 
537*f4a2713aSLionel Sambuc   ConsumeToken();
538*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
539*f4a2713aSLionel Sambuc   if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
540*f4a2713aSLionel Sambuc                          tok::r_paren))
541*f4a2713aSLionel Sambuc     return;
542*f4a2713aSLionel Sambuc 
543*f4a2713aSLionel Sambuc   // An empty declspec is perfectly legal and should not warn.  Additionally,
544*f4a2713aSLionel Sambuc   // you can specify multiple attributes per declspec.
545*f4a2713aSLionel Sambuc   while (Tok.getKind() != tok::r_paren) {
546*f4a2713aSLionel Sambuc     // We expect either a well-known identifier or a generic string.  Anything
547*f4a2713aSLionel Sambuc     // else is a malformed declspec.
548*f4a2713aSLionel Sambuc     bool IsString = Tok.getKind() == tok::string_literal ? true : false;
549*f4a2713aSLionel Sambuc     if (!IsString && Tok.getKind() != tok::identifier &&
550*f4a2713aSLionel Sambuc         Tok.getKind() != tok::kw_restrict) {
551*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_ms_declspec_type);
552*f4a2713aSLionel Sambuc       T.skipToEnd();
553*f4a2713aSLionel Sambuc       return;
554*f4a2713aSLionel Sambuc     }
555*f4a2713aSLionel Sambuc 
556*f4a2713aSLionel Sambuc     IdentifierInfo *AttrName;
557*f4a2713aSLionel Sambuc     SourceLocation AttrNameLoc;
558*f4a2713aSLionel Sambuc     if (IsString) {
559*f4a2713aSLionel Sambuc       SmallString<8> StrBuffer;
560*f4a2713aSLionel Sambuc       bool Invalid = false;
561*f4a2713aSLionel Sambuc       StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
562*f4a2713aSLionel Sambuc       if (Invalid) {
563*f4a2713aSLionel Sambuc         T.skipToEnd();
564*f4a2713aSLionel Sambuc         return;
565*f4a2713aSLionel Sambuc       }
566*f4a2713aSLionel Sambuc       AttrName = PP.getIdentifierInfo(Str);
567*f4a2713aSLionel Sambuc       AttrNameLoc = ConsumeStringToken();
568*f4a2713aSLionel Sambuc     } else {
569*f4a2713aSLionel Sambuc       AttrName = Tok.getIdentifierInfo();
570*f4a2713aSLionel Sambuc       AttrNameLoc = ConsumeToken();
571*f4a2713aSLionel Sambuc     }
572*f4a2713aSLionel Sambuc 
573*f4a2713aSLionel Sambuc     if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
574*f4a2713aSLionel Sambuc       // If we have a generic string, we will allow it because there is no
575*f4a2713aSLionel Sambuc       // documented list of allowable string declspecs, but we know they exist
576*f4a2713aSLionel Sambuc       // (for instance, SAL declspecs in older versions of MSVC).
577*f4a2713aSLionel Sambuc       //
578*f4a2713aSLionel Sambuc       // Alternatively, if the identifier is a simple one, then it requires no
579*f4a2713aSLionel Sambuc       // arguments and can be turned into an attribute directly.
580*f4a2713aSLionel Sambuc       Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
581*f4a2713aSLionel Sambuc                    AttributeList::AS_Declspec);
582*f4a2713aSLionel Sambuc     else
583*f4a2713aSLionel Sambuc       ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
584*f4a2713aSLionel Sambuc   }
585*f4a2713aSLionel Sambuc   T.consumeClose();
586*f4a2713aSLionel Sambuc }
587*f4a2713aSLionel Sambuc 
588*f4a2713aSLionel Sambuc void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
589*f4a2713aSLionel Sambuc   // Treat these like attributes
590*f4a2713aSLionel Sambuc   while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
591*f4a2713aSLionel Sambuc          Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___cdecl)   ||
592*f4a2713aSLionel Sambuc          Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64) ||
593*f4a2713aSLionel Sambuc          Tok.is(tok::kw___ptr32) || Tok.is(tok::kw___unaligned) ||
594*f4a2713aSLionel Sambuc          Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) {
595*f4a2713aSLionel Sambuc     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
596*f4a2713aSLionel Sambuc     SourceLocation AttrNameLoc = ConsumeToken();
597*f4a2713aSLionel Sambuc     attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
598*f4a2713aSLionel Sambuc                  AttributeList::AS_Keyword);
599*f4a2713aSLionel Sambuc   }
600*f4a2713aSLionel Sambuc }
601*f4a2713aSLionel Sambuc 
602*f4a2713aSLionel Sambuc void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
603*f4a2713aSLionel Sambuc   // Treat these like attributes
604*f4a2713aSLionel Sambuc   while (Tok.is(tok::kw___pascal)) {
605*f4a2713aSLionel Sambuc     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
606*f4a2713aSLionel Sambuc     SourceLocation AttrNameLoc = ConsumeToken();
607*f4a2713aSLionel Sambuc     attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
608*f4a2713aSLionel Sambuc                  AttributeList::AS_Keyword);
609*f4a2713aSLionel Sambuc   }
610*f4a2713aSLionel Sambuc }
611*f4a2713aSLionel Sambuc 
612*f4a2713aSLionel Sambuc void Parser::ParseOpenCLAttributes(ParsedAttributes &attrs) {
613*f4a2713aSLionel Sambuc   // Treat these like attributes
614*f4a2713aSLionel Sambuc   while (Tok.is(tok::kw___kernel)) {
615*f4a2713aSLionel Sambuc     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
616*f4a2713aSLionel Sambuc     SourceLocation AttrNameLoc = ConsumeToken();
617*f4a2713aSLionel Sambuc     attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
618*f4a2713aSLionel Sambuc                  AttributeList::AS_Keyword);
619*f4a2713aSLionel Sambuc   }
620*f4a2713aSLionel Sambuc }
621*f4a2713aSLionel Sambuc 
622*f4a2713aSLionel Sambuc void Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
623*f4a2713aSLionel Sambuc   // FIXME: The mapping from attribute spelling to semantics should be
624*f4a2713aSLionel Sambuc   //        performed in Sema, not here.
625*f4a2713aSLionel Sambuc   SourceLocation Loc = Tok.getLocation();
626*f4a2713aSLionel Sambuc   switch(Tok.getKind()) {
627*f4a2713aSLionel Sambuc     // OpenCL qualifiers:
628*f4a2713aSLionel Sambuc     case tok::kw___private:
629*f4a2713aSLionel Sambuc     case tok::kw_private:
630*f4a2713aSLionel Sambuc       DS.getAttributes().addNewInteger(
631*f4a2713aSLionel Sambuc           Actions.getASTContext(),
632*f4a2713aSLionel Sambuc           PP.getIdentifierInfo("address_space"), Loc, 0);
633*f4a2713aSLionel Sambuc       break;
634*f4a2713aSLionel Sambuc 
635*f4a2713aSLionel Sambuc     case tok::kw___global:
636*f4a2713aSLionel Sambuc       DS.getAttributes().addNewInteger(
637*f4a2713aSLionel Sambuc           Actions.getASTContext(),
638*f4a2713aSLionel Sambuc           PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
639*f4a2713aSLionel Sambuc       break;
640*f4a2713aSLionel Sambuc 
641*f4a2713aSLionel Sambuc     case tok::kw___local:
642*f4a2713aSLionel Sambuc       DS.getAttributes().addNewInteger(
643*f4a2713aSLionel Sambuc           Actions.getASTContext(),
644*f4a2713aSLionel Sambuc           PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
645*f4a2713aSLionel Sambuc       break;
646*f4a2713aSLionel Sambuc 
647*f4a2713aSLionel Sambuc     case tok::kw___constant:
648*f4a2713aSLionel Sambuc       DS.getAttributes().addNewInteger(
649*f4a2713aSLionel Sambuc           Actions.getASTContext(),
650*f4a2713aSLionel Sambuc           PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
651*f4a2713aSLionel Sambuc       break;
652*f4a2713aSLionel Sambuc 
653*f4a2713aSLionel Sambuc     case tok::kw___read_only:
654*f4a2713aSLionel Sambuc       DS.getAttributes().addNewInteger(
655*f4a2713aSLionel Sambuc           Actions.getASTContext(),
656*f4a2713aSLionel Sambuc           PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
657*f4a2713aSLionel Sambuc       break;
658*f4a2713aSLionel Sambuc 
659*f4a2713aSLionel Sambuc     case tok::kw___write_only:
660*f4a2713aSLionel Sambuc       DS.getAttributes().addNewInteger(
661*f4a2713aSLionel Sambuc           Actions.getASTContext(),
662*f4a2713aSLionel Sambuc           PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
663*f4a2713aSLionel Sambuc       break;
664*f4a2713aSLionel Sambuc 
665*f4a2713aSLionel Sambuc     case tok::kw___read_write:
666*f4a2713aSLionel Sambuc       DS.getAttributes().addNewInteger(
667*f4a2713aSLionel Sambuc           Actions.getASTContext(),
668*f4a2713aSLionel Sambuc           PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
669*f4a2713aSLionel Sambuc       break;
670*f4a2713aSLionel Sambuc     default: break;
671*f4a2713aSLionel Sambuc   }
672*f4a2713aSLionel Sambuc }
673*f4a2713aSLionel Sambuc 
674*f4a2713aSLionel Sambuc /// \brief Parse a version number.
675*f4a2713aSLionel Sambuc ///
676*f4a2713aSLionel Sambuc /// version:
677*f4a2713aSLionel Sambuc ///   simple-integer
678*f4a2713aSLionel Sambuc ///   simple-integer ',' simple-integer
679*f4a2713aSLionel Sambuc ///   simple-integer ',' simple-integer ',' simple-integer
680*f4a2713aSLionel Sambuc VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
681*f4a2713aSLionel Sambuc   Range = Tok.getLocation();
682*f4a2713aSLionel Sambuc 
683*f4a2713aSLionel Sambuc   if (!Tok.is(tok::numeric_constant)) {
684*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_version);
685*f4a2713aSLionel Sambuc     SkipUntil(tok::comma, tok::r_paren,
686*f4a2713aSLionel Sambuc               StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
687*f4a2713aSLionel Sambuc     return VersionTuple();
688*f4a2713aSLionel Sambuc   }
689*f4a2713aSLionel Sambuc 
690*f4a2713aSLionel Sambuc   // Parse the major (and possibly minor and subminor) versions, which
691*f4a2713aSLionel Sambuc   // are stored in the numeric constant. We utilize a quirk of the
692*f4a2713aSLionel Sambuc   // lexer, which is that it handles something like 1.2.3 as a single
693*f4a2713aSLionel Sambuc   // numeric constant, rather than two separate tokens.
694*f4a2713aSLionel Sambuc   SmallString<512> Buffer;
695*f4a2713aSLionel Sambuc   Buffer.resize(Tok.getLength()+1);
696*f4a2713aSLionel Sambuc   const char *ThisTokBegin = &Buffer[0];
697*f4a2713aSLionel Sambuc 
698*f4a2713aSLionel Sambuc   // Get the spelling of the token, which eliminates trigraphs, etc.
699*f4a2713aSLionel Sambuc   bool Invalid = false;
700*f4a2713aSLionel Sambuc   unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
701*f4a2713aSLionel Sambuc   if (Invalid)
702*f4a2713aSLionel Sambuc     return VersionTuple();
703*f4a2713aSLionel Sambuc 
704*f4a2713aSLionel Sambuc   // Parse the major version.
705*f4a2713aSLionel Sambuc   unsigned AfterMajor = 0;
706*f4a2713aSLionel Sambuc   unsigned Major = 0;
707*f4a2713aSLionel Sambuc   while (AfterMajor < ActualLength && isDigit(ThisTokBegin[AfterMajor])) {
708*f4a2713aSLionel Sambuc     Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';
709*f4a2713aSLionel Sambuc     ++AfterMajor;
710*f4a2713aSLionel Sambuc   }
711*f4a2713aSLionel Sambuc 
712*f4a2713aSLionel Sambuc   if (AfterMajor == 0) {
713*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_version);
714*f4a2713aSLionel Sambuc     SkipUntil(tok::comma, tok::r_paren,
715*f4a2713aSLionel Sambuc               StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
716*f4a2713aSLionel Sambuc     return VersionTuple();
717*f4a2713aSLionel Sambuc   }
718*f4a2713aSLionel Sambuc 
719*f4a2713aSLionel Sambuc   if (AfterMajor == ActualLength) {
720*f4a2713aSLionel Sambuc     ConsumeToken();
721*f4a2713aSLionel Sambuc 
722*f4a2713aSLionel Sambuc     // We only had a single version component.
723*f4a2713aSLionel Sambuc     if (Major == 0) {
724*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_zero_version);
725*f4a2713aSLionel Sambuc       return VersionTuple();
726*f4a2713aSLionel Sambuc     }
727*f4a2713aSLionel Sambuc 
728*f4a2713aSLionel Sambuc     return VersionTuple(Major);
729*f4a2713aSLionel Sambuc   }
730*f4a2713aSLionel Sambuc 
731*f4a2713aSLionel Sambuc   if (ThisTokBegin[AfterMajor] != '.' || (AfterMajor + 1 == ActualLength)) {
732*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_version);
733*f4a2713aSLionel Sambuc     SkipUntil(tok::comma, tok::r_paren,
734*f4a2713aSLionel Sambuc               StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
735*f4a2713aSLionel Sambuc     return VersionTuple();
736*f4a2713aSLionel Sambuc   }
737*f4a2713aSLionel Sambuc 
738*f4a2713aSLionel Sambuc   // Parse the minor version.
739*f4a2713aSLionel Sambuc   unsigned AfterMinor = AfterMajor + 1;
740*f4a2713aSLionel Sambuc   unsigned Minor = 0;
741*f4a2713aSLionel Sambuc   while (AfterMinor < ActualLength && isDigit(ThisTokBegin[AfterMinor])) {
742*f4a2713aSLionel Sambuc     Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';
743*f4a2713aSLionel Sambuc     ++AfterMinor;
744*f4a2713aSLionel Sambuc   }
745*f4a2713aSLionel Sambuc 
746*f4a2713aSLionel Sambuc   if (AfterMinor == ActualLength) {
747*f4a2713aSLionel Sambuc     ConsumeToken();
748*f4a2713aSLionel Sambuc 
749*f4a2713aSLionel Sambuc     // We had major.minor.
750*f4a2713aSLionel Sambuc     if (Major == 0 && Minor == 0) {
751*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_zero_version);
752*f4a2713aSLionel Sambuc       return VersionTuple();
753*f4a2713aSLionel Sambuc     }
754*f4a2713aSLionel Sambuc 
755*f4a2713aSLionel Sambuc     return VersionTuple(Major, Minor);
756*f4a2713aSLionel Sambuc   }
757*f4a2713aSLionel Sambuc 
758*f4a2713aSLionel Sambuc   // If what follows is not a '.', we have a problem.
759*f4a2713aSLionel Sambuc   if (ThisTokBegin[AfterMinor] != '.') {
760*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_version);
761*f4a2713aSLionel Sambuc     SkipUntil(tok::comma, tok::r_paren,
762*f4a2713aSLionel Sambuc               StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
763*f4a2713aSLionel Sambuc     return VersionTuple();
764*f4a2713aSLionel Sambuc   }
765*f4a2713aSLionel Sambuc 
766*f4a2713aSLionel Sambuc   // Parse the subminor version.
767*f4a2713aSLionel Sambuc   unsigned AfterSubminor = AfterMinor + 1;
768*f4a2713aSLionel Sambuc   unsigned Subminor = 0;
769*f4a2713aSLionel Sambuc   while (AfterSubminor < ActualLength && isDigit(ThisTokBegin[AfterSubminor])) {
770*f4a2713aSLionel Sambuc     Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';
771*f4a2713aSLionel Sambuc     ++AfterSubminor;
772*f4a2713aSLionel Sambuc   }
773*f4a2713aSLionel Sambuc 
774*f4a2713aSLionel Sambuc   if (AfterSubminor != ActualLength) {
775*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_version);
776*f4a2713aSLionel Sambuc     SkipUntil(tok::comma, tok::r_paren,
777*f4a2713aSLionel Sambuc               StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
778*f4a2713aSLionel Sambuc     return VersionTuple();
779*f4a2713aSLionel Sambuc   }
780*f4a2713aSLionel Sambuc   ConsumeToken();
781*f4a2713aSLionel Sambuc   return VersionTuple(Major, Minor, Subminor);
782*f4a2713aSLionel Sambuc }
783*f4a2713aSLionel Sambuc 
784*f4a2713aSLionel Sambuc /// \brief Parse the contents of the "availability" attribute.
785*f4a2713aSLionel Sambuc ///
786*f4a2713aSLionel Sambuc /// availability-attribute:
787*f4a2713aSLionel Sambuc ///   'availability' '(' platform ',' version-arg-list, opt-message')'
788*f4a2713aSLionel Sambuc ///
789*f4a2713aSLionel Sambuc /// platform:
790*f4a2713aSLionel Sambuc ///   identifier
791*f4a2713aSLionel Sambuc ///
792*f4a2713aSLionel Sambuc /// version-arg-list:
793*f4a2713aSLionel Sambuc ///   version-arg
794*f4a2713aSLionel Sambuc ///   version-arg ',' version-arg-list
795*f4a2713aSLionel Sambuc ///
796*f4a2713aSLionel Sambuc /// version-arg:
797*f4a2713aSLionel Sambuc ///   'introduced' '=' version
798*f4a2713aSLionel Sambuc ///   'deprecated' '=' version
799*f4a2713aSLionel Sambuc ///   'obsoleted' = version
800*f4a2713aSLionel Sambuc ///   'unavailable'
801*f4a2713aSLionel Sambuc /// opt-message:
802*f4a2713aSLionel Sambuc ///   'message' '=' <string>
803*f4a2713aSLionel Sambuc void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
804*f4a2713aSLionel Sambuc                                         SourceLocation AvailabilityLoc,
805*f4a2713aSLionel Sambuc                                         ParsedAttributes &attrs,
806*f4a2713aSLionel Sambuc                                         SourceLocation *endLoc) {
807*f4a2713aSLionel Sambuc   enum { Introduced, Deprecated, Obsoleted, Unknown };
808*f4a2713aSLionel Sambuc   AvailabilityChange Changes[Unknown];
809*f4a2713aSLionel Sambuc   ExprResult MessageExpr;
810*f4a2713aSLionel Sambuc 
811*f4a2713aSLionel Sambuc   // Opening '('.
812*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
813*f4a2713aSLionel Sambuc   if (T.consumeOpen()) {
814*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_lparen);
815*f4a2713aSLionel Sambuc     return;
816*f4a2713aSLionel Sambuc   }
817*f4a2713aSLionel Sambuc 
818*f4a2713aSLionel Sambuc   // Parse the platform name,
819*f4a2713aSLionel Sambuc   if (Tok.isNot(tok::identifier)) {
820*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_availability_expected_platform);
821*f4a2713aSLionel Sambuc     SkipUntil(tok::r_paren, StopAtSemi);
822*f4a2713aSLionel Sambuc     return;
823*f4a2713aSLionel Sambuc   }
824*f4a2713aSLionel Sambuc   IdentifierLoc *Platform = ParseIdentifierLoc();
825*f4a2713aSLionel Sambuc 
826*f4a2713aSLionel Sambuc   // Parse the ',' following the platform name.
827*f4a2713aSLionel Sambuc   if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
828*f4a2713aSLionel Sambuc     return;
829*f4a2713aSLionel Sambuc 
830*f4a2713aSLionel Sambuc   // If we haven't grabbed the pointers for the identifiers
831*f4a2713aSLionel Sambuc   // "introduced", "deprecated", and "obsoleted", do so now.
832*f4a2713aSLionel Sambuc   if (!Ident_introduced) {
833*f4a2713aSLionel Sambuc     Ident_introduced = PP.getIdentifierInfo("introduced");
834*f4a2713aSLionel Sambuc     Ident_deprecated = PP.getIdentifierInfo("deprecated");
835*f4a2713aSLionel Sambuc     Ident_obsoleted = PP.getIdentifierInfo("obsoleted");
836*f4a2713aSLionel Sambuc     Ident_unavailable = PP.getIdentifierInfo("unavailable");
837*f4a2713aSLionel Sambuc     Ident_message = PP.getIdentifierInfo("message");
838*f4a2713aSLionel Sambuc   }
839*f4a2713aSLionel Sambuc 
840*f4a2713aSLionel Sambuc   // Parse the set of introductions/deprecations/removals.
841*f4a2713aSLionel Sambuc   SourceLocation UnavailableLoc;
842*f4a2713aSLionel Sambuc   do {
843*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier)) {
844*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_availability_expected_change);
845*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
846*f4a2713aSLionel Sambuc       return;
847*f4a2713aSLionel Sambuc     }
848*f4a2713aSLionel Sambuc     IdentifierInfo *Keyword = Tok.getIdentifierInfo();
849*f4a2713aSLionel Sambuc     SourceLocation KeywordLoc = ConsumeToken();
850*f4a2713aSLionel Sambuc 
851*f4a2713aSLionel Sambuc     if (Keyword == Ident_unavailable) {
852*f4a2713aSLionel Sambuc       if (UnavailableLoc.isValid()) {
853*f4a2713aSLionel Sambuc         Diag(KeywordLoc, diag::err_availability_redundant)
854*f4a2713aSLionel Sambuc           << Keyword << SourceRange(UnavailableLoc);
855*f4a2713aSLionel Sambuc       }
856*f4a2713aSLionel Sambuc       UnavailableLoc = KeywordLoc;
857*f4a2713aSLionel Sambuc 
858*f4a2713aSLionel Sambuc       if (Tok.isNot(tok::comma))
859*f4a2713aSLionel Sambuc         break;
860*f4a2713aSLionel Sambuc 
861*f4a2713aSLionel Sambuc       ConsumeToken();
862*f4a2713aSLionel Sambuc       continue;
863*f4a2713aSLionel Sambuc     }
864*f4a2713aSLionel Sambuc 
865*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::equal)) {
866*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_expected_equal_after)
867*f4a2713aSLionel Sambuc         << Keyword;
868*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
869*f4a2713aSLionel Sambuc       return;
870*f4a2713aSLionel Sambuc     }
871*f4a2713aSLionel Sambuc     ConsumeToken();
872*f4a2713aSLionel Sambuc     if (Keyword == Ident_message) {
873*f4a2713aSLionel Sambuc       if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals.
874*f4a2713aSLionel Sambuc         Diag(Tok, diag::err_expected_string_literal)
875*f4a2713aSLionel Sambuc           << /*Source='availability attribute'*/2;
876*f4a2713aSLionel Sambuc         SkipUntil(tok::r_paren, StopAtSemi);
877*f4a2713aSLionel Sambuc         return;
878*f4a2713aSLionel Sambuc       }
879*f4a2713aSLionel Sambuc       MessageExpr = ParseStringLiteralExpression();
880*f4a2713aSLionel Sambuc       break;
881*f4a2713aSLionel Sambuc     }
882*f4a2713aSLionel Sambuc 
883*f4a2713aSLionel Sambuc     SourceRange VersionRange;
884*f4a2713aSLionel Sambuc     VersionTuple Version = ParseVersionTuple(VersionRange);
885*f4a2713aSLionel Sambuc 
886*f4a2713aSLionel Sambuc     if (Version.empty()) {
887*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
888*f4a2713aSLionel Sambuc       return;
889*f4a2713aSLionel Sambuc     }
890*f4a2713aSLionel Sambuc 
891*f4a2713aSLionel Sambuc     unsigned Index;
892*f4a2713aSLionel Sambuc     if (Keyword == Ident_introduced)
893*f4a2713aSLionel Sambuc       Index = Introduced;
894*f4a2713aSLionel Sambuc     else if (Keyword == Ident_deprecated)
895*f4a2713aSLionel Sambuc       Index = Deprecated;
896*f4a2713aSLionel Sambuc     else if (Keyword == Ident_obsoleted)
897*f4a2713aSLionel Sambuc       Index = Obsoleted;
898*f4a2713aSLionel Sambuc     else
899*f4a2713aSLionel Sambuc       Index = Unknown;
900*f4a2713aSLionel Sambuc 
901*f4a2713aSLionel Sambuc     if (Index < Unknown) {
902*f4a2713aSLionel Sambuc       if (!Changes[Index].KeywordLoc.isInvalid()) {
903*f4a2713aSLionel Sambuc         Diag(KeywordLoc, diag::err_availability_redundant)
904*f4a2713aSLionel Sambuc           << Keyword
905*f4a2713aSLionel Sambuc           << SourceRange(Changes[Index].KeywordLoc,
906*f4a2713aSLionel Sambuc                          Changes[Index].VersionRange.getEnd());
907*f4a2713aSLionel Sambuc       }
908*f4a2713aSLionel Sambuc 
909*f4a2713aSLionel Sambuc       Changes[Index].KeywordLoc = KeywordLoc;
910*f4a2713aSLionel Sambuc       Changes[Index].Version = Version;
911*f4a2713aSLionel Sambuc       Changes[Index].VersionRange = VersionRange;
912*f4a2713aSLionel Sambuc     } else {
913*f4a2713aSLionel Sambuc       Diag(KeywordLoc, diag::err_availability_unknown_change)
914*f4a2713aSLionel Sambuc         << Keyword << VersionRange;
915*f4a2713aSLionel Sambuc     }
916*f4a2713aSLionel Sambuc 
917*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::comma))
918*f4a2713aSLionel Sambuc       break;
919*f4a2713aSLionel Sambuc 
920*f4a2713aSLionel Sambuc     ConsumeToken();
921*f4a2713aSLionel Sambuc   } while (true);
922*f4a2713aSLionel Sambuc 
923*f4a2713aSLionel Sambuc   // Closing ')'.
924*f4a2713aSLionel Sambuc   if (T.consumeClose())
925*f4a2713aSLionel Sambuc     return;
926*f4a2713aSLionel Sambuc 
927*f4a2713aSLionel Sambuc   if (endLoc)
928*f4a2713aSLionel Sambuc     *endLoc = T.getCloseLocation();
929*f4a2713aSLionel Sambuc 
930*f4a2713aSLionel Sambuc   // The 'unavailable' availability cannot be combined with any other
931*f4a2713aSLionel Sambuc   // availability changes. Make sure that hasn't happened.
932*f4a2713aSLionel Sambuc   if (UnavailableLoc.isValid()) {
933*f4a2713aSLionel Sambuc     bool Complained = false;
934*f4a2713aSLionel Sambuc     for (unsigned Index = Introduced; Index != Unknown; ++Index) {
935*f4a2713aSLionel Sambuc       if (Changes[Index].KeywordLoc.isValid()) {
936*f4a2713aSLionel Sambuc         if (!Complained) {
937*f4a2713aSLionel Sambuc           Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
938*f4a2713aSLionel Sambuc             << SourceRange(Changes[Index].KeywordLoc,
939*f4a2713aSLionel Sambuc                            Changes[Index].VersionRange.getEnd());
940*f4a2713aSLionel Sambuc           Complained = true;
941*f4a2713aSLionel Sambuc         }
942*f4a2713aSLionel Sambuc 
943*f4a2713aSLionel Sambuc         // Clear out the availability.
944*f4a2713aSLionel Sambuc         Changes[Index] = AvailabilityChange();
945*f4a2713aSLionel Sambuc       }
946*f4a2713aSLionel Sambuc     }
947*f4a2713aSLionel Sambuc   }
948*f4a2713aSLionel Sambuc 
949*f4a2713aSLionel Sambuc   // Record this attribute
950*f4a2713aSLionel Sambuc   attrs.addNew(&Availability,
951*f4a2713aSLionel Sambuc                SourceRange(AvailabilityLoc, T.getCloseLocation()),
952*f4a2713aSLionel Sambuc                0, AvailabilityLoc,
953*f4a2713aSLionel Sambuc                Platform,
954*f4a2713aSLionel Sambuc                Changes[Introduced],
955*f4a2713aSLionel Sambuc                Changes[Deprecated],
956*f4a2713aSLionel Sambuc                Changes[Obsoleted],
957*f4a2713aSLionel Sambuc                UnavailableLoc, MessageExpr.take(),
958*f4a2713aSLionel Sambuc                AttributeList::AS_GNU);
959*f4a2713aSLionel Sambuc }
960*f4a2713aSLionel Sambuc 
961*f4a2713aSLionel Sambuc 
962*f4a2713aSLionel Sambuc // Late Parsed Attributes:
963*f4a2713aSLionel Sambuc // See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
964*f4a2713aSLionel Sambuc 
965*f4a2713aSLionel Sambuc void Parser::LateParsedDeclaration::ParseLexedAttributes() {}
966*f4a2713aSLionel Sambuc 
967*f4a2713aSLionel Sambuc void Parser::LateParsedClass::ParseLexedAttributes() {
968*f4a2713aSLionel Sambuc   Self->ParseLexedAttributes(*Class);
969*f4a2713aSLionel Sambuc }
970*f4a2713aSLionel Sambuc 
971*f4a2713aSLionel Sambuc void Parser::LateParsedAttribute::ParseLexedAttributes() {
972*f4a2713aSLionel Sambuc   Self->ParseLexedAttribute(*this, true, false);
973*f4a2713aSLionel Sambuc }
974*f4a2713aSLionel Sambuc 
975*f4a2713aSLionel Sambuc /// Wrapper class which calls ParseLexedAttribute, after setting up the
976*f4a2713aSLionel Sambuc /// scope appropriately.
977*f4a2713aSLionel Sambuc void Parser::ParseLexedAttributes(ParsingClass &Class) {
978*f4a2713aSLionel Sambuc   // Deal with templates
979*f4a2713aSLionel Sambuc   // FIXME: Test cases to make sure this does the right thing for templates.
980*f4a2713aSLionel Sambuc   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
981*f4a2713aSLionel Sambuc   ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
982*f4a2713aSLionel Sambuc                                 HasTemplateScope);
983*f4a2713aSLionel Sambuc   if (HasTemplateScope)
984*f4a2713aSLionel Sambuc     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
985*f4a2713aSLionel Sambuc 
986*f4a2713aSLionel Sambuc   // Set or update the scope flags.
987*f4a2713aSLionel Sambuc   bool AlreadyHasClassScope = Class.TopLevelClass;
988*f4a2713aSLionel Sambuc   unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
989*f4a2713aSLionel Sambuc   ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
990*f4a2713aSLionel Sambuc   ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
991*f4a2713aSLionel Sambuc 
992*f4a2713aSLionel Sambuc   // Enter the scope of nested classes
993*f4a2713aSLionel Sambuc   if (!AlreadyHasClassScope)
994*f4a2713aSLionel Sambuc     Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
995*f4a2713aSLionel Sambuc                                                 Class.TagOrTemplate);
996*f4a2713aSLionel Sambuc   if (!Class.LateParsedDeclarations.empty()) {
997*f4a2713aSLionel Sambuc     for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
998*f4a2713aSLionel Sambuc       Class.LateParsedDeclarations[i]->ParseLexedAttributes();
999*f4a2713aSLionel Sambuc     }
1000*f4a2713aSLionel Sambuc   }
1001*f4a2713aSLionel Sambuc 
1002*f4a2713aSLionel Sambuc   if (!AlreadyHasClassScope)
1003*f4a2713aSLionel Sambuc     Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
1004*f4a2713aSLionel Sambuc                                                  Class.TagOrTemplate);
1005*f4a2713aSLionel Sambuc }
1006*f4a2713aSLionel Sambuc 
1007*f4a2713aSLionel Sambuc 
1008*f4a2713aSLionel Sambuc /// \brief Parse all attributes in LAs, and attach them to Decl D.
1009*f4a2713aSLionel Sambuc void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
1010*f4a2713aSLionel Sambuc                                      bool EnterScope, bool OnDefinition) {
1011*f4a2713aSLionel Sambuc   assert(LAs.parseSoon() &&
1012*f4a2713aSLionel Sambuc          "Attribute list should be marked for immediate parsing.");
1013*f4a2713aSLionel Sambuc   for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
1014*f4a2713aSLionel Sambuc     if (D)
1015*f4a2713aSLionel Sambuc       LAs[i]->addDecl(D);
1016*f4a2713aSLionel Sambuc     ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
1017*f4a2713aSLionel Sambuc     delete LAs[i];
1018*f4a2713aSLionel Sambuc   }
1019*f4a2713aSLionel Sambuc   LAs.clear();
1020*f4a2713aSLionel Sambuc }
1021*f4a2713aSLionel Sambuc 
1022*f4a2713aSLionel Sambuc 
1023*f4a2713aSLionel Sambuc /// \brief Finish parsing an attribute for which parsing was delayed.
1024*f4a2713aSLionel Sambuc /// This will be called at the end of parsing a class declaration
1025*f4a2713aSLionel Sambuc /// for each LateParsedAttribute. We consume the saved tokens and
1026*f4a2713aSLionel Sambuc /// create an attribute with the arguments filled in. We add this
1027*f4a2713aSLionel Sambuc /// to the Attribute list for the decl.
1028*f4a2713aSLionel Sambuc void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
1029*f4a2713aSLionel Sambuc                                  bool EnterScope, bool OnDefinition) {
1030*f4a2713aSLionel Sambuc   // Save the current token position.
1031*f4a2713aSLionel Sambuc   SourceLocation OrigLoc = Tok.getLocation();
1032*f4a2713aSLionel Sambuc 
1033*f4a2713aSLionel Sambuc   // Append the current token at the end of the new token stream so that it
1034*f4a2713aSLionel Sambuc   // doesn't get lost.
1035*f4a2713aSLionel Sambuc   LA.Toks.push_back(Tok);
1036*f4a2713aSLionel Sambuc   PP.EnterTokenStream(LA.Toks.data(), LA.Toks.size(), true, false);
1037*f4a2713aSLionel Sambuc   // Consume the previously pushed token.
1038*f4a2713aSLionel Sambuc   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1039*f4a2713aSLionel Sambuc 
1040*f4a2713aSLionel Sambuc   if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
1041*f4a2713aSLionel Sambuc     // FIXME: Do not warn on C++11 attributes, once we start supporting
1042*f4a2713aSLionel Sambuc     // them here.
1043*f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_attribute_on_function_definition)
1044*f4a2713aSLionel Sambuc       << LA.AttrName.getName();
1045*f4a2713aSLionel Sambuc   }
1046*f4a2713aSLionel Sambuc 
1047*f4a2713aSLionel Sambuc   ParsedAttributes Attrs(AttrFactory);
1048*f4a2713aSLionel Sambuc   SourceLocation endLoc;
1049*f4a2713aSLionel Sambuc 
1050*f4a2713aSLionel Sambuc   if (LA.Decls.size() > 0) {
1051*f4a2713aSLionel Sambuc     Decl *D = LA.Decls[0];
1052*f4a2713aSLionel Sambuc     NamedDecl *ND  = dyn_cast<NamedDecl>(D);
1053*f4a2713aSLionel Sambuc     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
1054*f4a2713aSLionel Sambuc 
1055*f4a2713aSLionel Sambuc     // Allow 'this' within late-parsed attributes.
1056*f4a2713aSLionel Sambuc     Sema::CXXThisScopeRAII ThisScope(Actions, RD, /*TypeQuals=*/0,
1057*f4a2713aSLionel Sambuc                                      ND && ND->isCXXInstanceMember());
1058*f4a2713aSLionel Sambuc 
1059*f4a2713aSLionel Sambuc     if (LA.Decls.size() == 1) {
1060*f4a2713aSLionel Sambuc       // If the Decl is templatized, add template parameters to scope.
1061*f4a2713aSLionel Sambuc       bool HasTemplateScope = EnterScope && D->isTemplateDecl();
1062*f4a2713aSLionel Sambuc       ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
1063*f4a2713aSLionel Sambuc       if (HasTemplateScope)
1064*f4a2713aSLionel Sambuc         Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
1065*f4a2713aSLionel Sambuc 
1066*f4a2713aSLionel Sambuc       // If the Decl is on a function, add function parameters to the scope.
1067*f4a2713aSLionel Sambuc       bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
1068*f4a2713aSLionel Sambuc       ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope);
1069*f4a2713aSLionel Sambuc       if (HasFunScope)
1070*f4a2713aSLionel Sambuc         Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
1071*f4a2713aSLionel Sambuc 
1072*f4a2713aSLionel Sambuc       ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1073*f4a2713aSLionel Sambuc                             0, SourceLocation(), AttributeList::AS_GNU);
1074*f4a2713aSLionel Sambuc 
1075*f4a2713aSLionel Sambuc       if (HasFunScope) {
1076*f4a2713aSLionel Sambuc         Actions.ActOnExitFunctionContext();
1077*f4a2713aSLionel Sambuc         FnScope.Exit();  // Pop scope, and remove Decls from IdResolver
1078*f4a2713aSLionel Sambuc       }
1079*f4a2713aSLionel Sambuc       if (HasTemplateScope) {
1080*f4a2713aSLionel Sambuc         TempScope.Exit();
1081*f4a2713aSLionel Sambuc       }
1082*f4a2713aSLionel Sambuc     } else {
1083*f4a2713aSLionel Sambuc       // If there are multiple decls, then the decl cannot be within the
1084*f4a2713aSLionel Sambuc       // function scope.
1085*f4a2713aSLionel Sambuc       ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
1086*f4a2713aSLionel Sambuc                             0, SourceLocation(), AttributeList::AS_GNU);
1087*f4a2713aSLionel Sambuc     }
1088*f4a2713aSLionel Sambuc   } else {
1089*f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
1090*f4a2713aSLionel Sambuc   }
1091*f4a2713aSLionel Sambuc 
1092*f4a2713aSLionel Sambuc   for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
1093*f4a2713aSLionel Sambuc     Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
1094*f4a2713aSLionel Sambuc   }
1095*f4a2713aSLionel Sambuc 
1096*f4a2713aSLionel Sambuc   if (Tok.getLocation() != OrigLoc) {
1097*f4a2713aSLionel Sambuc     // Due to a parsing error, we either went over the cached tokens or
1098*f4a2713aSLionel Sambuc     // there are still cached tokens left, so we skip the leftover tokens.
1099*f4a2713aSLionel Sambuc     // Since this is an uncommon situation that should be avoided, use the
1100*f4a2713aSLionel Sambuc     // expensive isBeforeInTranslationUnit call.
1101*f4a2713aSLionel Sambuc     if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
1102*f4a2713aSLionel Sambuc                                                         OrigLoc))
1103*f4a2713aSLionel Sambuc     while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
1104*f4a2713aSLionel Sambuc       ConsumeAnyToken();
1105*f4a2713aSLionel Sambuc   }
1106*f4a2713aSLionel Sambuc }
1107*f4a2713aSLionel Sambuc 
1108*f4a2713aSLionel Sambuc /// \brief Wrapper around a case statement checking if AttrName is
1109*f4a2713aSLionel Sambuc /// one of the thread safety attributes
1110*f4a2713aSLionel Sambuc bool Parser::IsThreadSafetyAttribute(StringRef AttrName) {
1111*f4a2713aSLionel Sambuc   return llvm::StringSwitch<bool>(AttrName)
1112*f4a2713aSLionel Sambuc       .Case("guarded_by", true)
1113*f4a2713aSLionel Sambuc       .Case("guarded_var", true)
1114*f4a2713aSLionel Sambuc       .Case("pt_guarded_by", true)
1115*f4a2713aSLionel Sambuc       .Case("pt_guarded_var", true)
1116*f4a2713aSLionel Sambuc       .Case("lockable", true)
1117*f4a2713aSLionel Sambuc       .Case("scoped_lockable", true)
1118*f4a2713aSLionel Sambuc       .Case("no_thread_safety_analysis", true)
1119*f4a2713aSLionel Sambuc       .Case("acquired_after", true)
1120*f4a2713aSLionel Sambuc       .Case("acquired_before", true)
1121*f4a2713aSLionel Sambuc       .Case("exclusive_lock_function", true)
1122*f4a2713aSLionel Sambuc       .Case("shared_lock_function", true)
1123*f4a2713aSLionel Sambuc       .Case("exclusive_trylock_function", true)
1124*f4a2713aSLionel Sambuc       .Case("shared_trylock_function", true)
1125*f4a2713aSLionel Sambuc       .Case("unlock_function", true)
1126*f4a2713aSLionel Sambuc       .Case("lock_returned", true)
1127*f4a2713aSLionel Sambuc       .Case("locks_excluded", true)
1128*f4a2713aSLionel Sambuc       .Case("exclusive_locks_required", true)
1129*f4a2713aSLionel Sambuc       .Case("shared_locks_required", true)
1130*f4a2713aSLionel Sambuc       .Default(false);
1131*f4a2713aSLionel Sambuc }
1132*f4a2713aSLionel Sambuc 
1133*f4a2713aSLionel Sambuc /// \brief Parse the contents of thread safety attributes. These
1134*f4a2713aSLionel Sambuc /// should always be parsed as an expression list.
1135*f4a2713aSLionel Sambuc ///
1136*f4a2713aSLionel Sambuc /// We need to special case the parsing due to the fact that if the first token
1137*f4a2713aSLionel Sambuc /// of the first argument is an identifier, the main parse loop will store
1138*f4a2713aSLionel Sambuc /// that token as a "parameter" and the rest of
1139*f4a2713aSLionel Sambuc /// the arguments will be added to a list of "arguments". However,
1140*f4a2713aSLionel Sambuc /// subsequent tokens in the first argument are lost. We instead parse each
1141*f4a2713aSLionel Sambuc /// argument as an expression and add all arguments to the list of "arguments".
1142*f4a2713aSLionel Sambuc /// In future, we will take advantage of this special case to also
1143*f4a2713aSLionel Sambuc /// deal with some argument scoping issues here (for example, referring to a
1144*f4a2713aSLionel Sambuc /// function parameter in the attribute on that function).
1145*f4a2713aSLionel Sambuc void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
1146*f4a2713aSLionel Sambuc                                         SourceLocation AttrNameLoc,
1147*f4a2713aSLionel Sambuc                                         ParsedAttributes &Attrs,
1148*f4a2713aSLionel Sambuc                                         SourceLocation *EndLoc) {
1149*f4a2713aSLionel Sambuc   assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1150*f4a2713aSLionel Sambuc 
1151*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
1152*f4a2713aSLionel Sambuc   T.consumeOpen();
1153*f4a2713aSLionel Sambuc 
1154*f4a2713aSLionel Sambuc   ArgsVector ArgExprs;
1155*f4a2713aSLionel Sambuc   bool ArgExprsOk = true;
1156*f4a2713aSLionel Sambuc 
1157*f4a2713aSLionel Sambuc   // now parse the list of expressions
1158*f4a2713aSLionel Sambuc   while (Tok.isNot(tok::r_paren)) {
1159*f4a2713aSLionel Sambuc     EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
1160*f4a2713aSLionel Sambuc     ExprResult ArgExpr(ParseAssignmentExpression());
1161*f4a2713aSLionel Sambuc     if (ArgExpr.isInvalid()) {
1162*f4a2713aSLionel Sambuc       ArgExprsOk = false;
1163*f4a2713aSLionel Sambuc       T.consumeClose();
1164*f4a2713aSLionel Sambuc       break;
1165*f4a2713aSLionel Sambuc     } else {
1166*f4a2713aSLionel Sambuc       ArgExprs.push_back(ArgExpr.release());
1167*f4a2713aSLionel Sambuc     }
1168*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::comma))
1169*f4a2713aSLionel Sambuc       break;
1170*f4a2713aSLionel Sambuc     ConsumeToken(); // Eat the comma, move to the next argument
1171*f4a2713aSLionel Sambuc   }
1172*f4a2713aSLionel Sambuc   // Match the ')'.
1173*f4a2713aSLionel Sambuc   if (ArgExprsOk && !T.consumeClose()) {
1174*f4a2713aSLionel Sambuc     Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(),
1175*f4a2713aSLionel Sambuc                  ArgExprs.size(), AttributeList::AS_GNU);
1176*f4a2713aSLionel Sambuc   }
1177*f4a2713aSLionel Sambuc   if (EndLoc)
1178*f4a2713aSLionel Sambuc     *EndLoc = T.getCloseLocation();
1179*f4a2713aSLionel Sambuc }
1180*f4a2713aSLionel Sambuc 
1181*f4a2713aSLionel Sambuc void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
1182*f4a2713aSLionel Sambuc                                               SourceLocation AttrNameLoc,
1183*f4a2713aSLionel Sambuc                                               ParsedAttributes &Attrs,
1184*f4a2713aSLionel Sambuc                                               SourceLocation *EndLoc) {
1185*f4a2713aSLionel Sambuc   assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1186*f4a2713aSLionel Sambuc 
1187*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
1188*f4a2713aSLionel Sambuc   T.consumeOpen();
1189*f4a2713aSLionel Sambuc 
1190*f4a2713aSLionel Sambuc   if (Tok.isNot(tok::identifier)) {
1191*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_ident);
1192*f4a2713aSLionel Sambuc     T.skipToEnd();
1193*f4a2713aSLionel Sambuc     return;
1194*f4a2713aSLionel Sambuc   }
1195*f4a2713aSLionel Sambuc   IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1196*f4a2713aSLionel Sambuc 
1197*f4a2713aSLionel Sambuc   if (Tok.isNot(tok::comma)) {
1198*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_comma);
1199*f4a2713aSLionel Sambuc     T.skipToEnd();
1200*f4a2713aSLionel Sambuc     return;
1201*f4a2713aSLionel Sambuc   }
1202*f4a2713aSLionel Sambuc   ConsumeToken();
1203*f4a2713aSLionel Sambuc 
1204*f4a2713aSLionel Sambuc   SourceRange MatchingCTypeRange;
1205*f4a2713aSLionel Sambuc   TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);
1206*f4a2713aSLionel Sambuc   if (MatchingCType.isInvalid()) {
1207*f4a2713aSLionel Sambuc     T.skipToEnd();
1208*f4a2713aSLionel Sambuc     return;
1209*f4a2713aSLionel Sambuc   }
1210*f4a2713aSLionel Sambuc 
1211*f4a2713aSLionel Sambuc   bool LayoutCompatible = false;
1212*f4a2713aSLionel Sambuc   bool MustBeNull = false;
1213*f4a2713aSLionel Sambuc   while (Tok.is(tok::comma)) {
1214*f4a2713aSLionel Sambuc     ConsumeToken();
1215*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier)) {
1216*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_expected_ident);
1217*f4a2713aSLionel Sambuc       T.skipToEnd();
1218*f4a2713aSLionel Sambuc       return;
1219*f4a2713aSLionel Sambuc     }
1220*f4a2713aSLionel Sambuc     IdentifierInfo *Flag = Tok.getIdentifierInfo();
1221*f4a2713aSLionel Sambuc     if (Flag->isStr("layout_compatible"))
1222*f4a2713aSLionel Sambuc       LayoutCompatible = true;
1223*f4a2713aSLionel Sambuc     else if (Flag->isStr("must_be_null"))
1224*f4a2713aSLionel Sambuc       MustBeNull = true;
1225*f4a2713aSLionel Sambuc     else {
1226*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1227*f4a2713aSLionel Sambuc       T.skipToEnd();
1228*f4a2713aSLionel Sambuc       return;
1229*f4a2713aSLionel Sambuc     }
1230*f4a2713aSLionel Sambuc     ConsumeToken(); // consume flag
1231*f4a2713aSLionel Sambuc   }
1232*f4a2713aSLionel Sambuc 
1233*f4a2713aSLionel Sambuc   if (!T.consumeClose()) {
1234*f4a2713aSLionel Sambuc     Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
1235*f4a2713aSLionel Sambuc                                    ArgumentKind, MatchingCType.release(),
1236*f4a2713aSLionel Sambuc                                    LayoutCompatible, MustBeNull,
1237*f4a2713aSLionel Sambuc                                    AttributeList::AS_GNU);
1238*f4a2713aSLionel Sambuc   }
1239*f4a2713aSLionel Sambuc 
1240*f4a2713aSLionel Sambuc   if (EndLoc)
1241*f4a2713aSLionel Sambuc     *EndLoc = T.getCloseLocation();
1242*f4a2713aSLionel Sambuc }
1243*f4a2713aSLionel Sambuc 
1244*f4a2713aSLionel Sambuc /// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
1245*f4a2713aSLionel Sambuc /// of a C++11 attribute-specifier in a location where an attribute is not
1246*f4a2713aSLionel Sambuc /// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
1247*f4a2713aSLionel Sambuc /// situation.
1248*f4a2713aSLionel Sambuc ///
1249*f4a2713aSLionel Sambuc /// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
1250*f4a2713aSLionel Sambuc /// this doesn't appear to actually be an attribute-specifier, and the caller
1251*f4a2713aSLionel Sambuc /// should try to parse it.
1252*f4a2713aSLionel Sambuc bool Parser::DiagnoseProhibitedCXX11Attribute() {
1253*f4a2713aSLionel Sambuc   assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1254*f4a2713aSLionel Sambuc 
1255*f4a2713aSLionel Sambuc   switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1256*f4a2713aSLionel Sambuc   case CAK_NotAttributeSpecifier:
1257*f4a2713aSLionel Sambuc     // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1258*f4a2713aSLionel Sambuc     return false;
1259*f4a2713aSLionel Sambuc 
1260*f4a2713aSLionel Sambuc   case CAK_InvalidAttributeSpecifier:
1261*f4a2713aSLionel Sambuc     Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1262*f4a2713aSLionel Sambuc     return false;
1263*f4a2713aSLionel Sambuc 
1264*f4a2713aSLionel Sambuc   case CAK_AttributeSpecifier:
1265*f4a2713aSLionel Sambuc     // Parse and discard the attributes.
1266*f4a2713aSLionel Sambuc     SourceLocation BeginLoc = ConsumeBracket();
1267*f4a2713aSLionel Sambuc     ConsumeBracket();
1268*f4a2713aSLionel Sambuc     SkipUntil(tok::r_square);
1269*f4a2713aSLionel Sambuc     assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1270*f4a2713aSLionel Sambuc     SourceLocation EndLoc = ConsumeBracket();
1271*f4a2713aSLionel Sambuc     Diag(BeginLoc, diag::err_attributes_not_allowed)
1272*f4a2713aSLionel Sambuc       << SourceRange(BeginLoc, EndLoc);
1273*f4a2713aSLionel Sambuc     return true;
1274*f4a2713aSLionel Sambuc   }
1275*f4a2713aSLionel Sambuc   llvm_unreachable("All cases handled above.");
1276*f4a2713aSLionel Sambuc }
1277*f4a2713aSLionel Sambuc 
1278*f4a2713aSLionel Sambuc /// \brief We have found the opening square brackets of a C++11
1279*f4a2713aSLionel Sambuc /// attribute-specifier in a location where an attribute is not permitted, but
1280*f4a2713aSLionel Sambuc /// we know where the attributes ought to be written. Parse them anyway, and
1281*f4a2713aSLionel Sambuc /// provide a fixit moving them to the right place.
1282*f4a2713aSLionel Sambuc void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
1283*f4a2713aSLionel Sambuc                                              SourceLocation CorrectLocation) {
1284*f4a2713aSLionel Sambuc   assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||
1285*f4a2713aSLionel Sambuc          Tok.is(tok::kw_alignas));
1286*f4a2713aSLionel Sambuc 
1287*f4a2713aSLionel Sambuc   // Consume the attributes.
1288*f4a2713aSLionel Sambuc   SourceLocation Loc = Tok.getLocation();
1289*f4a2713aSLionel Sambuc   ParseCXX11Attributes(Attrs);
1290*f4a2713aSLionel Sambuc   CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true);
1291*f4a2713aSLionel Sambuc 
1292*f4a2713aSLionel Sambuc   Diag(Loc, diag::err_attributes_not_allowed)
1293*f4a2713aSLionel Sambuc     << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
1294*f4a2713aSLionel Sambuc     << FixItHint::CreateRemoval(AttrRange);
1295*f4a2713aSLionel Sambuc }
1296*f4a2713aSLionel Sambuc 
1297*f4a2713aSLionel Sambuc void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
1298*f4a2713aSLionel Sambuc   Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
1299*f4a2713aSLionel Sambuc     << attrs.Range;
1300*f4a2713aSLionel Sambuc }
1301*f4a2713aSLionel Sambuc 
1302*f4a2713aSLionel Sambuc void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs) {
1303*f4a2713aSLionel Sambuc   AttributeList *AttrList = attrs.getList();
1304*f4a2713aSLionel Sambuc   while (AttrList) {
1305*f4a2713aSLionel Sambuc     if (AttrList->isCXX11Attribute()) {
1306*f4a2713aSLionel Sambuc       Diag(AttrList->getLoc(), diag::err_attribute_not_type_attr)
1307*f4a2713aSLionel Sambuc         << AttrList->getName();
1308*f4a2713aSLionel Sambuc       AttrList->setInvalid();
1309*f4a2713aSLionel Sambuc     }
1310*f4a2713aSLionel Sambuc     AttrList = AttrList->getNext();
1311*f4a2713aSLionel Sambuc   }
1312*f4a2713aSLionel Sambuc }
1313*f4a2713aSLionel Sambuc 
1314*f4a2713aSLionel Sambuc /// ParseDeclaration - Parse a full 'declaration', which consists of
1315*f4a2713aSLionel Sambuc /// declaration-specifiers, some number of declarators, and a semicolon.
1316*f4a2713aSLionel Sambuc /// 'Context' should be a Declarator::TheContext value.  This returns the
1317*f4a2713aSLionel Sambuc /// location of the semicolon in DeclEnd.
1318*f4a2713aSLionel Sambuc ///
1319*f4a2713aSLionel Sambuc ///       declaration: [C99 6.7]
1320*f4a2713aSLionel Sambuc ///         block-declaration ->
1321*f4a2713aSLionel Sambuc ///           simple-declaration
1322*f4a2713aSLionel Sambuc ///           others                   [FIXME]
1323*f4a2713aSLionel Sambuc /// [C++]   template-declaration
1324*f4a2713aSLionel Sambuc /// [C++]   namespace-definition
1325*f4a2713aSLionel Sambuc /// [C++]   using-directive
1326*f4a2713aSLionel Sambuc /// [C++]   using-declaration
1327*f4a2713aSLionel Sambuc /// [C++11/C11] static_assert-declaration
1328*f4a2713aSLionel Sambuc ///         others... [FIXME]
1329*f4a2713aSLionel Sambuc ///
1330*f4a2713aSLionel Sambuc Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
1331*f4a2713aSLionel Sambuc                                                 unsigned Context,
1332*f4a2713aSLionel Sambuc                                                 SourceLocation &DeclEnd,
1333*f4a2713aSLionel Sambuc                                           ParsedAttributesWithRange &attrs) {
1334*f4a2713aSLionel Sambuc   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1335*f4a2713aSLionel Sambuc   // Must temporarily exit the objective-c container scope for
1336*f4a2713aSLionel Sambuc   // parsing c none objective-c decls.
1337*f4a2713aSLionel Sambuc   ObjCDeclContextSwitch ObjCDC(*this);
1338*f4a2713aSLionel Sambuc 
1339*f4a2713aSLionel Sambuc   Decl *SingleDecl = 0;
1340*f4a2713aSLionel Sambuc   Decl *OwnedType = 0;
1341*f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
1342*f4a2713aSLionel Sambuc   case tok::kw_template:
1343*f4a2713aSLionel Sambuc   case tok::kw_export:
1344*f4a2713aSLionel Sambuc     ProhibitAttributes(attrs);
1345*f4a2713aSLionel Sambuc     SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
1346*f4a2713aSLionel Sambuc     break;
1347*f4a2713aSLionel Sambuc   case tok::kw_inline:
1348*f4a2713aSLionel Sambuc     // Could be the start of an inline namespace. Allowed as an ext in C++03.
1349*f4a2713aSLionel Sambuc     if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
1350*f4a2713aSLionel Sambuc       ProhibitAttributes(attrs);
1351*f4a2713aSLionel Sambuc       SourceLocation InlineLoc = ConsumeToken();
1352*f4a2713aSLionel Sambuc       SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
1353*f4a2713aSLionel Sambuc       break;
1354*f4a2713aSLionel Sambuc     }
1355*f4a2713aSLionel Sambuc     return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
1356*f4a2713aSLionel Sambuc                                   true);
1357*f4a2713aSLionel Sambuc   case tok::kw_namespace:
1358*f4a2713aSLionel Sambuc     ProhibitAttributes(attrs);
1359*f4a2713aSLionel Sambuc     SingleDecl = ParseNamespace(Context, DeclEnd);
1360*f4a2713aSLionel Sambuc     break;
1361*f4a2713aSLionel Sambuc   case tok::kw_using:
1362*f4a2713aSLionel Sambuc     SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1363*f4a2713aSLionel Sambuc                                                   DeclEnd, attrs, &OwnedType);
1364*f4a2713aSLionel Sambuc     break;
1365*f4a2713aSLionel Sambuc   case tok::kw_static_assert:
1366*f4a2713aSLionel Sambuc   case tok::kw__Static_assert:
1367*f4a2713aSLionel Sambuc     ProhibitAttributes(attrs);
1368*f4a2713aSLionel Sambuc     SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1369*f4a2713aSLionel Sambuc     break;
1370*f4a2713aSLionel Sambuc   default:
1371*f4a2713aSLionel Sambuc     return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
1372*f4a2713aSLionel Sambuc   }
1373*f4a2713aSLionel Sambuc 
1374*f4a2713aSLionel Sambuc   // This routine returns a DeclGroup, if the thing we parsed only contains a
1375*f4a2713aSLionel Sambuc   // single decl, convert it now. Alias declarations can also declare a type;
1376*f4a2713aSLionel Sambuc   // include that too if it is present.
1377*f4a2713aSLionel Sambuc   return Actions.ConvertDeclToDeclGroup(SingleDecl, OwnedType);
1378*f4a2713aSLionel Sambuc }
1379*f4a2713aSLionel Sambuc 
1380*f4a2713aSLionel Sambuc ///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
1381*f4a2713aSLionel Sambuc ///         declaration-specifiers init-declarator-list[opt] ';'
1382*f4a2713aSLionel Sambuc /// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
1383*f4a2713aSLionel Sambuc ///             init-declarator-list ';'
1384*f4a2713aSLionel Sambuc ///[C90/C++]init-declarator-list ';'                             [TODO]
1385*f4a2713aSLionel Sambuc /// [OMP]   threadprivate-directive                              [TODO]
1386*f4a2713aSLionel Sambuc ///
1387*f4a2713aSLionel Sambuc ///       for-range-declaration: [C++11 6.5p1: stmt.ranged]
1388*f4a2713aSLionel Sambuc ///         attribute-specifier-seq[opt] type-specifier-seq declarator
1389*f4a2713aSLionel Sambuc ///
1390*f4a2713aSLionel Sambuc /// If RequireSemi is false, this does not check for a ';' at the end of the
1391*f4a2713aSLionel Sambuc /// declaration.  If it is true, it checks for and eats it.
1392*f4a2713aSLionel Sambuc ///
1393*f4a2713aSLionel Sambuc /// If FRI is non-null, we might be parsing a for-range-declaration instead
1394*f4a2713aSLionel Sambuc /// of a simple-declaration. If we find that we are, we also parse the
1395*f4a2713aSLionel Sambuc /// for-range-initializer, and place it here.
1396*f4a2713aSLionel Sambuc Parser::DeclGroupPtrTy
1397*f4a2713aSLionel Sambuc Parser::ParseSimpleDeclaration(StmtVector &Stmts, unsigned Context,
1398*f4a2713aSLionel Sambuc                                SourceLocation &DeclEnd,
1399*f4a2713aSLionel Sambuc                                ParsedAttributesWithRange &Attrs,
1400*f4a2713aSLionel Sambuc                                bool RequireSemi, ForRangeInit *FRI) {
1401*f4a2713aSLionel Sambuc   // Parse the common declaration-specifiers piece.
1402*f4a2713aSLionel Sambuc   ParsingDeclSpec DS(*this);
1403*f4a2713aSLionel Sambuc 
1404*f4a2713aSLionel Sambuc   DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1405*f4a2713aSLionel Sambuc   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext);
1406*f4a2713aSLionel Sambuc 
1407*f4a2713aSLionel Sambuc   // If we had a free-standing type definition with a missing semicolon, we
1408*f4a2713aSLionel Sambuc   // may get this far before the problem becomes obvious.
1409*f4a2713aSLionel Sambuc   if (DS.hasTagDefinition() &&
1410*f4a2713aSLionel Sambuc       DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext))
1411*f4a2713aSLionel Sambuc     return DeclGroupPtrTy();
1412*f4a2713aSLionel Sambuc 
1413*f4a2713aSLionel Sambuc   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1414*f4a2713aSLionel Sambuc   // declaration-specifiers init-declarator-list[opt] ';'
1415*f4a2713aSLionel Sambuc   if (Tok.is(tok::semi)) {
1416*f4a2713aSLionel Sambuc     ProhibitAttributes(Attrs);
1417*f4a2713aSLionel Sambuc     DeclEnd = Tok.getLocation();
1418*f4a2713aSLionel Sambuc     if (RequireSemi) ConsumeToken();
1419*f4a2713aSLionel Sambuc     Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
1420*f4a2713aSLionel Sambuc                                                        DS);
1421*f4a2713aSLionel Sambuc     DS.complete(TheDecl);
1422*f4a2713aSLionel Sambuc     return Actions.ConvertDeclToDeclGroup(TheDecl);
1423*f4a2713aSLionel Sambuc   }
1424*f4a2713aSLionel Sambuc 
1425*f4a2713aSLionel Sambuc   DS.takeAttributesFrom(Attrs);
1426*f4a2713aSLionel Sambuc   return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
1427*f4a2713aSLionel Sambuc }
1428*f4a2713aSLionel Sambuc 
1429*f4a2713aSLionel Sambuc /// Returns true if this might be the start of a declarator, or a common typo
1430*f4a2713aSLionel Sambuc /// for a declarator.
1431*f4a2713aSLionel Sambuc bool Parser::MightBeDeclarator(unsigned Context) {
1432*f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
1433*f4a2713aSLionel Sambuc   case tok::annot_cxxscope:
1434*f4a2713aSLionel Sambuc   case tok::annot_template_id:
1435*f4a2713aSLionel Sambuc   case tok::caret:
1436*f4a2713aSLionel Sambuc   case tok::code_completion:
1437*f4a2713aSLionel Sambuc   case tok::coloncolon:
1438*f4a2713aSLionel Sambuc   case tok::ellipsis:
1439*f4a2713aSLionel Sambuc   case tok::kw___attribute:
1440*f4a2713aSLionel Sambuc   case tok::kw_operator:
1441*f4a2713aSLionel Sambuc   case tok::l_paren:
1442*f4a2713aSLionel Sambuc   case tok::star:
1443*f4a2713aSLionel Sambuc     return true;
1444*f4a2713aSLionel Sambuc 
1445*f4a2713aSLionel Sambuc   case tok::amp:
1446*f4a2713aSLionel Sambuc   case tok::ampamp:
1447*f4a2713aSLionel Sambuc     return getLangOpts().CPlusPlus;
1448*f4a2713aSLionel Sambuc 
1449*f4a2713aSLionel Sambuc   case tok::l_square: // Might be an attribute on an unnamed bit-field.
1450*f4a2713aSLionel Sambuc     return Context == Declarator::MemberContext && getLangOpts().CPlusPlus11 &&
1451*f4a2713aSLionel Sambuc            NextToken().is(tok::l_square);
1452*f4a2713aSLionel Sambuc 
1453*f4a2713aSLionel Sambuc   case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
1454*f4a2713aSLionel Sambuc     return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
1455*f4a2713aSLionel Sambuc 
1456*f4a2713aSLionel Sambuc   case tok::identifier:
1457*f4a2713aSLionel Sambuc     switch (NextToken().getKind()) {
1458*f4a2713aSLionel Sambuc     case tok::code_completion:
1459*f4a2713aSLionel Sambuc     case tok::coloncolon:
1460*f4a2713aSLionel Sambuc     case tok::comma:
1461*f4a2713aSLionel Sambuc     case tok::equal:
1462*f4a2713aSLionel Sambuc     case tok::equalequal: // Might be a typo for '='.
1463*f4a2713aSLionel Sambuc     case tok::kw_alignas:
1464*f4a2713aSLionel Sambuc     case tok::kw_asm:
1465*f4a2713aSLionel Sambuc     case tok::kw___attribute:
1466*f4a2713aSLionel Sambuc     case tok::l_brace:
1467*f4a2713aSLionel Sambuc     case tok::l_paren:
1468*f4a2713aSLionel Sambuc     case tok::l_square:
1469*f4a2713aSLionel Sambuc     case tok::less:
1470*f4a2713aSLionel Sambuc     case tok::r_brace:
1471*f4a2713aSLionel Sambuc     case tok::r_paren:
1472*f4a2713aSLionel Sambuc     case tok::r_square:
1473*f4a2713aSLionel Sambuc     case tok::semi:
1474*f4a2713aSLionel Sambuc       return true;
1475*f4a2713aSLionel Sambuc 
1476*f4a2713aSLionel Sambuc     case tok::colon:
1477*f4a2713aSLionel Sambuc       // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
1478*f4a2713aSLionel Sambuc       // and in block scope it's probably a label. Inside a class definition,
1479*f4a2713aSLionel Sambuc       // this is a bit-field.
1480*f4a2713aSLionel Sambuc       return Context == Declarator::MemberContext ||
1481*f4a2713aSLionel Sambuc              (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
1482*f4a2713aSLionel Sambuc 
1483*f4a2713aSLionel Sambuc     case tok::identifier: // Possible virt-specifier.
1484*f4a2713aSLionel Sambuc       return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken());
1485*f4a2713aSLionel Sambuc 
1486*f4a2713aSLionel Sambuc     default:
1487*f4a2713aSLionel Sambuc       return false;
1488*f4a2713aSLionel Sambuc     }
1489*f4a2713aSLionel Sambuc 
1490*f4a2713aSLionel Sambuc   default:
1491*f4a2713aSLionel Sambuc     return false;
1492*f4a2713aSLionel Sambuc   }
1493*f4a2713aSLionel Sambuc }
1494*f4a2713aSLionel Sambuc 
1495*f4a2713aSLionel Sambuc /// Skip until we reach something which seems like a sensible place to pick
1496*f4a2713aSLionel Sambuc /// up parsing after a malformed declaration. This will sometimes stop sooner
1497*f4a2713aSLionel Sambuc /// than SkipUntil(tok::r_brace) would, but will never stop later.
1498*f4a2713aSLionel Sambuc void Parser::SkipMalformedDecl() {
1499*f4a2713aSLionel Sambuc   while (true) {
1500*f4a2713aSLionel Sambuc     switch (Tok.getKind()) {
1501*f4a2713aSLionel Sambuc     case tok::l_brace:
1502*f4a2713aSLionel Sambuc       // Skip until matching }, then stop. We've probably skipped over
1503*f4a2713aSLionel Sambuc       // a malformed class or function definition or similar.
1504*f4a2713aSLionel Sambuc       ConsumeBrace();
1505*f4a2713aSLionel Sambuc       SkipUntil(tok::r_brace);
1506*f4a2713aSLionel Sambuc       if (Tok.is(tok::comma) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try)) {
1507*f4a2713aSLionel Sambuc         // This declaration isn't over yet. Keep skipping.
1508*f4a2713aSLionel Sambuc         continue;
1509*f4a2713aSLionel Sambuc       }
1510*f4a2713aSLionel Sambuc       if (Tok.is(tok::semi))
1511*f4a2713aSLionel Sambuc         ConsumeToken();
1512*f4a2713aSLionel Sambuc       return;
1513*f4a2713aSLionel Sambuc 
1514*f4a2713aSLionel Sambuc     case tok::l_square:
1515*f4a2713aSLionel Sambuc       ConsumeBracket();
1516*f4a2713aSLionel Sambuc       SkipUntil(tok::r_square);
1517*f4a2713aSLionel Sambuc       continue;
1518*f4a2713aSLionel Sambuc 
1519*f4a2713aSLionel Sambuc     case tok::l_paren:
1520*f4a2713aSLionel Sambuc       ConsumeParen();
1521*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren);
1522*f4a2713aSLionel Sambuc       continue;
1523*f4a2713aSLionel Sambuc 
1524*f4a2713aSLionel Sambuc     case tok::r_brace:
1525*f4a2713aSLionel Sambuc       return;
1526*f4a2713aSLionel Sambuc 
1527*f4a2713aSLionel Sambuc     case tok::semi:
1528*f4a2713aSLionel Sambuc       ConsumeToken();
1529*f4a2713aSLionel Sambuc       return;
1530*f4a2713aSLionel Sambuc 
1531*f4a2713aSLionel Sambuc     case tok::kw_inline:
1532*f4a2713aSLionel Sambuc       // 'inline namespace' at the start of a line is almost certainly
1533*f4a2713aSLionel Sambuc       // a good place to pick back up parsing, except in an Objective-C
1534*f4a2713aSLionel Sambuc       // @interface context.
1535*f4a2713aSLionel Sambuc       if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&
1536*f4a2713aSLionel Sambuc           (!ParsingInObjCContainer || CurParsedObjCImpl))
1537*f4a2713aSLionel Sambuc         return;
1538*f4a2713aSLionel Sambuc       break;
1539*f4a2713aSLionel Sambuc 
1540*f4a2713aSLionel Sambuc     case tok::kw_namespace:
1541*f4a2713aSLionel Sambuc       // 'namespace' at the start of a line is almost certainly a good
1542*f4a2713aSLionel Sambuc       // place to pick back up parsing, except in an Objective-C
1543*f4a2713aSLionel Sambuc       // @interface context.
1544*f4a2713aSLionel Sambuc       if (Tok.isAtStartOfLine() &&
1545*f4a2713aSLionel Sambuc           (!ParsingInObjCContainer || CurParsedObjCImpl))
1546*f4a2713aSLionel Sambuc         return;
1547*f4a2713aSLionel Sambuc       break;
1548*f4a2713aSLionel Sambuc 
1549*f4a2713aSLionel Sambuc     case tok::at:
1550*f4a2713aSLionel Sambuc       // @end is very much like } in Objective-C contexts.
1551*f4a2713aSLionel Sambuc       if (NextToken().isObjCAtKeyword(tok::objc_end) &&
1552*f4a2713aSLionel Sambuc           ParsingInObjCContainer)
1553*f4a2713aSLionel Sambuc         return;
1554*f4a2713aSLionel Sambuc       break;
1555*f4a2713aSLionel Sambuc 
1556*f4a2713aSLionel Sambuc     case tok::minus:
1557*f4a2713aSLionel Sambuc     case tok::plus:
1558*f4a2713aSLionel Sambuc       // - and + probably start new method declarations in Objective-C contexts.
1559*f4a2713aSLionel Sambuc       if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
1560*f4a2713aSLionel Sambuc         return;
1561*f4a2713aSLionel Sambuc       break;
1562*f4a2713aSLionel Sambuc 
1563*f4a2713aSLionel Sambuc     case tok::eof:
1564*f4a2713aSLionel Sambuc       return;
1565*f4a2713aSLionel Sambuc 
1566*f4a2713aSLionel Sambuc     default:
1567*f4a2713aSLionel Sambuc       break;
1568*f4a2713aSLionel Sambuc     }
1569*f4a2713aSLionel Sambuc 
1570*f4a2713aSLionel Sambuc     ConsumeAnyToken();
1571*f4a2713aSLionel Sambuc   }
1572*f4a2713aSLionel Sambuc }
1573*f4a2713aSLionel Sambuc 
1574*f4a2713aSLionel Sambuc /// ParseDeclGroup - Having concluded that this is either a function
1575*f4a2713aSLionel Sambuc /// definition or a group of object declarations, actually parse the
1576*f4a2713aSLionel Sambuc /// result.
1577*f4a2713aSLionel Sambuc Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
1578*f4a2713aSLionel Sambuc                                               unsigned Context,
1579*f4a2713aSLionel Sambuc                                               bool AllowFunctionDefinitions,
1580*f4a2713aSLionel Sambuc                                               SourceLocation *DeclEnd,
1581*f4a2713aSLionel Sambuc                                               ForRangeInit *FRI) {
1582*f4a2713aSLionel Sambuc   // Parse the first declarator.
1583*f4a2713aSLionel Sambuc   ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
1584*f4a2713aSLionel Sambuc   ParseDeclarator(D);
1585*f4a2713aSLionel Sambuc 
1586*f4a2713aSLionel Sambuc   // Bail out if the first declarator didn't seem well-formed.
1587*f4a2713aSLionel Sambuc   if (!D.hasName() && !D.mayOmitIdentifier()) {
1588*f4a2713aSLionel Sambuc     SkipMalformedDecl();
1589*f4a2713aSLionel Sambuc     return DeclGroupPtrTy();
1590*f4a2713aSLionel Sambuc   }
1591*f4a2713aSLionel Sambuc 
1592*f4a2713aSLionel Sambuc   // Save late-parsed attributes for now; they need to be parsed in the
1593*f4a2713aSLionel Sambuc   // appropriate function scope after the function Decl has been constructed.
1594*f4a2713aSLionel Sambuc   // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList.
1595*f4a2713aSLionel Sambuc   LateParsedAttrList LateParsedAttrs(true);
1596*f4a2713aSLionel Sambuc   if (D.isFunctionDeclarator())
1597*f4a2713aSLionel Sambuc     MaybeParseGNUAttributes(D, &LateParsedAttrs);
1598*f4a2713aSLionel Sambuc 
1599*f4a2713aSLionel Sambuc   // Check to see if we have a function *definition* which must have a body.
1600*f4a2713aSLionel Sambuc   if (D.isFunctionDeclarator() &&
1601*f4a2713aSLionel Sambuc       // Look at the next token to make sure that this isn't a function
1602*f4a2713aSLionel Sambuc       // declaration.  We have to check this because __attribute__ might be the
1603*f4a2713aSLionel Sambuc       // start of a function definition in GCC-extended K&R C.
1604*f4a2713aSLionel Sambuc       !isDeclarationAfterDeclarator()) {
1605*f4a2713aSLionel Sambuc 
1606*f4a2713aSLionel Sambuc     if (AllowFunctionDefinitions) {
1607*f4a2713aSLionel Sambuc       if (isStartOfFunctionDefinition(D)) {
1608*f4a2713aSLionel Sambuc         if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
1609*f4a2713aSLionel Sambuc           Diag(Tok, diag::err_function_declared_typedef);
1610*f4a2713aSLionel Sambuc 
1611*f4a2713aSLionel Sambuc           // Recover by treating the 'typedef' as spurious.
1612*f4a2713aSLionel Sambuc           DS.ClearStorageClassSpecs();
1613*f4a2713aSLionel Sambuc         }
1614*f4a2713aSLionel Sambuc 
1615*f4a2713aSLionel Sambuc         Decl *TheDecl =
1616*f4a2713aSLionel Sambuc           ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs);
1617*f4a2713aSLionel Sambuc         return Actions.ConvertDeclToDeclGroup(TheDecl);
1618*f4a2713aSLionel Sambuc       }
1619*f4a2713aSLionel Sambuc 
1620*f4a2713aSLionel Sambuc       if (isDeclarationSpecifier()) {
1621*f4a2713aSLionel Sambuc         // If there is an invalid declaration specifier right after the function
1622*f4a2713aSLionel Sambuc         // prototype, then we must be in a missing semicolon case where this isn't
1623*f4a2713aSLionel Sambuc         // actually a body.  Just fall through into the code that handles it as a
1624*f4a2713aSLionel Sambuc         // prototype, and let the top-level code handle the erroneous declspec
1625*f4a2713aSLionel Sambuc         // where it would otherwise expect a comma or semicolon.
1626*f4a2713aSLionel Sambuc       } else {
1627*f4a2713aSLionel Sambuc         Diag(Tok, diag::err_expected_fn_body);
1628*f4a2713aSLionel Sambuc         SkipUntil(tok::semi);
1629*f4a2713aSLionel Sambuc         return DeclGroupPtrTy();
1630*f4a2713aSLionel Sambuc       }
1631*f4a2713aSLionel Sambuc     } else {
1632*f4a2713aSLionel Sambuc       if (Tok.is(tok::l_brace)) {
1633*f4a2713aSLionel Sambuc         Diag(Tok, diag::err_function_definition_not_allowed);
1634*f4a2713aSLionel Sambuc         SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
1635*f4a2713aSLionel Sambuc       }
1636*f4a2713aSLionel Sambuc     }
1637*f4a2713aSLionel Sambuc   }
1638*f4a2713aSLionel Sambuc 
1639*f4a2713aSLionel Sambuc   if (ParseAsmAttributesAfterDeclarator(D))
1640*f4a2713aSLionel Sambuc     return DeclGroupPtrTy();
1641*f4a2713aSLionel Sambuc 
1642*f4a2713aSLionel Sambuc   // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
1643*f4a2713aSLionel Sambuc   // must parse and analyze the for-range-initializer before the declaration is
1644*f4a2713aSLionel Sambuc   // analyzed.
1645*f4a2713aSLionel Sambuc   //
1646*f4a2713aSLionel Sambuc   // Handle the Objective-C for-in loop variable similarly, although we
1647*f4a2713aSLionel Sambuc   // don't need to parse the container in advance.
1648*f4a2713aSLionel Sambuc   if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
1649*f4a2713aSLionel Sambuc     bool IsForRangeLoop = false;
1650*f4a2713aSLionel Sambuc     if (Tok.is(tok::colon)) {
1651*f4a2713aSLionel Sambuc       IsForRangeLoop = true;
1652*f4a2713aSLionel Sambuc       FRI->ColonLoc = ConsumeToken();
1653*f4a2713aSLionel Sambuc       if (Tok.is(tok::l_brace))
1654*f4a2713aSLionel Sambuc         FRI->RangeExpr = ParseBraceInitializer();
1655*f4a2713aSLionel Sambuc       else
1656*f4a2713aSLionel Sambuc         FRI->RangeExpr = ParseExpression();
1657*f4a2713aSLionel Sambuc     }
1658*f4a2713aSLionel Sambuc 
1659*f4a2713aSLionel Sambuc     Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1660*f4a2713aSLionel Sambuc     if (IsForRangeLoop)
1661*f4a2713aSLionel Sambuc       Actions.ActOnCXXForRangeDecl(ThisDecl);
1662*f4a2713aSLionel Sambuc     Actions.FinalizeDeclaration(ThisDecl);
1663*f4a2713aSLionel Sambuc     D.complete(ThisDecl);
1664*f4a2713aSLionel Sambuc     return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl);
1665*f4a2713aSLionel Sambuc   }
1666*f4a2713aSLionel Sambuc 
1667*f4a2713aSLionel Sambuc   SmallVector<Decl *, 8> DeclsInGroup;
1668*f4a2713aSLionel Sambuc   Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
1669*f4a2713aSLionel Sambuc   if (LateParsedAttrs.size() > 0)
1670*f4a2713aSLionel Sambuc     ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
1671*f4a2713aSLionel Sambuc   D.complete(FirstDecl);
1672*f4a2713aSLionel Sambuc   if (FirstDecl)
1673*f4a2713aSLionel Sambuc     DeclsInGroup.push_back(FirstDecl);
1674*f4a2713aSLionel Sambuc 
1675*f4a2713aSLionel Sambuc   bool ExpectSemi = Context != Declarator::ForContext;
1676*f4a2713aSLionel Sambuc 
1677*f4a2713aSLionel Sambuc   // If we don't have a comma, it is either the end of the list (a ';') or an
1678*f4a2713aSLionel Sambuc   // error, bail out.
1679*f4a2713aSLionel Sambuc   while (Tok.is(tok::comma)) {
1680*f4a2713aSLionel Sambuc     SourceLocation CommaLoc = ConsumeToken();
1681*f4a2713aSLionel Sambuc 
1682*f4a2713aSLionel Sambuc     if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
1683*f4a2713aSLionel Sambuc       // This comma was followed by a line-break and something which can't be
1684*f4a2713aSLionel Sambuc       // the start of a declarator. The comma was probably a typo for a
1685*f4a2713aSLionel Sambuc       // semicolon.
1686*f4a2713aSLionel Sambuc       Diag(CommaLoc, diag::err_expected_semi_declaration)
1687*f4a2713aSLionel Sambuc         << FixItHint::CreateReplacement(CommaLoc, ";");
1688*f4a2713aSLionel Sambuc       ExpectSemi = false;
1689*f4a2713aSLionel Sambuc       break;
1690*f4a2713aSLionel Sambuc     }
1691*f4a2713aSLionel Sambuc 
1692*f4a2713aSLionel Sambuc     // Parse the next declarator.
1693*f4a2713aSLionel Sambuc     D.clear();
1694*f4a2713aSLionel Sambuc     D.setCommaLoc(CommaLoc);
1695*f4a2713aSLionel Sambuc 
1696*f4a2713aSLionel Sambuc     // Accept attributes in an init-declarator.  In the first declarator in a
1697*f4a2713aSLionel Sambuc     // declaration, these would be part of the declspec.  In subsequent
1698*f4a2713aSLionel Sambuc     // declarators, they become part of the declarator itself, so that they
1699*f4a2713aSLionel Sambuc     // don't apply to declarators after *this* one.  Examples:
1700*f4a2713aSLionel Sambuc     //    short __attribute__((common)) var;    -> declspec
1701*f4a2713aSLionel Sambuc     //    short var __attribute__((common));    -> declarator
1702*f4a2713aSLionel Sambuc     //    short x, __attribute__((common)) var;    -> declarator
1703*f4a2713aSLionel Sambuc     MaybeParseGNUAttributes(D);
1704*f4a2713aSLionel Sambuc 
1705*f4a2713aSLionel Sambuc     ParseDeclarator(D);
1706*f4a2713aSLionel Sambuc     if (!D.isInvalidType()) {
1707*f4a2713aSLionel Sambuc       Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);
1708*f4a2713aSLionel Sambuc       D.complete(ThisDecl);
1709*f4a2713aSLionel Sambuc       if (ThisDecl)
1710*f4a2713aSLionel Sambuc         DeclsInGroup.push_back(ThisDecl);
1711*f4a2713aSLionel Sambuc     }
1712*f4a2713aSLionel Sambuc   }
1713*f4a2713aSLionel Sambuc 
1714*f4a2713aSLionel Sambuc   if (DeclEnd)
1715*f4a2713aSLionel Sambuc     *DeclEnd = Tok.getLocation();
1716*f4a2713aSLionel Sambuc 
1717*f4a2713aSLionel Sambuc   if (ExpectSemi &&
1718*f4a2713aSLionel Sambuc       ExpectAndConsumeSemi(Context == Declarator::FileContext
1719*f4a2713aSLionel Sambuc                            ? diag::err_invalid_token_after_toplevel_declarator
1720*f4a2713aSLionel Sambuc                            : diag::err_expected_semi_declaration)) {
1721*f4a2713aSLionel Sambuc     // Okay, there was no semicolon and one was expected.  If we see a
1722*f4a2713aSLionel Sambuc     // declaration specifier, just assume it was missing and continue parsing.
1723*f4a2713aSLionel Sambuc     // Otherwise things are very confused and we skip to recover.
1724*f4a2713aSLionel Sambuc     if (!isDeclarationSpecifier()) {
1725*f4a2713aSLionel Sambuc       SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
1726*f4a2713aSLionel Sambuc       if (Tok.is(tok::semi))
1727*f4a2713aSLionel Sambuc         ConsumeToken();
1728*f4a2713aSLionel Sambuc     }
1729*f4a2713aSLionel Sambuc   }
1730*f4a2713aSLionel Sambuc 
1731*f4a2713aSLionel Sambuc   return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
1732*f4a2713aSLionel Sambuc }
1733*f4a2713aSLionel Sambuc 
1734*f4a2713aSLionel Sambuc /// Parse an optional simple-asm-expr and attributes, and attach them to a
1735*f4a2713aSLionel Sambuc /// declarator. Returns true on an error.
1736*f4a2713aSLionel Sambuc bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
1737*f4a2713aSLionel Sambuc   // If a simple-asm-expr is present, parse it.
1738*f4a2713aSLionel Sambuc   if (Tok.is(tok::kw_asm)) {
1739*f4a2713aSLionel Sambuc     SourceLocation Loc;
1740*f4a2713aSLionel Sambuc     ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1741*f4a2713aSLionel Sambuc     if (AsmLabel.isInvalid()) {
1742*f4a2713aSLionel Sambuc       SkipUntil(tok::semi, StopBeforeMatch);
1743*f4a2713aSLionel Sambuc       return true;
1744*f4a2713aSLionel Sambuc     }
1745*f4a2713aSLionel Sambuc 
1746*f4a2713aSLionel Sambuc     D.setAsmLabel(AsmLabel.release());
1747*f4a2713aSLionel Sambuc     D.SetRangeEnd(Loc);
1748*f4a2713aSLionel Sambuc   }
1749*f4a2713aSLionel Sambuc 
1750*f4a2713aSLionel Sambuc   MaybeParseGNUAttributes(D);
1751*f4a2713aSLionel Sambuc   return false;
1752*f4a2713aSLionel Sambuc }
1753*f4a2713aSLionel Sambuc 
1754*f4a2713aSLionel Sambuc /// \brief Parse 'declaration' after parsing 'declaration-specifiers
1755*f4a2713aSLionel Sambuc /// declarator'. This method parses the remainder of the declaration
1756*f4a2713aSLionel Sambuc /// (including any attributes or initializer, among other things) and
1757*f4a2713aSLionel Sambuc /// finalizes the declaration.
1758*f4a2713aSLionel Sambuc ///
1759*f4a2713aSLionel Sambuc ///       init-declarator: [C99 6.7]
1760*f4a2713aSLionel Sambuc ///         declarator
1761*f4a2713aSLionel Sambuc ///         declarator '=' initializer
1762*f4a2713aSLionel Sambuc /// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
1763*f4a2713aSLionel Sambuc /// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
1764*f4a2713aSLionel Sambuc /// [C++]   declarator initializer[opt]
1765*f4a2713aSLionel Sambuc ///
1766*f4a2713aSLionel Sambuc /// [C++] initializer:
1767*f4a2713aSLionel Sambuc /// [C++]   '=' initializer-clause
1768*f4a2713aSLionel Sambuc /// [C++]   '(' expression-list ')'
1769*f4a2713aSLionel Sambuc /// [C++0x] '=' 'default'                                                [TODO]
1770*f4a2713aSLionel Sambuc /// [C++0x] '=' 'delete'
1771*f4a2713aSLionel Sambuc /// [C++0x] braced-init-list
1772*f4a2713aSLionel Sambuc ///
1773*f4a2713aSLionel Sambuc /// According to the standard grammar, =default and =delete are function
1774*f4a2713aSLionel Sambuc /// definitions, but that definitely doesn't fit with the parser here.
1775*f4a2713aSLionel Sambuc ///
1776*f4a2713aSLionel Sambuc Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
1777*f4a2713aSLionel Sambuc                                      const ParsedTemplateInfo &TemplateInfo) {
1778*f4a2713aSLionel Sambuc   if (ParseAsmAttributesAfterDeclarator(D))
1779*f4a2713aSLionel Sambuc     return 0;
1780*f4a2713aSLionel Sambuc 
1781*f4a2713aSLionel Sambuc   return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
1782*f4a2713aSLionel Sambuc }
1783*f4a2713aSLionel Sambuc 
1784*f4a2713aSLionel Sambuc Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
1785*f4a2713aSLionel Sambuc                                      const ParsedTemplateInfo &TemplateInfo) {
1786*f4a2713aSLionel Sambuc   // Inform the current actions module that we just parsed this declarator.
1787*f4a2713aSLionel Sambuc   Decl *ThisDecl = 0;
1788*f4a2713aSLionel Sambuc   switch (TemplateInfo.Kind) {
1789*f4a2713aSLionel Sambuc   case ParsedTemplateInfo::NonTemplate:
1790*f4a2713aSLionel Sambuc     ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1791*f4a2713aSLionel Sambuc     break;
1792*f4a2713aSLionel Sambuc 
1793*f4a2713aSLionel Sambuc   case ParsedTemplateInfo::Template:
1794*f4a2713aSLionel Sambuc   case ParsedTemplateInfo::ExplicitSpecialization: {
1795*f4a2713aSLionel Sambuc     ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
1796*f4a2713aSLionel Sambuc                                                *TemplateInfo.TemplateParams,
1797*f4a2713aSLionel Sambuc                                                D);
1798*f4a2713aSLionel Sambuc     if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl))
1799*f4a2713aSLionel Sambuc       // Re-direct this decl to refer to the templated decl so that we can
1800*f4a2713aSLionel Sambuc       // initialize it.
1801*f4a2713aSLionel Sambuc       ThisDecl = VT->getTemplatedDecl();
1802*f4a2713aSLionel Sambuc     break;
1803*f4a2713aSLionel Sambuc   }
1804*f4a2713aSLionel Sambuc   case ParsedTemplateInfo::ExplicitInstantiation: {
1805*f4a2713aSLionel Sambuc     if (Tok.is(tok::semi)) {
1806*f4a2713aSLionel Sambuc       DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
1807*f4a2713aSLionel Sambuc           getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
1808*f4a2713aSLionel Sambuc       if (ThisRes.isInvalid()) {
1809*f4a2713aSLionel Sambuc         SkipUntil(tok::semi, StopBeforeMatch);
1810*f4a2713aSLionel Sambuc         return 0;
1811*f4a2713aSLionel Sambuc       }
1812*f4a2713aSLionel Sambuc       ThisDecl = ThisRes.get();
1813*f4a2713aSLionel Sambuc     } else {
1814*f4a2713aSLionel Sambuc       // FIXME: This check should be for a variable template instantiation only.
1815*f4a2713aSLionel Sambuc 
1816*f4a2713aSLionel Sambuc       // Check that this is a valid instantiation
1817*f4a2713aSLionel Sambuc       if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
1818*f4a2713aSLionel Sambuc         // If the declarator-id is not a template-id, issue a diagnostic and
1819*f4a2713aSLionel Sambuc         // recover by ignoring the 'template' keyword.
1820*f4a2713aSLionel Sambuc         Diag(Tok, diag::err_template_defn_explicit_instantiation)
1821*f4a2713aSLionel Sambuc             << 2 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
1822*f4a2713aSLionel Sambuc         ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
1823*f4a2713aSLionel Sambuc       } else {
1824*f4a2713aSLionel Sambuc         SourceLocation LAngleLoc =
1825*f4a2713aSLionel Sambuc             PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
1826*f4a2713aSLionel Sambuc         Diag(D.getIdentifierLoc(),
1827*f4a2713aSLionel Sambuc              diag::err_explicit_instantiation_with_definition)
1828*f4a2713aSLionel Sambuc             << SourceRange(TemplateInfo.TemplateLoc)
1829*f4a2713aSLionel Sambuc             << FixItHint::CreateInsertion(LAngleLoc, "<>");
1830*f4a2713aSLionel Sambuc 
1831*f4a2713aSLionel Sambuc         // Recover as if it were an explicit specialization.
1832*f4a2713aSLionel Sambuc         TemplateParameterLists FakedParamLists;
1833*f4a2713aSLionel Sambuc         FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
1834*f4a2713aSLionel Sambuc             0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0,
1835*f4a2713aSLionel Sambuc             LAngleLoc));
1836*f4a2713aSLionel Sambuc 
1837*f4a2713aSLionel Sambuc         ThisDecl =
1838*f4a2713aSLionel Sambuc             Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
1839*f4a2713aSLionel Sambuc       }
1840*f4a2713aSLionel Sambuc     }
1841*f4a2713aSLionel Sambuc     break;
1842*f4a2713aSLionel Sambuc     }
1843*f4a2713aSLionel Sambuc   }
1844*f4a2713aSLionel Sambuc 
1845*f4a2713aSLionel Sambuc   bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
1846*f4a2713aSLionel Sambuc 
1847*f4a2713aSLionel Sambuc   // Parse declarator '=' initializer.
1848*f4a2713aSLionel Sambuc   // If a '==' or '+=' is found, suggest a fixit to '='.
1849*f4a2713aSLionel Sambuc   if (isTokenEqualOrEqualTypo()) {
1850*f4a2713aSLionel Sambuc     ConsumeToken();
1851*f4a2713aSLionel Sambuc 
1852*f4a2713aSLionel Sambuc     if (Tok.is(tok::kw_delete)) {
1853*f4a2713aSLionel Sambuc       if (D.isFunctionDeclarator())
1854*f4a2713aSLionel Sambuc         Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1855*f4a2713aSLionel Sambuc           << 1 /* delete */;
1856*f4a2713aSLionel Sambuc       else
1857*f4a2713aSLionel Sambuc         Diag(ConsumeToken(), diag::err_deleted_non_function);
1858*f4a2713aSLionel Sambuc     } else if (Tok.is(tok::kw_default)) {
1859*f4a2713aSLionel Sambuc       if (D.isFunctionDeclarator())
1860*f4a2713aSLionel Sambuc         Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1861*f4a2713aSLionel Sambuc           << 0 /* default */;
1862*f4a2713aSLionel Sambuc       else
1863*f4a2713aSLionel Sambuc         Diag(ConsumeToken(), diag::err_default_special_members);
1864*f4a2713aSLionel Sambuc     } else {
1865*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1866*f4a2713aSLionel Sambuc         EnterScope(0);
1867*f4a2713aSLionel Sambuc         Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1868*f4a2713aSLionel Sambuc       }
1869*f4a2713aSLionel Sambuc 
1870*f4a2713aSLionel Sambuc       if (Tok.is(tok::code_completion)) {
1871*f4a2713aSLionel Sambuc         Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
1872*f4a2713aSLionel Sambuc         Actions.FinalizeDeclaration(ThisDecl);
1873*f4a2713aSLionel Sambuc         cutOffParsing();
1874*f4a2713aSLionel Sambuc         return 0;
1875*f4a2713aSLionel Sambuc       }
1876*f4a2713aSLionel Sambuc 
1877*f4a2713aSLionel Sambuc       ExprResult Init(ParseInitializer());
1878*f4a2713aSLionel Sambuc 
1879*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1880*f4a2713aSLionel Sambuc         Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1881*f4a2713aSLionel Sambuc         ExitScope();
1882*f4a2713aSLionel Sambuc       }
1883*f4a2713aSLionel Sambuc 
1884*f4a2713aSLionel Sambuc       if (Init.isInvalid()) {
1885*f4a2713aSLionel Sambuc         SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
1886*f4a2713aSLionel Sambuc         Actions.ActOnInitializerError(ThisDecl);
1887*f4a2713aSLionel Sambuc       } else
1888*f4a2713aSLionel Sambuc         Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1889*f4a2713aSLionel Sambuc                                      /*DirectInit=*/false, TypeContainsAuto);
1890*f4a2713aSLionel Sambuc     }
1891*f4a2713aSLionel Sambuc   } else if (Tok.is(tok::l_paren)) {
1892*f4a2713aSLionel Sambuc     // Parse C++ direct initializer: '(' expression-list ')'
1893*f4a2713aSLionel Sambuc     BalancedDelimiterTracker T(*this, tok::l_paren);
1894*f4a2713aSLionel Sambuc     T.consumeOpen();
1895*f4a2713aSLionel Sambuc 
1896*f4a2713aSLionel Sambuc     ExprVector Exprs;
1897*f4a2713aSLionel Sambuc     CommaLocsTy CommaLocs;
1898*f4a2713aSLionel Sambuc 
1899*f4a2713aSLionel Sambuc     if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1900*f4a2713aSLionel Sambuc       EnterScope(0);
1901*f4a2713aSLionel Sambuc       Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1902*f4a2713aSLionel Sambuc     }
1903*f4a2713aSLionel Sambuc 
1904*f4a2713aSLionel Sambuc     if (ParseExpressionList(Exprs, CommaLocs)) {
1905*f4a2713aSLionel Sambuc       Actions.ActOnInitializerError(ThisDecl);
1906*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi);
1907*f4a2713aSLionel Sambuc 
1908*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1909*f4a2713aSLionel Sambuc         Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1910*f4a2713aSLionel Sambuc         ExitScope();
1911*f4a2713aSLionel Sambuc       }
1912*f4a2713aSLionel Sambuc     } else {
1913*f4a2713aSLionel Sambuc       // Match the ')'.
1914*f4a2713aSLionel Sambuc       T.consumeClose();
1915*f4a2713aSLionel Sambuc 
1916*f4a2713aSLionel Sambuc       assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
1917*f4a2713aSLionel Sambuc              "Unexpected number of commas!");
1918*f4a2713aSLionel Sambuc 
1919*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
1920*f4a2713aSLionel Sambuc         Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1921*f4a2713aSLionel Sambuc         ExitScope();
1922*f4a2713aSLionel Sambuc       }
1923*f4a2713aSLionel Sambuc 
1924*f4a2713aSLionel Sambuc       ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
1925*f4a2713aSLionel Sambuc                                                           T.getCloseLocation(),
1926*f4a2713aSLionel Sambuc                                                           Exprs);
1927*f4a2713aSLionel Sambuc       Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
1928*f4a2713aSLionel Sambuc                                    /*DirectInit=*/true, TypeContainsAuto);
1929*f4a2713aSLionel Sambuc     }
1930*f4a2713aSLionel Sambuc   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
1931*f4a2713aSLionel Sambuc              (!CurParsedObjCImpl || !D.isFunctionDeclarator())) {
1932*f4a2713aSLionel Sambuc     // Parse C++0x braced-init-list.
1933*f4a2713aSLionel Sambuc     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
1934*f4a2713aSLionel Sambuc 
1935*f4a2713aSLionel Sambuc     if (D.getCXXScopeSpec().isSet()) {
1936*f4a2713aSLionel Sambuc       EnterScope(0);
1937*f4a2713aSLionel Sambuc       Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
1938*f4a2713aSLionel Sambuc     }
1939*f4a2713aSLionel Sambuc 
1940*f4a2713aSLionel Sambuc     ExprResult Init(ParseBraceInitializer());
1941*f4a2713aSLionel Sambuc 
1942*f4a2713aSLionel Sambuc     if (D.getCXXScopeSpec().isSet()) {
1943*f4a2713aSLionel Sambuc       Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
1944*f4a2713aSLionel Sambuc       ExitScope();
1945*f4a2713aSLionel Sambuc     }
1946*f4a2713aSLionel Sambuc 
1947*f4a2713aSLionel Sambuc     if (Init.isInvalid()) {
1948*f4a2713aSLionel Sambuc       Actions.ActOnInitializerError(ThisDecl);
1949*f4a2713aSLionel Sambuc     } else
1950*f4a2713aSLionel Sambuc       Actions.AddInitializerToDecl(ThisDecl, Init.take(),
1951*f4a2713aSLionel Sambuc                                    /*DirectInit=*/true, TypeContainsAuto);
1952*f4a2713aSLionel Sambuc 
1953*f4a2713aSLionel Sambuc   } else {
1954*f4a2713aSLionel Sambuc     Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
1955*f4a2713aSLionel Sambuc   }
1956*f4a2713aSLionel Sambuc 
1957*f4a2713aSLionel Sambuc   Actions.FinalizeDeclaration(ThisDecl);
1958*f4a2713aSLionel Sambuc 
1959*f4a2713aSLionel Sambuc   return ThisDecl;
1960*f4a2713aSLionel Sambuc }
1961*f4a2713aSLionel Sambuc 
1962*f4a2713aSLionel Sambuc /// ParseSpecifierQualifierList
1963*f4a2713aSLionel Sambuc ///        specifier-qualifier-list:
1964*f4a2713aSLionel Sambuc ///          type-specifier specifier-qualifier-list[opt]
1965*f4a2713aSLionel Sambuc ///          type-qualifier specifier-qualifier-list[opt]
1966*f4a2713aSLionel Sambuc /// [GNU]    attributes     specifier-qualifier-list[opt]
1967*f4a2713aSLionel Sambuc ///
1968*f4a2713aSLionel Sambuc void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
1969*f4a2713aSLionel Sambuc                                          DeclSpecContext DSC) {
1970*f4a2713aSLionel Sambuc   /// specifier-qualifier-list is a subset of declaration-specifiers.  Just
1971*f4a2713aSLionel Sambuc   /// parse declaration-specifiers and complain about extra stuff.
1972*f4a2713aSLionel Sambuc   /// TODO: diagnose attribute-specifiers and alignment-specifiers.
1973*f4a2713aSLionel Sambuc   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
1974*f4a2713aSLionel Sambuc 
1975*f4a2713aSLionel Sambuc   // Validate declspec for type-name.
1976*f4a2713aSLionel Sambuc   unsigned Specs = DS.getParsedSpecifiers();
1977*f4a2713aSLionel Sambuc   if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
1978*f4a2713aSLionel Sambuc       !DS.hasTypeSpecifier()) {
1979*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_type);
1980*f4a2713aSLionel Sambuc     DS.SetTypeSpecError();
1981*f4a2713aSLionel Sambuc   } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
1982*f4a2713aSLionel Sambuc              !DS.hasAttributes()) {
1983*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_typename_requires_specqual);
1984*f4a2713aSLionel Sambuc     if (!DS.hasTypeSpecifier())
1985*f4a2713aSLionel Sambuc       DS.SetTypeSpecError();
1986*f4a2713aSLionel Sambuc   }
1987*f4a2713aSLionel Sambuc 
1988*f4a2713aSLionel Sambuc   // Issue diagnostic and remove storage class if present.
1989*f4a2713aSLionel Sambuc   if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
1990*f4a2713aSLionel Sambuc     if (DS.getStorageClassSpecLoc().isValid())
1991*f4a2713aSLionel Sambuc       Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
1992*f4a2713aSLionel Sambuc     else
1993*f4a2713aSLionel Sambuc       Diag(DS.getThreadStorageClassSpecLoc(),
1994*f4a2713aSLionel Sambuc            diag::err_typename_invalid_storageclass);
1995*f4a2713aSLionel Sambuc     DS.ClearStorageClassSpecs();
1996*f4a2713aSLionel Sambuc   }
1997*f4a2713aSLionel Sambuc 
1998*f4a2713aSLionel Sambuc   // Issue diagnostic and remove function specfier if present.
1999*f4a2713aSLionel Sambuc   if (Specs & DeclSpec::PQ_FunctionSpecifier) {
2000*f4a2713aSLionel Sambuc     if (DS.isInlineSpecified())
2001*f4a2713aSLionel Sambuc       Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
2002*f4a2713aSLionel Sambuc     if (DS.isVirtualSpecified())
2003*f4a2713aSLionel Sambuc       Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
2004*f4a2713aSLionel Sambuc     if (DS.isExplicitSpecified())
2005*f4a2713aSLionel Sambuc       Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
2006*f4a2713aSLionel Sambuc     DS.ClearFunctionSpecs();
2007*f4a2713aSLionel Sambuc   }
2008*f4a2713aSLionel Sambuc 
2009*f4a2713aSLionel Sambuc   // Issue diagnostic and remove constexpr specfier if present.
2010*f4a2713aSLionel Sambuc   if (DS.isConstexprSpecified()) {
2011*f4a2713aSLionel Sambuc     Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
2012*f4a2713aSLionel Sambuc     DS.ClearConstexprSpec();
2013*f4a2713aSLionel Sambuc   }
2014*f4a2713aSLionel Sambuc }
2015*f4a2713aSLionel Sambuc 
2016*f4a2713aSLionel Sambuc /// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
2017*f4a2713aSLionel Sambuc /// specified token is valid after the identifier in a declarator which
2018*f4a2713aSLionel Sambuc /// immediately follows the declspec.  For example, these things are valid:
2019*f4a2713aSLionel Sambuc ///
2020*f4a2713aSLionel Sambuc ///      int x   [             4];         // direct-declarator
2021*f4a2713aSLionel Sambuc ///      int x   (             int y);     // direct-declarator
2022*f4a2713aSLionel Sambuc ///  int(int x   )                         // direct-declarator
2023*f4a2713aSLionel Sambuc ///      int x   ;                         // simple-declaration
2024*f4a2713aSLionel Sambuc ///      int x   =             17;         // init-declarator-list
2025*f4a2713aSLionel Sambuc ///      int x   ,             y;          // init-declarator-list
2026*f4a2713aSLionel Sambuc ///      int x   __asm__       ("foo");    // init-declarator-list
2027*f4a2713aSLionel Sambuc ///      int x   :             4;          // struct-declarator
2028*f4a2713aSLionel Sambuc ///      int x   {             5};         // C++'0x unified initializers
2029*f4a2713aSLionel Sambuc ///
2030*f4a2713aSLionel Sambuc /// This is not, because 'x' does not immediately follow the declspec (though
2031*f4a2713aSLionel Sambuc /// ')' happens to be valid anyway).
2032*f4a2713aSLionel Sambuc ///    int (x)
2033*f4a2713aSLionel Sambuc ///
2034*f4a2713aSLionel Sambuc static bool isValidAfterIdentifierInDeclarator(const Token &T) {
2035*f4a2713aSLionel Sambuc   return T.is(tok::l_square) || T.is(tok::l_paren) || T.is(tok::r_paren) ||
2036*f4a2713aSLionel Sambuc          T.is(tok::semi) || T.is(tok::comma) || T.is(tok::equal) ||
2037*f4a2713aSLionel Sambuc          T.is(tok::kw_asm) || T.is(tok::l_brace) || T.is(tok::colon);
2038*f4a2713aSLionel Sambuc }
2039*f4a2713aSLionel Sambuc 
2040*f4a2713aSLionel Sambuc 
2041*f4a2713aSLionel Sambuc /// ParseImplicitInt - This method is called when we have an non-typename
2042*f4a2713aSLionel Sambuc /// identifier in a declspec (which normally terminates the decl spec) when
2043*f4a2713aSLionel Sambuc /// the declspec has no type specifier.  In this case, the declspec is either
2044*f4a2713aSLionel Sambuc /// malformed or is "implicit int" (in K&R and C89).
2045*f4a2713aSLionel Sambuc ///
2046*f4a2713aSLionel Sambuc /// This method handles diagnosing this prettily and returns false if the
2047*f4a2713aSLionel Sambuc /// declspec is done being processed.  If it recovers and thinks there may be
2048*f4a2713aSLionel Sambuc /// other pieces of declspec after it, it returns true.
2049*f4a2713aSLionel Sambuc ///
2050*f4a2713aSLionel Sambuc bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
2051*f4a2713aSLionel Sambuc                               const ParsedTemplateInfo &TemplateInfo,
2052*f4a2713aSLionel Sambuc                               AccessSpecifier AS, DeclSpecContext DSC,
2053*f4a2713aSLionel Sambuc                               ParsedAttributesWithRange &Attrs) {
2054*f4a2713aSLionel Sambuc   assert(Tok.is(tok::identifier) && "should have identifier");
2055*f4a2713aSLionel Sambuc 
2056*f4a2713aSLionel Sambuc   SourceLocation Loc = Tok.getLocation();
2057*f4a2713aSLionel Sambuc   // If we see an identifier that is not a type name, we normally would
2058*f4a2713aSLionel Sambuc   // parse it as the identifer being declared.  However, when a typename
2059*f4a2713aSLionel Sambuc   // is typo'd or the definition is not included, this will incorrectly
2060*f4a2713aSLionel Sambuc   // parse the typename as the identifier name and fall over misparsing
2061*f4a2713aSLionel Sambuc   // later parts of the diagnostic.
2062*f4a2713aSLionel Sambuc   //
2063*f4a2713aSLionel Sambuc   // As such, we try to do some look-ahead in cases where this would
2064*f4a2713aSLionel Sambuc   // otherwise be an "implicit-int" case to see if this is invalid.  For
2065*f4a2713aSLionel Sambuc   // example: "static foo_t x = 4;"  In this case, if we parsed foo_t as
2066*f4a2713aSLionel Sambuc   // an identifier with implicit int, we'd get a parse error because the
2067*f4a2713aSLionel Sambuc   // next token is obviously invalid for a type.  Parse these as a case
2068*f4a2713aSLionel Sambuc   // with an invalid type specifier.
2069*f4a2713aSLionel Sambuc   assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
2070*f4a2713aSLionel Sambuc 
2071*f4a2713aSLionel Sambuc   // Since we know that this either implicit int (which is rare) or an
2072*f4a2713aSLionel Sambuc   // error, do lookahead to try to do better recovery. This never applies
2073*f4a2713aSLionel Sambuc   // within a type specifier. Outside of C++, we allow this even if the
2074*f4a2713aSLionel Sambuc   // language doesn't "officially" support implicit int -- we support
2075*f4a2713aSLionel Sambuc   // implicit int as an extension in C99 and C11.
2076*f4a2713aSLionel Sambuc   if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
2077*f4a2713aSLionel Sambuc       !getLangOpts().CPlusPlus &&
2078*f4a2713aSLionel Sambuc       isValidAfterIdentifierInDeclarator(NextToken())) {
2079*f4a2713aSLionel Sambuc     // If this token is valid for implicit int, e.g. "static x = 4", then
2080*f4a2713aSLionel Sambuc     // we just avoid eating the identifier, so it will be parsed as the
2081*f4a2713aSLionel Sambuc     // identifier in the declarator.
2082*f4a2713aSLionel Sambuc     return false;
2083*f4a2713aSLionel Sambuc   }
2084*f4a2713aSLionel Sambuc 
2085*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus &&
2086*f4a2713aSLionel Sambuc       DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
2087*f4a2713aSLionel Sambuc     // Don't require a type specifier if we have the 'auto' storage class
2088*f4a2713aSLionel Sambuc     // specifier in C++98 -- we'll promote it to a type specifier.
2089*f4a2713aSLionel Sambuc     if (SS)
2090*f4a2713aSLionel Sambuc       AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);
2091*f4a2713aSLionel Sambuc     return false;
2092*f4a2713aSLionel Sambuc   }
2093*f4a2713aSLionel Sambuc 
2094*f4a2713aSLionel Sambuc   // Otherwise, if we don't consume this token, we are going to emit an
2095*f4a2713aSLionel Sambuc   // error anyway.  Try to recover from various common problems.  Check
2096*f4a2713aSLionel Sambuc   // to see if this was a reference to a tag name without a tag specified.
2097*f4a2713aSLionel Sambuc   // This is a common problem in C (saying 'foo' instead of 'struct foo').
2098*f4a2713aSLionel Sambuc   //
2099*f4a2713aSLionel Sambuc   // C++ doesn't need this, and isTagName doesn't take SS.
2100*f4a2713aSLionel Sambuc   if (SS == 0) {
2101*f4a2713aSLionel Sambuc     const char *TagName = 0, *FixitTagName = 0;
2102*f4a2713aSLionel Sambuc     tok::TokenKind TagKind = tok::unknown;
2103*f4a2713aSLionel Sambuc 
2104*f4a2713aSLionel Sambuc     switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
2105*f4a2713aSLionel Sambuc       default: break;
2106*f4a2713aSLionel Sambuc       case DeclSpec::TST_enum:
2107*f4a2713aSLionel Sambuc         TagName="enum"  ; FixitTagName = "enum "  ; TagKind=tok::kw_enum ;break;
2108*f4a2713aSLionel Sambuc       case DeclSpec::TST_union:
2109*f4a2713aSLionel Sambuc         TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
2110*f4a2713aSLionel Sambuc       case DeclSpec::TST_struct:
2111*f4a2713aSLionel Sambuc         TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
2112*f4a2713aSLionel Sambuc       case DeclSpec::TST_interface:
2113*f4a2713aSLionel Sambuc         TagName="__interface"; FixitTagName = "__interface ";
2114*f4a2713aSLionel Sambuc         TagKind=tok::kw___interface;break;
2115*f4a2713aSLionel Sambuc       case DeclSpec::TST_class:
2116*f4a2713aSLionel Sambuc         TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
2117*f4a2713aSLionel Sambuc     }
2118*f4a2713aSLionel Sambuc 
2119*f4a2713aSLionel Sambuc     if (TagName) {
2120*f4a2713aSLionel Sambuc       IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2121*f4a2713aSLionel Sambuc       LookupResult R(Actions, TokenName, SourceLocation(),
2122*f4a2713aSLionel Sambuc                      Sema::LookupOrdinaryName);
2123*f4a2713aSLionel Sambuc 
2124*f4a2713aSLionel Sambuc       Diag(Loc, diag::err_use_of_tag_name_without_tag)
2125*f4a2713aSLionel Sambuc         << TokenName << TagName << getLangOpts().CPlusPlus
2126*f4a2713aSLionel Sambuc         << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
2127*f4a2713aSLionel Sambuc 
2128*f4a2713aSLionel Sambuc       if (Actions.LookupParsedName(R, getCurScope(), SS)) {
2129*f4a2713aSLionel Sambuc         for (LookupResult::iterator I = R.begin(), IEnd = R.end();
2130*f4a2713aSLionel Sambuc              I != IEnd; ++I)
2131*f4a2713aSLionel Sambuc           Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2132*f4a2713aSLionel Sambuc             << TokenName << TagName;
2133*f4a2713aSLionel Sambuc       }
2134*f4a2713aSLionel Sambuc 
2135*f4a2713aSLionel Sambuc       // Parse this as a tag as if the missing tag were present.
2136*f4a2713aSLionel Sambuc       if (TagKind == tok::kw_enum)
2137*f4a2713aSLionel Sambuc         ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
2138*f4a2713aSLionel Sambuc       else
2139*f4a2713aSLionel Sambuc         ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2140*f4a2713aSLionel Sambuc                             /*EnteringContext*/ false, DSC_normal, Attrs);
2141*f4a2713aSLionel Sambuc       return true;
2142*f4a2713aSLionel Sambuc     }
2143*f4a2713aSLionel Sambuc   }
2144*f4a2713aSLionel Sambuc 
2145*f4a2713aSLionel Sambuc   // Determine whether this identifier could plausibly be the name of something
2146*f4a2713aSLionel Sambuc   // being declared (with a missing type).
2147*f4a2713aSLionel Sambuc   if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
2148*f4a2713aSLionel Sambuc       (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
2149*f4a2713aSLionel Sambuc     // Look ahead to the next token to try to figure out what this declaration
2150*f4a2713aSLionel Sambuc     // was supposed to be.
2151*f4a2713aSLionel Sambuc     switch (NextToken().getKind()) {
2152*f4a2713aSLionel Sambuc     case tok::l_paren: {
2153*f4a2713aSLionel Sambuc       // static x(4); // 'x' is not a type
2154*f4a2713aSLionel Sambuc       // x(int n);    // 'x' is not a type
2155*f4a2713aSLionel Sambuc       // x (*p)[];    // 'x' is a type
2156*f4a2713aSLionel Sambuc       //
2157*f4a2713aSLionel Sambuc       // Since we're in an error case (or the rare 'implicit int in C++' MS
2158*f4a2713aSLionel Sambuc       // extension), we can afford to perform a tentative parse to determine
2159*f4a2713aSLionel Sambuc       // which case we're in.
2160*f4a2713aSLionel Sambuc       TentativeParsingAction PA(*this);
2161*f4a2713aSLionel Sambuc       ConsumeToken();
2162*f4a2713aSLionel Sambuc       TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
2163*f4a2713aSLionel Sambuc       PA.Revert();
2164*f4a2713aSLionel Sambuc 
2165*f4a2713aSLionel Sambuc       if (TPR != TPResult::False()) {
2166*f4a2713aSLionel Sambuc         // The identifier is followed by a parenthesized declarator.
2167*f4a2713aSLionel Sambuc         // It's supposed to be a type.
2168*f4a2713aSLionel Sambuc         break;
2169*f4a2713aSLionel Sambuc       }
2170*f4a2713aSLionel Sambuc 
2171*f4a2713aSLionel Sambuc       // If we're in a context where we could be declaring a constructor,
2172*f4a2713aSLionel Sambuc       // check whether this is a constructor declaration with a bogus name.
2173*f4a2713aSLionel Sambuc       if (DSC == DSC_class || (DSC == DSC_top_level && SS)) {
2174*f4a2713aSLionel Sambuc         IdentifierInfo *II = Tok.getIdentifierInfo();
2175*f4a2713aSLionel Sambuc         if (Actions.isCurrentClassNameTypo(II, SS)) {
2176*f4a2713aSLionel Sambuc           Diag(Loc, diag::err_constructor_bad_name)
2177*f4a2713aSLionel Sambuc             << Tok.getIdentifierInfo() << II
2178*f4a2713aSLionel Sambuc             << FixItHint::CreateReplacement(Tok.getLocation(), II->getName());
2179*f4a2713aSLionel Sambuc           Tok.setIdentifierInfo(II);
2180*f4a2713aSLionel Sambuc         }
2181*f4a2713aSLionel Sambuc       }
2182*f4a2713aSLionel Sambuc       // Fall through.
2183*f4a2713aSLionel Sambuc     }
2184*f4a2713aSLionel Sambuc     case tok::comma:
2185*f4a2713aSLionel Sambuc     case tok::equal:
2186*f4a2713aSLionel Sambuc     case tok::kw_asm:
2187*f4a2713aSLionel Sambuc     case tok::l_brace:
2188*f4a2713aSLionel Sambuc     case tok::l_square:
2189*f4a2713aSLionel Sambuc     case tok::semi:
2190*f4a2713aSLionel Sambuc       // This looks like a variable or function declaration. The type is
2191*f4a2713aSLionel Sambuc       // probably missing. We're done parsing decl-specifiers.
2192*f4a2713aSLionel Sambuc       if (SS)
2193*f4a2713aSLionel Sambuc         AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);
2194*f4a2713aSLionel Sambuc       return false;
2195*f4a2713aSLionel Sambuc 
2196*f4a2713aSLionel Sambuc     default:
2197*f4a2713aSLionel Sambuc       // This is probably supposed to be a type. This includes cases like:
2198*f4a2713aSLionel Sambuc       //   int f(itn);
2199*f4a2713aSLionel Sambuc       //   struct S { unsinged : 4; };
2200*f4a2713aSLionel Sambuc       break;
2201*f4a2713aSLionel Sambuc     }
2202*f4a2713aSLionel Sambuc   }
2203*f4a2713aSLionel Sambuc 
2204*f4a2713aSLionel Sambuc   // This is almost certainly an invalid type name. Let the action emit a
2205*f4a2713aSLionel Sambuc   // diagnostic and attempt to recover.
2206*f4a2713aSLionel Sambuc   ParsedType T;
2207*f4a2713aSLionel Sambuc   IdentifierInfo *II = Tok.getIdentifierInfo();
2208*f4a2713aSLionel Sambuc   if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
2209*f4a2713aSLionel Sambuc     // The action emitted a diagnostic, so we don't have to.
2210*f4a2713aSLionel Sambuc     if (T) {
2211*f4a2713aSLionel Sambuc       // The action has suggested that the type T could be used. Set that as
2212*f4a2713aSLionel Sambuc       // the type in the declaration specifiers, consume the would-be type
2213*f4a2713aSLionel Sambuc       // name token, and we're done.
2214*f4a2713aSLionel Sambuc       const char *PrevSpec;
2215*f4a2713aSLionel Sambuc       unsigned DiagID;
2216*f4a2713aSLionel Sambuc       DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
2217*f4a2713aSLionel Sambuc       DS.SetRangeEnd(Tok.getLocation());
2218*f4a2713aSLionel Sambuc       ConsumeToken();
2219*f4a2713aSLionel Sambuc       // There may be other declaration specifiers after this.
2220*f4a2713aSLionel Sambuc       return true;
2221*f4a2713aSLionel Sambuc     } else if (II != Tok.getIdentifierInfo()) {
2222*f4a2713aSLionel Sambuc       // If no type was suggested, the correction is to a keyword
2223*f4a2713aSLionel Sambuc       Tok.setKind(II->getTokenID());
2224*f4a2713aSLionel Sambuc       // There may be other declaration specifiers after this.
2225*f4a2713aSLionel Sambuc       return true;
2226*f4a2713aSLionel Sambuc     }
2227*f4a2713aSLionel Sambuc 
2228*f4a2713aSLionel Sambuc     // Fall through; the action had no suggestion for us.
2229*f4a2713aSLionel Sambuc   } else {
2230*f4a2713aSLionel Sambuc     // The action did not emit a diagnostic, so emit one now.
2231*f4a2713aSLionel Sambuc     SourceRange R;
2232*f4a2713aSLionel Sambuc     if (SS) R = SS->getRange();
2233*f4a2713aSLionel Sambuc     Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
2234*f4a2713aSLionel Sambuc   }
2235*f4a2713aSLionel Sambuc 
2236*f4a2713aSLionel Sambuc   // Mark this as an error.
2237*f4a2713aSLionel Sambuc   DS.SetTypeSpecError();
2238*f4a2713aSLionel Sambuc   DS.SetRangeEnd(Tok.getLocation());
2239*f4a2713aSLionel Sambuc   ConsumeToken();
2240*f4a2713aSLionel Sambuc 
2241*f4a2713aSLionel Sambuc   // TODO: Could inject an invalid typedef decl in an enclosing scope to
2242*f4a2713aSLionel Sambuc   // avoid rippling error messages on subsequent uses of the same type,
2243*f4a2713aSLionel Sambuc   // could be useful if #include was forgotten.
2244*f4a2713aSLionel Sambuc   return false;
2245*f4a2713aSLionel Sambuc }
2246*f4a2713aSLionel Sambuc 
2247*f4a2713aSLionel Sambuc /// \brief Determine the declaration specifier context from the declarator
2248*f4a2713aSLionel Sambuc /// context.
2249*f4a2713aSLionel Sambuc ///
2250*f4a2713aSLionel Sambuc /// \param Context the declarator context, which is one of the
2251*f4a2713aSLionel Sambuc /// Declarator::TheContext enumerator values.
2252*f4a2713aSLionel Sambuc Parser::DeclSpecContext
2253*f4a2713aSLionel Sambuc Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
2254*f4a2713aSLionel Sambuc   if (Context == Declarator::MemberContext)
2255*f4a2713aSLionel Sambuc     return DSC_class;
2256*f4a2713aSLionel Sambuc   if (Context == Declarator::FileContext)
2257*f4a2713aSLionel Sambuc     return DSC_top_level;
2258*f4a2713aSLionel Sambuc   if (Context == Declarator::TrailingReturnContext)
2259*f4a2713aSLionel Sambuc     return DSC_trailing;
2260*f4a2713aSLionel Sambuc   return DSC_normal;
2261*f4a2713aSLionel Sambuc }
2262*f4a2713aSLionel Sambuc 
2263*f4a2713aSLionel Sambuc /// ParseAlignArgument - Parse the argument to an alignment-specifier.
2264*f4a2713aSLionel Sambuc ///
2265*f4a2713aSLionel Sambuc /// FIXME: Simply returns an alignof() expression if the argument is a
2266*f4a2713aSLionel Sambuc /// type. Ideally, the type should be propagated directly into Sema.
2267*f4a2713aSLionel Sambuc ///
2268*f4a2713aSLionel Sambuc /// [C11]   type-id
2269*f4a2713aSLionel Sambuc /// [C11]   constant-expression
2270*f4a2713aSLionel Sambuc /// [C++0x] type-id ...[opt]
2271*f4a2713aSLionel Sambuc /// [C++0x] assignment-expression ...[opt]
2272*f4a2713aSLionel Sambuc ExprResult Parser::ParseAlignArgument(SourceLocation Start,
2273*f4a2713aSLionel Sambuc                                       SourceLocation &EllipsisLoc) {
2274*f4a2713aSLionel Sambuc   ExprResult ER;
2275*f4a2713aSLionel Sambuc   if (isTypeIdInParens()) {
2276*f4a2713aSLionel Sambuc     SourceLocation TypeLoc = Tok.getLocation();
2277*f4a2713aSLionel Sambuc     ParsedType Ty = ParseTypeName().get();
2278*f4a2713aSLionel Sambuc     SourceRange TypeRange(Start, Tok.getLocation());
2279*f4a2713aSLionel Sambuc     ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
2280*f4a2713aSLionel Sambuc                                                Ty.getAsOpaquePtr(), TypeRange);
2281*f4a2713aSLionel Sambuc   } else
2282*f4a2713aSLionel Sambuc     ER = ParseConstantExpression();
2283*f4a2713aSLionel Sambuc 
2284*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus11 && Tok.is(tok::ellipsis))
2285*f4a2713aSLionel Sambuc     EllipsisLoc = ConsumeToken();
2286*f4a2713aSLionel Sambuc 
2287*f4a2713aSLionel Sambuc   return ER;
2288*f4a2713aSLionel Sambuc }
2289*f4a2713aSLionel Sambuc 
2290*f4a2713aSLionel Sambuc /// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
2291*f4a2713aSLionel Sambuc /// attribute to Attrs.
2292*f4a2713aSLionel Sambuc ///
2293*f4a2713aSLionel Sambuc /// alignment-specifier:
2294*f4a2713aSLionel Sambuc /// [C11]   '_Alignas' '(' type-id ')'
2295*f4a2713aSLionel Sambuc /// [C11]   '_Alignas' '(' constant-expression ')'
2296*f4a2713aSLionel Sambuc /// [C++11] 'alignas' '(' type-id ...[opt] ')'
2297*f4a2713aSLionel Sambuc /// [C++11] 'alignas' '(' assignment-expression ...[opt] ')'
2298*f4a2713aSLionel Sambuc void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
2299*f4a2713aSLionel Sambuc                                      SourceLocation *EndLoc) {
2300*f4a2713aSLionel Sambuc   assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
2301*f4a2713aSLionel Sambuc          "Not an alignment-specifier!");
2302*f4a2713aSLionel Sambuc 
2303*f4a2713aSLionel Sambuc   IdentifierInfo *KWName = Tok.getIdentifierInfo();
2304*f4a2713aSLionel Sambuc   SourceLocation KWLoc = ConsumeToken();
2305*f4a2713aSLionel Sambuc 
2306*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
2307*f4a2713aSLionel Sambuc   if (T.expectAndConsume(diag::err_expected_lparen))
2308*f4a2713aSLionel Sambuc     return;
2309*f4a2713aSLionel Sambuc 
2310*f4a2713aSLionel Sambuc   SourceLocation EllipsisLoc;
2311*f4a2713aSLionel Sambuc   ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
2312*f4a2713aSLionel Sambuc   if (ArgExpr.isInvalid()) {
2313*f4a2713aSLionel Sambuc     T.skipToEnd();
2314*f4a2713aSLionel Sambuc     return;
2315*f4a2713aSLionel Sambuc   }
2316*f4a2713aSLionel Sambuc 
2317*f4a2713aSLionel Sambuc   T.consumeClose();
2318*f4a2713aSLionel Sambuc   if (EndLoc)
2319*f4a2713aSLionel Sambuc     *EndLoc = T.getCloseLocation();
2320*f4a2713aSLionel Sambuc 
2321*f4a2713aSLionel Sambuc   ArgsVector ArgExprs;
2322*f4a2713aSLionel Sambuc   ArgExprs.push_back(ArgExpr.release());
2323*f4a2713aSLionel Sambuc   Attrs.addNew(KWName, KWLoc, 0, KWLoc, ArgExprs.data(), 1,
2324*f4a2713aSLionel Sambuc                AttributeList::AS_Keyword, EllipsisLoc);
2325*f4a2713aSLionel Sambuc }
2326*f4a2713aSLionel Sambuc 
2327*f4a2713aSLionel Sambuc /// Determine whether we're looking at something that might be a declarator
2328*f4a2713aSLionel Sambuc /// in a simple-declaration. If it can't possibly be a declarator, maybe
2329*f4a2713aSLionel Sambuc /// diagnose a missing semicolon after a prior tag definition in the decl
2330*f4a2713aSLionel Sambuc /// specifier.
2331*f4a2713aSLionel Sambuc ///
2332*f4a2713aSLionel Sambuc /// \return \c true if an error occurred and this can't be any kind of
2333*f4a2713aSLionel Sambuc /// declaration.
2334*f4a2713aSLionel Sambuc bool
2335*f4a2713aSLionel Sambuc Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
2336*f4a2713aSLionel Sambuc                                               DeclSpecContext DSContext,
2337*f4a2713aSLionel Sambuc                                               LateParsedAttrList *LateAttrs) {
2338*f4a2713aSLionel Sambuc   assert(DS.hasTagDefinition() && "shouldn't call this");
2339*f4a2713aSLionel Sambuc 
2340*f4a2713aSLionel Sambuc   bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2341*f4a2713aSLionel Sambuc   bool HasMissingSemi = false;
2342*f4a2713aSLionel Sambuc 
2343*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus &&
2344*f4a2713aSLionel Sambuc       (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
2345*f4a2713aSLionel Sambuc        Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) &&
2346*f4a2713aSLionel Sambuc       TryAnnotateCXXScopeToken(EnteringContext)) {
2347*f4a2713aSLionel Sambuc     SkipMalformedDecl();
2348*f4a2713aSLionel Sambuc     return true;
2349*f4a2713aSLionel Sambuc   }
2350*f4a2713aSLionel Sambuc 
2351*f4a2713aSLionel Sambuc   // Determine whether the following tokens could possibly be a
2352*f4a2713aSLionel Sambuc   // declarator.
2353*f4a2713aSLionel Sambuc   if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
2354*f4a2713aSLionel Sambuc     const Token &Next = NextToken();
2355*f4a2713aSLionel Sambuc     // These tokens cannot come after the declarator-id in a
2356*f4a2713aSLionel Sambuc     // simple-declaration, and are likely to come after a type-specifier.
2357*f4a2713aSLionel Sambuc     HasMissingSemi = Next.is(tok::star) || Next.is(tok::amp) ||
2358*f4a2713aSLionel Sambuc                      Next.is(tok::ampamp) || Next.is(tok::identifier) ||
2359*f4a2713aSLionel Sambuc                      Next.is(tok::annot_cxxscope) ||
2360*f4a2713aSLionel Sambuc                      Next.is(tok::coloncolon);
2361*f4a2713aSLionel Sambuc   } else if (Tok.is(tok::annot_cxxscope) &&
2362*f4a2713aSLionel Sambuc              NextToken().is(tok::identifier) &&
2363*f4a2713aSLionel Sambuc              DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
2364*f4a2713aSLionel Sambuc     // We almost certainly have a missing semicolon. Look up the name and
2365*f4a2713aSLionel Sambuc     // check; if it names a type, we're missing a semicolon.
2366*f4a2713aSLionel Sambuc     CXXScopeSpec SS;
2367*f4a2713aSLionel Sambuc     Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2368*f4a2713aSLionel Sambuc                                                  Tok.getAnnotationRange(), SS);
2369*f4a2713aSLionel Sambuc     const Token &Next = NextToken();
2370*f4a2713aSLionel Sambuc     IdentifierInfo *Name = Next.getIdentifierInfo();
2371*f4a2713aSLionel Sambuc     Sema::NameClassification Classification =
2372*f4a2713aSLionel Sambuc         Actions.ClassifyName(getCurScope(), SS, Name, Next.getLocation(),
2373*f4a2713aSLionel Sambuc                              NextToken(), /*IsAddressOfOperand*/false);
2374*f4a2713aSLionel Sambuc     switch (Classification.getKind()) {
2375*f4a2713aSLionel Sambuc     case Sema::NC_Error:
2376*f4a2713aSLionel Sambuc       SkipMalformedDecl();
2377*f4a2713aSLionel Sambuc       return true;
2378*f4a2713aSLionel Sambuc 
2379*f4a2713aSLionel Sambuc     case Sema::NC_Keyword:
2380*f4a2713aSLionel Sambuc     case Sema::NC_NestedNameSpecifier:
2381*f4a2713aSLionel Sambuc       llvm_unreachable("typo correction and nested name specifiers not "
2382*f4a2713aSLionel Sambuc                        "possible here");
2383*f4a2713aSLionel Sambuc 
2384*f4a2713aSLionel Sambuc     case Sema::NC_Type:
2385*f4a2713aSLionel Sambuc     case Sema::NC_TypeTemplate:
2386*f4a2713aSLionel Sambuc       // Not a previously-declared non-type entity.
2387*f4a2713aSLionel Sambuc       HasMissingSemi = true;
2388*f4a2713aSLionel Sambuc       break;
2389*f4a2713aSLionel Sambuc 
2390*f4a2713aSLionel Sambuc     case Sema::NC_Unknown:
2391*f4a2713aSLionel Sambuc     case Sema::NC_Expression:
2392*f4a2713aSLionel Sambuc     case Sema::NC_VarTemplate:
2393*f4a2713aSLionel Sambuc     case Sema::NC_FunctionTemplate:
2394*f4a2713aSLionel Sambuc       // Might be a redeclaration of a prior entity.
2395*f4a2713aSLionel Sambuc       HasMissingSemi = false;
2396*f4a2713aSLionel Sambuc       break;
2397*f4a2713aSLionel Sambuc     }
2398*f4a2713aSLionel Sambuc   } else if (Tok.is(tok::kw_typename) || Tok.is(tok::annot_typename)) {
2399*f4a2713aSLionel Sambuc     HasMissingSemi = true;
2400*f4a2713aSLionel Sambuc   }
2401*f4a2713aSLionel Sambuc 
2402*f4a2713aSLionel Sambuc   if (!HasMissingSemi)
2403*f4a2713aSLionel Sambuc     return false;
2404*f4a2713aSLionel Sambuc 
2405*f4a2713aSLionel Sambuc   Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getLocEnd()),
2406*f4a2713aSLionel Sambuc        diag::err_expected_semi_after_tagdecl)
2407*f4a2713aSLionel Sambuc     << DeclSpec::getSpecifierName(DS.getTypeSpecType());
2408*f4a2713aSLionel Sambuc 
2409*f4a2713aSLionel Sambuc   // Try to recover from the typo, by dropping the tag definition and parsing
2410*f4a2713aSLionel Sambuc   // the problematic tokens as a type.
2411*f4a2713aSLionel Sambuc   //
2412*f4a2713aSLionel Sambuc   // FIXME: Split the DeclSpec into pieces for the standalone
2413*f4a2713aSLionel Sambuc   // declaration and pieces for the following declaration, instead
2414*f4a2713aSLionel Sambuc   // of assuming that all the other pieces attach to new declaration,
2415*f4a2713aSLionel Sambuc   // and call ParsedFreeStandingDeclSpec as appropriate.
2416*f4a2713aSLionel Sambuc   DS.ClearTypeSpecType();
2417*f4a2713aSLionel Sambuc   ParsedTemplateInfo NotATemplate;
2418*f4a2713aSLionel Sambuc   ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
2419*f4a2713aSLionel Sambuc   return false;
2420*f4a2713aSLionel Sambuc }
2421*f4a2713aSLionel Sambuc 
2422*f4a2713aSLionel Sambuc /// ParseDeclarationSpecifiers
2423*f4a2713aSLionel Sambuc ///       declaration-specifiers: [C99 6.7]
2424*f4a2713aSLionel Sambuc ///         storage-class-specifier declaration-specifiers[opt]
2425*f4a2713aSLionel Sambuc ///         type-specifier declaration-specifiers[opt]
2426*f4a2713aSLionel Sambuc /// [C99]   function-specifier declaration-specifiers[opt]
2427*f4a2713aSLionel Sambuc /// [C11]   alignment-specifier declaration-specifiers[opt]
2428*f4a2713aSLionel Sambuc /// [GNU]   attributes declaration-specifiers[opt]
2429*f4a2713aSLionel Sambuc /// [Clang] '__module_private__' declaration-specifiers[opt]
2430*f4a2713aSLionel Sambuc ///
2431*f4a2713aSLionel Sambuc ///       storage-class-specifier: [C99 6.7.1]
2432*f4a2713aSLionel Sambuc ///         'typedef'
2433*f4a2713aSLionel Sambuc ///         'extern'
2434*f4a2713aSLionel Sambuc ///         'static'
2435*f4a2713aSLionel Sambuc ///         'auto'
2436*f4a2713aSLionel Sambuc ///         'register'
2437*f4a2713aSLionel Sambuc /// [C++]   'mutable'
2438*f4a2713aSLionel Sambuc /// [C++11] 'thread_local'
2439*f4a2713aSLionel Sambuc /// [C11]   '_Thread_local'
2440*f4a2713aSLionel Sambuc /// [GNU]   '__thread'
2441*f4a2713aSLionel Sambuc ///       function-specifier: [C99 6.7.4]
2442*f4a2713aSLionel Sambuc /// [C99]   'inline'
2443*f4a2713aSLionel Sambuc /// [C++]   'virtual'
2444*f4a2713aSLionel Sambuc /// [C++]   'explicit'
2445*f4a2713aSLionel Sambuc /// [OpenCL] '__kernel'
2446*f4a2713aSLionel Sambuc ///       'friend': [C++ dcl.friend]
2447*f4a2713aSLionel Sambuc ///       'constexpr': [C++0x dcl.constexpr]
2448*f4a2713aSLionel Sambuc 
2449*f4a2713aSLionel Sambuc ///
2450*f4a2713aSLionel Sambuc void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
2451*f4a2713aSLionel Sambuc                                         const ParsedTemplateInfo &TemplateInfo,
2452*f4a2713aSLionel Sambuc                                         AccessSpecifier AS,
2453*f4a2713aSLionel Sambuc                                         DeclSpecContext DSContext,
2454*f4a2713aSLionel Sambuc                                         LateParsedAttrList *LateAttrs) {
2455*f4a2713aSLionel Sambuc   if (DS.getSourceRange().isInvalid()) {
2456*f4a2713aSLionel Sambuc     DS.SetRangeStart(Tok.getLocation());
2457*f4a2713aSLionel Sambuc     DS.SetRangeEnd(Tok.getLocation());
2458*f4a2713aSLionel Sambuc   }
2459*f4a2713aSLionel Sambuc 
2460*f4a2713aSLionel Sambuc   bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
2461*f4a2713aSLionel Sambuc   bool AttrsLastTime = false;
2462*f4a2713aSLionel Sambuc   ParsedAttributesWithRange attrs(AttrFactory);
2463*f4a2713aSLionel Sambuc   while (1) {
2464*f4a2713aSLionel Sambuc     bool isInvalid = false;
2465*f4a2713aSLionel Sambuc     const char *PrevSpec = 0;
2466*f4a2713aSLionel Sambuc     unsigned DiagID = 0;
2467*f4a2713aSLionel Sambuc 
2468*f4a2713aSLionel Sambuc     SourceLocation Loc = Tok.getLocation();
2469*f4a2713aSLionel Sambuc 
2470*f4a2713aSLionel Sambuc     switch (Tok.getKind()) {
2471*f4a2713aSLionel Sambuc     default:
2472*f4a2713aSLionel Sambuc     DoneWithDeclSpec:
2473*f4a2713aSLionel Sambuc       if (!AttrsLastTime)
2474*f4a2713aSLionel Sambuc         ProhibitAttributes(attrs);
2475*f4a2713aSLionel Sambuc       else {
2476*f4a2713aSLionel Sambuc         // Reject C++11 attributes that appertain to decl specifiers as
2477*f4a2713aSLionel Sambuc         // we don't support any C++11 attributes that appertain to decl
2478*f4a2713aSLionel Sambuc         // specifiers. This also conforms to what g++ 4.8 is doing.
2479*f4a2713aSLionel Sambuc         ProhibitCXX11Attributes(attrs);
2480*f4a2713aSLionel Sambuc 
2481*f4a2713aSLionel Sambuc         DS.takeAttributesFrom(attrs);
2482*f4a2713aSLionel Sambuc       }
2483*f4a2713aSLionel Sambuc 
2484*f4a2713aSLionel Sambuc       // If this is not a declaration specifier token, we're done reading decl
2485*f4a2713aSLionel Sambuc       // specifiers.  First verify that DeclSpec's are consistent.
2486*f4a2713aSLionel Sambuc       DS.Finish(Diags, PP);
2487*f4a2713aSLionel Sambuc       return;
2488*f4a2713aSLionel Sambuc 
2489*f4a2713aSLionel Sambuc     case tok::l_square:
2490*f4a2713aSLionel Sambuc     case tok::kw_alignas:
2491*f4a2713aSLionel Sambuc       if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier())
2492*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2493*f4a2713aSLionel Sambuc 
2494*f4a2713aSLionel Sambuc       ProhibitAttributes(attrs);
2495*f4a2713aSLionel Sambuc       // FIXME: It would be good to recover by accepting the attributes,
2496*f4a2713aSLionel Sambuc       //        but attempting to do that now would cause serious
2497*f4a2713aSLionel Sambuc       //        madness in terms of diagnostics.
2498*f4a2713aSLionel Sambuc       attrs.clear();
2499*f4a2713aSLionel Sambuc       attrs.Range = SourceRange();
2500*f4a2713aSLionel Sambuc 
2501*f4a2713aSLionel Sambuc       ParseCXX11Attributes(attrs);
2502*f4a2713aSLionel Sambuc       AttrsLastTime = true;
2503*f4a2713aSLionel Sambuc       continue;
2504*f4a2713aSLionel Sambuc 
2505*f4a2713aSLionel Sambuc     case tok::code_completion: {
2506*f4a2713aSLionel Sambuc       Sema::ParserCompletionContext CCC = Sema::PCC_Namespace;
2507*f4a2713aSLionel Sambuc       if (DS.hasTypeSpecifier()) {
2508*f4a2713aSLionel Sambuc         bool AllowNonIdentifiers
2509*f4a2713aSLionel Sambuc           = (getCurScope()->getFlags() & (Scope::ControlScope |
2510*f4a2713aSLionel Sambuc                                           Scope::BlockScope |
2511*f4a2713aSLionel Sambuc                                           Scope::TemplateParamScope |
2512*f4a2713aSLionel Sambuc                                           Scope::FunctionPrototypeScope |
2513*f4a2713aSLionel Sambuc                                           Scope::AtCatchScope)) == 0;
2514*f4a2713aSLionel Sambuc         bool AllowNestedNameSpecifiers
2515*f4a2713aSLionel Sambuc           = DSContext == DSC_top_level ||
2516*f4a2713aSLionel Sambuc             (DSContext == DSC_class && DS.isFriendSpecified());
2517*f4a2713aSLionel Sambuc 
2518*f4a2713aSLionel Sambuc         Actions.CodeCompleteDeclSpec(getCurScope(), DS,
2519*f4a2713aSLionel Sambuc                                      AllowNonIdentifiers,
2520*f4a2713aSLionel Sambuc                                      AllowNestedNameSpecifiers);
2521*f4a2713aSLionel Sambuc         return cutOffParsing();
2522*f4a2713aSLionel Sambuc       }
2523*f4a2713aSLionel Sambuc 
2524*f4a2713aSLionel Sambuc       if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
2525*f4a2713aSLionel Sambuc         CCC = Sema::PCC_LocalDeclarationSpecifiers;
2526*f4a2713aSLionel Sambuc       else if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
2527*f4a2713aSLionel Sambuc         CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate
2528*f4a2713aSLionel Sambuc                                     : Sema::PCC_Template;
2529*f4a2713aSLionel Sambuc       else if (DSContext == DSC_class)
2530*f4a2713aSLionel Sambuc         CCC = Sema::PCC_Class;
2531*f4a2713aSLionel Sambuc       else if (CurParsedObjCImpl)
2532*f4a2713aSLionel Sambuc         CCC = Sema::PCC_ObjCImplementation;
2533*f4a2713aSLionel Sambuc 
2534*f4a2713aSLionel Sambuc       Actions.CodeCompleteOrdinaryName(getCurScope(), CCC);
2535*f4a2713aSLionel Sambuc       return cutOffParsing();
2536*f4a2713aSLionel Sambuc     }
2537*f4a2713aSLionel Sambuc 
2538*f4a2713aSLionel Sambuc     case tok::coloncolon: // ::foo::bar
2539*f4a2713aSLionel Sambuc       // C++ scope specifier.  Annotate and loop, or bail out on error.
2540*f4a2713aSLionel Sambuc       if (TryAnnotateCXXScopeToken(EnteringContext)) {
2541*f4a2713aSLionel Sambuc         if (!DS.hasTypeSpecifier())
2542*f4a2713aSLionel Sambuc           DS.SetTypeSpecError();
2543*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2544*f4a2713aSLionel Sambuc       }
2545*f4a2713aSLionel Sambuc       if (Tok.is(tok::coloncolon)) // ::new or ::delete
2546*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2547*f4a2713aSLionel Sambuc       continue;
2548*f4a2713aSLionel Sambuc 
2549*f4a2713aSLionel Sambuc     case tok::annot_cxxscope: {
2550*f4a2713aSLionel Sambuc       if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
2551*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2552*f4a2713aSLionel Sambuc 
2553*f4a2713aSLionel Sambuc       CXXScopeSpec SS;
2554*f4a2713aSLionel Sambuc       Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
2555*f4a2713aSLionel Sambuc                                                    Tok.getAnnotationRange(),
2556*f4a2713aSLionel Sambuc                                                    SS);
2557*f4a2713aSLionel Sambuc 
2558*f4a2713aSLionel Sambuc       // We are looking for a qualified typename.
2559*f4a2713aSLionel Sambuc       Token Next = NextToken();
2560*f4a2713aSLionel Sambuc       if (Next.is(tok::annot_template_id) &&
2561*f4a2713aSLionel Sambuc           static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
2562*f4a2713aSLionel Sambuc             ->Kind == TNK_Type_template) {
2563*f4a2713aSLionel Sambuc         // We have a qualified template-id, e.g., N::A<int>
2564*f4a2713aSLionel Sambuc 
2565*f4a2713aSLionel Sambuc         // C++ [class.qual]p2:
2566*f4a2713aSLionel Sambuc         //   In a lookup in which the constructor is an acceptable lookup
2567*f4a2713aSLionel Sambuc         //   result and the nested-name-specifier nominates a class C:
2568*f4a2713aSLionel Sambuc         //
2569*f4a2713aSLionel Sambuc         //     - if the name specified after the
2570*f4a2713aSLionel Sambuc         //       nested-name-specifier, when looked up in C, is the
2571*f4a2713aSLionel Sambuc         //       injected-class-name of C (Clause 9), or
2572*f4a2713aSLionel Sambuc         //
2573*f4a2713aSLionel Sambuc         //     - if the name specified after the nested-name-specifier
2574*f4a2713aSLionel Sambuc         //       is the same as the identifier or the
2575*f4a2713aSLionel Sambuc         //       simple-template-id's template-name in the last
2576*f4a2713aSLionel Sambuc         //       component of the nested-name-specifier,
2577*f4a2713aSLionel Sambuc         //
2578*f4a2713aSLionel Sambuc         //   the name is instead considered to name the constructor of
2579*f4a2713aSLionel Sambuc         //   class C.
2580*f4a2713aSLionel Sambuc         //
2581*f4a2713aSLionel Sambuc         // Thus, if the template-name is actually the constructor
2582*f4a2713aSLionel Sambuc         // name, then the code is ill-formed; this interpretation is
2583*f4a2713aSLionel Sambuc         // reinforced by the NAD status of core issue 635.
2584*f4a2713aSLionel Sambuc         TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next);
2585*f4a2713aSLionel Sambuc         if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
2586*f4a2713aSLionel Sambuc             TemplateId->Name &&
2587*f4a2713aSLionel Sambuc             Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
2588*f4a2713aSLionel Sambuc           if (isConstructorDeclarator()) {
2589*f4a2713aSLionel Sambuc             // The user meant this to be an out-of-line constructor
2590*f4a2713aSLionel Sambuc             // definition, but template arguments are not allowed
2591*f4a2713aSLionel Sambuc             // there.  Just allow this as a constructor; we'll
2592*f4a2713aSLionel Sambuc             // complain about it later.
2593*f4a2713aSLionel Sambuc             goto DoneWithDeclSpec;
2594*f4a2713aSLionel Sambuc           }
2595*f4a2713aSLionel Sambuc 
2596*f4a2713aSLionel Sambuc           // The user meant this to name a type, but it actually names
2597*f4a2713aSLionel Sambuc           // a constructor with some extraneous template
2598*f4a2713aSLionel Sambuc           // arguments. Complain, then parse it as a type as the user
2599*f4a2713aSLionel Sambuc           // intended.
2600*f4a2713aSLionel Sambuc           Diag(TemplateId->TemplateNameLoc,
2601*f4a2713aSLionel Sambuc                diag::err_out_of_line_template_id_names_constructor)
2602*f4a2713aSLionel Sambuc             << TemplateId->Name;
2603*f4a2713aSLionel Sambuc         }
2604*f4a2713aSLionel Sambuc 
2605*f4a2713aSLionel Sambuc         DS.getTypeSpecScope() = SS;
2606*f4a2713aSLionel Sambuc         ConsumeToken(); // The C++ scope.
2607*f4a2713aSLionel Sambuc         assert(Tok.is(tok::annot_template_id) &&
2608*f4a2713aSLionel Sambuc                "ParseOptionalCXXScopeSpecifier not working");
2609*f4a2713aSLionel Sambuc         AnnotateTemplateIdTokenAsType();
2610*f4a2713aSLionel Sambuc         continue;
2611*f4a2713aSLionel Sambuc       }
2612*f4a2713aSLionel Sambuc 
2613*f4a2713aSLionel Sambuc       if (Next.is(tok::annot_typename)) {
2614*f4a2713aSLionel Sambuc         DS.getTypeSpecScope() = SS;
2615*f4a2713aSLionel Sambuc         ConsumeToken(); // The C++ scope.
2616*f4a2713aSLionel Sambuc         if (Tok.getAnnotationValue()) {
2617*f4a2713aSLionel Sambuc           ParsedType T = getTypeAnnotation(Tok);
2618*f4a2713aSLionel Sambuc           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
2619*f4a2713aSLionel Sambuc                                          Tok.getAnnotationEndLoc(),
2620*f4a2713aSLionel Sambuc                                          PrevSpec, DiagID, T);
2621*f4a2713aSLionel Sambuc           if (isInvalid)
2622*f4a2713aSLionel Sambuc             break;
2623*f4a2713aSLionel Sambuc         }
2624*f4a2713aSLionel Sambuc         else
2625*f4a2713aSLionel Sambuc           DS.SetTypeSpecError();
2626*f4a2713aSLionel Sambuc         DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2627*f4a2713aSLionel Sambuc         ConsumeToken(); // The typename
2628*f4a2713aSLionel Sambuc       }
2629*f4a2713aSLionel Sambuc 
2630*f4a2713aSLionel Sambuc       if (Next.isNot(tok::identifier))
2631*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2632*f4a2713aSLionel Sambuc 
2633*f4a2713aSLionel Sambuc       // If we're in a context where the identifier could be a class name,
2634*f4a2713aSLionel Sambuc       // check whether this is a constructor declaration.
2635*f4a2713aSLionel Sambuc       if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
2636*f4a2713aSLionel Sambuc           Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
2637*f4a2713aSLionel Sambuc                                      &SS)) {
2638*f4a2713aSLionel Sambuc         if (isConstructorDeclarator())
2639*f4a2713aSLionel Sambuc           goto DoneWithDeclSpec;
2640*f4a2713aSLionel Sambuc 
2641*f4a2713aSLionel Sambuc         // As noted in C++ [class.qual]p2 (cited above), when the name
2642*f4a2713aSLionel Sambuc         // of the class is qualified in a context where it could name
2643*f4a2713aSLionel Sambuc         // a constructor, its a constructor name. However, we've
2644*f4a2713aSLionel Sambuc         // looked at the declarator, and the user probably meant this
2645*f4a2713aSLionel Sambuc         // to be a type. Complain that it isn't supposed to be treated
2646*f4a2713aSLionel Sambuc         // as a type, then proceed to parse it as a type.
2647*f4a2713aSLionel Sambuc         Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor)
2648*f4a2713aSLionel Sambuc           << Next.getIdentifierInfo();
2649*f4a2713aSLionel Sambuc       }
2650*f4a2713aSLionel Sambuc 
2651*f4a2713aSLionel Sambuc       ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
2652*f4a2713aSLionel Sambuc                                                Next.getLocation(),
2653*f4a2713aSLionel Sambuc                                                getCurScope(), &SS,
2654*f4a2713aSLionel Sambuc                                                false, false, ParsedType(),
2655*f4a2713aSLionel Sambuc                                                /*IsCtorOrDtorName=*/false,
2656*f4a2713aSLionel Sambuc                                                /*NonTrivialSourceInfo=*/true);
2657*f4a2713aSLionel Sambuc 
2658*f4a2713aSLionel Sambuc       // If the referenced identifier is not a type, then this declspec is
2659*f4a2713aSLionel Sambuc       // erroneous: We already checked about that it has no type specifier, and
2660*f4a2713aSLionel Sambuc       // C++ doesn't have implicit int.  Diagnose it as a typo w.r.t. to the
2661*f4a2713aSLionel Sambuc       // typename.
2662*f4a2713aSLionel Sambuc       if (!TypeRep) {
2663*f4a2713aSLionel Sambuc         ConsumeToken();   // Eat the scope spec so the identifier is current.
2664*f4a2713aSLionel Sambuc         ParsedAttributesWithRange Attrs(AttrFactory);
2665*f4a2713aSLionel Sambuc         if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
2666*f4a2713aSLionel Sambuc           if (!Attrs.empty()) {
2667*f4a2713aSLionel Sambuc             AttrsLastTime = true;
2668*f4a2713aSLionel Sambuc             attrs.takeAllFrom(Attrs);
2669*f4a2713aSLionel Sambuc           }
2670*f4a2713aSLionel Sambuc           continue;
2671*f4a2713aSLionel Sambuc         }
2672*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2673*f4a2713aSLionel Sambuc       }
2674*f4a2713aSLionel Sambuc 
2675*f4a2713aSLionel Sambuc       DS.getTypeSpecScope() = SS;
2676*f4a2713aSLionel Sambuc       ConsumeToken(); // The C++ scope.
2677*f4a2713aSLionel Sambuc 
2678*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2679*f4a2713aSLionel Sambuc                                      DiagID, TypeRep);
2680*f4a2713aSLionel Sambuc       if (isInvalid)
2681*f4a2713aSLionel Sambuc         break;
2682*f4a2713aSLionel Sambuc 
2683*f4a2713aSLionel Sambuc       DS.SetRangeEnd(Tok.getLocation());
2684*f4a2713aSLionel Sambuc       ConsumeToken(); // The typename.
2685*f4a2713aSLionel Sambuc 
2686*f4a2713aSLionel Sambuc       continue;
2687*f4a2713aSLionel Sambuc     }
2688*f4a2713aSLionel Sambuc 
2689*f4a2713aSLionel Sambuc     case tok::annot_typename: {
2690*f4a2713aSLionel Sambuc       // If we've previously seen a tag definition, we were almost surely
2691*f4a2713aSLionel Sambuc       // missing a semicolon after it.
2692*f4a2713aSLionel Sambuc       if (DS.hasTypeSpecifier() && DS.hasTagDefinition())
2693*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2694*f4a2713aSLionel Sambuc 
2695*f4a2713aSLionel Sambuc       if (Tok.getAnnotationValue()) {
2696*f4a2713aSLionel Sambuc         ParsedType T = getTypeAnnotation(Tok);
2697*f4a2713aSLionel Sambuc         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2698*f4a2713aSLionel Sambuc                                        DiagID, T);
2699*f4a2713aSLionel Sambuc       } else
2700*f4a2713aSLionel Sambuc         DS.SetTypeSpecError();
2701*f4a2713aSLionel Sambuc 
2702*f4a2713aSLionel Sambuc       if (isInvalid)
2703*f4a2713aSLionel Sambuc         break;
2704*f4a2713aSLionel Sambuc 
2705*f4a2713aSLionel Sambuc       DS.SetRangeEnd(Tok.getAnnotationEndLoc());
2706*f4a2713aSLionel Sambuc       ConsumeToken(); // The typename
2707*f4a2713aSLionel Sambuc 
2708*f4a2713aSLionel Sambuc       // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2709*f4a2713aSLionel Sambuc       // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
2710*f4a2713aSLionel Sambuc       // Objective-C interface.
2711*f4a2713aSLionel Sambuc       if (Tok.is(tok::less) && getLangOpts().ObjC1)
2712*f4a2713aSLionel Sambuc         ParseObjCProtocolQualifiers(DS);
2713*f4a2713aSLionel Sambuc 
2714*f4a2713aSLionel Sambuc       continue;
2715*f4a2713aSLionel Sambuc     }
2716*f4a2713aSLionel Sambuc 
2717*f4a2713aSLionel Sambuc     case tok::kw___is_signed:
2718*f4a2713aSLionel Sambuc       // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
2719*f4a2713aSLionel Sambuc       // typically treats it as a trait. If we see __is_signed as it appears
2720*f4a2713aSLionel Sambuc       // in libstdc++, e.g.,
2721*f4a2713aSLionel Sambuc       //
2722*f4a2713aSLionel Sambuc       //   static const bool __is_signed;
2723*f4a2713aSLionel Sambuc       //
2724*f4a2713aSLionel Sambuc       // then treat __is_signed as an identifier rather than as a keyword.
2725*f4a2713aSLionel Sambuc       if (DS.getTypeSpecType() == TST_bool &&
2726*f4a2713aSLionel Sambuc           DS.getTypeQualifiers() == DeclSpec::TQ_const &&
2727*f4a2713aSLionel Sambuc           DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2728*f4a2713aSLionel Sambuc         Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
2729*f4a2713aSLionel Sambuc         Tok.setKind(tok::identifier);
2730*f4a2713aSLionel Sambuc       }
2731*f4a2713aSLionel Sambuc 
2732*f4a2713aSLionel Sambuc       // We're done with the declaration-specifiers.
2733*f4a2713aSLionel Sambuc       goto DoneWithDeclSpec;
2734*f4a2713aSLionel Sambuc 
2735*f4a2713aSLionel Sambuc       // typedef-name
2736*f4a2713aSLionel Sambuc     case tok::kw_decltype:
2737*f4a2713aSLionel Sambuc     case tok::identifier: {
2738*f4a2713aSLionel Sambuc       // In C++, check to see if this is a scope specifier like foo::bar::, if
2739*f4a2713aSLionel Sambuc       // so handle it as such.  This is important for ctor parsing.
2740*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus) {
2741*f4a2713aSLionel Sambuc         if (TryAnnotateCXXScopeToken(EnteringContext)) {
2742*f4a2713aSLionel Sambuc           if (!DS.hasTypeSpecifier())
2743*f4a2713aSLionel Sambuc             DS.SetTypeSpecError();
2744*f4a2713aSLionel Sambuc           goto DoneWithDeclSpec;
2745*f4a2713aSLionel Sambuc         }
2746*f4a2713aSLionel Sambuc         if (!Tok.is(tok::identifier))
2747*f4a2713aSLionel Sambuc           continue;
2748*f4a2713aSLionel Sambuc       }
2749*f4a2713aSLionel Sambuc 
2750*f4a2713aSLionel Sambuc       // This identifier can only be a typedef name if we haven't already seen
2751*f4a2713aSLionel Sambuc       // a type-specifier.  Without this check we misparse:
2752*f4a2713aSLionel Sambuc       //  typedef int X; struct Y { short X; };  as 'short int'.
2753*f4a2713aSLionel Sambuc       if (DS.hasTypeSpecifier())
2754*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2755*f4a2713aSLionel Sambuc 
2756*f4a2713aSLionel Sambuc       // Check for need to substitute AltiVec keyword tokens.
2757*f4a2713aSLionel Sambuc       if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
2758*f4a2713aSLionel Sambuc         break;
2759*f4a2713aSLionel Sambuc 
2760*f4a2713aSLionel Sambuc       // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
2761*f4a2713aSLionel Sambuc       //                allow the use of a typedef name as a type specifier.
2762*f4a2713aSLionel Sambuc       if (DS.isTypeAltiVecVector())
2763*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2764*f4a2713aSLionel Sambuc 
2765*f4a2713aSLionel Sambuc       ParsedType TypeRep =
2766*f4a2713aSLionel Sambuc         Actions.getTypeName(*Tok.getIdentifierInfo(),
2767*f4a2713aSLionel Sambuc                             Tok.getLocation(), getCurScope());
2768*f4a2713aSLionel Sambuc 
2769*f4a2713aSLionel Sambuc       // If this is not a typedef name, don't parse it as part of the declspec,
2770*f4a2713aSLionel Sambuc       // it must be an implicit int or an error.
2771*f4a2713aSLionel Sambuc       if (!TypeRep) {
2772*f4a2713aSLionel Sambuc         ParsedAttributesWithRange Attrs(AttrFactory);
2773*f4a2713aSLionel Sambuc         if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) {
2774*f4a2713aSLionel Sambuc           if (!Attrs.empty()) {
2775*f4a2713aSLionel Sambuc             AttrsLastTime = true;
2776*f4a2713aSLionel Sambuc             attrs.takeAllFrom(Attrs);
2777*f4a2713aSLionel Sambuc           }
2778*f4a2713aSLionel Sambuc           continue;
2779*f4a2713aSLionel Sambuc         }
2780*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2781*f4a2713aSLionel Sambuc       }
2782*f4a2713aSLionel Sambuc 
2783*f4a2713aSLionel Sambuc       // If we're in a context where the identifier could be a class name,
2784*f4a2713aSLionel Sambuc       // check whether this is a constructor declaration.
2785*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
2786*f4a2713aSLionel Sambuc           Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
2787*f4a2713aSLionel Sambuc           isConstructorDeclarator())
2788*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2789*f4a2713aSLionel Sambuc 
2790*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
2791*f4a2713aSLionel Sambuc                                      DiagID, TypeRep);
2792*f4a2713aSLionel Sambuc       if (isInvalid)
2793*f4a2713aSLionel Sambuc         break;
2794*f4a2713aSLionel Sambuc 
2795*f4a2713aSLionel Sambuc       DS.SetRangeEnd(Tok.getLocation());
2796*f4a2713aSLionel Sambuc       ConsumeToken(); // The identifier
2797*f4a2713aSLionel Sambuc 
2798*f4a2713aSLionel Sambuc       // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
2799*f4a2713aSLionel Sambuc       // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
2800*f4a2713aSLionel Sambuc       // Objective-C interface.
2801*f4a2713aSLionel Sambuc       if (Tok.is(tok::less) && getLangOpts().ObjC1)
2802*f4a2713aSLionel Sambuc         ParseObjCProtocolQualifiers(DS);
2803*f4a2713aSLionel Sambuc 
2804*f4a2713aSLionel Sambuc       // Need to support trailing type qualifiers (e.g. "id<p> const").
2805*f4a2713aSLionel Sambuc       // If a type specifier follows, it will be diagnosed elsewhere.
2806*f4a2713aSLionel Sambuc       continue;
2807*f4a2713aSLionel Sambuc     }
2808*f4a2713aSLionel Sambuc 
2809*f4a2713aSLionel Sambuc       // type-name
2810*f4a2713aSLionel Sambuc     case tok::annot_template_id: {
2811*f4a2713aSLionel Sambuc       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2812*f4a2713aSLionel Sambuc       if (TemplateId->Kind != TNK_Type_template) {
2813*f4a2713aSLionel Sambuc         // This template-id does not refer to a type name, so we're
2814*f4a2713aSLionel Sambuc         // done with the type-specifiers.
2815*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2816*f4a2713aSLionel Sambuc       }
2817*f4a2713aSLionel Sambuc 
2818*f4a2713aSLionel Sambuc       // If we're in a context where the template-id could be a
2819*f4a2713aSLionel Sambuc       // constructor name or specialization, check whether this is a
2820*f4a2713aSLionel Sambuc       // constructor declaration.
2821*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
2822*f4a2713aSLionel Sambuc           Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
2823*f4a2713aSLionel Sambuc           isConstructorDeclarator())
2824*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
2825*f4a2713aSLionel Sambuc 
2826*f4a2713aSLionel Sambuc       // Turn the template-id annotation token into a type annotation
2827*f4a2713aSLionel Sambuc       // token, then try again to parse it as a type-specifier.
2828*f4a2713aSLionel Sambuc       AnnotateTemplateIdTokenAsType();
2829*f4a2713aSLionel Sambuc       continue;
2830*f4a2713aSLionel Sambuc     }
2831*f4a2713aSLionel Sambuc 
2832*f4a2713aSLionel Sambuc     // GNU attributes support.
2833*f4a2713aSLionel Sambuc     case tok::kw___attribute:
2834*f4a2713aSLionel Sambuc       ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
2835*f4a2713aSLionel Sambuc       continue;
2836*f4a2713aSLionel Sambuc 
2837*f4a2713aSLionel Sambuc     // Microsoft declspec support.
2838*f4a2713aSLionel Sambuc     case tok::kw___declspec:
2839*f4a2713aSLionel Sambuc       ParseMicrosoftDeclSpec(DS.getAttributes());
2840*f4a2713aSLionel Sambuc       continue;
2841*f4a2713aSLionel Sambuc 
2842*f4a2713aSLionel Sambuc     // Microsoft single token adornments.
2843*f4a2713aSLionel Sambuc     case tok::kw___forceinline: {
2844*f4a2713aSLionel Sambuc       isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID);
2845*f4a2713aSLionel Sambuc       IdentifierInfo *AttrName = Tok.getIdentifierInfo();
2846*f4a2713aSLionel Sambuc       SourceLocation AttrNameLoc = Tok.getLocation();
2847*f4a2713aSLionel Sambuc       // FIXME: This does not work correctly if it is set to be a declspec
2848*f4a2713aSLionel Sambuc       //        attribute, and a GNU attribute is simply incorrect.
2849*f4a2713aSLionel Sambuc       DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
2850*f4a2713aSLionel Sambuc                                 AttributeList::AS_GNU);
2851*f4a2713aSLionel Sambuc       break;
2852*f4a2713aSLionel Sambuc     }
2853*f4a2713aSLionel Sambuc 
2854*f4a2713aSLionel Sambuc     case tok::kw___sptr:
2855*f4a2713aSLionel Sambuc     case tok::kw___uptr:
2856*f4a2713aSLionel Sambuc     case tok::kw___ptr64:
2857*f4a2713aSLionel Sambuc     case tok::kw___ptr32:
2858*f4a2713aSLionel Sambuc     case tok::kw___w64:
2859*f4a2713aSLionel Sambuc     case tok::kw___cdecl:
2860*f4a2713aSLionel Sambuc     case tok::kw___stdcall:
2861*f4a2713aSLionel Sambuc     case tok::kw___fastcall:
2862*f4a2713aSLionel Sambuc     case tok::kw___thiscall:
2863*f4a2713aSLionel Sambuc     case tok::kw___unaligned:
2864*f4a2713aSLionel Sambuc       ParseMicrosoftTypeAttributes(DS.getAttributes());
2865*f4a2713aSLionel Sambuc       continue;
2866*f4a2713aSLionel Sambuc 
2867*f4a2713aSLionel Sambuc     // Borland single token adornments.
2868*f4a2713aSLionel Sambuc     case tok::kw___pascal:
2869*f4a2713aSLionel Sambuc       ParseBorlandTypeAttributes(DS.getAttributes());
2870*f4a2713aSLionel Sambuc       continue;
2871*f4a2713aSLionel Sambuc 
2872*f4a2713aSLionel Sambuc     // OpenCL single token adornments.
2873*f4a2713aSLionel Sambuc     case tok::kw___kernel:
2874*f4a2713aSLionel Sambuc       ParseOpenCLAttributes(DS.getAttributes());
2875*f4a2713aSLionel Sambuc       continue;
2876*f4a2713aSLionel Sambuc 
2877*f4a2713aSLionel Sambuc     // storage-class-specifier
2878*f4a2713aSLionel Sambuc     case tok::kw_typedef:
2879*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
2880*f4a2713aSLionel Sambuc                                          PrevSpec, DiagID);
2881*f4a2713aSLionel Sambuc       break;
2882*f4a2713aSLionel Sambuc     case tok::kw_extern:
2883*f4a2713aSLionel Sambuc       if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
2884*f4a2713aSLionel Sambuc         Diag(Tok, diag::ext_thread_before) << "extern";
2885*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
2886*f4a2713aSLionel Sambuc                                          PrevSpec, DiagID);
2887*f4a2713aSLionel Sambuc       break;
2888*f4a2713aSLionel Sambuc     case tok::kw___private_extern__:
2889*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
2890*f4a2713aSLionel Sambuc                                          Loc, PrevSpec, DiagID);
2891*f4a2713aSLionel Sambuc       break;
2892*f4a2713aSLionel Sambuc     case tok::kw_static:
2893*f4a2713aSLionel Sambuc       if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
2894*f4a2713aSLionel Sambuc         Diag(Tok, diag::ext_thread_before) << "static";
2895*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
2896*f4a2713aSLionel Sambuc                                          PrevSpec, DiagID);
2897*f4a2713aSLionel Sambuc       break;
2898*f4a2713aSLionel Sambuc     case tok::kw_auto:
2899*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus11) {
2900*f4a2713aSLionel Sambuc         if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
2901*f4a2713aSLionel Sambuc           isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2902*f4a2713aSLionel Sambuc                                              PrevSpec, DiagID);
2903*f4a2713aSLionel Sambuc           if (!isInvalid)
2904*f4a2713aSLionel Sambuc             Diag(Tok, diag::ext_auto_storage_class)
2905*f4a2713aSLionel Sambuc               << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
2906*f4a2713aSLionel Sambuc         } else
2907*f4a2713aSLionel Sambuc           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
2908*f4a2713aSLionel Sambuc                                          DiagID);
2909*f4a2713aSLionel Sambuc       } else
2910*f4a2713aSLionel Sambuc         isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
2911*f4a2713aSLionel Sambuc                                            PrevSpec, DiagID);
2912*f4a2713aSLionel Sambuc       break;
2913*f4a2713aSLionel Sambuc     case tok::kw_register:
2914*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
2915*f4a2713aSLionel Sambuc                                          PrevSpec, DiagID);
2916*f4a2713aSLionel Sambuc       break;
2917*f4a2713aSLionel Sambuc     case tok::kw_mutable:
2918*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
2919*f4a2713aSLionel Sambuc                                          PrevSpec, DiagID);
2920*f4a2713aSLionel Sambuc       break;
2921*f4a2713aSLionel Sambuc     case tok::kw___thread:
2922*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,
2923*f4a2713aSLionel Sambuc                                                PrevSpec, DiagID);
2924*f4a2713aSLionel Sambuc       break;
2925*f4a2713aSLionel Sambuc     case tok::kw_thread_local:
2926*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS_thread_local, Loc,
2927*f4a2713aSLionel Sambuc                                                PrevSpec, DiagID);
2928*f4a2713aSLionel Sambuc       break;
2929*f4a2713aSLionel Sambuc     case tok::kw__Thread_local:
2930*f4a2713aSLionel Sambuc       isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,
2931*f4a2713aSLionel Sambuc                                                Loc, PrevSpec, DiagID);
2932*f4a2713aSLionel Sambuc       break;
2933*f4a2713aSLionel Sambuc 
2934*f4a2713aSLionel Sambuc     // function-specifier
2935*f4a2713aSLionel Sambuc     case tok::kw_inline:
2936*f4a2713aSLionel Sambuc       isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);
2937*f4a2713aSLionel Sambuc       break;
2938*f4a2713aSLionel Sambuc     case tok::kw_virtual:
2939*f4a2713aSLionel Sambuc       isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
2940*f4a2713aSLionel Sambuc       break;
2941*f4a2713aSLionel Sambuc     case tok::kw_explicit:
2942*f4a2713aSLionel Sambuc       isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID);
2943*f4a2713aSLionel Sambuc       break;
2944*f4a2713aSLionel Sambuc     case tok::kw__Noreturn:
2945*f4a2713aSLionel Sambuc       if (!getLangOpts().C11)
2946*f4a2713aSLionel Sambuc         Diag(Loc, diag::ext_c11_noreturn);
2947*f4a2713aSLionel Sambuc       isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);
2948*f4a2713aSLionel Sambuc       break;
2949*f4a2713aSLionel Sambuc 
2950*f4a2713aSLionel Sambuc     // alignment-specifier
2951*f4a2713aSLionel Sambuc     case tok::kw__Alignas:
2952*f4a2713aSLionel Sambuc       if (!getLangOpts().C11)
2953*f4a2713aSLionel Sambuc         Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
2954*f4a2713aSLionel Sambuc       ParseAlignmentSpecifier(DS.getAttributes());
2955*f4a2713aSLionel Sambuc       continue;
2956*f4a2713aSLionel Sambuc 
2957*f4a2713aSLionel Sambuc     // friend
2958*f4a2713aSLionel Sambuc     case tok::kw_friend:
2959*f4a2713aSLionel Sambuc       if (DSContext == DSC_class)
2960*f4a2713aSLionel Sambuc         isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
2961*f4a2713aSLionel Sambuc       else {
2962*f4a2713aSLionel Sambuc         PrevSpec = ""; // not actually used by the diagnostic
2963*f4a2713aSLionel Sambuc         DiagID = diag::err_friend_invalid_in_context;
2964*f4a2713aSLionel Sambuc         isInvalid = true;
2965*f4a2713aSLionel Sambuc       }
2966*f4a2713aSLionel Sambuc       break;
2967*f4a2713aSLionel Sambuc 
2968*f4a2713aSLionel Sambuc     // Modules
2969*f4a2713aSLionel Sambuc     case tok::kw___module_private__:
2970*f4a2713aSLionel Sambuc       isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
2971*f4a2713aSLionel Sambuc       break;
2972*f4a2713aSLionel Sambuc 
2973*f4a2713aSLionel Sambuc     // constexpr
2974*f4a2713aSLionel Sambuc     case tok::kw_constexpr:
2975*f4a2713aSLionel Sambuc       isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
2976*f4a2713aSLionel Sambuc       break;
2977*f4a2713aSLionel Sambuc 
2978*f4a2713aSLionel Sambuc     // type-specifier
2979*f4a2713aSLionel Sambuc     case tok::kw_short:
2980*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
2981*f4a2713aSLionel Sambuc                                       DiagID);
2982*f4a2713aSLionel Sambuc       break;
2983*f4a2713aSLionel Sambuc     case tok::kw_long:
2984*f4a2713aSLionel Sambuc       if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
2985*f4a2713aSLionel Sambuc         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
2986*f4a2713aSLionel Sambuc                                         DiagID);
2987*f4a2713aSLionel Sambuc       else
2988*f4a2713aSLionel Sambuc         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2989*f4a2713aSLionel Sambuc                                         DiagID);
2990*f4a2713aSLionel Sambuc       break;
2991*f4a2713aSLionel Sambuc     case tok::kw___int64:
2992*f4a2713aSLionel Sambuc         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
2993*f4a2713aSLionel Sambuc                                         DiagID);
2994*f4a2713aSLionel Sambuc       break;
2995*f4a2713aSLionel Sambuc     case tok::kw_signed:
2996*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
2997*f4a2713aSLionel Sambuc                                      DiagID);
2998*f4a2713aSLionel Sambuc       break;
2999*f4a2713aSLionel Sambuc     case tok::kw_unsigned:
3000*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
3001*f4a2713aSLionel Sambuc                                      DiagID);
3002*f4a2713aSLionel Sambuc       break;
3003*f4a2713aSLionel Sambuc     case tok::kw__Complex:
3004*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
3005*f4a2713aSLionel Sambuc                                         DiagID);
3006*f4a2713aSLionel Sambuc       break;
3007*f4a2713aSLionel Sambuc     case tok::kw__Imaginary:
3008*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
3009*f4a2713aSLionel Sambuc                                         DiagID);
3010*f4a2713aSLionel Sambuc       break;
3011*f4a2713aSLionel Sambuc     case tok::kw_void:
3012*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
3013*f4a2713aSLionel Sambuc                                      DiagID);
3014*f4a2713aSLionel Sambuc       break;
3015*f4a2713aSLionel Sambuc     case tok::kw_char:
3016*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
3017*f4a2713aSLionel Sambuc                                      DiagID);
3018*f4a2713aSLionel Sambuc       break;
3019*f4a2713aSLionel Sambuc     case tok::kw_int:
3020*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
3021*f4a2713aSLionel Sambuc                                      DiagID);
3022*f4a2713aSLionel Sambuc       break;
3023*f4a2713aSLionel Sambuc     case tok::kw___int128:
3024*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
3025*f4a2713aSLionel Sambuc                                      DiagID);
3026*f4a2713aSLionel Sambuc       break;
3027*f4a2713aSLionel Sambuc     case tok::kw_half:
3028*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
3029*f4a2713aSLionel Sambuc                                      DiagID);
3030*f4a2713aSLionel Sambuc       break;
3031*f4a2713aSLionel Sambuc     case tok::kw_float:
3032*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
3033*f4a2713aSLionel Sambuc                                      DiagID);
3034*f4a2713aSLionel Sambuc       break;
3035*f4a2713aSLionel Sambuc     case tok::kw_double:
3036*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
3037*f4a2713aSLionel Sambuc                                      DiagID);
3038*f4a2713aSLionel Sambuc       break;
3039*f4a2713aSLionel Sambuc     case tok::kw_wchar_t:
3040*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
3041*f4a2713aSLionel Sambuc                                      DiagID);
3042*f4a2713aSLionel Sambuc       break;
3043*f4a2713aSLionel Sambuc     case tok::kw_char16_t:
3044*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
3045*f4a2713aSLionel Sambuc                                      DiagID);
3046*f4a2713aSLionel Sambuc       break;
3047*f4a2713aSLionel Sambuc     case tok::kw_char32_t:
3048*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
3049*f4a2713aSLionel Sambuc                                      DiagID);
3050*f4a2713aSLionel Sambuc       break;
3051*f4a2713aSLionel Sambuc     case tok::kw_bool:
3052*f4a2713aSLionel Sambuc     case tok::kw__Bool:
3053*f4a2713aSLionel Sambuc       if (Tok.is(tok::kw_bool) &&
3054*f4a2713aSLionel Sambuc           DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
3055*f4a2713aSLionel Sambuc           DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
3056*f4a2713aSLionel Sambuc         PrevSpec = ""; // Not used by the diagnostic.
3057*f4a2713aSLionel Sambuc         DiagID = diag::err_bool_redeclaration;
3058*f4a2713aSLionel Sambuc         // For better error recovery.
3059*f4a2713aSLionel Sambuc         Tok.setKind(tok::identifier);
3060*f4a2713aSLionel Sambuc         isInvalid = true;
3061*f4a2713aSLionel Sambuc       } else {
3062*f4a2713aSLionel Sambuc         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
3063*f4a2713aSLionel Sambuc                                        DiagID);
3064*f4a2713aSLionel Sambuc       }
3065*f4a2713aSLionel Sambuc       break;
3066*f4a2713aSLionel Sambuc     case tok::kw__Decimal32:
3067*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
3068*f4a2713aSLionel Sambuc                                      DiagID);
3069*f4a2713aSLionel Sambuc       break;
3070*f4a2713aSLionel Sambuc     case tok::kw__Decimal64:
3071*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
3072*f4a2713aSLionel Sambuc                                      DiagID);
3073*f4a2713aSLionel Sambuc       break;
3074*f4a2713aSLionel Sambuc     case tok::kw__Decimal128:
3075*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
3076*f4a2713aSLionel Sambuc                                      DiagID);
3077*f4a2713aSLionel Sambuc       break;
3078*f4a2713aSLionel Sambuc     case tok::kw___vector:
3079*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
3080*f4a2713aSLionel Sambuc       break;
3081*f4a2713aSLionel Sambuc     case tok::kw___pixel:
3082*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
3083*f4a2713aSLionel Sambuc       break;
3084*f4a2713aSLionel Sambuc     case tok::kw_image1d_t:
3085*f4a2713aSLionel Sambuc        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc,
3086*f4a2713aSLionel Sambuc                                       PrevSpec, DiagID);
3087*f4a2713aSLionel Sambuc       break;
3088*f4a2713aSLionel Sambuc     case tok::kw_image1d_array_t:
3089*f4a2713aSLionel Sambuc        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc,
3090*f4a2713aSLionel Sambuc                                       PrevSpec, DiagID);
3091*f4a2713aSLionel Sambuc       break;
3092*f4a2713aSLionel Sambuc     case tok::kw_image1d_buffer_t:
3093*f4a2713aSLionel Sambuc        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc,
3094*f4a2713aSLionel Sambuc                                       PrevSpec, DiagID);
3095*f4a2713aSLionel Sambuc       break;
3096*f4a2713aSLionel Sambuc     case tok::kw_image2d_t:
3097*f4a2713aSLionel Sambuc        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc,
3098*f4a2713aSLionel Sambuc                                       PrevSpec, DiagID);
3099*f4a2713aSLionel Sambuc       break;
3100*f4a2713aSLionel Sambuc     case tok::kw_image2d_array_t:
3101*f4a2713aSLionel Sambuc        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc,
3102*f4a2713aSLionel Sambuc                                       PrevSpec, DiagID);
3103*f4a2713aSLionel Sambuc       break;
3104*f4a2713aSLionel Sambuc     case tok::kw_image3d_t:
3105*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc,
3106*f4a2713aSLionel Sambuc                                      PrevSpec, DiagID);
3107*f4a2713aSLionel Sambuc       break;
3108*f4a2713aSLionel Sambuc     case tok::kw_sampler_t:
3109*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc,
3110*f4a2713aSLionel Sambuc                                      PrevSpec, DiagID);
3111*f4a2713aSLionel Sambuc       break;
3112*f4a2713aSLionel Sambuc     case tok::kw_event_t:
3113*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc,
3114*f4a2713aSLionel Sambuc                                      PrevSpec, DiagID);
3115*f4a2713aSLionel Sambuc       break;
3116*f4a2713aSLionel Sambuc     case tok::kw___unknown_anytype:
3117*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
3118*f4a2713aSLionel Sambuc                                      PrevSpec, DiagID);
3119*f4a2713aSLionel Sambuc       break;
3120*f4a2713aSLionel Sambuc 
3121*f4a2713aSLionel Sambuc     // class-specifier:
3122*f4a2713aSLionel Sambuc     case tok::kw_class:
3123*f4a2713aSLionel Sambuc     case tok::kw_struct:
3124*f4a2713aSLionel Sambuc     case tok::kw___interface:
3125*f4a2713aSLionel Sambuc     case tok::kw_union: {
3126*f4a2713aSLionel Sambuc       tok::TokenKind Kind = Tok.getKind();
3127*f4a2713aSLionel Sambuc       ConsumeToken();
3128*f4a2713aSLionel Sambuc 
3129*f4a2713aSLionel Sambuc       // These are attributes following class specifiers.
3130*f4a2713aSLionel Sambuc       // To produce better diagnostic, we parse them when
3131*f4a2713aSLionel Sambuc       // parsing class specifier.
3132*f4a2713aSLionel Sambuc       ParsedAttributesWithRange Attributes(AttrFactory);
3133*f4a2713aSLionel Sambuc       ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
3134*f4a2713aSLionel Sambuc                           EnteringContext, DSContext, Attributes);
3135*f4a2713aSLionel Sambuc 
3136*f4a2713aSLionel Sambuc       // If there are attributes following class specifier,
3137*f4a2713aSLionel Sambuc       // take them over and handle them here.
3138*f4a2713aSLionel Sambuc       if (!Attributes.empty()) {
3139*f4a2713aSLionel Sambuc         AttrsLastTime = true;
3140*f4a2713aSLionel Sambuc         attrs.takeAllFrom(Attributes);
3141*f4a2713aSLionel Sambuc       }
3142*f4a2713aSLionel Sambuc       continue;
3143*f4a2713aSLionel Sambuc     }
3144*f4a2713aSLionel Sambuc 
3145*f4a2713aSLionel Sambuc     // enum-specifier:
3146*f4a2713aSLionel Sambuc     case tok::kw_enum:
3147*f4a2713aSLionel Sambuc       ConsumeToken();
3148*f4a2713aSLionel Sambuc       ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
3149*f4a2713aSLionel Sambuc       continue;
3150*f4a2713aSLionel Sambuc 
3151*f4a2713aSLionel Sambuc     // cv-qualifier:
3152*f4a2713aSLionel Sambuc     case tok::kw_const:
3153*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
3154*f4a2713aSLionel Sambuc                                  getLangOpts());
3155*f4a2713aSLionel Sambuc       break;
3156*f4a2713aSLionel Sambuc     case tok::kw_volatile:
3157*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
3158*f4a2713aSLionel Sambuc                                  getLangOpts());
3159*f4a2713aSLionel Sambuc       break;
3160*f4a2713aSLionel Sambuc     case tok::kw_restrict:
3161*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
3162*f4a2713aSLionel Sambuc                                  getLangOpts());
3163*f4a2713aSLionel Sambuc       break;
3164*f4a2713aSLionel Sambuc 
3165*f4a2713aSLionel Sambuc     // C++ typename-specifier:
3166*f4a2713aSLionel Sambuc     case tok::kw_typename:
3167*f4a2713aSLionel Sambuc       if (TryAnnotateTypeOrScopeToken()) {
3168*f4a2713aSLionel Sambuc         DS.SetTypeSpecError();
3169*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
3170*f4a2713aSLionel Sambuc       }
3171*f4a2713aSLionel Sambuc       if (!Tok.is(tok::kw_typename))
3172*f4a2713aSLionel Sambuc         continue;
3173*f4a2713aSLionel Sambuc       break;
3174*f4a2713aSLionel Sambuc 
3175*f4a2713aSLionel Sambuc     // GNU typeof support.
3176*f4a2713aSLionel Sambuc     case tok::kw_typeof:
3177*f4a2713aSLionel Sambuc       ParseTypeofSpecifier(DS);
3178*f4a2713aSLionel Sambuc       continue;
3179*f4a2713aSLionel Sambuc 
3180*f4a2713aSLionel Sambuc     case tok::annot_decltype:
3181*f4a2713aSLionel Sambuc       ParseDecltypeSpecifier(DS);
3182*f4a2713aSLionel Sambuc       continue;
3183*f4a2713aSLionel Sambuc 
3184*f4a2713aSLionel Sambuc     case tok::kw___underlying_type:
3185*f4a2713aSLionel Sambuc       ParseUnderlyingTypeSpecifier(DS);
3186*f4a2713aSLionel Sambuc       continue;
3187*f4a2713aSLionel Sambuc 
3188*f4a2713aSLionel Sambuc     case tok::kw__Atomic:
3189*f4a2713aSLionel Sambuc       // C11 6.7.2.4/4:
3190*f4a2713aSLionel Sambuc       //   If the _Atomic keyword is immediately followed by a left parenthesis,
3191*f4a2713aSLionel Sambuc       //   it is interpreted as a type specifier (with a type name), not as a
3192*f4a2713aSLionel Sambuc       //   type qualifier.
3193*f4a2713aSLionel Sambuc       if (NextToken().is(tok::l_paren)) {
3194*f4a2713aSLionel Sambuc         ParseAtomicSpecifier(DS);
3195*f4a2713aSLionel Sambuc         continue;
3196*f4a2713aSLionel Sambuc       }
3197*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
3198*f4a2713aSLionel Sambuc                                  getLangOpts());
3199*f4a2713aSLionel Sambuc       break;
3200*f4a2713aSLionel Sambuc 
3201*f4a2713aSLionel Sambuc     // OpenCL qualifiers:
3202*f4a2713aSLionel Sambuc     case tok::kw_private:
3203*f4a2713aSLionel Sambuc       if (!getLangOpts().OpenCL)
3204*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
3205*f4a2713aSLionel Sambuc     case tok::kw___private:
3206*f4a2713aSLionel Sambuc     case tok::kw___global:
3207*f4a2713aSLionel Sambuc     case tok::kw___local:
3208*f4a2713aSLionel Sambuc     case tok::kw___constant:
3209*f4a2713aSLionel Sambuc     case tok::kw___read_only:
3210*f4a2713aSLionel Sambuc     case tok::kw___write_only:
3211*f4a2713aSLionel Sambuc     case tok::kw___read_write:
3212*f4a2713aSLionel Sambuc       ParseOpenCLQualifiers(DS);
3213*f4a2713aSLionel Sambuc       break;
3214*f4a2713aSLionel Sambuc 
3215*f4a2713aSLionel Sambuc     case tok::less:
3216*f4a2713aSLionel Sambuc       // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
3217*f4a2713aSLionel Sambuc       // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,
3218*f4a2713aSLionel Sambuc       // but we support it.
3219*f4a2713aSLionel Sambuc       if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
3220*f4a2713aSLionel Sambuc         goto DoneWithDeclSpec;
3221*f4a2713aSLionel Sambuc 
3222*f4a2713aSLionel Sambuc       if (!ParseObjCProtocolQualifiers(DS))
3223*f4a2713aSLionel Sambuc         Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
3224*f4a2713aSLionel Sambuc           << FixItHint::CreateInsertion(Loc, "id")
3225*f4a2713aSLionel Sambuc           << SourceRange(Loc, DS.getSourceRange().getEnd());
3226*f4a2713aSLionel Sambuc 
3227*f4a2713aSLionel Sambuc       // Need to support trailing type qualifiers (e.g. "id<p> const").
3228*f4a2713aSLionel Sambuc       // If a type specifier follows, it will be diagnosed elsewhere.
3229*f4a2713aSLionel Sambuc       continue;
3230*f4a2713aSLionel Sambuc     }
3231*f4a2713aSLionel Sambuc     // If the specifier wasn't legal, issue a diagnostic.
3232*f4a2713aSLionel Sambuc     if (isInvalid) {
3233*f4a2713aSLionel Sambuc       assert(PrevSpec && "Method did not return previous specifier!");
3234*f4a2713aSLionel Sambuc       assert(DiagID);
3235*f4a2713aSLionel Sambuc 
3236*f4a2713aSLionel Sambuc       if (DiagID == diag::ext_duplicate_declspec)
3237*f4a2713aSLionel Sambuc         Diag(Tok, DiagID)
3238*f4a2713aSLionel Sambuc           << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
3239*f4a2713aSLionel Sambuc       else
3240*f4a2713aSLionel Sambuc         Diag(Tok, DiagID) << PrevSpec;
3241*f4a2713aSLionel Sambuc     }
3242*f4a2713aSLionel Sambuc 
3243*f4a2713aSLionel Sambuc     DS.SetRangeEnd(Tok.getLocation());
3244*f4a2713aSLionel Sambuc     if (DiagID != diag::err_bool_redeclaration)
3245*f4a2713aSLionel Sambuc       ConsumeToken();
3246*f4a2713aSLionel Sambuc 
3247*f4a2713aSLionel Sambuc     AttrsLastTime = false;
3248*f4a2713aSLionel Sambuc   }
3249*f4a2713aSLionel Sambuc }
3250*f4a2713aSLionel Sambuc 
3251*f4a2713aSLionel Sambuc /// ParseStructDeclaration - Parse a struct declaration without the terminating
3252*f4a2713aSLionel Sambuc /// semicolon.
3253*f4a2713aSLionel Sambuc ///
3254*f4a2713aSLionel Sambuc ///       struct-declaration:
3255*f4a2713aSLionel Sambuc ///         specifier-qualifier-list struct-declarator-list
3256*f4a2713aSLionel Sambuc /// [GNU]   __extension__ struct-declaration
3257*f4a2713aSLionel Sambuc /// [GNU]   specifier-qualifier-list
3258*f4a2713aSLionel Sambuc ///       struct-declarator-list:
3259*f4a2713aSLionel Sambuc ///         struct-declarator
3260*f4a2713aSLionel Sambuc ///         struct-declarator-list ',' struct-declarator
3261*f4a2713aSLionel Sambuc /// [GNU]   struct-declarator-list ',' attributes[opt] struct-declarator
3262*f4a2713aSLionel Sambuc ///       struct-declarator:
3263*f4a2713aSLionel Sambuc ///         declarator
3264*f4a2713aSLionel Sambuc /// [GNU]   declarator attributes[opt]
3265*f4a2713aSLionel Sambuc ///         declarator[opt] ':' constant-expression
3266*f4a2713aSLionel Sambuc /// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
3267*f4a2713aSLionel Sambuc ///
3268*f4a2713aSLionel Sambuc void Parser::
3269*f4a2713aSLionel Sambuc ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
3270*f4a2713aSLionel Sambuc 
3271*f4a2713aSLionel Sambuc   if (Tok.is(tok::kw___extension__)) {
3272*f4a2713aSLionel Sambuc     // __extension__ silences extension warnings in the subexpression.
3273*f4a2713aSLionel Sambuc     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
3274*f4a2713aSLionel Sambuc     ConsumeToken();
3275*f4a2713aSLionel Sambuc     return ParseStructDeclaration(DS, Fields);
3276*f4a2713aSLionel Sambuc   }
3277*f4a2713aSLionel Sambuc 
3278*f4a2713aSLionel Sambuc   // Parse the common specifier-qualifiers-list piece.
3279*f4a2713aSLionel Sambuc   ParseSpecifierQualifierList(DS);
3280*f4a2713aSLionel Sambuc 
3281*f4a2713aSLionel Sambuc   // If there are no declarators, this is a free-standing declaration
3282*f4a2713aSLionel Sambuc   // specifier. Let the actions module cope with it.
3283*f4a2713aSLionel Sambuc   if (Tok.is(tok::semi)) {
3284*f4a2713aSLionel Sambuc     Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
3285*f4a2713aSLionel Sambuc                                                        DS);
3286*f4a2713aSLionel Sambuc     DS.complete(TheDecl);
3287*f4a2713aSLionel Sambuc     return;
3288*f4a2713aSLionel Sambuc   }
3289*f4a2713aSLionel Sambuc 
3290*f4a2713aSLionel Sambuc   // Read struct-declarators until we find the semicolon.
3291*f4a2713aSLionel Sambuc   bool FirstDeclarator = true;
3292*f4a2713aSLionel Sambuc   SourceLocation CommaLoc;
3293*f4a2713aSLionel Sambuc   while (1) {
3294*f4a2713aSLionel Sambuc     ParsingFieldDeclarator DeclaratorInfo(*this, DS);
3295*f4a2713aSLionel Sambuc     DeclaratorInfo.D.setCommaLoc(CommaLoc);
3296*f4a2713aSLionel Sambuc 
3297*f4a2713aSLionel Sambuc     // Attributes are only allowed here on successive declarators.
3298*f4a2713aSLionel Sambuc     if (!FirstDeclarator)
3299*f4a2713aSLionel Sambuc       MaybeParseGNUAttributes(DeclaratorInfo.D);
3300*f4a2713aSLionel Sambuc 
3301*f4a2713aSLionel Sambuc     /// struct-declarator: declarator
3302*f4a2713aSLionel Sambuc     /// struct-declarator: declarator[opt] ':' constant-expression
3303*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::colon)) {
3304*f4a2713aSLionel Sambuc       // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
3305*f4a2713aSLionel Sambuc       ColonProtectionRAIIObject X(*this);
3306*f4a2713aSLionel Sambuc       ParseDeclarator(DeclaratorInfo.D);
3307*f4a2713aSLionel Sambuc     }
3308*f4a2713aSLionel Sambuc 
3309*f4a2713aSLionel Sambuc     if (Tok.is(tok::colon)) {
3310*f4a2713aSLionel Sambuc       ConsumeToken();
3311*f4a2713aSLionel Sambuc       ExprResult Res(ParseConstantExpression());
3312*f4a2713aSLionel Sambuc       if (Res.isInvalid())
3313*f4a2713aSLionel Sambuc         SkipUntil(tok::semi, StopBeforeMatch);
3314*f4a2713aSLionel Sambuc       else
3315*f4a2713aSLionel Sambuc         DeclaratorInfo.BitfieldSize = Res.release();
3316*f4a2713aSLionel Sambuc     }
3317*f4a2713aSLionel Sambuc 
3318*f4a2713aSLionel Sambuc     // If attributes exist after the declarator, parse them.
3319*f4a2713aSLionel Sambuc     MaybeParseGNUAttributes(DeclaratorInfo.D);
3320*f4a2713aSLionel Sambuc 
3321*f4a2713aSLionel Sambuc     // We're done with this declarator;  invoke the callback.
3322*f4a2713aSLionel Sambuc     Fields.invoke(DeclaratorInfo);
3323*f4a2713aSLionel Sambuc 
3324*f4a2713aSLionel Sambuc     // If we don't have a comma, it is either the end of the list (a ';')
3325*f4a2713aSLionel Sambuc     // or an error, bail out.
3326*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::comma))
3327*f4a2713aSLionel Sambuc       return;
3328*f4a2713aSLionel Sambuc 
3329*f4a2713aSLionel Sambuc     // Consume the comma.
3330*f4a2713aSLionel Sambuc     CommaLoc = ConsumeToken();
3331*f4a2713aSLionel Sambuc 
3332*f4a2713aSLionel Sambuc     FirstDeclarator = false;
3333*f4a2713aSLionel Sambuc   }
3334*f4a2713aSLionel Sambuc }
3335*f4a2713aSLionel Sambuc 
3336*f4a2713aSLionel Sambuc /// ParseStructUnionBody
3337*f4a2713aSLionel Sambuc ///       struct-contents:
3338*f4a2713aSLionel Sambuc ///         struct-declaration-list
3339*f4a2713aSLionel Sambuc /// [EXT]   empty
3340*f4a2713aSLionel Sambuc /// [GNU]   "struct-declaration-list" without terminatoring ';'
3341*f4a2713aSLionel Sambuc ///       struct-declaration-list:
3342*f4a2713aSLionel Sambuc ///         struct-declaration
3343*f4a2713aSLionel Sambuc ///         struct-declaration-list struct-declaration
3344*f4a2713aSLionel Sambuc /// [OBC]   '@' 'defs' '(' class-name ')'
3345*f4a2713aSLionel Sambuc ///
3346*f4a2713aSLionel Sambuc void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
3347*f4a2713aSLionel Sambuc                                   unsigned TagType, Decl *TagDecl) {
3348*f4a2713aSLionel Sambuc   PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
3349*f4a2713aSLionel Sambuc                                       "parsing struct/union body");
3350*f4a2713aSLionel Sambuc   assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");
3351*f4a2713aSLionel Sambuc 
3352*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_brace);
3353*f4a2713aSLionel Sambuc   if (T.consumeOpen())
3354*f4a2713aSLionel Sambuc     return;
3355*f4a2713aSLionel Sambuc 
3356*f4a2713aSLionel Sambuc   ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
3357*f4a2713aSLionel Sambuc   Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
3358*f4a2713aSLionel Sambuc 
3359*f4a2713aSLionel Sambuc   SmallVector<Decl *, 32> FieldDecls;
3360*f4a2713aSLionel Sambuc 
3361*f4a2713aSLionel Sambuc   // While we still have something to read, read the declarations in the struct.
3362*f4a2713aSLionel Sambuc   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3363*f4a2713aSLionel Sambuc     // Each iteration of this loop reads one struct-declaration.
3364*f4a2713aSLionel Sambuc 
3365*f4a2713aSLionel Sambuc     // Check for extraneous top-level semicolon.
3366*f4a2713aSLionel Sambuc     if (Tok.is(tok::semi)) {
3367*f4a2713aSLionel Sambuc       ConsumeExtraSemi(InsideStruct, TagType);
3368*f4a2713aSLionel Sambuc       continue;
3369*f4a2713aSLionel Sambuc     }
3370*f4a2713aSLionel Sambuc 
3371*f4a2713aSLionel Sambuc     // Parse _Static_assert declaration.
3372*f4a2713aSLionel Sambuc     if (Tok.is(tok::kw__Static_assert)) {
3373*f4a2713aSLionel Sambuc       SourceLocation DeclEnd;
3374*f4a2713aSLionel Sambuc       ParseStaticAssertDeclaration(DeclEnd);
3375*f4a2713aSLionel Sambuc       continue;
3376*f4a2713aSLionel Sambuc     }
3377*f4a2713aSLionel Sambuc 
3378*f4a2713aSLionel Sambuc     if (Tok.is(tok::annot_pragma_pack)) {
3379*f4a2713aSLionel Sambuc       HandlePragmaPack();
3380*f4a2713aSLionel Sambuc       continue;
3381*f4a2713aSLionel Sambuc     }
3382*f4a2713aSLionel Sambuc 
3383*f4a2713aSLionel Sambuc     if (Tok.is(tok::annot_pragma_align)) {
3384*f4a2713aSLionel Sambuc       HandlePragmaAlign();
3385*f4a2713aSLionel Sambuc       continue;
3386*f4a2713aSLionel Sambuc     }
3387*f4a2713aSLionel Sambuc 
3388*f4a2713aSLionel Sambuc     if (!Tok.is(tok::at)) {
3389*f4a2713aSLionel Sambuc       struct CFieldCallback : FieldCallback {
3390*f4a2713aSLionel Sambuc         Parser &P;
3391*f4a2713aSLionel Sambuc         Decl *TagDecl;
3392*f4a2713aSLionel Sambuc         SmallVectorImpl<Decl *> &FieldDecls;
3393*f4a2713aSLionel Sambuc 
3394*f4a2713aSLionel Sambuc         CFieldCallback(Parser &P, Decl *TagDecl,
3395*f4a2713aSLionel Sambuc                        SmallVectorImpl<Decl *> &FieldDecls) :
3396*f4a2713aSLionel Sambuc           P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
3397*f4a2713aSLionel Sambuc 
3398*f4a2713aSLionel Sambuc         void invoke(ParsingFieldDeclarator &FD) {
3399*f4a2713aSLionel Sambuc           // Install the declarator into the current TagDecl.
3400*f4a2713aSLionel Sambuc           Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
3401*f4a2713aSLionel Sambuc                               FD.D.getDeclSpec().getSourceRange().getBegin(),
3402*f4a2713aSLionel Sambuc                                                  FD.D, FD.BitfieldSize);
3403*f4a2713aSLionel Sambuc           FieldDecls.push_back(Field);
3404*f4a2713aSLionel Sambuc           FD.complete(Field);
3405*f4a2713aSLionel Sambuc         }
3406*f4a2713aSLionel Sambuc       } Callback(*this, TagDecl, FieldDecls);
3407*f4a2713aSLionel Sambuc 
3408*f4a2713aSLionel Sambuc       // Parse all the comma separated declarators.
3409*f4a2713aSLionel Sambuc       ParsingDeclSpec DS(*this);
3410*f4a2713aSLionel Sambuc       ParseStructDeclaration(DS, Callback);
3411*f4a2713aSLionel Sambuc     } else { // Handle @defs
3412*f4a2713aSLionel Sambuc       ConsumeToken();
3413*f4a2713aSLionel Sambuc       if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
3414*f4a2713aSLionel Sambuc         Diag(Tok, diag::err_unexpected_at);
3415*f4a2713aSLionel Sambuc         SkipUntil(tok::semi);
3416*f4a2713aSLionel Sambuc         continue;
3417*f4a2713aSLionel Sambuc       }
3418*f4a2713aSLionel Sambuc       ConsumeToken();
3419*f4a2713aSLionel Sambuc       ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
3420*f4a2713aSLionel Sambuc       if (!Tok.is(tok::identifier)) {
3421*f4a2713aSLionel Sambuc         Diag(Tok, diag::err_expected_ident);
3422*f4a2713aSLionel Sambuc         SkipUntil(tok::semi);
3423*f4a2713aSLionel Sambuc         continue;
3424*f4a2713aSLionel Sambuc       }
3425*f4a2713aSLionel Sambuc       SmallVector<Decl *, 16> Fields;
3426*f4a2713aSLionel Sambuc       Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
3427*f4a2713aSLionel Sambuc                         Tok.getIdentifierInfo(), Fields);
3428*f4a2713aSLionel Sambuc       FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
3429*f4a2713aSLionel Sambuc       ConsumeToken();
3430*f4a2713aSLionel Sambuc       ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
3431*f4a2713aSLionel Sambuc     }
3432*f4a2713aSLionel Sambuc 
3433*f4a2713aSLionel Sambuc     if (Tok.is(tok::semi)) {
3434*f4a2713aSLionel Sambuc       ConsumeToken();
3435*f4a2713aSLionel Sambuc     } else if (Tok.is(tok::r_brace)) {
3436*f4a2713aSLionel Sambuc       ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
3437*f4a2713aSLionel Sambuc       break;
3438*f4a2713aSLionel Sambuc     } else {
3439*f4a2713aSLionel Sambuc       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
3440*f4a2713aSLionel Sambuc       // Skip to end of block or statement to avoid ext-warning on extra ';'.
3441*f4a2713aSLionel Sambuc       SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
3442*f4a2713aSLionel Sambuc       // If we stopped at a ';', eat it.
3443*f4a2713aSLionel Sambuc       if (Tok.is(tok::semi)) ConsumeToken();
3444*f4a2713aSLionel Sambuc     }
3445*f4a2713aSLionel Sambuc   }
3446*f4a2713aSLionel Sambuc 
3447*f4a2713aSLionel Sambuc   T.consumeClose();
3448*f4a2713aSLionel Sambuc 
3449*f4a2713aSLionel Sambuc   ParsedAttributes attrs(AttrFactory);
3450*f4a2713aSLionel Sambuc   // If attributes exist after struct contents, parse them.
3451*f4a2713aSLionel Sambuc   MaybeParseGNUAttributes(attrs);
3452*f4a2713aSLionel Sambuc 
3453*f4a2713aSLionel Sambuc   Actions.ActOnFields(getCurScope(),
3454*f4a2713aSLionel Sambuc                       RecordLoc, TagDecl, FieldDecls,
3455*f4a2713aSLionel Sambuc                       T.getOpenLocation(), T.getCloseLocation(),
3456*f4a2713aSLionel Sambuc                       attrs.getList());
3457*f4a2713aSLionel Sambuc   StructScope.Exit();
3458*f4a2713aSLionel Sambuc   Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
3459*f4a2713aSLionel Sambuc                                    T.getCloseLocation());
3460*f4a2713aSLionel Sambuc }
3461*f4a2713aSLionel Sambuc 
3462*f4a2713aSLionel Sambuc /// ParseEnumSpecifier
3463*f4a2713aSLionel Sambuc ///       enum-specifier: [C99 6.7.2.2]
3464*f4a2713aSLionel Sambuc ///         'enum' identifier[opt] '{' enumerator-list '}'
3465*f4a2713aSLionel Sambuc ///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
3466*f4a2713aSLionel Sambuc /// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
3467*f4a2713aSLionel Sambuc ///                                                 '}' attributes[opt]
3468*f4a2713aSLionel Sambuc /// [MS]    'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
3469*f4a2713aSLionel Sambuc ///                                                 '}'
3470*f4a2713aSLionel Sambuc ///         'enum' identifier
3471*f4a2713aSLionel Sambuc /// [GNU]   'enum' attributes[opt] identifier
3472*f4a2713aSLionel Sambuc ///
3473*f4a2713aSLionel Sambuc /// [C++11] enum-head '{' enumerator-list[opt] '}'
3474*f4a2713aSLionel Sambuc /// [C++11] enum-head '{' enumerator-list ','  '}'
3475*f4a2713aSLionel Sambuc ///
3476*f4a2713aSLionel Sambuc ///       enum-head: [C++11]
3477*f4a2713aSLionel Sambuc ///         enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
3478*f4a2713aSLionel Sambuc ///         enum-key attribute-specifier-seq[opt] nested-name-specifier
3479*f4a2713aSLionel Sambuc ///             identifier enum-base[opt]
3480*f4a2713aSLionel Sambuc ///
3481*f4a2713aSLionel Sambuc ///       enum-key: [C++11]
3482*f4a2713aSLionel Sambuc ///         'enum'
3483*f4a2713aSLionel Sambuc ///         'enum' 'class'
3484*f4a2713aSLionel Sambuc ///         'enum' 'struct'
3485*f4a2713aSLionel Sambuc ///
3486*f4a2713aSLionel Sambuc ///       enum-base: [C++11]
3487*f4a2713aSLionel Sambuc ///         ':' type-specifier-seq
3488*f4a2713aSLionel Sambuc ///
3489*f4a2713aSLionel Sambuc /// [C++] elaborated-type-specifier:
3490*f4a2713aSLionel Sambuc /// [C++]   'enum' '::'[opt] nested-name-specifier[opt] identifier
3491*f4a2713aSLionel Sambuc ///
3492*f4a2713aSLionel Sambuc void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
3493*f4a2713aSLionel Sambuc                                 const ParsedTemplateInfo &TemplateInfo,
3494*f4a2713aSLionel Sambuc                                 AccessSpecifier AS, DeclSpecContext DSC) {
3495*f4a2713aSLionel Sambuc   // Parse the tag portion of this.
3496*f4a2713aSLionel Sambuc   if (Tok.is(tok::code_completion)) {
3497*f4a2713aSLionel Sambuc     // Code completion for an enum name.
3498*f4a2713aSLionel Sambuc     Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
3499*f4a2713aSLionel Sambuc     return cutOffParsing();
3500*f4a2713aSLionel Sambuc   }
3501*f4a2713aSLionel Sambuc 
3502*f4a2713aSLionel Sambuc   // If attributes exist after tag, parse them.
3503*f4a2713aSLionel Sambuc   ParsedAttributesWithRange attrs(AttrFactory);
3504*f4a2713aSLionel Sambuc   MaybeParseGNUAttributes(attrs);
3505*f4a2713aSLionel Sambuc   MaybeParseCXX11Attributes(attrs);
3506*f4a2713aSLionel Sambuc 
3507*f4a2713aSLionel Sambuc   // If declspecs exist after tag, parse them.
3508*f4a2713aSLionel Sambuc   while (Tok.is(tok::kw___declspec))
3509*f4a2713aSLionel Sambuc     ParseMicrosoftDeclSpec(attrs);
3510*f4a2713aSLionel Sambuc 
3511*f4a2713aSLionel Sambuc   SourceLocation ScopedEnumKWLoc;
3512*f4a2713aSLionel Sambuc   bool IsScopedUsingClassTag = false;
3513*f4a2713aSLionel Sambuc 
3514*f4a2713aSLionel Sambuc   // In C++11, recognize 'enum class' and 'enum struct'.
3515*f4a2713aSLionel Sambuc   if (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct)) {
3516*f4a2713aSLionel Sambuc     Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum
3517*f4a2713aSLionel Sambuc                                         : diag::ext_scoped_enum);
3518*f4a2713aSLionel Sambuc     IsScopedUsingClassTag = Tok.is(tok::kw_class);
3519*f4a2713aSLionel Sambuc     ScopedEnumKWLoc = ConsumeToken();
3520*f4a2713aSLionel Sambuc 
3521*f4a2713aSLionel Sambuc     // Attributes are not allowed between these keywords.  Diagnose,
3522*f4a2713aSLionel Sambuc     // but then just treat them like they appeared in the right place.
3523*f4a2713aSLionel Sambuc     ProhibitAttributes(attrs);
3524*f4a2713aSLionel Sambuc 
3525*f4a2713aSLionel Sambuc     // They are allowed afterwards, though.
3526*f4a2713aSLionel Sambuc     MaybeParseGNUAttributes(attrs);
3527*f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(attrs);
3528*f4a2713aSLionel Sambuc     while (Tok.is(tok::kw___declspec))
3529*f4a2713aSLionel Sambuc       ParseMicrosoftDeclSpec(attrs);
3530*f4a2713aSLionel Sambuc   }
3531*f4a2713aSLionel Sambuc 
3532*f4a2713aSLionel Sambuc   // C++11 [temp.explicit]p12:
3533*f4a2713aSLionel Sambuc   //   The usual access controls do not apply to names used to specify
3534*f4a2713aSLionel Sambuc   //   explicit instantiations.
3535*f4a2713aSLionel Sambuc   // We extend this to also cover explicit specializations.  Note that
3536*f4a2713aSLionel Sambuc   // we don't suppress if this turns out to be an elaborated type
3537*f4a2713aSLionel Sambuc   // specifier.
3538*f4a2713aSLionel Sambuc   bool shouldDelayDiagsInTag =
3539*f4a2713aSLionel Sambuc     (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3540*f4a2713aSLionel Sambuc      TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3541*f4a2713aSLionel Sambuc   SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
3542*f4a2713aSLionel Sambuc 
3543*f4a2713aSLionel Sambuc   // Enum definitions should not be parsed in a trailing-return-type.
3544*f4a2713aSLionel Sambuc   bool AllowDeclaration = DSC != DSC_trailing;
3545*f4a2713aSLionel Sambuc 
3546*f4a2713aSLionel Sambuc   bool AllowFixedUnderlyingType = AllowDeclaration &&
3547*f4a2713aSLionel Sambuc     (getLangOpts().CPlusPlus11 || getLangOpts().MicrosoftExt ||
3548*f4a2713aSLionel Sambuc      getLangOpts().ObjC2);
3549*f4a2713aSLionel Sambuc 
3550*f4a2713aSLionel Sambuc   CXXScopeSpec &SS = DS.getTypeSpecScope();
3551*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus) {
3552*f4a2713aSLionel Sambuc     // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
3553*f4a2713aSLionel Sambuc     // if a fixed underlying type is allowed.
3554*f4a2713aSLionel Sambuc     ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
3555*f4a2713aSLionel Sambuc 
3556*f4a2713aSLionel Sambuc     if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
3557*f4a2713aSLionel Sambuc                                        /*EnteringContext=*/true))
3558*f4a2713aSLionel Sambuc       return;
3559*f4a2713aSLionel Sambuc 
3560*f4a2713aSLionel Sambuc     if (SS.isSet() && Tok.isNot(tok::identifier)) {
3561*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_expected_ident);
3562*f4a2713aSLionel Sambuc       if (Tok.isNot(tok::l_brace)) {
3563*f4a2713aSLionel Sambuc         // Has no name and is not a definition.
3564*f4a2713aSLionel Sambuc         // Skip the rest of this declarator, up until the comma or semicolon.
3565*f4a2713aSLionel Sambuc         SkipUntil(tok::comma, StopAtSemi);
3566*f4a2713aSLionel Sambuc         return;
3567*f4a2713aSLionel Sambuc       }
3568*f4a2713aSLionel Sambuc     }
3569*f4a2713aSLionel Sambuc   }
3570*f4a2713aSLionel Sambuc 
3571*f4a2713aSLionel Sambuc   // Must have either 'enum name' or 'enum {...}'.
3572*f4a2713aSLionel Sambuc   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
3573*f4a2713aSLionel Sambuc       !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
3574*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_expected_ident_lbrace);
3575*f4a2713aSLionel Sambuc 
3576*f4a2713aSLionel Sambuc     // Skip the rest of this declarator, up until the comma or semicolon.
3577*f4a2713aSLionel Sambuc     SkipUntil(tok::comma, StopAtSemi);
3578*f4a2713aSLionel Sambuc     return;
3579*f4a2713aSLionel Sambuc   }
3580*f4a2713aSLionel Sambuc 
3581*f4a2713aSLionel Sambuc   // If an identifier is present, consume and remember it.
3582*f4a2713aSLionel Sambuc   IdentifierInfo *Name = 0;
3583*f4a2713aSLionel Sambuc   SourceLocation NameLoc;
3584*f4a2713aSLionel Sambuc   if (Tok.is(tok::identifier)) {
3585*f4a2713aSLionel Sambuc     Name = Tok.getIdentifierInfo();
3586*f4a2713aSLionel Sambuc     NameLoc = ConsumeToken();
3587*f4a2713aSLionel Sambuc   }
3588*f4a2713aSLionel Sambuc 
3589*f4a2713aSLionel Sambuc   if (!Name && ScopedEnumKWLoc.isValid()) {
3590*f4a2713aSLionel Sambuc     // C++0x 7.2p2: The optional identifier shall not be omitted in the
3591*f4a2713aSLionel Sambuc     // declaration of a scoped enumeration.
3592*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_scoped_enum_missing_identifier);
3593*f4a2713aSLionel Sambuc     ScopedEnumKWLoc = SourceLocation();
3594*f4a2713aSLionel Sambuc     IsScopedUsingClassTag = false;
3595*f4a2713aSLionel Sambuc   }
3596*f4a2713aSLionel Sambuc 
3597*f4a2713aSLionel Sambuc   // Okay, end the suppression area.  We'll decide whether to emit the
3598*f4a2713aSLionel Sambuc   // diagnostics in a second.
3599*f4a2713aSLionel Sambuc   if (shouldDelayDiagsInTag)
3600*f4a2713aSLionel Sambuc     diagsFromTag.done();
3601*f4a2713aSLionel Sambuc 
3602*f4a2713aSLionel Sambuc   TypeResult BaseType;
3603*f4a2713aSLionel Sambuc 
3604*f4a2713aSLionel Sambuc   // Parse the fixed underlying type.
3605*f4a2713aSLionel Sambuc   bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3606*f4a2713aSLionel Sambuc   if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
3607*f4a2713aSLionel Sambuc     bool PossibleBitfield = false;
3608*f4a2713aSLionel Sambuc     if (CanBeBitfield) {
3609*f4a2713aSLionel Sambuc       // If we're in class scope, this can either be an enum declaration with
3610*f4a2713aSLionel Sambuc       // an underlying type, or a declaration of a bitfield member. We try to
3611*f4a2713aSLionel Sambuc       // use a simple disambiguation scheme first to catch the common cases
3612*f4a2713aSLionel Sambuc       // (integer literal, sizeof); if it's still ambiguous, we then consider
3613*f4a2713aSLionel Sambuc       // anything that's a simple-type-specifier followed by '(' as an
3614*f4a2713aSLionel Sambuc       // expression. This suffices because function types are not valid
3615*f4a2713aSLionel Sambuc       // underlying types anyway.
3616*f4a2713aSLionel Sambuc       EnterExpressionEvaluationContext Unevaluated(Actions,
3617*f4a2713aSLionel Sambuc                                                    Sema::ConstantEvaluated);
3618*f4a2713aSLionel Sambuc       TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
3619*f4a2713aSLionel Sambuc       // If the next token starts an expression, we know we're parsing a
3620*f4a2713aSLionel Sambuc       // bit-field. This is the common case.
3621*f4a2713aSLionel Sambuc       if (TPR == TPResult::True())
3622*f4a2713aSLionel Sambuc         PossibleBitfield = true;
3623*f4a2713aSLionel Sambuc       // If the next token starts a type-specifier-seq, it may be either a
3624*f4a2713aSLionel Sambuc       // a fixed underlying type or the start of a function-style cast in C++;
3625*f4a2713aSLionel Sambuc       // lookahead one more token to see if it's obvious that we have a
3626*f4a2713aSLionel Sambuc       // fixed underlying type.
3627*f4a2713aSLionel Sambuc       else if (TPR == TPResult::False() &&
3628*f4a2713aSLionel Sambuc                GetLookAheadToken(2).getKind() == tok::semi) {
3629*f4a2713aSLionel Sambuc         // Consume the ':'.
3630*f4a2713aSLionel Sambuc         ConsumeToken();
3631*f4a2713aSLionel Sambuc       } else {
3632*f4a2713aSLionel Sambuc         // We have the start of a type-specifier-seq, so we have to perform
3633*f4a2713aSLionel Sambuc         // tentative parsing to determine whether we have an expression or a
3634*f4a2713aSLionel Sambuc         // type.
3635*f4a2713aSLionel Sambuc         TentativeParsingAction TPA(*this);
3636*f4a2713aSLionel Sambuc 
3637*f4a2713aSLionel Sambuc         // Consume the ':'.
3638*f4a2713aSLionel Sambuc         ConsumeToken();
3639*f4a2713aSLionel Sambuc 
3640*f4a2713aSLionel Sambuc         // If we see a type specifier followed by an open-brace, we have an
3641*f4a2713aSLionel Sambuc         // ambiguity between an underlying type and a C++11 braced
3642*f4a2713aSLionel Sambuc         // function-style cast. Resolve this by always treating it as an
3643*f4a2713aSLionel Sambuc         // underlying type.
3644*f4a2713aSLionel Sambuc         // FIXME: The standard is not entirely clear on how to disambiguate in
3645*f4a2713aSLionel Sambuc         // this case.
3646*f4a2713aSLionel Sambuc         if ((getLangOpts().CPlusPlus &&
3647*f4a2713aSLionel Sambuc              isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
3648*f4a2713aSLionel Sambuc             (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
3649*f4a2713aSLionel Sambuc           // We'll parse this as a bitfield later.
3650*f4a2713aSLionel Sambuc           PossibleBitfield = true;
3651*f4a2713aSLionel Sambuc           TPA.Revert();
3652*f4a2713aSLionel Sambuc         } else {
3653*f4a2713aSLionel Sambuc           // We have a type-specifier-seq.
3654*f4a2713aSLionel Sambuc           TPA.Commit();
3655*f4a2713aSLionel Sambuc         }
3656*f4a2713aSLionel Sambuc       }
3657*f4a2713aSLionel Sambuc     } else {
3658*f4a2713aSLionel Sambuc       // Consume the ':'.
3659*f4a2713aSLionel Sambuc       ConsumeToken();
3660*f4a2713aSLionel Sambuc     }
3661*f4a2713aSLionel Sambuc 
3662*f4a2713aSLionel Sambuc     if (!PossibleBitfield) {
3663*f4a2713aSLionel Sambuc       SourceRange Range;
3664*f4a2713aSLionel Sambuc       BaseType = ParseTypeName(&Range);
3665*f4a2713aSLionel Sambuc 
3666*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus11) {
3667*f4a2713aSLionel Sambuc         Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
3668*f4a2713aSLionel Sambuc       } else if (!getLangOpts().ObjC2) {
3669*f4a2713aSLionel Sambuc         if (getLangOpts().CPlusPlus)
3670*f4a2713aSLionel Sambuc           Diag(StartLoc, diag::ext_cxx11_enum_fixed_underlying_type) << Range;
3671*f4a2713aSLionel Sambuc         else
3672*f4a2713aSLionel Sambuc           Diag(StartLoc, diag::ext_c_enum_fixed_underlying_type) << Range;
3673*f4a2713aSLionel Sambuc       }
3674*f4a2713aSLionel Sambuc     }
3675*f4a2713aSLionel Sambuc   }
3676*f4a2713aSLionel Sambuc 
3677*f4a2713aSLionel Sambuc   // There are four options here.  If we have 'friend enum foo;' then this is a
3678*f4a2713aSLionel Sambuc   // friend declaration, and cannot have an accompanying definition. If we have
3679*f4a2713aSLionel Sambuc   // 'enum foo;', then this is a forward declaration.  If we have
3680*f4a2713aSLionel Sambuc   // 'enum foo {...' then this is a definition. Otherwise we have something
3681*f4a2713aSLionel Sambuc   // like 'enum foo xyz', a reference.
3682*f4a2713aSLionel Sambuc   //
3683*f4a2713aSLionel Sambuc   // This is needed to handle stuff like this right (C99 6.7.2.3p11):
3684*f4a2713aSLionel Sambuc   // enum foo {..};  void bar() { enum foo; }    <- new foo in bar.
3685*f4a2713aSLionel Sambuc   // enum foo {..};  void bar() { enum foo x; }  <- use of old foo.
3686*f4a2713aSLionel Sambuc   //
3687*f4a2713aSLionel Sambuc   Sema::TagUseKind TUK;
3688*f4a2713aSLionel Sambuc   if (!AllowDeclaration) {
3689*f4a2713aSLionel Sambuc     TUK = Sema::TUK_Reference;
3690*f4a2713aSLionel Sambuc   } else if (Tok.is(tok::l_brace)) {
3691*f4a2713aSLionel Sambuc     if (DS.isFriendSpecified()) {
3692*f4a2713aSLionel Sambuc       Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
3693*f4a2713aSLionel Sambuc         << SourceRange(DS.getFriendSpecLoc());
3694*f4a2713aSLionel Sambuc       ConsumeBrace();
3695*f4a2713aSLionel Sambuc       SkipUntil(tok::r_brace, StopAtSemi);
3696*f4a2713aSLionel Sambuc       TUK = Sema::TUK_Friend;
3697*f4a2713aSLionel Sambuc     } else {
3698*f4a2713aSLionel Sambuc       TUK = Sema::TUK_Definition;
3699*f4a2713aSLionel Sambuc     }
3700*f4a2713aSLionel Sambuc   } else if (DSC != DSC_type_specifier &&
3701*f4a2713aSLionel Sambuc              (Tok.is(tok::semi) ||
3702*f4a2713aSLionel Sambuc               (Tok.isAtStartOfLine() &&
3703*f4a2713aSLionel Sambuc                !isValidAfterTypeSpecifier(CanBeBitfield)))) {
3704*f4a2713aSLionel Sambuc     TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
3705*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::semi)) {
3706*f4a2713aSLionel Sambuc       // A semicolon was missing after this declaration. Diagnose and recover.
3707*f4a2713aSLionel Sambuc       ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
3708*f4a2713aSLionel Sambuc                        "enum");
3709*f4a2713aSLionel Sambuc       PP.EnterToken(Tok);
3710*f4a2713aSLionel Sambuc       Tok.setKind(tok::semi);
3711*f4a2713aSLionel Sambuc     }
3712*f4a2713aSLionel Sambuc   } else {
3713*f4a2713aSLionel Sambuc     TUK = Sema::TUK_Reference;
3714*f4a2713aSLionel Sambuc   }
3715*f4a2713aSLionel Sambuc 
3716*f4a2713aSLionel Sambuc   // If this is an elaborated type specifier, and we delayed
3717*f4a2713aSLionel Sambuc   // diagnostics before, just merge them into the current pool.
3718*f4a2713aSLionel Sambuc   if (TUK == Sema::TUK_Reference && shouldDelayDiagsInTag) {
3719*f4a2713aSLionel Sambuc     diagsFromTag.redelay();
3720*f4a2713aSLionel Sambuc   }
3721*f4a2713aSLionel Sambuc 
3722*f4a2713aSLionel Sambuc   MultiTemplateParamsArg TParams;
3723*f4a2713aSLionel Sambuc   if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
3724*f4a2713aSLionel Sambuc       TUK != Sema::TUK_Reference) {
3725*f4a2713aSLionel Sambuc     if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {
3726*f4a2713aSLionel Sambuc       // Skip the rest of this declarator, up until the comma or semicolon.
3727*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_enum_template);
3728*f4a2713aSLionel Sambuc       SkipUntil(tok::comma, StopAtSemi);
3729*f4a2713aSLionel Sambuc       return;
3730*f4a2713aSLionel Sambuc     }
3731*f4a2713aSLionel Sambuc 
3732*f4a2713aSLionel Sambuc     if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
3733*f4a2713aSLionel Sambuc       // Enumerations can't be explicitly instantiated.
3734*f4a2713aSLionel Sambuc       DS.SetTypeSpecError();
3735*f4a2713aSLionel Sambuc       Diag(StartLoc, diag::err_explicit_instantiation_enum);
3736*f4a2713aSLionel Sambuc       return;
3737*f4a2713aSLionel Sambuc     }
3738*f4a2713aSLionel Sambuc 
3739*f4a2713aSLionel Sambuc     assert(TemplateInfo.TemplateParams && "no template parameters");
3740*f4a2713aSLionel Sambuc     TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
3741*f4a2713aSLionel Sambuc                                      TemplateInfo.TemplateParams->size());
3742*f4a2713aSLionel Sambuc   }
3743*f4a2713aSLionel Sambuc 
3744*f4a2713aSLionel Sambuc   if (TUK == Sema::TUK_Reference)
3745*f4a2713aSLionel Sambuc     ProhibitAttributes(attrs);
3746*f4a2713aSLionel Sambuc 
3747*f4a2713aSLionel Sambuc   if (!Name && TUK != Sema::TUK_Definition) {
3748*f4a2713aSLionel Sambuc     Diag(Tok, diag::err_enumerator_unnamed_no_def);
3749*f4a2713aSLionel Sambuc 
3750*f4a2713aSLionel Sambuc     // Skip the rest of this declarator, up until the comma or semicolon.
3751*f4a2713aSLionel Sambuc     SkipUntil(tok::comma, StopAtSemi);
3752*f4a2713aSLionel Sambuc     return;
3753*f4a2713aSLionel Sambuc   }
3754*f4a2713aSLionel Sambuc 
3755*f4a2713aSLionel Sambuc   bool Owned = false;
3756*f4a2713aSLionel Sambuc   bool IsDependent = false;
3757*f4a2713aSLionel Sambuc   const char *PrevSpec = 0;
3758*f4a2713aSLionel Sambuc   unsigned DiagID;
3759*f4a2713aSLionel Sambuc   Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
3760*f4a2713aSLionel Sambuc                                    StartLoc, SS, Name, NameLoc, attrs.getList(),
3761*f4a2713aSLionel Sambuc                                    AS, DS.getModulePrivateSpecLoc(), TParams,
3762*f4a2713aSLionel Sambuc                                    Owned, IsDependent, ScopedEnumKWLoc,
3763*f4a2713aSLionel Sambuc                                    IsScopedUsingClassTag, BaseType);
3764*f4a2713aSLionel Sambuc 
3765*f4a2713aSLionel Sambuc   if (IsDependent) {
3766*f4a2713aSLionel Sambuc     // This enum has a dependent nested-name-specifier. Handle it as a
3767*f4a2713aSLionel Sambuc     // dependent tag.
3768*f4a2713aSLionel Sambuc     if (!Name) {
3769*f4a2713aSLionel Sambuc       DS.SetTypeSpecError();
3770*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_expected_type_name_after_typename);
3771*f4a2713aSLionel Sambuc       return;
3772*f4a2713aSLionel Sambuc     }
3773*f4a2713aSLionel Sambuc 
3774*f4a2713aSLionel Sambuc     TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
3775*f4a2713aSLionel Sambuc                                                 TUK, SS, Name, StartLoc,
3776*f4a2713aSLionel Sambuc                                                 NameLoc);
3777*f4a2713aSLionel Sambuc     if (Type.isInvalid()) {
3778*f4a2713aSLionel Sambuc       DS.SetTypeSpecError();
3779*f4a2713aSLionel Sambuc       return;
3780*f4a2713aSLionel Sambuc     }
3781*f4a2713aSLionel Sambuc 
3782*f4a2713aSLionel Sambuc     if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
3783*f4a2713aSLionel Sambuc                            NameLoc.isValid() ? NameLoc : StartLoc,
3784*f4a2713aSLionel Sambuc                            PrevSpec, DiagID, Type.get()))
3785*f4a2713aSLionel Sambuc       Diag(StartLoc, DiagID) << PrevSpec;
3786*f4a2713aSLionel Sambuc 
3787*f4a2713aSLionel Sambuc     return;
3788*f4a2713aSLionel Sambuc   }
3789*f4a2713aSLionel Sambuc 
3790*f4a2713aSLionel Sambuc   if (!TagDecl) {
3791*f4a2713aSLionel Sambuc     // The action failed to produce an enumeration tag. If this is a
3792*f4a2713aSLionel Sambuc     // definition, consume the entire definition.
3793*f4a2713aSLionel Sambuc     if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
3794*f4a2713aSLionel Sambuc       ConsumeBrace();
3795*f4a2713aSLionel Sambuc       SkipUntil(tok::r_brace, StopAtSemi);
3796*f4a2713aSLionel Sambuc     }
3797*f4a2713aSLionel Sambuc 
3798*f4a2713aSLionel Sambuc     DS.SetTypeSpecError();
3799*f4a2713aSLionel Sambuc     return;
3800*f4a2713aSLionel Sambuc   }
3801*f4a2713aSLionel Sambuc 
3802*f4a2713aSLionel Sambuc   if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference)
3803*f4a2713aSLionel Sambuc     ParseEnumBody(StartLoc, TagDecl);
3804*f4a2713aSLionel Sambuc 
3805*f4a2713aSLionel Sambuc   if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
3806*f4a2713aSLionel Sambuc                          NameLoc.isValid() ? NameLoc : StartLoc,
3807*f4a2713aSLionel Sambuc                          PrevSpec, DiagID, TagDecl, Owned))
3808*f4a2713aSLionel Sambuc     Diag(StartLoc, DiagID) << PrevSpec;
3809*f4a2713aSLionel Sambuc }
3810*f4a2713aSLionel Sambuc 
3811*f4a2713aSLionel Sambuc /// ParseEnumBody - Parse a {} enclosed enumerator-list.
3812*f4a2713aSLionel Sambuc ///       enumerator-list:
3813*f4a2713aSLionel Sambuc ///         enumerator
3814*f4a2713aSLionel Sambuc ///         enumerator-list ',' enumerator
3815*f4a2713aSLionel Sambuc ///       enumerator:
3816*f4a2713aSLionel Sambuc ///         enumeration-constant
3817*f4a2713aSLionel Sambuc ///         enumeration-constant '=' constant-expression
3818*f4a2713aSLionel Sambuc ///       enumeration-constant:
3819*f4a2713aSLionel Sambuc ///         identifier
3820*f4a2713aSLionel Sambuc ///
3821*f4a2713aSLionel Sambuc void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
3822*f4a2713aSLionel Sambuc   // Enter the scope of the enum body and start the definition.
3823*f4a2713aSLionel Sambuc   ParseScope EnumScope(this, Scope::DeclScope);
3824*f4a2713aSLionel Sambuc   Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
3825*f4a2713aSLionel Sambuc 
3826*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_brace);
3827*f4a2713aSLionel Sambuc   T.consumeOpen();
3828*f4a2713aSLionel Sambuc 
3829*f4a2713aSLionel Sambuc   // C does not allow an empty enumerator-list, C++ does [dcl.enum].
3830*f4a2713aSLionel Sambuc   if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
3831*f4a2713aSLionel Sambuc     Diag(Tok, diag::error_empty_enum);
3832*f4a2713aSLionel Sambuc 
3833*f4a2713aSLionel Sambuc   SmallVector<Decl *, 32> EnumConstantDecls;
3834*f4a2713aSLionel Sambuc 
3835*f4a2713aSLionel Sambuc   Decl *LastEnumConstDecl = 0;
3836*f4a2713aSLionel Sambuc 
3837*f4a2713aSLionel Sambuc   // Parse the enumerator-list.
3838*f4a2713aSLionel Sambuc   while (Tok.is(tok::identifier)) {
3839*f4a2713aSLionel Sambuc     IdentifierInfo *Ident = Tok.getIdentifierInfo();
3840*f4a2713aSLionel Sambuc     SourceLocation IdentLoc = ConsumeToken();
3841*f4a2713aSLionel Sambuc 
3842*f4a2713aSLionel Sambuc     // If attributes exist after the enumerator, parse them.
3843*f4a2713aSLionel Sambuc     ParsedAttributesWithRange attrs(AttrFactory);
3844*f4a2713aSLionel Sambuc     MaybeParseGNUAttributes(attrs);
3845*f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(attrs);
3846*f4a2713aSLionel Sambuc     ProhibitAttributes(attrs);
3847*f4a2713aSLionel Sambuc 
3848*f4a2713aSLionel Sambuc     SourceLocation EqualLoc;
3849*f4a2713aSLionel Sambuc     ExprResult AssignedVal;
3850*f4a2713aSLionel Sambuc     ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
3851*f4a2713aSLionel Sambuc 
3852*f4a2713aSLionel Sambuc     if (Tok.is(tok::equal)) {
3853*f4a2713aSLionel Sambuc       EqualLoc = ConsumeToken();
3854*f4a2713aSLionel Sambuc       AssignedVal = ParseConstantExpression();
3855*f4a2713aSLionel Sambuc       if (AssignedVal.isInvalid())
3856*f4a2713aSLionel Sambuc         SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
3857*f4a2713aSLionel Sambuc     }
3858*f4a2713aSLionel Sambuc 
3859*f4a2713aSLionel Sambuc     // Install the enumerator constant into EnumDecl.
3860*f4a2713aSLionel Sambuc     Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
3861*f4a2713aSLionel Sambuc                                                     LastEnumConstDecl,
3862*f4a2713aSLionel Sambuc                                                     IdentLoc, Ident,
3863*f4a2713aSLionel Sambuc                                                     attrs.getList(), EqualLoc,
3864*f4a2713aSLionel Sambuc                                                     AssignedVal.release());
3865*f4a2713aSLionel Sambuc     PD.complete(EnumConstDecl);
3866*f4a2713aSLionel Sambuc 
3867*f4a2713aSLionel Sambuc     EnumConstantDecls.push_back(EnumConstDecl);
3868*f4a2713aSLionel Sambuc     LastEnumConstDecl = EnumConstDecl;
3869*f4a2713aSLionel Sambuc 
3870*f4a2713aSLionel Sambuc     if (Tok.is(tok::identifier)) {
3871*f4a2713aSLionel Sambuc       // We're missing a comma between enumerators.
3872*f4a2713aSLionel Sambuc       SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
3873*f4a2713aSLionel Sambuc       Diag(Loc, diag::err_enumerator_list_missing_comma)
3874*f4a2713aSLionel Sambuc         << FixItHint::CreateInsertion(Loc, ", ");
3875*f4a2713aSLionel Sambuc       continue;
3876*f4a2713aSLionel Sambuc     }
3877*f4a2713aSLionel Sambuc 
3878*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::comma))
3879*f4a2713aSLionel Sambuc       break;
3880*f4a2713aSLionel Sambuc     SourceLocation CommaLoc = ConsumeToken();
3881*f4a2713aSLionel Sambuc 
3882*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier)) {
3883*f4a2713aSLionel Sambuc       if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)
3884*f4a2713aSLionel Sambuc         Diag(CommaLoc, getLangOpts().CPlusPlus ?
3885*f4a2713aSLionel Sambuc                diag::ext_enumerator_list_comma_cxx :
3886*f4a2713aSLionel Sambuc                diag::ext_enumerator_list_comma_c)
3887*f4a2713aSLionel Sambuc           << FixItHint::CreateRemoval(CommaLoc);
3888*f4a2713aSLionel Sambuc       else if (getLangOpts().CPlusPlus11)
3889*f4a2713aSLionel Sambuc         Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
3890*f4a2713aSLionel Sambuc           << FixItHint::CreateRemoval(CommaLoc);
3891*f4a2713aSLionel Sambuc     }
3892*f4a2713aSLionel Sambuc   }
3893*f4a2713aSLionel Sambuc 
3894*f4a2713aSLionel Sambuc   // Eat the }.
3895*f4a2713aSLionel Sambuc   T.consumeClose();
3896*f4a2713aSLionel Sambuc 
3897*f4a2713aSLionel Sambuc   // If attributes exist after the identifier list, parse them.
3898*f4a2713aSLionel Sambuc   ParsedAttributes attrs(AttrFactory);
3899*f4a2713aSLionel Sambuc   MaybeParseGNUAttributes(attrs);
3900*f4a2713aSLionel Sambuc 
3901*f4a2713aSLionel Sambuc   Actions.ActOnEnumBody(StartLoc, T.getOpenLocation(), T.getCloseLocation(),
3902*f4a2713aSLionel Sambuc                         EnumDecl, EnumConstantDecls,
3903*f4a2713aSLionel Sambuc                         getCurScope(),
3904*f4a2713aSLionel Sambuc                         attrs.getList());
3905*f4a2713aSLionel Sambuc 
3906*f4a2713aSLionel Sambuc   EnumScope.Exit();
3907*f4a2713aSLionel Sambuc   Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl,
3908*f4a2713aSLionel Sambuc                                    T.getCloseLocation());
3909*f4a2713aSLionel Sambuc 
3910*f4a2713aSLionel Sambuc   // The next token must be valid after an enum definition. If not, a ';'
3911*f4a2713aSLionel Sambuc   // was probably forgotten.
3912*f4a2713aSLionel Sambuc   bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
3913*f4a2713aSLionel Sambuc   if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
3914*f4a2713aSLionel Sambuc     ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
3915*f4a2713aSLionel Sambuc     // Push this token back into the preprocessor and change our current token
3916*f4a2713aSLionel Sambuc     // to ';' so that the rest of the code recovers as though there were an
3917*f4a2713aSLionel Sambuc     // ';' after the definition.
3918*f4a2713aSLionel Sambuc     PP.EnterToken(Tok);
3919*f4a2713aSLionel Sambuc     Tok.setKind(tok::semi);
3920*f4a2713aSLionel Sambuc   }
3921*f4a2713aSLionel Sambuc }
3922*f4a2713aSLionel Sambuc 
3923*f4a2713aSLionel Sambuc /// isTypeSpecifierQualifier - Return true if the current token could be the
3924*f4a2713aSLionel Sambuc /// start of a type-qualifier-list.
3925*f4a2713aSLionel Sambuc bool Parser::isTypeQualifier() const {
3926*f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
3927*f4a2713aSLionel Sambuc   default: return false;
3928*f4a2713aSLionel Sambuc 
3929*f4a2713aSLionel Sambuc     // type-qualifier only in OpenCL
3930*f4a2713aSLionel Sambuc   case tok::kw_private:
3931*f4a2713aSLionel Sambuc     return getLangOpts().OpenCL;
3932*f4a2713aSLionel Sambuc 
3933*f4a2713aSLionel Sambuc     // type-qualifier
3934*f4a2713aSLionel Sambuc   case tok::kw_const:
3935*f4a2713aSLionel Sambuc   case tok::kw_volatile:
3936*f4a2713aSLionel Sambuc   case tok::kw_restrict:
3937*f4a2713aSLionel Sambuc   case tok::kw___private:
3938*f4a2713aSLionel Sambuc   case tok::kw___local:
3939*f4a2713aSLionel Sambuc   case tok::kw___global:
3940*f4a2713aSLionel Sambuc   case tok::kw___constant:
3941*f4a2713aSLionel Sambuc   case tok::kw___read_only:
3942*f4a2713aSLionel Sambuc   case tok::kw___read_write:
3943*f4a2713aSLionel Sambuc   case tok::kw___write_only:
3944*f4a2713aSLionel Sambuc     return true;
3945*f4a2713aSLionel Sambuc   }
3946*f4a2713aSLionel Sambuc }
3947*f4a2713aSLionel Sambuc 
3948*f4a2713aSLionel Sambuc /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
3949*f4a2713aSLionel Sambuc /// is definitely a type-specifier.  Return false if it isn't part of a type
3950*f4a2713aSLionel Sambuc /// specifier or if we're not sure.
3951*f4a2713aSLionel Sambuc bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
3952*f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
3953*f4a2713aSLionel Sambuc   default: return false;
3954*f4a2713aSLionel Sambuc     // type-specifiers
3955*f4a2713aSLionel Sambuc   case tok::kw_short:
3956*f4a2713aSLionel Sambuc   case tok::kw_long:
3957*f4a2713aSLionel Sambuc   case tok::kw___int64:
3958*f4a2713aSLionel Sambuc   case tok::kw___int128:
3959*f4a2713aSLionel Sambuc   case tok::kw_signed:
3960*f4a2713aSLionel Sambuc   case tok::kw_unsigned:
3961*f4a2713aSLionel Sambuc   case tok::kw__Complex:
3962*f4a2713aSLionel Sambuc   case tok::kw__Imaginary:
3963*f4a2713aSLionel Sambuc   case tok::kw_void:
3964*f4a2713aSLionel Sambuc   case tok::kw_char:
3965*f4a2713aSLionel Sambuc   case tok::kw_wchar_t:
3966*f4a2713aSLionel Sambuc   case tok::kw_char16_t:
3967*f4a2713aSLionel Sambuc   case tok::kw_char32_t:
3968*f4a2713aSLionel Sambuc   case tok::kw_int:
3969*f4a2713aSLionel Sambuc   case tok::kw_half:
3970*f4a2713aSLionel Sambuc   case tok::kw_float:
3971*f4a2713aSLionel Sambuc   case tok::kw_double:
3972*f4a2713aSLionel Sambuc   case tok::kw_bool:
3973*f4a2713aSLionel Sambuc   case tok::kw__Bool:
3974*f4a2713aSLionel Sambuc   case tok::kw__Decimal32:
3975*f4a2713aSLionel Sambuc   case tok::kw__Decimal64:
3976*f4a2713aSLionel Sambuc   case tok::kw__Decimal128:
3977*f4a2713aSLionel Sambuc   case tok::kw___vector:
3978*f4a2713aSLionel Sambuc 
3979*f4a2713aSLionel Sambuc     // OpenCL specific types:
3980*f4a2713aSLionel Sambuc   case tok::kw_image1d_t:
3981*f4a2713aSLionel Sambuc   case tok::kw_image1d_array_t:
3982*f4a2713aSLionel Sambuc   case tok::kw_image1d_buffer_t:
3983*f4a2713aSLionel Sambuc   case tok::kw_image2d_t:
3984*f4a2713aSLionel Sambuc   case tok::kw_image2d_array_t:
3985*f4a2713aSLionel Sambuc   case tok::kw_image3d_t:
3986*f4a2713aSLionel Sambuc   case tok::kw_sampler_t:
3987*f4a2713aSLionel Sambuc   case tok::kw_event_t:
3988*f4a2713aSLionel Sambuc 
3989*f4a2713aSLionel Sambuc     // struct-or-union-specifier (C99) or class-specifier (C++)
3990*f4a2713aSLionel Sambuc   case tok::kw_class:
3991*f4a2713aSLionel Sambuc   case tok::kw_struct:
3992*f4a2713aSLionel Sambuc   case tok::kw___interface:
3993*f4a2713aSLionel Sambuc   case tok::kw_union:
3994*f4a2713aSLionel Sambuc     // enum-specifier
3995*f4a2713aSLionel Sambuc   case tok::kw_enum:
3996*f4a2713aSLionel Sambuc 
3997*f4a2713aSLionel Sambuc     // typedef-name
3998*f4a2713aSLionel Sambuc   case tok::annot_typename:
3999*f4a2713aSLionel Sambuc     return true;
4000*f4a2713aSLionel Sambuc   }
4001*f4a2713aSLionel Sambuc }
4002*f4a2713aSLionel Sambuc 
4003*f4a2713aSLionel Sambuc /// isTypeSpecifierQualifier - Return true if the current token could be the
4004*f4a2713aSLionel Sambuc /// start of a specifier-qualifier-list.
4005*f4a2713aSLionel Sambuc bool Parser::isTypeSpecifierQualifier() {
4006*f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
4007*f4a2713aSLionel Sambuc   default: return false;
4008*f4a2713aSLionel Sambuc 
4009*f4a2713aSLionel Sambuc   case tok::identifier:   // foo::bar
4010*f4a2713aSLionel Sambuc     if (TryAltiVecVectorToken())
4011*f4a2713aSLionel Sambuc       return true;
4012*f4a2713aSLionel Sambuc     // Fall through.
4013*f4a2713aSLionel Sambuc   case tok::kw_typename:  // typename T::type
4014*f4a2713aSLionel Sambuc     // Annotate typenames and C++ scope specifiers.  If we get one, just
4015*f4a2713aSLionel Sambuc     // recurse to handle whatever we get.
4016*f4a2713aSLionel Sambuc     if (TryAnnotateTypeOrScopeToken())
4017*f4a2713aSLionel Sambuc       return true;
4018*f4a2713aSLionel Sambuc     if (Tok.is(tok::identifier))
4019*f4a2713aSLionel Sambuc       return false;
4020*f4a2713aSLionel Sambuc     return isTypeSpecifierQualifier();
4021*f4a2713aSLionel Sambuc 
4022*f4a2713aSLionel Sambuc   case tok::coloncolon:   // ::foo::bar
4023*f4a2713aSLionel Sambuc     if (NextToken().is(tok::kw_new) ||    // ::new
4024*f4a2713aSLionel Sambuc         NextToken().is(tok::kw_delete))   // ::delete
4025*f4a2713aSLionel Sambuc       return false;
4026*f4a2713aSLionel Sambuc 
4027*f4a2713aSLionel Sambuc     if (TryAnnotateTypeOrScopeToken())
4028*f4a2713aSLionel Sambuc       return true;
4029*f4a2713aSLionel Sambuc     return isTypeSpecifierQualifier();
4030*f4a2713aSLionel Sambuc 
4031*f4a2713aSLionel Sambuc     // GNU attributes support.
4032*f4a2713aSLionel Sambuc   case tok::kw___attribute:
4033*f4a2713aSLionel Sambuc     // GNU typeof support.
4034*f4a2713aSLionel Sambuc   case tok::kw_typeof:
4035*f4a2713aSLionel Sambuc 
4036*f4a2713aSLionel Sambuc     // type-specifiers
4037*f4a2713aSLionel Sambuc   case tok::kw_short:
4038*f4a2713aSLionel Sambuc   case tok::kw_long:
4039*f4a2713aSLionel Sambuc   case tok::kw___int64:
4040*f4a2713aSLionel Sambuc   case tok::kw___int128:
4041*f4a2713aSLionel Sambuc   case tok::kw_signed:
4042*f4a2713aSLionel Sambuc   case tok::kw_unsigned:
4043*f4a2713aSLionel Sambuc   case tok::kw__Complex:
4044*f4a2713aSLionel Sambuc   case tok::kw__Imaginary:
4045*f4a2713aSLionel Sambuc   case tok::kw_void:
4046*f4a2713aSLionel Sambuc   case tok::kw_char:
4047*f4a2713aSLionel Sambuc   case tok::kw_wchar_t:
4048*f4a2713aSLionel Sambuc   case tok::kw_char16_t:
4049*f4a2713aSLionel Sambuc   case tok::kw_char32_t:
4050*f4a2713aSLionel Sambuc   case tok::kw_int:
4051*f4a2713aSLionel Sambuc   case tok::kw_half:
4052*f4a2713aSLionel Sambuc   case tok::kw_float:
4053*f4a2713aSLionel Sambuc   case tok::kw_double:
4054*f4a2713aSLionel Sambuc   case tok::kw_bool:
4055*f4a2713aSLionel Sambuc   case tok::kw__Bool:
4056*f4a2713aSLionel Sambuc   case tok::kw__Decimal32:
4057*f4a2713aSLionel Sambuc   case tok::kw__Decimal64:
4058*f4a2713aSLionel Sambuc   case tok::kw__Decimal128:
4059*f4a2713aSLionel Sambuc   case tok::kw___vector:
4060*f4a2713aSLionel Sambuc 
4061*f4a2713aSLionel Sambuc     // OpenCL specific types:
4062*f4a2713aSLionel Sambuc   case tok::kw_image1d_t:
4063*f4a2713aSLionel Sambuc   case tok::kw_image1d_array_t:
4064*f4a2713aSLionel Sambuc   case tok::kw_image1d_buffer_t:
4065*f4a2713aSLionel Sambuc   case tok::kw_image2d_t:
4066*f4a2713aSLionel Sambuc   case tok::kw_image2d_array_t:
4067*f4a2713aSLionel Sambuc   case tok::kw_image3d_t:
4068*f4a2713aSLionel Sambuc   case tok::kw_sampler_t:
4069*f4a2713aSLionel Sambuc   case tok::kw_event_t:
4070*f4a2713aSLionel Sambuc 
4071*f4a2713aSLionel Sambuc     // struct-or-union-specifier (C99) or class-specifier (C++)
4072*f4a2713aSLionel Sambuc   case tok::kw_class:
4073*f4a2713aSLionel Sambuc   case tok::kw_struct:
4074*f4a2713aSLionel Sambuc   case tok::kw___interface:
4075*f4a2713aSLionel Sambuc   case tok::kw_union:
4076*f4a2713aSLionel Sambuc     // enum-specifier
4077*f4a2713aSLionel Sambuc   case tok::kw_enum:
4078*f4a2713aSLionel Sambuc 
4079*f4a2713aSLionel Sambuc     // type-qualifier
4080*f4a2713aSLionel Sambuc   case tok::kw_const:
4081*f4a2713aSLionel Sambuc   case tok::kw_volatile:
4082*f4a2713aSLionel Sambuc   case tok::kw_restrict:
4083*f4a2713aSLionel Sambuc 
4084*f4a2713aSLionel Sambuc     // Debugger support.
4085*f4a2713aSLionel Sambuc   case tok::kw___unknown_anytype:
4086*f4a2713aSLionel Sambuc 
4087*f4a2713aSLionel Sambuc     // typedef-name
4088*f4a2713aSLionel Sambuc   case tok::annot_typename:
4089*f4a2713aSLionel Sambuc     return true;
4090*f4a2713aSLionel Sambuc 
4091*f4a2713aSLionel Sambuc     // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4092*f4a2713aSLionel Sambuc   case tok::less:
4093*f4a2713aSLionel Sambuc     return getLangOpts().ObjC1;
4094*f4a2713aSLionel Sambuc 
4095*f4a2713aSLionel Sambuc   case tok::kw___cdecl:
4096*f4a2713aSLionel Sambuc   case tok::kw___stdcall:
4097*f4a2713aSLionel Sambuc   case tok::kw___fastcall:
4098*f4a2713aSLionel Sambuc   case tok::kw___thiscall:
4099*f4a2713aSLionel Sambuc   case tok::kw___w64:
4100*f4a2713aSLionel Sambuc   case tok::kw___ptr64:
4101*f4a2713aSLionel Sambuc   case tok::kw___ptr32:
4102*f4a2713aSLionel Sambuc   case tok::kw___pascal:
4103*f4a2713aSLionel Sambuc   case tok::kw___unaligned:
4104*f4a2713aSLionel Sambuc 
4105*f4a2713aSLionel Sambuc   case tok::kw___private:
4106*f4a2713aSLionel Sambuc   case tok::kw___local:
4107*f4a2713aSLionel Sambuc   case tok::kw___global:
4108*f4a2713aSLionel Sambuc   case tok::kw___constant:
4109*f4a2713aSLionel Sambuc   case tok::kw___read_only:
4110*f4a2713aSLionel Sambuc   case tok::kw___read_write:
4111*f4a2713aSLionel Sambuc   case tok::kw___write_only:
4112*f4a2713aSLionel Sambuc 
4113*f4a2713aSLionel Sambuc     return true;
4114*f4a2713aSLionel Sambuc 
4115*f4a2713aSLionel Sambuc   case tok::kw_private:
4116*f4a2713aSLionel Sambuc     return getLangOpts().OpenCL;
4117*f4a2713aSLionel Sambuc 
4118*f4a2713aSLionel Sambuc   // C11 _Atomic
4119*f4a2713aSLionel Sambuc   case tok::kw__Atomic:
4120*f4a2713aSLionel Sambuc     return true;
4121*f4a2713aSLionel Sambuc   }
4122*f4a2713aSLionel Sambuc }
4123*f4a2713aSLionel Sambuc 
4124*f4a2713aSLionel Sambuc /// isDeclarationSpecifier() - Return true if the current token is part of a
4125*f4a2713aSLionel Sambuc /// declaration specifier.
4126*f4a2713aSLionel Sambuc ///
4127*f4a2713aSLionel Sambuc /// \param DisambiguatingWithExpression True to indicate that the purpose of
4128*f4a2713aSLionel Sambuc /// this check is to disambiguate between an expression and a declaration.
4129*f4a2713aSLionel Sambuc bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
4130*f4a2713aSLionel Sambuc   switch (Tok.getKind()) {
4131*f4a2713aSLionel Sambuc   default: return false;
4132*f4a2713aSLionel Sambuc 
4133*f4a2713aSLionel Sambuc   case tok::kw_private:
4134*f4a2713aSLionel Sambuc     return getLangOpts().OpenCL;
4135*f4a2713aSLionel Sambuc 
4136*f4a2713aSLionel Sambuc   case tok::identifier:   // foo::bar
4137*f4a2713aSLionel Sambuc     // Unfortunate hack to support "Class.factoryMethod" notation.
4138*f4a2713aSLionel Sambuc     if (getLangOpts().ObjC1 && NextToken().is(tok::period))
4139*f4a2713aSLionel Sambuc       return false;
4140*f4a2713aSLionel Sambuc     if (TryAltiVecVectorToken())
4141*f4a2713aSLionel Sambuc       return true;
4142*f4a2713aSLionel Sambuc     // Fall through.
4143*f4a2713aSLionel Sambuc   case tok::kw_decltype: // decltype(T())::type
4144*f4a2713aSLionel Sambuc   case tok::kw_typename: // typename T::type
4145*f4a2713aSLionel Sambuc     // Annotate typenames and C++ scope specifiers.  If we get one, just
4146*f4a2713aSLionel Sambuc     // recurse to handle whatever we get.
4147*f4a2713aSLionel Sambuc     if (TryAnnotateTypeOrScopeToken())
4148*f4a2713aSLionel Sambuc       return true;
4149*f4a2713aSLionel Sambuc     if (Tok.is(tok::identifier))
4150*f4a2713aSLionel Sambuc       return false;
4151*f4a2713aSLionel Sambuc 
4152*f4a2713aSLionel Sambuc     // If we're in Objective-C and we have an Objective-C class type followed
4153*f4a2713aSLionel Sambuc     // by an identifier and then either ':' or ']', in a place where an
4154*f4a2713aSLionel Sambuc     // expression is permitted, then this is probably a class message send
4155*f4a2713aSLionel Sambuc     // missing the initial '['. In this case, we won't consider this to be
4156*f4a2713aSLionel Sambuc     // the start of a declaration.
4157*f4a2713aSLionel Sambuc     if (DisambiguatingWithExpression &&
4158*f4a2713aSLionel Sambuc         isStartOfObjCClassMessageMissingOpenBracket())
4159*f4a2713aSLionel Sambuc       return false;
4160*f4a2713aSLionel Sambuc 
4161*f4a2713aSLionel Sambuc     return isDeclarationSpecifier();
4162*f4a2713aSLionel Sambuc 
4163*f4a2713aSLionel Sambuc   case tok::coloncolon:   // ::foo::bar
4164*f4a2713aSLionel Sambuc     if (NextToken().is(tok::kw_new) ||    // ::new
4165*f4a2713aSLionel Sambuc         NextToken().is(tok::kw_delete))   // ::delete
4166*f4a2713aSLionel Sambuc       return false;
4167*f4a2713aSLionel Sambuc 
4168*f4a2713aSLionel Sambuc     // Annotate typenames and C++ scope specifiers.  If we get one, just
4169*f4a2713aSLionel Sambuc     // recurse to handle whatever we get.
4170*f4a2713aSLionel Sambuc     if (TryAnnotateTypeOrScopeToken())
4171*f4a2713aSLionel Sambuc       return true;
4172*f4a2713aSLionel Sambuc     return isDeclarationSpecifier();
4173*f4a2713aSLionel Sambuc 
4174*f4a2713aSLionel Sambuc     // storage-class-specifier
4175*f4a2713aSLionel Sambuc   case tok::kw_typedef:
4176*f4a2713aSLionel Sambuc   case tok::kw_extern:
4177*f4a2713aSLionel Sambuc   case tok::kw___private_extern__:
4178*f4a2713aSLionel Sambuc   case tok::kw_static:
4179*f4a2713aSLionel Sambuc   case tok::kw_auto:
4180*f4a2713aSLionel Sambuc   case tok::kw_register:
4181*f4a2713aSLionel Sambuc   case tok::kw___thread:
4182*f4a2713aSLionel Sambuc   case tok::kw_thread_local:
4183*f4a2713aSLionel Sambuc   case tok::kw__Thread_local:
4184*f4a2713aSLionel Sambuc 
4185*f4a2713aSLionel Sambuc     // Modules
4186*f4a2713aSLionel Sambuc   case tok::kw___module_private__:
4187*f4a2713aSLionel Sambuc 
4188*f4a2713aSLionel Sambuc     // Debugger support
4189*f4a2713aSLionel Sambuc   case tok::kw___unknown_anytype:
4190*f4a2713aSLionel Sambuc 
4191*f4a2713aSLionel Sambuc     // type-specifiers
4192*f4a2713aSLionel Sambuc   case tok::kw_short:
4193*f4a2713aSLionel Sambuc   case tok::kw_long:
4194*f4a2713aSLionel Sambuc   case tok::kw___int64:
4195*f4a2713aSLionel Sambuc   case tok::kw___int128:
4196*f4a2713aSLionel Sambuc   case tok::kw_signed:
4197*f4a2713aSLionel Sambuc   case tok::kw_unsigned:
4198*f4a2713aSLionel Sambuc   case tok::kw__Complex:
4199*f4a2713aSLionel Sambuc   case tok::kw__Imaginary:
4200*f4a2713aSLionel Sambuc   case tok::kw_void:
4201*f4a2713aSLionel Sambuc   case tok::kw_char:
4202*f4a2713aSLionel Sambuc   case tok::kw_wchar_t:
4203*f4a2713aSLionel Sambuc   case tok::kw_char16_t:
4204*f4a2713aSLionel Sambuc   case tok::kw_char32_t:
4205*f4a2713aSLionel Sambuc 
4206*f4a2713aSLionel Sambuc   case tok::kw_int:
4207*f4a2713aSLionel Sambuc   case tok::kw_half:
4208*f4a2713aSLionel Sambuc   case tok::kw_float:
4209*f4a2713aSLionel Sambuc   case tok::kw_double:
4210*f4a2713aSLionel Sambuc   case tok::kw_bool:
4211*f4a2713aSLionel Sambuc   case tok::kw__Bool:
4212*f4a2713aSLionel Sambuc   case tok::kw__Decimal32:
4213*f4a2713aSLionel Sambuc   case tok::kw__Decimal64:
4214*f4a2713aSLionel Sambuc   case tok::kw__Decimal128:
4215*f4a2713aSLionel Sambuc   case tok::kw___vector:
4216*f4a2713aSLionel Sambuc 
4217*f4a2713aSLionel Sambuc     // OpenCL specific types:
4218*f4a2713aSLionel Sambuc   case tok::kw_image1d_t:
4219*f4a2713aSLionel Sambuc   case tok::kw_image1d_array_t:
4220*f4a2713aSLionel Sambuc   case tok::kw_image1d_buffer_t:
4221*f4a2713aSLionel Sambuc   case tok::kw_image2d_t:
4222*f4a2713aSLionel Sambuc   case tok::kw_image2d_array_t:
4223*f4a2713aSLionel Sambuc   case tok::kw_image3d_t:
4224*f4a2713aSLionel Sambuc   case tok::kw_sampler_t:
4225*f4a2713aSLionel Sambuc   case tok::kw_event_t:
4226*f4a2713aSLionel Sambuc 
4227*f4a2713aSLionel Sambuc     // struct-or-union-specifier (C99) or class-specifier (C++)
4228*f4a2713aSLionel Sambuc   case tok::kw_class:
4229*f4a2713aSLionel Sambuc   case tok::kw_struct:
4230*f4a2713aSLionel Sambuc   case tok::kw_union:
4231*f4a2713aSLionel Sambuc   case tok::kw___interface:
4232*f4a2713aSLionel Sambuc     // enum-specifier
4233*f4a2713aSLionel Sambuc   case tok::kw_enum:
4234*f4a2713aSLionel Sambuc 
4235*f4a2713aSLionel Sambuc     // type-qualifier
4236*f4a2713aSLionel Sambuc   case tok::kw_const:
4237*f4a2713aSLionel Sambuc   case tok::kw_volatile:
4238*f4a2713aSLionel Sambuc   case tok::kw_restrict:
4239*f4a2713aSLionel Sambuc 
4240*f4a2713aSLionel Sambuc     // function-specifier
4241*f4a2713aSLionel Sambuc   case tok::kw_inline:
4242*f4a2713aSLionel Sambuc   case tok::kw_virtual:
4243*f4a2713aSLionel Sambuc   case tok::kw_explicit:
4244*f4a2713aSLionel Sambuc   case tok::kw__Noreturn:
4245*f4a2713aSLionel Sambuc 
4246*f4a2713aSLionel Sambuc     // alignment-specifier
4247*f4a2713aSLionel Sambuc   case tok::kw__Alignas:
4248*f4a2713aSLionel Sambuc 
4249*f4a2713aSLionel Sambuc     // friend keyword.
4250*f4a2713aSLionel Sambuc   case tok::kw_friend:
4251*f4a2713aSLionel Sambuc 
4252*f4a2713aSLionel Sambuc     // static_assert-declaration
4253*f4a2713aSLionel Sambuc   case tok::kw__Static_assert:
4254*f4a2713aSLionel Sambuc 
4255*f4a2713aSLionel Sambuc     // GNU typeof support.
4256*f4a2713aSLionel Sambuc   case tok::kw_typeof:
4257*f4a2713aSLionel Sambuc 
4258*f4a2713aSLionel Sambuc     // GNU attributes.
4259*f4a2713aSLionel Sambuc   case tok::kw___attribute:
4260*f4a2713aSLionel Sambuc 
4261*f4a2713aSLionel Sambuc     // C++11 decltype and constexpr.
4262*f4a2713aSLionel Sambuc   case tok::annot_decltype:
4263*f4a2713aSLionel Sambuc   case tok::kw_constexpr:
4264*f4a2713aSLionel Sambuc 
4265*f4a2713aSLionel Sambuc     // C11 _Atomic
4266*f4a2713aSLionel Sambuc   case tok::kw__Atomic:
4267*f4a2713aSLionel Sambuc     return true;
4268*f4a2713aSLionel Sambuc 
4269*f4a2713aSLionel Sambuc     // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
4270*f4a2713aSLionel Sambuc   case tok::less:
4271*f4a2713aSLionel Sambuc     return getLangOpts().ObjC1;
4272*f4a2713aSLionel Sambuc 
4273*f4a2713aSLionel Sambuc     // typedef-name
4274*f4a2713aSLionel Sambuc   case tok::annot_typename:
4275*f4a2713aSLionel Sambuc     return !DisambiguatingWithExpression ||
4276*f4a2713aSLionel Sambuc            !isStartOfObjCClassMessageMissingOpenBracket();
4277*f4a2713aSLionel Sambuc 
4278*f4a2713aSLionel Sambuc   case tok::kw___declspec:
4279*f4a2713aSLionel Sambuc   case tok::kw___cdecl:
4280*f4a2713aSLionel Sambuc   case tok::kw___stdcall:
4281*f4a2713aSLionel Sambuc   case tok::kw___fastcall:
4282*f4a2713aSLionel Sambuc   case tok::kw___thiscall:
4283*f4a2713aSLionel Sambuc   case tok::kw___w64:
4284*f4a2713aSLionel Sambuc   case tok::kw___sptr:
4285*f4a2713aSLionel Sambuc   case tok::kw___uptr:
4286*f4a2713aSLionel Sambuc   case tok::kw___ptr64:
4287*f4a2713aSLionel Sambuc   case tok::kw___ptr32:
4288*f4a2713aSLionel Sambuc   case tok::kw___forceinline:
4289*f4a2713aSLionel Sambuc   case tok::kw___pascal:
4290*f4a2713aSLionel Sambuc   case tok::kw___unaligned:
4291*f4a2713aSLionel Sambuc 
4292*f4a2713aSLionel Sambuc   case tok::kw___private:
4293*f4a2713aSLionel Sambuc   case tok::kw___local:
4294*f4a2713aSLionel Sambuc   case tok::kw___global:
4295*f4a2713aSLionel Sambuc   case tok::kw___constant:
4296*f4a2713aSLionel Sambuc   case tok::kw___read_only:
4297*f4a2713aSLionel Sambuc   case tok::kw___read_write:
4298*f4a2713aSLionel Sambuc   case tok::kw___write_only:
4299*f4a2713aSLionel Sambuc 
4300*f4a2713aSLionel Sambuc     return true;
4301*f4a2713aSLionel Sambuc   }
4302*f4a2713aSLionel Sambuc }
4303*f4a2713aSLionel Sambuc 
4304*f4a2713aSLionel Sambuc bool Parser::isConstructorDeclarator() {
4305*f4a2713aSLionel Sambuc   TentativeParsingAction TPA(*this);
4306*f4a2713aSLionel Sambuc 
4307*f4a2713aSLionel Sambuc   // Parse the C++ scope specifier.
4308*f4a2713aSLionel Sambuc   CXXScopeSpec SS;
4309*f4a2713aSLionel Sambuc   if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
4310*f4a2713aSLionel Sambuc                                      /*EnteringContext=*/true)) {
4311*f4a2713aSLionel Sambuc     TPA.Revert();
4312*f4a2713aSLionel Sambuc     return false;
4313*f4a2713aSLionel Sambuc   }
4314*f4a2713aSLionel Sambuc 
4315*f4a2713aSLionel Sambuc   // Parse the constructor name.
4316*f4a2713aSLionel Sambuc   if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
4317*f4a2713aSLionel Sambuc     // We already know that we have a constructor name; just consume
4318*f4a2713aSLionel Sambuc     // the token.
4319*f4a2713aSLionel Sambuc     ConsumeToken();
4320*f4a2713aSLionel Sambuc   } else {
4321*f4a2713aSLionel Sambuc     TPA.Revert();
4322*f4a2713aSLionel Sambuc     return false;
4323*f4a2713aSLionel Sambuc   }
4324*f4a2713aSLionel Sambuc 
4325*f4a2713aSLionel Sambuc   // Current class name must be followed by a left parenthesis.
4326*f4a2713aSLionel Sambuc   if (Tok.isNot(tok::l_paren)) {
4327*f4a2713aSLionel Sambuc     TPA.Revert();
4328*f4a2713aSLionel Sambuc     return false;
4329*f4a2713aSLionel Sambuc   }
4330*f4a2713aSLionel Sambuc   ConsumeParen();
4331*f4a2713aSLionel Sambuc 
4332*f4a2713aSLionel Sambuc   // A right parenthesis, or ellipsis followed by a right parenthesis signals
4333*f4a2713aSLionel Sambuc   // that we have a constructor.
4334*f4a2713aSLionel Sambuc   if (Tok.is(tok::r_paren) ||
4335*f4a2713aSLionel Sambuc       (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {
4336*f4a2713aSLionel Sambuc     TPA.Revert();
4337*f4a2713aSLionel Sambuc     return true;
4338*f4a2713aSLionel Sambuc   }
4339*f4a2713aSLionel Sambuc 
4340*f4a2713aSLionel Sambuc   // A C++11 attribute here signals that we have a constructor, and is an
4341*f4a2713aSLionel Sambuc   // attribute on the first constructor parameter.
4342*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus11 &&
4343*f4a2713aSLionel Sambuc       isCXX11AttributeSpecifier(/*Disambiguate*/ false,
4344*f4a2713aSLionel Sambuc                                 /*OuterMightBeMessageSend*/ true)) {
4345*f4a2713aSLionel Sambuc     TPA.Revert();
4346*f4a2713aSLionel Sambuc     return true;
4347*f4a2713aSLionel Sambuc   }
4348*f4a2713aSLionel Sambuc 
4349*f4a2713aSLionel Sambuc   // If we need to, enter the specified scope.
4350*f4a2713aSLionel Sambuc   DeclaratorScopeObj DeclScopeObj(*this, SS);
4351*f4a2713aSLionel Sambuc   if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
4352*f4a2713aSLionel Sambuc     DeclScopeObj.EnterDeclaratorScope();
4353*f4a2713aSLionel Sambuc 
4354*f4a2713aSLionel Sambuc   // Optionally skip Microsoft attributes.
4355*f4a2713aSLionel Sambuc   ParsedAttributes Attrs(AttrFactory);
4356*f4a2713aSLionel Sambuc   MaybeParseMicrosoftAttributes(Attrs);
4357*f4a2713aSLionel Sambuc 
4358*f4a2713aSLionel Sambuc   // Check whether the next token(s) are part of a declaration
4359*f4a2713aSLionel Sambuc   // specifier, in which case we have the start of a parameter and,
4360*f4a2713aSLionel Sambuc   // therefore, we know that this is a constructor.
4361*f4a2713aSLionel Sambuc   bool IsConstructor = false;
4362*f4a2713aSLionel Sambuc   if (isDeclarationSpecifier())
4363*f4a2713aSLionel Sambuc     IsConstructor = true;
4364*f4a2713aSLionel Sambuc   else if (Tok.is(tok::identifier) ||
4365*f4a2713aSLionel Sambuc            (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
4366*f4a2713aSLionel Sambuc     // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
4367*f4a2713aSLionel Sambuc     // This might be a parenthesized member name, but is more likely to
4368*f4a2713aSLionel Sambuc     // be a constructor declaration with an invalid argument type. Keep
4369*f4a2713aSLionel Sambuc     // looking.
4370*f4a2713aSLionel Sambuc     if (Tok.is(tok::annot_cxxscope))
4371*f4a2713aSLionel Sambuc       ConsumeToken();
4372*f4a2713aSLionel Sambuc     ConsumeToken();
4373*f4a2713aSLionel Sambuc 
4374*f4a2713aSLionel Sambuc     // If this is not a constructor, we must be parsing a declarator,
4375*f4a2713aSLionel Sambuc     // which must have one of the following syntactic forms (see the
4376*f4a2713aSLionel Sambuc     // grammar extract at the start of ParseDirectDeclarator):
4377*f4a2713aSLionel Sambuc     switch (Tok.getKind()) {
4378*f4a2713aSLionel Sambuc     case tok::l_paren:
4379*f4a2713aSLionel Sambuc       // C(X   (   int));
4380*f4a2713aSLionel Sambuc     case tok::l_square:
4381*f4a2713aSLionel Sambuc       // C(X   [   5]);
4382*f4a2713aSLionel Sambuc       // C(X   [   [attribute]]);
4383*f4a2713aSLionel Sambuc     case tok::coloncolon:
4384*f4a2713aSLionel Sambuc       // C(X   ::   Y);
4385*f4a2713aSLionel Sambuc       // C(X   ::   *p);
4386*f4a2713aSLionel Sambuc     case tok::r_paren:
4387*f4a2713aSLionel Sambuc       // C(X   )
4388*f4a2713aSLionel Sambuc       // Assume this isn't a constructor, rather than assuming it's a
4389*f4a2713aSLionel Sambuc       // constructor with an unnamed parameter of an ill-formed type.
4390*f4a2713aSLionel Sambuc       break;
4391*f4a2713aSLionel Sambuc 
4392*f4a2713aSLionel Sambuc     default:
4393*f4a2713aSLionel Sambuc       IsConstructor = true;
4394*f4a2713aSLionel Sambuc       break;
4395*f4a2713aSLionel Sambuc     }
4396*f4a2713aSLionel Sambuc   }
4397*f4a2713aSLionel Sambuc 
4398*f4a2713aSLionel Sambuc   TPA.Revert();
4399*f4a2713aSLionel Sambuc   return IsConstructor;
4400*f4a2713aSLionel Sambuc }
4401*f4a2713aSLionel Sambuc 
4402*f4a2713aSLionel Sambuc /// ParseTypeQualifierListOpt
4403*f4a2713aSLionel Sambuc ///          type-qualifier-list: [C99 6.7.5]
4404*f4a2713aSLionel Sambuc ///            type-qualifier
4405*f4a2713aSLionel Sambuc /// [vendor]   attributes
4406*f4a2713aSLionel Sambuc ///              [ only if VendorAttributesAllowed=true ]
4407*f4a2713aSLionel Sambuc ///            type-qualifier-list type-qualifier
4408*f4a2713aSLionel Sambuc /// [vendor]   type-qualifier-list attributes
4409*f4a2713aSLionel Sambuc ///              [ only if VendorAttributesAllowed=true ]
4410*f4a2713aSLionel Sambuc /// [C++0x]    attribute-specifier[opt] is allowed before cv-qualifier-seq
4411*f4a2713aSLionel Sambuc ///              [ only if CXX11AttributesAllowed=true ]
4412*f4a2713aSLionel Sambuc /// Note: vendor can be GNU, MS, etc.
4413*f4a2713aSLionel Sambuc ///
4414*f4a2713aSLionel Sambuc void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
4415*f4a2713aSLionel Sambuc                                        bool VendorAttributesAllowed,
4416*f4a2713aSLionel Sambuc                                        bool CXX11AttributesAllowed,
4417*f4a2713aSLionel Sambuc                                        bool AtomicAllowed,
4418*f4a2713aSLionel Sambuc                                        bool IdentifierRequired) {
4419*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed &&
4420*f4a2713aSLionel Sambuc       isCXX11AttributeSpecifier()) {
4421*f4a2713aSLionel Sambuc     ParsedAttributesWithRange attrs(AttrFactory);
4422*f4a2713aSLionel Sambuc     ParseCXX11Attributes(attrs);
4423*f4a2713aSLionel Sambuc     DS.takeAttributesFrom(attrs);
4424*f4a2713aSLionel Sambuc   }
4425*f4a2713aSLionel Sambuc 
4426*f4a2713aSLionel Sambuc   SourceLocation EndLoc;
4427*f4a2713aSLionel Sambuc 
4428*f4a2713aSLionel Sambuc   while (1) {
4429*f4a2713aSLionel Sambuc     bool isInvalid = false;
4430*f4a2713aSLionel Sambuc     const char *PrevSpec = 0;
4431*f4a2713aSLionel Sambuc     unsigned DiagID = 0;
4432*f4a2713aSLionel Sambuc     SourceLocation Loc = Tok.getLocation();
4433*f4a2713aSLionel Sambuc 
4434*f4a2713aSLionel Sambuc     switch (Tok.getKind()) {
4435*f4a2713aSLionel Sambuc     case tok::code_completion:
4436*f4a2713aSLionel Sambuc       Actions.CodeCompleteTypeQualifiers(DS);
4437*f4a2713aSLionel Sambuc       return cutOffParsing();
4438*f4a2713aSLionel Sambuc 
4439*f4a2713aSLionel Sambuc     case tok::kw_const:
4440*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,
4441*f4a2713aSLionel Sambuc                                  getLangOpts());
4442*f4a2713aSLionel Sambuc       break;
4443*f4a2713aSLionel Sambuc     case tok::kw_volatile:
4444*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
4445*f4a2713aSLionel Sambuc                                  getLangOpts());
4446*f4a2713aSLionel Sambuc       break;
4447*f4a2713aSLionel Sambuc     case tok::kw_restrict:
4448*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
4449*f4a2713aSLionel Sambuc                                  getLangOpts());
4450*f4a2713aSLionel Sambuc       break;
4451*f4a2713aSLionel Sambuc     case tok::kw__Atomic:
4452*f4a2713aSLionel Sambuc       if (!AtomicAllowed)
4453*f4a2713aSLionel Sambuc         goto DoneWithTypeQuals;
4454*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
4455*f4a2713aSLionel Sambuc                                  getLangOpts());
4456*f4a2713aSLionel Sambuc       break;
4457*f4a2713aSLionel Sambuc 
4458*f4a2713aSLionel Sambuc     // OpenCL qualifiers:
4459*f4a2713aSLionel Sambuc     case tok::kw_private:
4460*f4a2713aSLionel Sambuc       if (!getLangOpts().OpenCL)
4461*f4a2713aSLionel Sambuc         goto DoneWithTypeQuals;
4462*f4a2713aSLionel Sambuc     case tok::kw___private:
4463*f4a2713aSLionel Sambuc     case tok::kw___global:
4464*f4a2713aSLionel Sambuc     case tok::kw___local:
4465*f4a2713aSLionel Sambuc     case tok::kw___constant:
4466*f4a2713aSLionel Sambuc     case tok::kw___read_only:
4467*f4a2713aSLionel Sambuc     case tok::kw___write_only:
4468*f4a2713aSLionel Sambuc     case tok::kw___read_write:
4469*f4a2713aSLionel Sambuc       ParseOpenCLQualifiers(DS);
4470*f4a2713aSLionel Sambuc       break;
4471*f4a2713aSLionel Sambuc 
4472*f4a2713aSLionel Sambuc     case tok::kw___uptr:
4473*f4a2713aSLionel Sambuc       // GNU libc headers in C mode use '__uptr' as an identifer which conflicts
4474*f4a2713aSLionel Sambuc       // with the MS modifier keyword.
4475*f4a2713aSLionel Sambuc       if (VendorAttributesAllowed && !getLangOpts().CPlusPlus &&
4476*f4a2713aSLionel Sambuc           IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi) &&
4477*f4a2713aSLionel Sambuc           PP.getSourceManager().isInSystemHeader(Loc)) {
4478*f4a2713aSLionel Sambuc         Tok.setKind(tok::identifier);
4479*f4a2713aSLionel Sambuc         continue;
4480*f4a2713aSLionel Sambuc       }
4481*f4a2713aSLionel Sambuc     case tok::kw___sptr:
4482*f4a2713aSLionel Sambuc     case tok::kw___w64:
4483*f4a2713aSLionel Sambuc     case tok::kw___ptr64:
4484*f4a2713aSLionel Sambuc     case tok::kw___ptr32:
4485*f4a2713aSLionel Sambuc     case tok::kw___cdecl:
4486*f4a2713aSLionel Sambuc     case tok::kw___stdcall:
4487*f4a2713aSLionel Sambuc     case tok::kw___fastcall:
4488*f4a2713aSLionel Sambuc     case tok::kw___thiscall:
4489*f4a2713aSLionel Sambuc     case tok::kw___unaligned:
4490*f4a2713aSLionel Sambuc       if (VendorAttributesAllowed) {
4491*f4a2713aSLionel Sambuc         ParseMicrosoftTypeAttributes(DS.getAttributes());
4492*f4a2713aSLionel Sambuc         continue;
4493*f4a2713aSLionel Sambuc       }
4494*f4a2713aSLionel Sambuc       goto DoneWithTypeQuals;
4495*f4a2713aSLionel Sambuc     case tok::kw___pascal:
4496*f4a2713aSLionel Sambuc       if (VendorAttributesAllowed) {
4497*f4a2713aSLionel Sambuc         ParseBorlandTypeAttributes(DS.getAttributes());
4498*f4a2713aSLionel Sambuc         continue;
4499*f4a2713aSLionel Sambuc       }
4500*f4a2713aSLionel Sambuc       goto DoneWithTypeQuals;
4501*f4a2713aSLionel Sambuc     case tok::kw___attribute:
4502*f4a2713aSLionel Sambuc       if (VendorAttributesAllowed) {
4503*f4a2713aSLionel Sambuc         ParseGNUAttributes(DS.getAttributes());
4504*f4a2713aSLionel Sambuc         continue; // do *not* consume the next token!
4505*f4a2713aSLionel Sambuc       }
4506*f4a2713aSLionel Sambuc       // otherwise, FALL THROUGH!
4507*f4a2713aSLionel Sambuc     default:
4508*f4a2713aSLionel Sambuc       DoneWithTypeQuals:
4509*f4a2713aSLionel Sambuc       // If this is not a type-qualifier token, we're done reading type
4510*f4a2713aSLionel Sambuc       // qualifiers.  First verify that DeclSpec's are consistent.
4511*f4a2713aSLionel Sambuc       DS.Finish(Diags, PP);
4512*f4a2713aSLionel Sambuc       if (EndLoc.isValid())
4513*f4a2713aSLionel Sambuc         DS.SetRangeEnd(EndLoc);
4514*f4a2713aSLionel Sambuc       return;
4515*f4a2713aSLionel Sambuc     }
4516*f4a2713aSLionel Sambuc 
4517*f4a2713aSLionel Sambuc     // If the specifier combination wasn't legal, issue a diagnostic.
4518*f4a2713aSLionel Sambuc     if (isInvalid) {
4519*f4a2713aSLionel Sambuc       assert(PrevSpec && "Method did not return previous specifier!");
4520*f4a2713aSLionel Sambuc       Diag(Tok, DiagID) << PrevSpec;
4521*f4a2713aSLionel Sambuc     }
4522*f4a2713aSLionel Sambuc     EndLoc = ConsumeToken();
4523*f4a2713aSLionel Sambuc   }
4524*f4a2713aSLionel Sambuc }
4525*f4a2713aSLionel Sambuc 
4526*f4a2713aSLionel Sambuc 
4527*f4a2713aSLionel Sambuc /// ParseDeclarator - Parse and verify a newly-initialized declarator.
4528*f4a2713aSLionel Sambuc ///
4529*f4a2713aSLionel Sambuc void Parser::ParseDeclarator(Declarator &D) {
4530*f4a2713aSLionel Sambuc   /// This implements the 'declarator' production in the C grammar, then checks
4531*f4a2713aSLionel Sambuc   /// for well-formedness and issues diagnostics.
4532*f4a2713aSLionel Sambuc   ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
4533*f4a2713aSLionel Sambuc }
4534*f4a2713aSLionel Sambuc 
4535*f4a2713aSLionel Sambuc static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) {
4536*f4a2713aSLionel Sambuc   if (Kind == tok::star || Kind == tok::caret)
4537*f4a2713aSLionel Sambuc     return true;
4538*f4a2713aSLionel Sambuc 
4539*f4a2713aSLionel Sambuc   // We parse rvalue refs in C++03, because otherwise the errors are scary.
4540*f4a2713aSLionel Sambuc   if (!Lang.CPlusPlus)
4541*f4a2713aSLionel Sambuc     return false;
4542*f4a2713aSLionel Sambuc 
4543*f4a2713aSLionel Sambuc   return Kind == tok::amp || Kind == tok::ampamp;
4544*f4a2713aSLionel Sambuc }
4545*f4a2713aSLionel Sambuc 
4546*f4a2713aSLionel Sambuc /// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
4547*f4a2713aSLionel Sambuc /// is parsed by the function passed to it. Pass null, and the direct-declarator
4548*f4a2713aSLionel Sambuc /// isn't parsed at all, making this function effectively parse the C++
4549*f4a2713aSLionel Sambuc /// ptr-operator production.
4550*f4a2713aSLionel Sambuc ///
4551*f4a2713aSLionel Sambuc /// If the grammar of this construct is extended, matching changes must also be
4552*f4a2713aSLionel Sambuc /// made to TryParseDeclarator and MightBeDeclarator, and possibly to
4553*f4a2713aSLionel Sambuc /// isConstructorDeclarator.
4554*f4a2713aSLionel Sambuc ///
4555*f4a2713aSLionel Sambuc ///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
4556*f4a2713aSLionel Sambuc /// [C]     pointer[opt] direct-declarator
4557*f4a2713aSLionel Sambuc /// [C++]   direct-declarator
4558*f4a2713aSLionel Sambuc /// [C++]   ptr-operator declarator
4559*f4a2713aSLionel Sambuc ///
4560*f4a2713aSLionel Sambuc ///       pointer: [C99 6.7.5]
4561*f4a2713aSLionel Sambuc ///         '*' type-qualifier-list[opt]
4562*f4a2713aSLionel Sambuc ///         '*' type-qualifier-list[opt] pointer
4563*f4a2713aSLionel Sambuc ///
4564*f4a2713aSLionel Sambuc ///       ptr-operator:
4565*f4a2713aSLionel Sambuc ///         '*' cv-qualifier-seq[opt]
4566*f4a2713aSLionel Sambuc ///         '&'
4567*f4a2713aSLionel Sambuc /// [C++0x] '&&'
4568*f4a2713aSLionel Sambuc /// [GNU]   '&' restrict[opt] attributes[opt]
4569*f4a2713aSLionel Sambuc /// [GNU?]  '&&' restrict[opt] attributes[opt]
4570*f4a2713aSLionel Sambuc ///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
4571*f4a2713aSLionel Sambuc void Parser::ParseDeclaratorInternal(Declarator &D,
4572*f4a2713aSLionel Sambuc                                      DirectDeclParseFunction DirectDeclParser) {
4573*f4a2713aSLionel Sambuc   if (Diags.hasAllExtensionsSilenced())
4574*f4a2713aSLionel Sambuc     D.setExtension();
4575*f4a2713aSLionel Sambuc 
4576*f4a2713aSLionel Sambuc   // C++ member pointers start with a '::' or a nested-name.
4577*f4a2713aSLionel Sambuc   // Member pointers get special handling, since there's no place for the
4578*f4a2713aSLionel Sambuc   // scope spec in the generic path below.
4579*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus &&
4580*f4a2713aSLionel Sambuc       (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
4581*f4a2713aSLionel Sambuc        Tok.is(tok::annot_cxxscope))) {
4582*f4a2713aSLionel Sambuc     bool EnteringContext = D.getContext() == Declarator::FileContext ||
4583*f4a2713aSLionel Sambuc                            D.getContext() == Declarator::MemberContext;
4584*f4a2713aSLionel Sambuc     CXXScopeSpec SS;
4585*f4a2713aSLionel Sambuc     ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext);
4586*f4a2713aSLionel Sambuc 
4587*f4a2713aSLionel Sambuc     if (SS.isNotEmpty()) {
4588*f4a2713aSLionel Sambuc       if (Tok.isNot(tok::star)) {
4589*f4a2713aSLionel Sambuc         // The scope spec really belongs to the direct-declarator.
4590*f4a2713aSLionel Sambuc         if (D.mayHaveIdentifier())
4591*f4a2713aSLionel Sambuc           D.getCXXScopeSpec() = SS;
4592*f4a2713aSLionel Sambuc         else
4593*f4a2713aSLionel Sambuc           AnnotateScopeToken(SS, true);
4594*f4a2713aSLionel Sambuc 
4595*f4a2713aSLionel Sambuc         if (DirectDeclParser)
4596*f4a2713aSLionel Sambuc           (this->*DirectDeclParser)(D);
4597*f4a2713aSLionel Sambuc         return;
4598*f4a2713aSLionel Sambuc       }
4599*f4a2713aSLionel Sambuc 
4600*f4a2713aSLionel Sambuc       SourceLocation Loc = ConsumeToken();
4601*f4a2713aSLionel Sambuc       D.SetRangeEnd(Loc);
4602*f4a2713aSLionel Sambuc       DeclSpec DS(AttrFactory);
4603*f4a2713aSLionel Sambuc       ParseTypeQualifierListOpt(DS);
4604*f4a2713aSLionel Sambuc       D.ExtendWithDeclSpec(DS);
4605*f4a2713aSLionel Sambuc 
4606*f4a2713aSLionel Sambuc       // Recurse to parse whatever is left.
4607*f4a2713aSLionel Sambuc       ParseDeclaratorInternal(D, DirectDeclParser);
4608*f4a2713aSLionel Sambuc 
4609*f4a2713aSLionel Sambuc       // Sema will have to catch (syntactically invalid) pointers into global
4610*f4a2713aSLionel Sambuc       // scope. It has to catch pointers into namespace scope anyway.
4611*f4a2713aSLionel Sambuc       D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
4612*f4a2713aSLionel Sambuc                                                       Loc),
4613*f4a2713aSLionel Sambuc                     DS.getAttributes(),
4614*f4a2713aSLionel Sambuc                     /* Don't replace range end. */SourceLocation());
4615*f4a2713aSLionel Sambuc       return;
4616*f4a2713aSLionel Sambuc     }
4617*f4a2713aSLionel Sambuc   }
4618*f4a2713aSLionel Sambuc 
4619*f4a2713aSLionel Sambuc   tok::TokenKind Kind = Tok.getKind();
4620*f4a2713aSLionel Sambuc   // Not a pointer, C++ reference, or block.
4621*f4a2713aSLionel Sambuc   if (!isPtrOperatorToken(Kind, getLangOpts())) {
4622*f4a2713aSLionel Sambuc     if (DirectDeclParser)
4623*f4a2713aSLionel Sambuc       (this->*DirectDeclParser)(D);
4624*f4a2713aSLionel Sambuc     return;
4625*f4a2713aSLionel Sambuc   }
4626*f4a2713aSLionel Sambuc 
4627*f4a2713aSLionel Sambuc   // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
4628*f4a2713aSLionel Sambuc   // '&&' -> rvalue reference
4629*f4a2713aSLionel Sambuc   SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.
4630*f4a2713aSLionel Sambuc   D.SetRangeEnd(Loc);
4631*f4a2713aSLionel Sambuc 
4632*f4a2713aSLionel Sambuc   if (Kind == tok::star || Kind == tok::caret) {
4633*f4a2713aSLionel Sambuc     // Is a pointer.
4634*f4a2713aSLionel Sambuc     DeclSpec DS(AttrFactory);
4635*f4a2713aSLionel Sambuc 
4636*f4a2713aSLionel Sambuc     // FIXME: GNU attributes are not allowed here in a new-type-id.
4637*f4a2713aSLionel Sambuc     ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier());
4638*f4a2713aSLionel Sambuc     D.ExtendWithDeclSpec(DS);
4639*f4a2713aSLionel Sambuc 
4640*f4a2713aSLionel Sambuc     // Recursively parse the declarator.
4641*f4a2713aSLionel Sambuc     ParseDeclaratorInternal(D, DirectDeclParser);
4642*f4a2713aSLionel Sambuc     if (Kind == tok::star)
4643*f4a2713aSLionel Sambuc       // Remember that we parsed a pointer type, and remember the type-quals.
4644*f4a2713aSLionel Sambuc       D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
4645*f4a2713aSLionel Sambuc                                                 DS.getConstSpecLoc(),
4646*f4a2713aSLionel Sambuc                                                 DS.getVolatileSpecLoc(),
4647*f4a2713aSLionel Sambuc                                                 DS.getRestrictSpecLoc()),
4648*f4a2713aSLionel Sambuc                     DS.getAttributes(),
4649*f4a2713aSLionel Sambuc                     SourceLocation());
4650*f4a2713aSLionel Sambuc     else
4651*f4a2713aSLionel Sambuc       // Remember that we parsed a Block type, and remember the type-quals.
4652*f4a2713aSLionel Sambuc       D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
4653*f4a2713aSLionel Sambuc                                                      Loc),
4654*f4a2713aSLionel Sambuc                     DS.getAttributes(),
4655*f4a2713aSLionel Sambuc                     SourceLocation());
4656*f4a2713aSLionel Sambuc   } else {
4657*f4a2713aSLionel Sambuc     // Is a reference
4658*f4a2713aSLionel Sambuc     DeclSpec DS(AttrFactory);
4659*f4a2713aSLionel Sambuc 
4660*f4a2713aSLionel Sambuc     // Complain about rvalue references in C++03, but then go on and build
4661*f4a2713aSLionel Sambuc     // the declarator.
4662*f4a2713aSLionel Sambuc     if (Kind == tok::ampamp)
4663*f4a2713aSLionel Sambuc       Diag(Loc, getLangOpts().CPlusPlus11 ?
4664*f4a2713aSLionel Sambuc            diag::warn_cxx98_compat_rvalue_reference :
4665*f4a2713aSLionel Sambuc            diag::ext_rvalue_reference);
4666*f4a2713aSLionel Sambuc 
4667*f4a2713aSLionel Sambuc     // GNU-style and C++11 attributes are allowed here, as is restrict.
4668*f4a2713aSLionel Sambuc     ParseTypeQualifierListOpt(DS);
4669*f4a2713aSLionel Sambuc     D.ExtendWithDeclSpec(DS);
4670*f4a2713aSLionel Sambuc 
4671*f4a2713aSLionel Sambuc     // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
4672*f4a2713aSLionel Sambuc     // cv-qualifiers are introduced through the use of a typedef or of a
4673*f4a2713aSLionel Sambuc     // template type argument, in which case the cv-qualifiers are ignored.
4674*f4a2713aSLionel Sambuc     if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
4675*f4a2713aSLionel Sambuc       if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
4676*f4a2713aSLionel Sambuc         Diag(DS.getConstSpecLoc(),
4677*f4a2713aSLionel Sambuc              diag::err_invalid_reference_qualifier_application) << "const";
4678*f4a2713aSLionel Sambuc       if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
4679*f4a2713aSLionel Sambuc         Diag(DS.getVolatileSpecLoc(),
4680*f4a2713aSLionel Sambuc              diag::err_invalid_reference_qualifier_application) << "volatile";
4681*f4a2713aSLionel Sambuc       // 'restrict' is permitted as an extension.
4682*f4a2713aSLionel Sambuc       if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
4683*f4a2713aSLionel Sambuc         Diag(DS.getAtomicSpecLoc(),
4684*f4a2713aSLionel Sambuc              diag::err_invalid_reference_qualifier_application) << "_Atomic";
4685*f4a2713aSLionel Sambuc     }
4686*f4a2713aSLionel Sambuc 
4687*f4a2713aSLionel Sambuc     // Recursively parse the declarator.
4688*f4a2713aSLionel Sambuc     ParseDeclaratorInternal(D, DirectDeclParser);
4689*f4a2713aSLionel Sambuc 
4690*f4a2713aSLionel Sambuc     if (D.getNumTypeObjects() > 0) {
4691*f4a2713aSLionel Sambuc       // C++ [dcl.ref]p4: There shall be no references to references.
4692*f4a2713aSLionel Sambuc       DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);
4693*f4a2713aSLionel Sambuc       if (InnerChunk.Kind == DeclaratorChunk::Reference) {
4694*f4a2713aSLionel Sambuc         if (const IdentifierInfo *II = D.getIdentifier())
4695*f4a2713aSLionel Sambuc           Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4696*f4a2713aSLionel Sambuc            << II;
4697*f4a2713aSLionel Sambuc         else
4698*f4a2713aSLionel Sambuc           Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
4699*f4a2713aSLionel Sambuc             << "type name";
4700*f4a2713aSLionel Sambuc 
4701*f4a2713aSLionel Sambuc         // Once we've complained about the reference-to-reference, we
4702*f4a2713aSLionel Sambuc         // can go ahead and build the (technically ill-formed)
4703*f4a2713aSLionel Sambuc         // declarator: reference collapsing will take care of it.
4704*f4a2713aSLionel Sambuc       }
4705*f4a2713aSLionel Sambuc     }
4706*f4a2713aSLionel Sambuc 
4707*f4a2713aSLionel Sambuc     // Remember that we parsed a reference type.
4708*f4a2713aSLionel Sambuc     D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
4709*f4a2713aSLionel Sambuc                                                 Kind == tok::amp),
4710*f4a2713aSLionel Sambuc                   DS.getAttributes(),
4711*f4a2713aSLionel Sambuc                   SourceLocation());
4712*f4a2713aSLionel Sambuc   }
4713*f4a2713aSLionel Sambuc }
4714*f4a2713aSLionel Sambuc 
4715*f4a2713aSLionel Sambuc static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
4716*f4a2713aSLionel Sambuc                                       SourceLocation EllipsisLoc) {
4717*f4a2713aSLionel Sambuc   if (EllipsisLoc.isValid()) {
4718*f4a2713aSLionel Sambuc     FixItHint Insertion;
4719*f4a2713aSLionel Sambuc     if (!D.getEllipsisLoc().isValid()) {
4720*f4a2713aSLionel Sambuc       Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
4721*f4a2713aSLionel Sambuc       D.setEllipsisLoc(EllipsisLoc);
4722*f4a2713aSLionel Sambuc     }
4723*f4a2713aSLionel Sambuc     P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
4724*f4a2713aSLionel Sambuc       << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
4725*f4a2713aSLionel Sambuc   }
4726*f4a2713aSLionel Sambuc }
4727*f4a2713aSLionel Sambuc 
4728*f4a2713aSLionel Sambuc /// ParseDirectDeclarator
4729*f4a2713aSLionel Sambuc ///       direct-declarator: [C99 6.7.5]
4730*f4a2713aSLionel Sambuc /// [C99]   identifier
4731*f4a2713aSLionel Sambuc ///         '(' declarator ')'
4732*f4a2713aSLionel Sambuc /// [GNU]   '(' attributes declarator ')'
4733*f4a2713aSLionel Sambuc /// [C90]   direct-declarator '[' constant-expression[opt] ']'
4734*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
4735*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
4736*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
4737*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
4738*f4a2713aSLionel Sambuc /// [C++11] direct-declarator '[' constant-expression[opt] ']'
4739*f4a2713aSLionel Sambuc ///                    attribute-specifier-seq[opt]
4740*f4a2713aSLionel Sambuc ///         direct-declarator '(' parameter-type-list ')'
4741*f4a2713aSLionel Sambuc ///         direct-declarator '(' identifier-list[opt] ')'
4742*f4a2713aSLionel Sambuc /// [GNU]   direct-declarator '(' parameter-forward-declarations
4743*f4a2713aSLionel Sambuc ///                    parameter-type-list[opt] ')'
4744*f4a2713aSLionel Sambuc /// [C++]   direct-declarator '(' parameter-declaration-clause ')'
4745*f4a2713aSLionel Sambuc ///                    cv-qualifier-seq[opt] exception-specification[opt]
4746*f4a2713aSLionel Sambuc /// [C++11] direct-declarator '(' parameter-declaration-clause ')'
4747*f4a2713aSLionel Sambuc ///                    attribute-specifier-seq[opt] cv-qualifier-seq[opt]
4748*f4a2713aSLionel Sambuc ///                    ref-qualifier[opt] exception-specification[opt]
4749*f4a2713aSLionel Sambuc /// [C++]   declarator-id
4750*f4a2713aSLionel Sambuc /// [C++11] declarator-id attribute-specifier-seq[opt]
4751*f4a2713aSLionel Sambuc ///
4752*f4a2713aSLionel Sambuc ///       declarator-id: [C++ 8]
4753*f4a2713aSLionel Sambuc ///         '...'[opt] id-expression
4754*f4a2713aSLionel Sambuc ///         '::'[opt] nested-name-specifier[opt] type-name
4755*f4a2713aSLionel Sambuc ///
4756*f4a2713aSLionel Sambuc ///       id-expression: [C++ 5.1]
4757*f4a2713aSLionel Sambuc ///         unqualified-id
4758*f4a2713aSLionel Sambuc ///         qualified-id
4759*f4a2713aSLionel Sambuc ///
4760*f4a2713aSLionel Sambuc ///       unqualified-id: [C++ 5.1]
4761*f4a2713aSLionel Sambuc ///         identifier
4762*f4a2713aSLionel Sambuc ///         operator-function-id
4763*f4a2713aSLionel Sambuc ///         conversion-function-id
4764*f4a2713aSLionel Sambuc ///          '~' class-name
4765*f4a2713aSLionel Sambuc ///         template-id
4766*f4a2713aSLionel Sambuc ///
4767*f4a2713aSLionel Sambuc /// Note, any additional constructs added here may need corresponding changes
4768*f4a2713aSLionel Sambuc /// in isConstructorDeclarator.
4769*f4a2713aSLionel Sambuc void Parser::ParseDirectDeclarator(Declarator &D) {
4770*f4a2713aSLionel Sambuc   DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
4771*f4a2713aSLionel Sambuc 
4772*f4a2713aSLionel Sambuc   if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
4773*f4a2713aSLionel Sambuc     // ParseDeclaratorInternal might already have parsed the scope.
4774*f4a2713aSLionel Sambuc     if (D.getCXXScopeSpec().isEmpty()) {
4775*f4a2713aSLionel Sambuc       bool EnteringContext = D.getContext() == Declarator::FileContext ||
4776*f4a2713aSLionel Sambuc                              D.getContext() == Declarator::MemberContext;
4777*f4a2713aSLionel Sambuc       ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(),
4778*f4a2713aSLionel Sambuc                                      EnteringContext);
4779*f4a2713aSLionel Sambuc     }
4780*f4a2713aSLionel Sambuc 
4781*f4a2713aSLionel Sambuc     if (D.getCXXScopeSpec().isValid()) {
4782*f4a2713aSLionel Sambuc       if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
4783*f4a2713aSLionel Sambuc         // Change the declaration context for name lookup, until this function
4784*f4a2713aSLionel Sambuc         // is exited (and the declarator has been parsed).
4785*f4a2713aSLionel Sambuc         DeclScopeObj.EnterDeclaratorScope();
4786*f4a2713aSLionel Sambuc     }
4787*f4a2713aSLionel Sambuc 
4788*f4a2713aSLionel Sambuc     // C++0x [dcl.fct]p14:
4789*f4a2713aSLionel Sambuc     //   There is a syntactic ambiguity when an ellipsis occurs at the end
4790*f4a2713aSLionel Sambuc     //   of a parameter-declaration-clause without a preceding comma. In
4791*f4a2713aSLionel Sambuc     //   this case, the ellipsis is parsed as part of the
4792*f4a2713aSLionel Sambuc     //   abstract-declarator if the type of the parameter names a template
4793*f4a2713aSLionel Sambuc     //   parameter pack that has not been expanded; otherwise, it is parsed
4794*f4a2713aSLionel Sambuc     //   as part of the parameter-declaration-clause.
4795*f4a2713aSLionel Sambuc     if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
4796*f4a2713aSLionel Sambuc         !((D.getContext() == Declarator::PrototypeContext ||
4797*f4a2713aSLionel Sambuc            D.getContext() == Declarator::LambdaExprParameterContext ||
4798*f4a2713aSLionel Sambuc            D.getContext() == Declarator::BlockLiteralContext) &&
4799*f4a2713aSLionel Sambuc           NextToken().is(tok::r_paren) &&
4800*f4a2713aSLionel Sambuc           !D.hasGroupingParens() &&
4801*f4a2713aSLionel Sambuc           !Actions.containsUnexpandedParameterPacks(D))) {
4802*f4a2713aSLionel Sambuc       SourceLocation EllipsisLoc = ConsumeToken();
4803*f4a2713aSLionel Sambuc       if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) {
4804*f4a2713aSLionel Sambuc         // The ellipsis was put in the wrong place. Recover, and explain to
4805*f4a2713aSLionel Sambuc         // the user what they should have done.
4806*f4a2713aSLionel Sambuc         ParseDeclarator(D);
4807*f4a2713aSLionel Sambuc         diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
4808*f4a2713aSLionel Sambuc         return;
4809*f4a2713aSLionel Sambuc       } else
4810*f4a2713aSLionel Sambuc         D.setEllipsisLoc(EllipsisLoc);
4811*f4a2713aSLionel Sambuc 
4812*f4a2713aSLionel Sambuc       // The ellipsis can't be followed by a parenthesized declarator. We
4813*f4a2713aSLionel Sambuc       // check for that in ParseParenDeclarator, after we have disambiguated
4814*f4a2713aSLionel Sambuc       // the l_paren token.
4815*f4a2713aSLionel Sambuc     }
4816*f4a2713aSLionel Sambuc 
4817*f4a2713aSLionel Sambuc     if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
4818*f4a2713aSLionel Sambuc         Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
4819*f4a2713aSLionel Sambuc       // We found something that indicates the start of an unqualified-id.
4820*f4a2713aSLionel Sambuc       // Parse that unqualified-id.
4821*f4a2713aSLionel Sambuc       bool AllowConstructorName;
4822*f4a2713aSLionel Sambuc       if (D.getDeclSpec().hasTypeSpecifier())
4823*f4a2713aSLionel Sambuc         AllowConstructorName = false;
4824*f4a2713aSLionel Sambuc       else if (D.getCXXScopeSpec().isSet())
4825*f4a2713aSLionel Sambuc         AllowConstructorName =
4826*f4a2713aSLionel Sambuc           (D.getContext() == Declarator::FileContext ||
4827*f4a2713aSLionel Sambuc            D.getContext() == Declarator::MemberContext);
4828*f4a2713aSLionel Sambuc       else
4829*f4a2713aSLionel Sambuc         AllowConstructorName = (D.getContext() == Declarator::MemberContext);
4830*f4a2713aSLionel Sambuc 
4831*f4a2713aSLionel Sambuc       SourceLocation TemplateKWLoc;
4832*f4a2713aSLionel Sambuc       if (ParseUnqualifiedId(D.getCXXScopeSpec(),
4833*f4a2713aSLionel Sambuc                              /*EnteringContext=*/true,
4834*f4a2713aSLionel Sambuc                              /*AllowDestructorName=*/true,
4835*f4a2713aSLionel Sambuc                              AllowConstructorName,
4836*f4a2713aSLionel Sambuc                              ParsedType(),
4837*f4a2713aSLionel Sambuc                              TemplateKWLoc,
4838*f4a2713aSLionel Sambuc                              D.getName()) ||
4839*f4a2713aSLionel Sambuc           // Once we're past the identifier, if the scope was bad, mark the
4840*f4a2713aSLionel Sambuc           // whole declarator bad.
4841*f4a2713aSLionel Sambuc           D.getCXXScopeSpec().isInvalid()) {
4842*f4a2713aSLionel Sambuc         D.SetIdentifier(0, Tok.getLocation());
4843*f4a2713aSLionel Sambuc         D.setInvalidType(true);
4844*f4a2713aSLionel Sambuc       } else {
4845*f4a2713aSLionel Sambuc         // Parsed the unqualified-id; update range information and move along.
4846*f4a2713aSLionel Sambuc         if (D.getSourceRange().getBegin().isInvalid())
4847*f4a2713aSLionel Sambuc           D.SetRangeBegin(D.getName().getSourceRange().getBegin());
4848*f4a2713aSLionel Sambuc         D.SetRangeEnd(D.getName().getSourceRange().getEnd());
4849*f4a2713aSLionel Sambuc       }
4850*f4a2713aSLionel Sambuc       goto PastIdentifier;
4851*f4a2713aSLionel Sambuc     }
4852*f4a2713aSLionel Sambuc   } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
4853*f4a2713aSLionel Sambuc     assert(!getLangOpts().CPlusPlus &&
4854*f4a2713aSLionel Sambuc            "There's a C++-specific check for tok::identifier above");
4855*f4a2713aSLionel Sambuc     assert(Tok.getIdentifierInfo() && "Not an identifier?");
4856*f4a2713aSLionel Sambuc     D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
4857*f4a2713aSLionel Sambuc     ConsumeToken();
4858*f4a2713aSLionel Sambuc     goto PastIdentifier;
4859*f4a2713aSLionel Sambuc   } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
4860*f4a2713aSLionel Sambuc     // A virt-specifier isn't treated as an identifier if it appears after a
4861*f4a2713aSLionel Sambuc     // trailing-return-type.
4862*f4a2713aSLionel Sambuc     if (D.getContext() != Declarator::TrailingReturnContext ||
4863*f4a2713aSLionel Sambuc         !isCXX11VirtSpecifier(Tok)) {
4864*f4a2713aSLionel Sambuc       Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
4865*f4a2713aSLionel Sambuc         << FixItHint::CreateRemoval(Tok.getLocation());
4866*f4a2713aSLionel Sambuc       D.SetIdentifier(0, Tok.getLocation());
4867*f4a2713aSLionel Sambuc       ConsumeToken();
4868*f4a2713aSLionel Sambuc       goto PastIdentifier;
4869*f4a2713aSLionel Sambuc     }
4870*f4a2713aSLionel Sambuc   }
4871*f4a2713aSLionel Sambuc 
4872*f4a2713aSLionel Sambuc   if (Tok.is(tok::l_paren)) {
4873*f4a2713aSLionel Sambuc     // direct-declarator: '(' declarator ')'
4874*f4a2713aSLionel Sambuc     // direct-declarator: '(' attributes declarator ')'
4875*f4a2713aSLionel Sambuc     // Example: 'char (*X)'   or 'int (*XX)(void)'
4876*f4a2713aSLionel Sambuc     ParseParenDeclarator(D);
4877*f4a2713aSLionel Sambuc 
4878*f4a2713aSLionel Sambuc     // If the declarator was parenthesized, we entered the declarator
4879*f4a2713aSLionel Sambuc     // scope when parsing the parenthesized declarator, then exited
4880*f4a2713aSLionel Sambuc     // the scope already. Re-enter the scope, if we need to.
4881*f4a2713aSLionel Sambuc     if (D.getCXXScopeSpec().isSet()) {
4882*f4a2713aSLionel Sambuc       // If there was an error parsing parenthesized declarator, declarator
4883*f4a2713aSLionel Sambuc       // scope may have been entered before. Don't do it again.
4884*f4a2713aSLionel Sambuc       if (!D.isInvalidType() &&
4885*f4a2713aSLionel Sambuc           Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec()))
4886*f4a2713aSLionel Sambuc         // Change the declaration context for name lookup, until this function
4887*f4a2713aSLionel Sambuc         // is exited (and the declarator has been parsed).
4888*f4a2713aSLionel Sambuc         DeclScopeObj.EnterDeclaratorScope();
4889*f4a2713aSLionel Sambuc     }
4890*f4a2713aSLionel Sambuc   } else if (D.mayOmitIdentifier()) {
4891*f4a2713aSLionel Sambuc     // This could be something simple like "int" (in which case the declarator
4892*f4a2713aSLionel Sambuc     // portion is empty), if an abstract-declarator is allowed.
4893*f4a2713aSLionel Sambuc     D.SetIdentifier(0, Tok.getLocation());
4894*f4a2713aSLionel Sambuc 
4895*f4a2713aSLionel Sambuc     // The grammar for abstract-pack-declarator does not allow grouping parens.
4896*f4a2713aSLionel Sambuc     // FIXME: Revisit this once core issue 1488 is resolved.
4897*f4a2713aSLionel Sambuc     if (D.hasEllipsis() && D.hasGroupingParens())
4898*f4a2713aSLionel Sambuc       Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()),
4899*f4a2713aSLionel Sambuc            diag::ext_abstract_pack_declarator_parens);
4900*f4a2713aSLionel Sambuc   } else {
4901*f4a2713aSLionel Sambuc     if (Tok.getKind() == tok::annot_pragma_parser_crash)
4902*f4a2713aSLionel Sambuc       LLVM_BUILTIN_TRAP;
4903*f4a2713aSLionel Sambuc     if (D.getContext() == Declarator::MemberContext)
4904*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_expected_member_name_or_semi)
4905*f4a2713aSLionel Sambuc         << D.getDeclSpec().getSourceRange();
4906*f4a2713aSLionel Sambuc     else if (getLangOpts().CPlusPlus) {
4907*f4a2713aSLionel Sambuc       if (Tok.is(tok::period) || Tok.is(tok::arrow))
4908*f4a2713aSLionel Sambuc         Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
4909*f4a2713aSLionel Sambuc       else {
4910*f4a2713aSLionel Sambuc         SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();
4911*f4a2713aSLionel Sambuc         if (Tok.isAtStartOfLine() && Loc.isValid())
4912*f4a2713aSLionel Sambuc           Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
4913*f4a2713aSLionel Sambuc               << getLangOpts().CPlusPlus;
4914*f4a2713aSLionel Sambuc         else
4915*f4a2713aSLionel Sambuc           Diag(Tok, diag::err_expected_unqualified_id)
4916*f4a2713aSLionel Sambuc               << getLangOpts().CPlusPlus;
4917*f4a2713aSLionel Sambuc       }
4918*f4a2713aSLionel Sambuc     } else
4919*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_expected_ident_lparen);
4920*f4a2713aSLionel Sambuc     D.SetIdentifier(0, Tok.getLocation());
4921*f4a2713aSLionel Sambuc     D.setInvalidType(true);
4922*f4a2713aSLionel Sambuc   }
4923*f4a2713aSLionel Sambuc 
4924*f4a2713aSLionel Sambuc  PastIdentifier:
4925*f4a2713aSLionel Sambuc   assert(D.isPastIdentifier() &&
4926*f4a2713aSLionel Sambuc          "Haven't past the location of the identifier yet?");
4927*f4a2713aSLionel Sambuc 
4928*f4a2713aSLionel Sambuc   // Don't parse attributes unless we have parsed an unparenthesized name.
4929*f4a2713aSLionel Sambuc   if (D.hasName() && !D.getNumTypeObjects())
4930*f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(D);
4931*f4a2713aSLionel Sambuc 
4932*f4a2713aSLionel Sambuc   while (1) {
4933*f4a2713aSLionel Sambuc     if (Tok.is(tok::l_paren)) {
4934*f4a2713aSLionel Sambuc       // Enter function-declaration scope, limiting any declarators to the
4935*f4a2713aSLionel Sambuc       // function prototype scope, including parameter declarators.
4936*f4a2713aSLionel Sambuc       ParseScope PrototypeScope(this,
4937*f4a2713aSLionel Sambuc                                 Scope::FunctionPrototypeScope|Scope::DeclScope|
4938*f4a2713aSLionel Sambuc                                 (D.isFunctionDeclaratorAFunctionDeclaration()
4939*f4a2713aSLionel Sambuc                                    ? Scope::FunctionDeclarationScope : 0));
4940*f4a2713aSLionel Sambuc 
4941*f4a2713aSLionel Sambuc       // The paren may be part of a C++ direct initializer, eg. "int x(1);".
4942*f4a2713aSLionel Sambuc       // In such a case, check if we actually have a function declarator; if it
4943*f4a2713aSLionel Sambuc       // is not, the declarator has been fully parsed.
4944*f4a2713aSLionel Sambuc       bool IsAmbiguous = false;
4945*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
4946*f4a2713aSLionel Sambuc         // The name of the declarator, if any, is tentatively declared within
4947*f4a2713aSLionel Sambuc         // a possible direct initializer.
4948*f4a2713aSLionel Sambuc         TentativelyDeclaredIdentifiers.push_back(D.getIdentifier());
4949*f4a2713aSLionel Sambuc         bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
4950*f4a2713aSLionel Sambuc         TentativelyDeclaredIdentifiers.pop_back();
4951*f4a2713aSLionel Sambuc         if (!IsFunctionDecl)
4952*f4a2713aSLionel Sambuc           break;
4953*f4a2713aSLionel Sambuc       }
4954*f4a2713aSLionel Sambuc       ParsedAttributes attrs(AttrFactory);
4955*f4a2713aSLionel Sambuc       BalancedDelimiterTracker T(*this, tok::l_paren);
4956*f4a2713aSLionel Sambuc       T.consumeOpen();
4957*f4a2713aSLionel Sambuc       ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
4958*f4a2713aSLionel Sambuc       PrototypeScope.Exit();
4959*f4a2713aSLionel Sambuc     } else if (Tok.is(tok::l_square)) {
4960*f4a2713aSLionel Sambuc       ParseBracketDeclarator(D);
4961*f4a2713aSLionel Sambuc     } else {
4962*f4a2713aSLionel Sambuc       break;
4963*f4a2713aSLionel Sambuc     }
4964*f4a2713aSLionel Sambuc   }
4965*f4a2713aSLionel Sambuc }
4966*f4a2713aSLionel Sambuc 
4967*f4a2713aSLionel Sambuc /// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
4968*f4a2713aSLionel Sambuc /// only called before the identifier, so these are most likely just grouping
4969*f4a2713aSLionel Sambuc /// parens for precedence.  If we find that these are actually function
4970*f4a2713aSLionel Sambuc /// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
4971*f4a2713aSLionel Sambuc ///
4972*f4a2713aSLionel Sambuc ///       direct-declarator:
4973*f4a2713aSLionel Sambuc ///         '(' declarator ')'
4974*f4a2713aSLionel Sambuc /// [GNU]   '(' attributes declarator ')'
4975*f4a2713aSLionel Sambuc ///         direct-declarator '(' parameter-type-list ')'
4976*f4a2713aSLionel Sambuc ///         direct-declarator '(' identifier-list[opt] ')'
4977*f4a2713aSLionel Sambuc /// [GNU]   direct-declarator '(' parameter-forward-declarations
4978*f4a2713aSLionel Sambuc ///                    parameter-type-list[opt] ')'
4979*f4a2713aSLionel Sambuc ///
4980*f4a2713aSLionel Sambuc void Parser::ParseParenDeclarator(Declarator &D) {
4981*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
4982*f4a2713aSLionel Sambuc   T.consumeOpen();
4983*f4a2713aSLionel Sambuc 
4984*f4a2713aSLionel Sambuc   assert(!D.isPastIdentifier() && "Should be called before passing identifier");
4985*f4a2713aSLionel Sambuc 
4986*f4a2713aSLionel Sambuc   // Eat any attributes before we look at whether this is a grouping or function
4987*f4a2713aSLionel Sambuc   // declarator paren.  If this is a grouping paren, the attribute applies to
4988*f4a2713aSLionel Sambuc   // the type being built up, for example:
4989*f4a2713aSLionel Sambuc   //     int (__attribute__(()) *x)(long y)
4990*f4a2713aSLionel Sambuc   // If this ends up not being a grouping paren, the attribute applies to the
4991*f4a2713aSLionel Sambuc   // first argument, for example:
4992*f4a2713aSLionel Sambuc   //     int (__attribute__(()) int x)
4993*f4a2713aSLionel Sambuc   // In either case, we need to eat any attributes to be able to determine what
4994*f4a2713aSLionel Sambuc   // sort of paren this is.
4995*f4a2713aSLionel Sambuc   //
4996*f4a2713aSLionel Sambuc   ParsedAttributes attrs(AttrFactory);
4997*f4a2713aSLionel Sambuc   bool RequiresArg = false;
4998*f4a2713aSLionel Sambuc   if (Tok.is(tok::kw___attribute)) {
4999*f4a2713aSLionel Sambuc     ParseGNUAttributes(attrs);
5000*f4a2713aSLionel Sambuc 
5001*f4a2713aSLionel Sambuc     // We require that the argument list (if this is a non-grouping paren) be
5002*f4a2713aSLionel Sambuc     // present even if the attribute list was empty.
5003*f4a2713aSLionel Sambuc     RequiresArg = true;
5004*f4a2713aSLionel Sambuc   }
5005*f4a2713aSLionel Sambuc 
5006*f4a2713aSLionel Sambuc   // Eat any Microsoft extensions.
5007*f4a2713aSLionel Sambuc   ParseMicrosoftTypeAttributes(attrs);
5008*f4a2713aSLionel Sambuc 
5009*f4a2713aSLionel Sambuc   // Eat any Borland extensions.
5010*f4a2713aSLionel Sambuc   if  (Tok.is(tok::kw___pascal))
5011*f4a2713aSLionel Sambuc     ParseBorlandTypeAttributes(attrs);
5012*f4a2713aSLionel Sambuc 
5013*f4a2713aSLionel Sambuc   // If we haven't past the identifier yet (or where the identifier would be
5014*f4a2713aSLionel Sambuc   // stored, if this is an abstract declarator), then this is probably just
5015*f4a2713aSLionel Sambuc   // grouping parens. However, if this could be an abstract-declarator, then
5016*f4a2713aSLionel Sambuc   // this could also be the start of function arguments (consider 'void()').
5017*f4a2713aSLionel Sambuc   bool isGrouping;
5018*f4a2713aSLionel Sambuc 
5019*f4a2713aSLionel Sambuc   if (!D.mayOmitIdentifier()) {
5020*f4a2713aSLionel Sambuc     // If this can't be an abstract-declarator, this *must* be a grouping
5021*f4a2713aSLionel Sambuc     // paren, because we haven't seen the identifier yet.
5022*f4a2713aSLionel Sambuc     isGrouping = true;
5023*f4a2713aSLionel Sambuc   } else if (Tok.is(tok::r_paren) ||           // 'int()' is a function.
5024*f4a2713aSLionel Sambuc              (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
5025*f4a2713aSLionel Sambuc               NextToken().is(tok::r_paren)) || // C++ int(...)
5026*f4a2713aSLionel Sambuc              isDeclarationSpecifier() ||       // 'int(int)' is a function.
5027*f4a2713aSLionel Sambuc              isCXX11AttributeSpecifier()) {    // 'int([[]]int)' is a function.
5028*f4a2713aSLionel Sambuc     // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
5029*f4a2713aSLionel Sambuc     // considered to be a type, not a K&R identifier-list.
5030*f4a2713aSLionel Sambuc     isGrouping = false;
5031*f4a2713aSLionel Sambuc   } else {
5032*f4a2713aSLionel Sambuc     // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
5033*f4a2713aSLionel Sambuc     isGrouping = true;
5034*f4a2713aSLionel Sambuc   }
5035*f4a2713aSLionel Sambuc 
5036*f4a2713aSLionel Sambuc   // If this is a grouping paren, handle:
5037*f4a2713aSLionel Sambuc   // direct-declarator: '(' declarator ')'
5038*f4a2713aSLionel Sambuc   // direct-declarator: '(' attributes declarator ')'
5039*f4a2713aSLionel Sambuc   if (isGrouping) {
5040*f4a2713aSLionel Sambuc     SourceLocation EllipsisLoc = D.getEllipsisLoc();
5041*f4a2713aSLionel Sambuc     D.setEllipsisLoc(SourceLocation());
5042*f4a2713aSLionel Sambuc 
5043*f4a2713aSLionel Sambuc     bool hadGroupingParens = D.hasGroupingParens();
5044*f4a2713aSLionel Sambuc     D.setGroupingParens(true);
5045*f4a2713aSLionel Sambuc     ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
5046*f4a2713aSLionel Sambuc     // Match the ')'.
5047*f4a2713aSLionel Sambuc     T.consumeClose();
5048*f4a2713aSLionel Sambuc     D.AddTypeInfo(DeclaratorChunk::getParen(T.getOpenLocation(),
5049*f4a2713aSLionel Sambuc                                             T.getCloseLocation()),
5050*f4a2713aSLionel Sambuc                   attrs, T.getCloseLocation());
5051*f4a2713aSLionel Sambuc 
5052*f4a2713aSLionel Sambuc     D.setGroupingParens(hadGroupingParens);
5053*f4a2713aSLionel Sambuc 
5054*f4a2713aSLionel Sambuc     // An ellipsis cannot be placed outside parentheses.
5055*f4a2713aSLionel Sambuc     if (EllipsisLoc.isValid())
5056*f4a2713aSLionel Sambuc       diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
5057*f4a2713aSLionel Sambuc 
5058*f4a2713aSLionel Sambuc     return;
5059*f4a2713aSLionel Sambuc   }
5060*f4a2713aSLionel Sambuc 
5061*f4a2713aSLionel Sambuc   // Okay, if this wasn't a grouping paren, it must be the start of a function
5062*f4a2713aSLionel Sambuc   // argument list.  Recognize that this declarator will never have an
5063*f4a2713aSLionel Sambuc   // identifier (and remember where it would have been), then call into
5064*f4a2713aSLionel Sambuc   // ParseFunctionDeclarator to handle of argument list.
5065*f4a2713aSLionel Sambuc   D.SetIdentifier(0, Tok.getLocation());
5066*f4a2713aSLionel Sambuc 
5067*f4a2713aSLionel Sambuc   // Enter function-declaration scope, limiting any declarators to the
5068*f4a2713aSLionel Sambuc   // function prototype scope, including parameter declarators.
5069*f4a2713aSLionel Sambuc   ParseScope PrototypeScope(this,
5070*f4a2713aSLionel Sambuc                             Scope::FunctionPrototypeScope | Scope::DeclScope |
5071*f4a2713aSLionel Sambuc                             (D.isFunctionDeclaratorAFunctionDeclaration()
5072*f4a2713aSLionel Sambuc                                ? Scope::FunctionDeclarationScope : 0));
5073*f4a2713aSLionel Sambuc   ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
5074*f4a2713aSLionel Sambuc   PrototypeScope.Exit();
5075*f4a2713aSLionel Sambuc }
5076*f4a2713aSLionel Sambuc 
5077*f4a2713aSLionel Sambuc /// ParseFunctionDeclarator - We are after the identifier and have parsed the
5078*f4a2713aSLionel Sambuc /// declarator D up to a paren, which indicates that we are parsing function
5079*f4a2713aSLionel Sambuc /// arguments.
5080*f4a2713aSLionel Sambuc ///
5081*f4a2713aSLionel Sambuc /// If FirstArgAttrs is non-null, then the caller parsed those arguments
5082*f4a2713aSLionel Sambuc /// immediately after the open paren - they should be considered to be the
5083*f4a2713aSLionel Sambuc /// first argument of a parameter.
5084*f4a2713aSLionel Sambuc ///
5085*f4a2713aSLionel Sambuc /// If RequiresArg is true, then the first argument of the function is required
5086*f4a2713aSLionel Sambuc /// to be present and required to not be an identifier list.
5087*f4a2713aSLionel Sambuc ///
5088*f4a2713aSLionel Sambuc /// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
5089*f4a2713aSLionel Sambuc /// (C++11) ref-qualifier[opt], exception-specification[opt],
5090*f4a2713aSLionel Sambuc /// (C++11) attribute-specifier-seq[opt], and (C++11) trailing-return-type[opt].
5091*f4a2713aSLionel Sambuc ///
5092*f4a2713aSLionel Sambuc /// [C++11] exception-specification:
5093*f4a2713aSLionel Sambuc ///           dynamic-exception-specification
5094*f4a2713aSLionel Sambuc ///           noexcept-specification
5095*f4a2713aSLionel Sambuc ///
5096*f4a2713aSLionel Sambuc void Parser::ParseFunctionDeclarator(Declarator &D,
5097*f4a2713aSLionel Sambuc                                      ParsedAttributes &FirstArgAttrs,
5098*f4a2713aSLionel Sambuc                                      BalancedDelimiterTracker &Tracker,
5099*f4a2713aSLionel Sambuc                                      bool IsAmbiguous,
5100*f4a2713aSLionel Sambuc                                      bool RequiresArg) {
5101*f4a2713aSLionel Sambuc   assert(getCurScope()->isFunctionPrototypeScope() &&
5102*f4a2713aSLionel Sambuc          "Should call from a Function scope");
5103*f4a2713aSLionel Sambuc   // lparen is already consumed!
5104*f4a2713aSLionel Sambuc   assert(D.isPastIdentifier() && "Should not call before identifier!");
5105*f4a2713aSLionel Sambuc 
5106*f4a2713aSLionel Sambuc   // This should be true when the function has typed arguments.
5107*f4a2713aSLionel Sambuc   // Otherwise, it is treated as a K&R-style function.
5108*f4a2713aSLionel Sambuc   bool HasProto = false;
5109*f4a2713aSLionel Sambuc   // Build up an array of information about the parsed arguments.
5110*f4a2713aSLionel Sambuc   SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
5111*f4a2713aSLionel Sambuc   // Remember where we see an ellipsis, if any.
5112*f4a2713aSLionel Sambuc   SourceLocation EllipsisLoc;
5113*f4a2713aSLionel Sambuc 
5114*f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
5115*f4a2713aSLionel Sambuc   bool RefQualifierIsLValueRef = true;
5116*f4a2713aSLionel Sambuc   SourceLocation RefQualifierLoc;
5117*f4a2713aSLionel Sambuc   SourceLocation ConstQualifierLoc;
5118*f4a2713aSLionel Sambuc   SourceLocation VolatileQualifierLoc;
5119*f4a2713aSLionel Sambuc   ExceptionSpecificationType ESpecType = EST_None;
5120*f4a2713aSLionel Sambuc   SourceRange ESpecRange;
5121*f4a2713aSLionel Sambuc   SmallVector<ParsedType, 2> DynamicExceptions;
5122*f4a2713aSLionel Sambuc   SmallVector<SourceRange, 2> DynamicExceptionRanges;
5123*f4a2713aSLionel Sambuc   ExprResult NoexceptExpr;
5124*f4a2713aSLionel Sambuc   ParsedAttributes FnAttrs(AttrFactory);
5125*f4a2713aSLionel Sambuc   TypeResult TrailingReturnType;
5126*f4a2713aSLionel Sambuc 
5127*f4a2713aSLionel Sambuc   Actions.ActOnStartFunctionDeclarator();
5128*f4a2713aSLionel Sambuc   /* LocalEndLoc is the end location for the local FunctionTypeLoc.
5129*f4a2713aSLionel Sambuc      EndLoc is the end location for the function declarator.
5130*f4a2713aSLionel Sambuc      They differ for trailing return types. */
5131*f4a2713aSLionel Sambuc   SourceLocation StartLoc, LocalEndLoc, EndLoc;
5132*f4a2713aSLionel Sambuc   SourceLocation LParenLoc, RParenLoc;
5133*f4a2713aSLionel Sambuc   LParenLoc = Tracker.getOpenLocation();
5134*f4a2713aSLionel Sambuc   StartLoc = LParenLoc;
5135*f4a2713aSLionel Sambuc 
5136*f4a2713aSLionel Sambuc   if (isFunctionDeclaratorIdentifierList()) {
5137*f4a2713aSLionel Sambuc     if (RequiresArg)
5138*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_argument_required_after_attribute);
5139*f4a2713aSLionel Sambuc 
5140*f4a2713aSLionel Sambuc     ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
5141*f4a2713aSLionel Sambuc 
5142*f4a2713aSLionel Sambuc     Tracker.consumeClose();
5143*f4a2713aSLionel Sambuc     RParenLoc = Tracker.getCloseLocation();
5144*f4a2713aSLionel Sambuc     LocalEndLoc = RParenLoc;
5145*f4a2713aSLionel Sambuc     EndLoc = RParenLoc;
5146*f4a2713aSLionel Sambuc   } else {
5147*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::r_paren))
5148*f4a2713aSLionel Sambuc       ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo,
5149*f4a2713aSLionel Sambuc                                       EllipsisLoc);
5150*f4a2713aSLionel Sambuc     else if (RequiresArg)
5151*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_argument_required_after_attribute);
5152*f4a2713aSLionel Sambuc 
5153*f4a2713aSLionel Sambuc     HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
5154*f4a2713aSLionel Sambuc 
5155*f4a2713aSLionel Sambuc     // If we have the closing ')', eat it.
5156*f4a2713aSLionel Sambuc     Tracker.consumeClose();
5157*f4a2713aSLionel Sambuc     RParenLoc = Tracker.getCloseLocation();
5158*f4a2713aSLionel Sambuc     LocalEndLoc = RParenLoc;
5159*f4a2713aSLionel Sambuc     EndLoc = RParenLoc;
5160*f4a2713aSLionel Sambuc 
5161*f4a2713aSLionel Sambuc     if (getLangOpts().CPlusPlus) {
5162*f4a2713aSLionel Sambuc       // FIXME: Accept these components in any order, and produce fixits to
5163*f4a2713aSLionel Sambuc       // correct the order if the user gets it wrong. Ideally we should deal
5164*f4a2713aSLionel Sambuc       // with the virt-specifier-seq and pure-specifier in the same way.
5165*f4a2713aSLionel Sambuc 
5166*f4a2713aSLionel Sambuc       // Parse cv-qualifier-seq[opt].
5167*f4a2713aSLionel Sambuc       ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false,
5168*f4a2713aSLionel Sambuc                                 /*CXX11AttributesAllowed*/ false,
5169*f4a2713aSLionel Sambuc                                 /*AtomicAllowed*/ false);
5170*f4a2713aSLionel Sambuc       if (!DS.getSourceRange().getEnd().isInvalid()) {
5171*f4a2713aSLionel Sambuc         EndLoc = DS.getSourceRange().getEnd();
5172*f4a2713aSLionel Sambuc         ConstQualifierLoc = DS.getConstSpecLoc();
5173*f4a2713aSLionel Sambuc         VolatileQualifierLoc = DS.getVolatileSpecLoc();
5174*f4a2713aSLionel Sambuc       }
5175*f4a2713aSLionel Sambuc 
5176*f4a2713aSLionel Sambuc       // Parse ref-qualifier[opt].
5177*f4a2713aSLionel Sambuc       if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
5178*f4a2713aSLionel Sambuc         Diag(Tok, getLangOpts().CPlusPlus11 ?
5179*f4a2713aSLionel Sambuc              diag::warn_cxx98_compat_ref_qualifier :
5180*f4a2713aSLionel Sambuc              diag::ext_ref_qualifier);
5181*f4a2713aSLionel Sambuc 
5182*f4a2713aSLionel Sambuc         RefQualifierIsLValueRef = Tok.is(tok::amp);
5183*f4a2713aSLionel Sambuc         RefQualifierLoc = ConsumeToken();
5184*f4a2713aSLionel Sambuc         EndLoc = RefQualifierLoc;
5185*f4a2713aSLionel Sambuc       }
5186*f4a2713aSLionel Sambuc 
5187*f4a2713aSLionel Sambuc       // C++11 [expr.prim.general]p3:
5188*f4a2713aSLionel Sambuc       //   If a declaration declares a member function or member function
5189*f4a2713aSLionel Sambuc       //   template of a class X, the expression this is a prvalue of type
5190*f4a2713aSLionel Sambuc       //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
5191*f4a2713aSLionel Sambuc       //   and the end of the function-definition, member-declarator, or
5192*f4a2713aSLionel Sambuc       //   declarator.
5193*f4a2713aSLionel Sambuc       // FIXME: currently, "static" case isn't handled correctly.
5194*f4a2713aSLionel Sambuc       bool IsCXX11MemberFunction =
5195*f4a2713aSLionel Sambuc         getLangOpts().CPlusPlus11 &&
5196*f4a2713aSLionel Sambuc         (D.getContext() == Declarator::MemberContext
5197*f4a2713aSLionel Sambuc          ? !D.getDeclSpec().isFriendSpecified()
5198*f4a2713aSLionel Sambuc          : D.getContext() == Declarator::FileContext &&
5199*f4a2713aSLionel Sambuc            D.getCXXScopeSpec().isValid() &&
5200*f4a2713aSLionel Sambuc            Actions.CurContext->isRecord());
5201*f4a2713aSLionel Sambuc       Sema::CXXThisScopeRAII ThisScope(Actions,
5202*f4a2713aSLionel Sambuc                                dyn_cast<CXXRecordDecl>(Actions.CurContext),
5203*f4a2713aSLionel Sambuc                                DS.getTypeQualifiers() |
5204*f4a2713aSLionel Sambuc                                (D.getDeclSpec().isConstexprSpecified() &&
5205*f4a2713aSLionel Sambuc                                 !getLangOpts().CPlusPlus1y
5206*f4a2713aSLionel Sambuc                                   ? Qualifiers::Const : 0),
5207*f4a2713aSLionel Sambuc                                IsCXX11MemberFunction);
5208*f4a2713aSLionel Sambuc 
5209*f4a2713aSLionel Sambuc       // Parse exception-specification[opt].
5210*f4a2713aSLionel Sambuc       ESpecType = tryParseExceptionSpecification(ESpecRange,
5211*f4a2713aSLionel Sambuc                                                  DynamicExceptions,
5212*f4a2713aSLionel Sambuc                                                  DynamicExceptionRanges,
5213*f4a2713aSLionel Sambuc                                                  NoexceptExpr);
5214*f4a2713aSLionel Sambuc       if (ESpecType != EST_None)
5215*f4a2713aSLionel Sambuc         EndLoc = ESpecRange.getEnd();
5216*f4a2713aSLionel Sambuc 
5217*f4a2713aSLionel Sambuc       // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
5218*f4a2713aSLionel Sambuc       // after the exception-specification.
5219*f4a2713aSLionel Sambuc       MaybeParseCXX11Attributes(FnAttrs);
5220*f4a2713aSLionel Sambuc 
5221*f4a2713aSLionel Sambuc       // Parse trailing-return-type[opt].
5222*f4a2713aSLionel Sambuc       LocalEndLoc = EndLoc;
5223*f4a2713aSLionel Sambuc       if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) {
5224*f4a2713aSLionel Sambuc         Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
5225*f4a2713aSLionel Sambuc         if (D.getDeclSpec().getTypeSpecType() == TST_auto)
5226*f4a2713aSLionel Sambuc           StartLoc = D.getDeclSpec().getTypeSpecTypeLoc();
5227*f4a2713aSLionel Sambuc         LocalEndLoc = Tok.getLocation();
5228*f4a2713aSLionel Sambuc         SourceRange Range;
5229*f4a2713aSLionel Sambuc         TrailingReturnType = ParseTrailingReturnType(Range);
5230*f4a2713aSLionel Sambuc         EndLoc = Range.getEnd();
5231*f4a2713aSLionel Sambuc       }
5232*f4a2713aSLionel Sambuc     }
5233*f4a2713aSLionel Sambuc   }
5234*f4a2713aSLionel Sambuc 
5235*f4a2713aSLionel Sambuc   // Remember that we parsed a function type, and remember the attributes.
5236*f4a2713aSLionel Sambuc   D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
5237*f4a2713aSLionel Sambuc                                              IsAmbiguous,
5238*f4a2713aSLionel Sambuc                                              LParenLoc,
5239*f4a2713aSLionel Sambuc                                              ParamInfo.data(), ParamInfo.size(),
5240*f4a2713aSLionel Sambuc                                              EllipsisLoc, RParenLoc,
5241*f4a2713aSLionel Sambuc                                              DS.getTypeQualifiers(),
5242*f4a2713aSLionel Sambuc                                              RefQualifierIsLValueRef,
5243*f4a2713aSLionel Sambuc                                              RefQualifierLoc, ConstQualifierLoc,
5244*f4a2713aSLionel Sambuc                                              VolatileQualifierLoc,
5245*f4a2713aSLionel Sambuc                                              /*MutableLoc=*/SourceLocation(),
5246*f4a2713aSLionel Sambuc                                              ESpecType, ESpecRange.getBegin(),
5247*f4a2713aSLionel Sambuc                                              DynamicExceptions.data(),
5248*f4a2713aSLionel Sambuc                                              DynamicExceptionRanges.data(),
5249*f4a2713aSLionel Sambuc                                              DynamicExceptions.size(),
5250*f4a2713aSLionel Sambuc                                              NoexceptExpr.isUsable() ?
5251*f4a2713aSLionel Sambuc                                                NoexceptExpr.get() : 0,
5252*f4a2713aSLionel Sambuc                                              StartLoc, LocalEndLoc, D,
5253*f4a2713aSLionel Sambuc                                              TrailingReturnType),
5254*f4a2713aSLionel Sambuc                 FnAttrs, EndLoc);
5255*f4a2713aSLionel Sambuc 
5256*f4a2713aSLionel Sambuc   Actions.ActOnEndFunctionDeclarator();
5257*f4a2713aSLionel Sambuc }
5258*f4a2713aSLionel Sambuc 
5259*f4a2713aSLionel Sambuc /// isFunctionDeclaratorIdentifierList - This parameter list may have an
5260*f4a2713aSLionel Sambuc /// identifier list form for a K&R-style function:  void foo(a,b,c)
5261*f4a2713aSLionel Sambuc ///
5262*f4a2713aSLionel Sambuc /// Note that identifier-lists are only allowed for normal declarators, not for
5263*f4a2713aSLionel Sambuc /// abstract-declarators.
5264*f4a2713aSLionel Sambuc bool Parser::isFunctionDeclaratorIdentifierList() {
5265*f4a2713aSLionel Sambuc   return !getLangOpts().CPlusPlus
5266*f4a2713aSLionel Sambuc          && Tok.is(tok::identifier)
5267*f4a2713aSLionel Sambuc          && !TryAltiVecVectorToken()
5268*f4a2713aSLionel Sambuc          // K&R identifier lists can't have typedefs as identifiers, per C99
5269*f4a2713aSLionel Sambuc          // 6.7.5.3p11.
5270*f4a2713aSLionel Sambuc          && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))
5271*f4a2713aSLionel Sambuc          // Identifier lists follow a really simple grammar: the identifiers can
5272*f4a2713aSLionel Sambuc          // be followed *only* by a ", identifier" or ")".  However, K&R
5273*f4a2713aSLionel Sambuc          // identifier lists are really rare in the brave new modern world, and
5274*f4a2713aSLionel Sambuc          // it is very common for someone to typo a type in a non-K&R style
5275*f4a2713aSLionel Sambuc          // list.  If we are presented with something like: "void foo(intptr x,
5276*f4a2713aSLionel Sambuc          // float y)", we don't want to start parsing the function declarator as
5277*f4a2713aSLionel Sambuc          // though it is a K&R style declarator just because intptr is an
5278*f4a2713aSLionel Sambuc          // invalid type.
5279*f4a2713aSLionel Sambuc          //
5280*f4a2713aSLionel Sambuc          // To handle this, we check to see if the token after the first
5281*f4a2713aSLionel Sambuc          // identifier is a "," or ")".  Only then do we parse it as an
5282*f4a2713aSLionel Sambuc          // identifier list.
5283*f4a2713aSLionel Sambuc          && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren));
5284*f4a2713aSLionel Sambuc }
5285*f4a2713aSLionel Sambuc 
5286*f4a2713aSLionel Sambuc /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
5287*f4a2713aSLionel Sambuc /// we found a K&R-style identifier list instead of a typed parameter list.
5288*f4a2713aSLionel Sambuc ///
5289*f4a2713aSLionel Sambuc /// After returning, ParamInfo will hold the parsed parameters.
5290*f4a2713aSLionel Sambuc ///
5291*f4a2713aSLionel Sambuc ///       identifier-list: [C99 6.7.5]
5292*f4a2713aSLionel Sambuc ///         identifier
5293*f4a2713aSLionel Sambuc ///         identifier-list ',' identifier
5294*f4a2713aSLionel Sambuc ///
5295*f4a2713aSLionel Sambuc void Parser::ParseFunctionDeclaratorIdentifierList(
5296*f4a2713aSLionel Sambuc        Declarator &D,
5297*f4a2713aSLionel Sambuc        SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {
5298*f4a2713aSLionel Sambuc   // If there was no identifier specified for the declarator, either we are in
5299*f4a2713aSLionel Sambuc   // an abstract-declarator, or we are in a parameter declarator which was found
5300*f4a2713aSLionel Sambuc   // to be abstract.  In abstract-declarators, identifier lists are not valid:
5301*f4a2713aSLionel Sambuc   // diagnose this.
5302*f4a2713aSLionel Sambuc   if (!D.getIdentifier())
5303*f4a2713aSLionel Sambuc     Diag(Tok, diag::ext_ident_list_in_param);
5304*f4a2713aSLionel Sambuc 
5305*f4a2713aSLionel Sambuc   // Maintain an efficient lookup of params we have seen so far.
5306*f4a2713aSLionel Sambuc   llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
5307*f4a2713aSLionel Sambuc 
5308*f4a2713aSLionel Sambuc   while (1) {
5309*f4a2713aSLionel Sambuc     // If this isn't an identifier, report the error and skip until ')'.
5310*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::identifier)) {
5311*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_expected_ident);
5312*f4a2713aSLionel Sambuc       SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
5313*f4a2713aSLionel Sambuc       // Forget we parsed anything.
5314*f4a2713aSLionel Sambuc       ParamInfo.clear();
5315*f4a2713aSLionel Sambuc       return;
5316*f4a2713aSLionel Sambuc     }
5317*f4a2713aSLionel Sambuc 
5318*f4a2713aSLionel Sambuc     IdentifierInfo *ParmII = Tok.getIdentifierInfo();
5319*f4a2713aSLionel Sambuc 
5320*f4a2713aSLionel Sambuc     // Reject 'typedef int y; int test(x, y)', but continue parsing.
5321*f4a2713aSLionel Sambuc     if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
5322*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
5323*f4a2713aSLionel Sambuc 
5324*f4a2713aSLionel Sambuc     // Verify that the argument identifier has not already been mentioned.
5325*f4a2713aSLionel Sambuc     if (!ParamsSoFar.insert(ParmII)) {
5326*f4a2713aSLionel Sambuc       Diag(Tok, diag::err_param_redefinition) << ParmII;
5327*f4a2713aSLionel Sambuc     } else {
5328*f4a2713aSLionel Sambuc       // Remember this identifier in ParamInfo.
5329*f4a2713aSLionel Sambuc       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
5330*f4a2713aSLionel Sambuc                                                      Tok.getLocation(),
5331*f4a2713aSLionel Sambuc                                                      0));
5332*f4a2713aSLionel Sambuc     }
5333*f4a2713aSLionel Sambuc 
5334*f4a2713aSLionel Sambuc     // Eat the identifier.
5335*f4a2713aSLionel Sambuc     ConsumeToken();
5336*f4a2713aSLionel Sambuc 
5337*f4a2713aSLionel Sambuc     // The list continues if we see a comma.
5338*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::comma))
5339*f4a2713aSLionel Sambuc       break;
5340*f4a2713aSLionel Sambuc     ConsumeToken();
5341*f4a2713aSLionel Sambuc   }
5342*f4a2713aSLionel Sambuc }
5343*f4a2713aSLionel Sambuc 
5344*f4a2713aSLionel Sambuc /// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
5345*f4a2713aSLionel Sambuc /// after the opening parenthesis. This function will not parse a K&R-style
5346*f4a2713aSLionel Sambuc /// identifier list.
5347*f4a2713aSLionel Sambuc ///
5348*f4a2713aSLionel Sambuc /// D is the declarator being parsed.  If FirstArgAttrs is non-null, then the
5349*f4a2713aSLionel Sambuc /// caller parsed those arguments immediately after the open paren - they should
5350*f4a2713aSLionel Sambuc /// be considered to be part of the first parameter.
5351*f4a2713aSLionel Sambuc ///
5352*f4a2713aSLionel Sambuc /// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
5353*f4a2713aSLionel Sambuc /// be the location of the ellipsis, if any was parsed.
5354*f4a2713aSLionel Sambuc ///
5355*f4a2713aSLionel Sambuc ///       parameter-type-list: [C99 6.7.5]
5356*f4a2713aSLionel Sambuc ///         parameter-list
5357*f4a2713aSLionel Sambuc ///         parameter-list ',' '...'
5358*f4a2713aSLionel Sambuc /// [C++]   parameter-list '...'
5359*f4a2713aSLionel Sambuc ///
5360*f4a2713aSLionel Sambuc ///       parameter-list: [C99 6.7.5]
5361*f4a2713aSLionel Sambuc ///         parameter-declaration
5362*f4a2713aSLionel Sambuc ///         parameter-list ',' parameter-declaration
5363*f4a2713aSLionel Sambuc ///
5364*f4a2713aSLionel Sambuc ///       parameter-declaration: [C99 6.7.5]
5365*f4a2713aSLionel Sambuc ///         declaration-specifiers declarator
5366*f4a2713aSLionel Sambuc /// [C++]   declaration-specifiers declarator '=' assignment-expression
5367*f4a2713aSLionel Sambuc /// [C++11]                                       initializer-clause
5368*f4a2713aSLionel Sambuc /// [GNU]   declaration-specifiers declarator attributes
5369*f4a2713aSLionel Sambuc ///         declaration-specifiers abstract-declarator[opt]
5370*f4a2713aSLionel Sambuc /// [C++]   declaration-specifiers abstract-declarator[opt]
5371*f4a2713aSLionel Sambuc ///           '=' assignment-expression
5372*f4a2713aSLionel Sambuc /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
5373*f4a2713aSLionel Sambuc /// [C++11] attribute-specifier-seq parameter-declaration
5374*f4a2713aSLionel Sambuc ///
5375*f4a2713aSLionel Sambuc void Parser::ParseParameterDeclarationClause(
5376*f4a2713aSLionel Sambuc        Declarator &D,
5377*f4a2713aSLionel Sambuc        ParsedAttributes &FirstArgAttrs,
5378*f4a2713aSLionel Sambuc        SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
5379*f4a2713aSLionel Sambuc        SourceLocation &EllipsisLoc) {
5380*f4a2713aSLionel Sambuc   while (1) {
5381*f4a2713aSLionel Sambuc     if (Tok.is(tok::ellipsis)) {
5382*f4a2713aSLionel Sambuc       // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
5383*f4a2713aSLionel Sambuc       // before deciding this was a parameter-declaration-clause.
5384*f4a2713aSLionel Sambuc       EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
5385*f4a2713aSLionel Sambuc       break;
5386*f4a2713aSLionel Sambuc     }
5387*f4a2713aSLionel Sambuc 
5388*f4a2713aSLionel Sambuc     // Parse the declaration-specifiers.
5389*f4a2713aSLionel Sambuc     // Just use the ParsingDeclaration "scope" of the declarator.
5390*f4a2713aSLionel Sambuc     DeclSpec DS(AttrFactory);
5391*f4a2713aSLionel Sambuc 
5392*f4a2713aSLionel Sambuc     // Parse any C++11 attributes.
5393*f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(DS.getAttributes());
5394*f4a2713aSLionel Sambuc 
5395*f4a2713aSLionel Sambuc     // Skip any Microsoft attributes before a param.
5396*f4a2713aSLionel Sambuc     MaybeParseMicrosoftAttributes(DS.getAttributes());
5397*f4a2713aSLionel Sambuc 
5398*f4a2713aSLionel Sambuc     SourceLocation DSStart = Tok.getLocation();
5399*f4a2713aSLionel Sambuc 
5400*f4a2713aSLionel Sambuc     // If the caller parsed attributes for the first argument, add them now.
5401*f4a2713aSLionel Sambuc     // Take them so that we only apply the attributes to the first parameter.
5402*f4a2713aSLionel Sambuc     // FIXME: If we can leave the attributes in the token stream somehow, we can
5403*f4a2713aSLionel Sambuc     // get rid of a parameter (FirstArgAttrs) and this statement. It might be
5404*f4a2713aSLionel Sambuc     // too much hassle.
5405*f4a2713aSLionel Sambuc     DS.takeAttributesFrom(FirstArgAttrs);
5406*f4a2713aSLionel Sambuc 
5407*f4a2713aSLionel Sambuc     ParseDeclarationSpecifiers(DS);
5408*f4a2713aSLionel Sambuc 
5409*f4a2713aSLionel Sambuc 
5410*f4a2713aSLionel Sambuc     // Parse the declarator.  This is "PrototypeContext" or
5411*f4a2713aSLionel Sambuc     // "LambdaExprParameterContext", because we must accept either
5412*f4a2713aSLionel Sambuc     // 'declarator' or 'abstract-declarator' here.
5413*f4a2713aSLionel Sambuc     Declarator ParmDeclarator(DS,
5414*f4a2713aSLionel Sambuc               D.getContext() == Declarator::LambdaExprContext ?
5415*f4a2713aSLionel Sambuc                                   Declarator::LambdaExprParameterContext :
5416*f4a2713aSLionel Sambuc                                                 Declarator::PrototypeContext);
5417*f4a2713aSLionel Sambuc     ParseDeclarator(ParmDeclarator);
5418*f4a2713aSLionel Sambuc 
5419*f4a2713aSLionel Sambuc     // Parse GNU attributes, if present.
5420*f4a2713aSLionel Sambuc     MaybeParseGNUAttributes(ParmDeclarator);
5421*f4a2713aSLionel Sambuc 
5422*f4a2713aSLionel Sambuc     // Remember this parsed parameter in ParamInfo.
5423*f4a2713aSLionel Sambuc     IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
5424*f4a2713aSLionel Sambuc 
5425*f4a2713aSLionel Sambuc     // DefArgToks is used when the parsing of default arguments needs
5426*f4a2713aSLionel Sambuc     // to be delayed.
5427*f4a2713aSLionel Sambuc     CachedTokens *DefArgToks = 0;
5428*f4a2713aSLionel Sambuc 
5429*f4a2713aSLionel Sambuc     // If no parameter was specified, verify that *something* was specified,
5430*f4a2713aSLionel Sambuc     // otherwise we have a missing type and identifier.
5431*f4a2713aSLionel Sambuc     if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 &&
5432*f4a2713aSLionel Sambuc         ParmDeclarator.getNumTypeObjects() == 0) {
5433*f4a2713aSLionel Sambuc       // Completely missing, emit error.
5434*f4a2713aSLionel Sambuc       Diag(DSStart, diag::err_missing_param);
5435*f4a2713aSLionel Sambuc     } else {
5436*f4a2713aSLionel Sambuc       // Otherwise, we have something.  Add it and let semantic analysis try
5437*f4a2713aSLionel Sambuc       // to grok it and add the result to the ParamInfo we are building.
5438*f4a2713aSLionel Sambuc 
5439*f4a2713aSLionel Sambuc       // Inform the actions module about the parameter declarator, so it gets
5440*f4a2713aSLionel Sambuc       // added to the current scope.
5441*f4a2713aSLionel Sambuc       Decl *Param = Actions.ActOnParamDeclarator(getCurScope(),
5442*f4a2713aSLionel Sambuc                                                        ParmDeclarator);
5443*f4a2713aSLionel Sambuc       // Parse the default argument, if any. We parse the default
5444*f4a2713aSLionel Sambuc       // arguments in all dialects; the semantic analysis in
5445*f4a2713aSLionel Sambuc       // ActOnParamDefaultArgument will reject the default argument in
5446*f4a2713aSLionel Sambuc       // C.
5447*f4a2713aSLionel Sambuc       if (Tok.is(tok::equal)) {
5448*f4a2713aSLionel Sambuc         SourceLocation EqualLoc = Tok.getLocation();
5449*f4a2713aSLionel Sambuc 
5450*f4a2713aSLionel Sambuc         // Parse the default argument
5451*f4a2713aSLionel Sambuc         if (D.getContext() == Declarator::MemberContext) {
5452*f4a2713aSLionel Sambuc           // If we're inside a class definition, cache the tokens
5453*f4a2713aSLionel Sambuc           // corresponding to the default argument. We'll actually parse
5454*f4a2713aSLionel Sambuc           // them when we see the end of the class definition.
5455*f4a2713aSLionel Sambuc           // FIXME: Can we use a smart pointer for Toks?
5456*f4a2713aSLionel Sambuc           DefArgToks = new CachedTokens;
5457*f4a2713aSLionel Sambuc 
5458*f4a2713aSLionel Sambuc           if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) {
5459*f4a2713aSLionel Sambuc             delete DefArgToks;
5460*f4a2713aSLionel Sambuc             DefArgToks = 0;
5461*f4a2713aSLionel Sambuc             Actions.ActOnParamDefaultArgumentError(Param);
5462*f4a2713aSLionel Sambuc           } else {
5463*f4a2713aSLionel Sambuc             // Mark the end of the default argument so that we know when to
5464*f4a2713aSLionel Sambuc             // stop when we parse it later on.
5465*f4a2713aSLionel Sambuc             Token DefArgEnd;
5466*f4a2713aSLionel Sambuc             DefArgEnd.startToken();
5467*f4a2713aSLionel Sambuc             DefArgEnd.setKind(tok::cxx_defaultarg_end);
5468*f4a2713aSLionel Sambuc             DefArgEnd.setLocation(Tok.getLocation());
5469*f4a2713aSLionel Sambuc             DefArgToks->push_back(DefArgEnd);
5470*f4a2713aSLionel Sambuc             Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
5471*f4a2713aSLionel Sambuc                                                 (*DefArgToks)[1].getLocation());
5472*f4a2713aSLionel Sambuc           }
5473*f4a2713aSLionel Sambuc         } else {
5474*f4a2713aSLionel Sambuc           // Consume the '='.
5475*f4a2713aSLionel Sambuc           ConsumeToken();
5476*f4a2713aSLionel Sambuc 
5477*f4a2713aSLionel Sambuc           // The argument isn't actually potentially evaluated unless it is
5478*f4a2713aSLionel Sambuc           // used.
5479*f4a2713aSLionel Sambuc           EnterExpressionEvaluationContext Eval(Actions,
5480*f4a2713aSLionel Sambuc                                               Sema::PotentiallyEvaluatedIfUsed,
5481*f4a2713aSLionel Sambuc                                                 Param);
5482*f4a2713aSLionel Sambuc 
5483*f4a2713aSLionel Sambuc           ExprResult DefArgResult;
5484*f4a2713aSLionel Sambuc           if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
5485*f4a2713aSLionel Sambuc             Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
5486*f4a2713aSLionel Sambuc             DefArgResult = ParseBraceInitializer();
5487*f4a2713aSLionel Sambuc           } else
5488*f4a2713aSLionel Sambuc             DefArgResult = ParseAssignmentExpression();
5489*f4a2713aSLionel Sambuc           if (DefArgResult.isInvalid()) {
5490*f4a2713aSLionel Sambuc             Actions.ActOnParamDefaultArgumentError(Param);
5491*f4a2713aSLionel Sambuc             SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
5492*f4a2713aSLionel Sambuc           } else {
5493*f4a2713aSLionel Sambuc             // Inform the actions module about the default argument
5494*f4a2713aSLionel Sambuc             Actions.ActOnParamDefaultArgument(Param, EqualLoc,
5495*f4a2713aSLionel Sambuc                                               DefArgResult.take());
5496*f4a2713aSLionel Sambuc           }
5497*f4a2713aSLionel Sambuc         }
5498*f4a2713aSLionel Sambuc       }
5499*f4a2713aSLionel Sambuc 
5500*f4a2713aSLionel Sambuc       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
5501*f4a2713aSLionel Sambuc                                           ParmDeclarator.getIdentifierLoc(),
5502*f4a2713aSLionel Sambuc                                           Param, DefArgToks));
5503*f4a2713aSLionel Sambuc     }
5504*f4a2713aSLionel Sambuc 
5505*f4a2713aSLionel Sambuc     // If the next token is a comma, consume it and keep reading arguments.
5506*f4a2713aSLionel Sambuc     if (Tok.isNot(tok::comma)) {
5507*f4a2713aSLionel Sambuc       if (Tok.is(tok::ellipsis)) {
5508*f4a2713aSLionel Sambuc         EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
5509*f4a2713aSLionel Sambuc 
5510*f4a2713aSLionel Sambuc         if (!getLangOpts().CPlusPlus) {
5511*f4a2713aSLionel Sambuc           // We have ellipsis without a preceding ',', which is ill-formed
5512*f4a2713aSLionel Sambuc           // in C. Complain and provide the fix.
5513*f4a2713aSLionel Sambuc           Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
5514*f4a2713aSLionel Sambuc             << FixItHint::CreateInsertion(EllipsisLoc, ", ");
5515*f4a2713aSLionel Sambuc         }
5516*f4a2713aSLionel Sambuc       }
5517*f4a2713aSLionel Sambuc 
5518*f4a2713aSLionel Sambuc       break;
5519*f4a2713aSLionel Sambuc     }
5520*f4a2713aSLionel Sambuc 
5521*f4a2713aSLionel Sambuc     // Consume the comma.
5522*f4a2713aSLionel Sambuc     ConsumeToken();
5523*f4a2713aSLionel Sambuc   }
5524*f4a2713aSLionel Sambuc 
5525*f4a2713aSLionel Sambuc }
5526*f4a2713aSLionel Sambuc 
5527*f4a2713aSLionel Sambuc /// [C90]   direct-declarator '[' constant-expression[opt] ']'
5528*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
5529*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
5530*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
5531*f4a2713aSLionel Sambuc /// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
5532*f4a2713aSLionel Sambuc /// [C++11] direct-declarator '[' constant-expression[opt] ']'
5533*f4a2713aSLionel Sambuc ///                           attribute-specifier-seq[opt]
5534*f4a2713aSLionel Sambuc void Parser::ParseBracketDeclarator(Declarator &D) {
5535*f4a2713aSLionel Sambuc   if (CheckProhibitedCXX11Attribute())
5536*f4a2713aSLionel Sambuc     return;
5537*f4a2713aSLionel Sambuc 
5538*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_square);
5539*f4a2713aSLionel Sambuc   T.consumeOpen();
5540*f4a2713aSLionel Sambuc 
5541*f4a2713aSLionel Sambuc   // C array syntax has many features, but by-far the most common is [] and [4].
5542*f4a2713aSLionel Sambuc   // This code does a fast path to handle some of the most obvious cases.
5543*f4a2713aSLionel Sambuc   if (Tok.getKind() == tok::r_square) {
5544*f4a2713aSLionel Sambuc     T.consumeClose();
5545*f4a2713aSLionel Sambuc     ParsedAttributes attrs(AttrFactory);
5546*f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(attrs);
5547*f4a2713aSLionel Sambuc 
5548*f4a2713aSLionel Sambuc     // Remember that we parsed the empty array type.
5549*f4a2713aSLionel Sambuc     ExprResult NumElements;
5550*f4a2713aSLionel Sambuc     D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
5551*f4a2713aSLionel Sambuc                                             T.getOpenLocation(),
5552*f4a2713aSLionel Sambuc                                             T.getCloseLocation()),
5553*f4a2713aSLionel Sambuc                   attrs, T.getCloseLocation());
5554*f4a2713aSLionel Sambuc     return;
5555*f4a2713aSLionel Sambuc   } else if (Tok.getKind() == tok::numeric_constant &&
5556*f4a2713aSLionel Sambuc              GetLookAheadToken(1).is(tok::r_square)) {
5557*f4a2713aSLionel Sambuc     // [4] is very common.  Parse the numeric constant expression.
5558*f4a2713aSLionel Sambuc     ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
5559*f4a2713aSLionel Sambuc     ConsumeToken();
5560*f4a2713aSLionel Sambuc 
5561*f4a2713aSLionel Sambuc     T.consumeClose();
5562*f4a2713aSLionel Sambuc     ParsedAttributes attrs(AttrFactory);
5563*f4a2713aSLionel Sambuc     MaybeParseCXX11Attributes(attrs);
5564*f4a2713aSLionel Sambuc 
5565*f4a2713aSLionel Sambuc     // Remember that we parsed a array type, and remember its features.
5566*f4a2713aSLionel Sambuc     D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
5567*f4a2713aSLionel Sambuc                                             ExprRes.release(),
5568*f4a2713aSLionel Sambuc                                             T.getOpenLocation(),
5569*f4a2713aSLionel Sambuc                                             T.getCloseLocation()),
5570*f4a2713aSLionel Sambuc                   attrs, T.getCloseLocation());
5571*f4a2713aSLionel Sambuc     return;
5572*f4a2713aSLionel Sambuc   }
5573*f4a2713aSLionel Sambuc 
5574*f4a2713aSLionel Sambuc   // If valid, this location is the position where we read the 'static' keyword.
5575*f4a2713aSLionel Sambuc   SourceLocation StaticLoc;
5576*f4a2713aSLionel Sambuc   if (Tok.is(tok::kw_static))
5577*f4a2713aSLionel Sambuc     StaticLoc = ConsumeToken();
5578*f4a2713aSLionel Sambuc 
5579*f4a2713aSLionel Sambuc   // If there is a type-qualifier-list, read it now.
5580*f4a2713aSLionel Sambuc   // Type qualifiers in an array subscript are a C99 feature.
5581*f4a2713aSLionel Sambuc   DeclSpec DS(AttrFactory);
5582*f4a2713aSLionel Sambuc   ParseTypeQualifierListOpt(DS, false /*no attributes*/);
5583*f4a2713aSLionel Sambuc 
5584*f4a2713aSLionel Sambuc   // If we haven't already read 'static', check to see if there is one after the
5585*f4a2713aSLionel Sambuc   // type-qualifier-list.
5586*f4a2713aSLionel Sambuc   if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
5587*f4a2713aSLionel Sambuc     StaticLoc = ConsumeToken();
5588*f4a2713aSLionel Sambuc 
5589*f4a2713aSLionel Sambuc   // Handle "direct-declarator [ type-qual-list[opt] * ]".
5590*f4a2713aSLionel Sambuc   bool isStar = false;
5591*f4a2713aSLionel Sambuc   ExprResult NumElements;
5592*f4a2713aSLionel Sambuc 
5593*f4a2713aSLionel Sambuc   // Handle the case where we have '[*]' as the array size.  However, a leading
5594*f4a2713aSLionel Sambuc   // star could be the start of an expression, for example 'X[*p + 4]'.  Verify
5595*f4a2713aSLionel Sambuc   // the token after the star is a ']'.  Since stars in arrays are
5596*f4a2713aSLionel Sambuc   // infrequent, use of lookahead is not costly here.
5597*f4a2713aSLionel Sambuc   if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
5598*f4a2713aSLionel Sambuc     ConsumeToken();  // Eat the '*'.
5599*f4a2713aSLionel Sambuc 
5600*f4a2713aSLionel Sambuc     if (StaticLoc.isValid()) {
5601*f4a2713aSLionel Sambuc       Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
5602*f4a2713aSLionel Sambuc       StaticLoc = SourceLocation();  // Drop the static.
5603*f4a2713aSLionel Sambuc     }
5604*f4a2713aSLionel Sambuc     isStar = true;
5605*f4a2713aSLionel Sambuc   } else if (Tok.isNot(tok::r_square)) {
5606*f4a2713aSLionel Sambuc     // Note, in C89, this production uses the constant-expr production instead
5607*f4a2713aSLionel Sambuc     // of assignment-expr.  The only difference is that assignment-expr allows
5608*f4a2713aSLionel Sambuc     // things like '=' and '*='.  Sema rejects these in C89 mode because they
5609*f4a2713aSLionel Sambuc     // are not i-c-e's, so we don't need to distinguish between the two here.
5610*f4a2713aSLionel Sambuc 
5611*f4a2713aSLionel Sambuc     // Parse the constant-expression or assignment-expression now (depending
5612*f4a2713aSLionel Sambuc     // on dialect).
5613*f4a2713aSLionel Sambuc     if (getLangOpts().CPlusPlus) {
5614*f4a2713aSLionel Sambuc       NumElements = ParseConstantExpression();
5615*f4a2713aSLionel Sambuc     } else {
5616*f4a2713aSLionel Sambuc       EnterExpressionEvaluationContext Unevaluated(Actions,
5617*f4a2713aSLionel Sambuc                                                    Sema::ConstantEvaluated);
5618*f4a2713aSLionel Sambuc       NumElements = ParseAssignmentExpression();
5619*f4a2713aSLionel Sambuc     }
5620*f4a2713aSLionel Sambuc   }
5621*f4a2713aSLionel Sambuc 
5622*f4a2713aSLionel Sambuc   // If there was an error parsing the assignment-expression, recover.
5623*f4a2713aSLionel Sambuc   if (NumElements.isInvalid()) {
5624*f4a2713aSLionel Sambuc     D.setInvalidType(true);
5625*f4a2713aSLionel Sambuc     // If the expression was invalid, skip it.
5626*f4a2713aSLionel Sambuc     SkipUntil(tok::r_square, StopAtSemi);
5627*f4a2713aSLionel Sambuc     return;
5628*f4a2713aSLionel Sambuc   }
5629*f4a2713aSLionel Sambuc 
5630*f4a2713aSLionel Sambuc   T.consumeClose();
5631*f4a2713aSLionel Sambuc 
5632*f4a2713aSLionel Sambuc   ParsedAttributes attrs(AttrFactory);
5633*f4a2713aSLionel Sambuc   MaybeParseCXX11Attributes(attrs);
5634*f4a2713aSLionel Sambuc 
5635*f4a2713aSLionel Sambuc   // Remember that we parsed a array type, and remember its features.
5636*f4a2713aSLionel Sambuc   D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
5637*f4a2713aSLionel Sambuc                                           StaticLoc.isValid(), isStar,
5638*f4a2713aSLionel Sambuc                                           NumElements.release(),
5639*f4a2713aSLionel Sambuc                                           T.getOpenLocation(),
5640*f4a2713aSLionel Sambuc                                           T.getCloseLocation()),
5641*f4a2713aSLionel Sambuc                 attrs, T.getCloseLocation());
5642*f4a2713aSLionel Sambuc }
5643*f4a2713aSLionel Sambuc 
5644*f4a2713aSLionel Sambuc /// [GNU]   typeof-specifier:
5645*f4a2713aSLionel Sambuc ///           typeof ( expressions )
5646*f4a2713aSLionel Sambuc ///           typeof ( type-name )
5647*f4a2713aSLionel Sambuc /// [GNU/C++] typeof unary-expression
5648*f4a2713aSLionel Sambuc ///
5649*f4a2713aSLionel Sambuc void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
5650*f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier");
5651*f4a2713aSLionel Sambuc   Token OpTok = Tok;
5652*f4a2713aSLionel Sambuc   SourceLocation StartLoc = ConsumeToken();
5653*f4a2713aSLionel Sambuc 
5654*f4a2713aSLionel Sambuc   const bool hasParens = Tok.is(tok::l_paren);
5655*f4a2713aSLionel Sambuc 
5656*f4a2713aSLionel Sambuc   EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
5657*f4a2713aSLionel Sambuc                                                Sema::ReuseLambdaContextDecl);
5658*f4a2713aSLionel Sambuc 
5659*f4a2713aSLionel Sambuc   bool isCastExpr;
5660*f4a2713aSLionel Sambuc   ParsedType CastTy;
5661*f4a2713aSLionel Sambuc   SourceRange CastRange;
5662*f4a2713aSLionel Sambuc   ExprResult Operand = ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr,
5663*f4a2713aSLionel Sambuc                                                           CastTy, CastRange);
5664*f4a2713aSLionel Sambuc   if (hasParens)
5665*f4a2713aSLionel Sambuc     DS.setTypeofParensRange(CastRange);
5666*f4a2713aSLionel Sambuc 
5667*f4a2713aSLionel Sambuc   if (CastRange.getEnd().isInvalid())
5668*f4a2713aSLionel Sambuc     // FIXME: Not accurate, the range gets one token more than it should.
5669*f4a2713aSLionel Sambuc     DS.SetRangeEnd(Tok.getLocation());
5670*f4a2713aSLionel Sambuc   else
5671*f4a2713aSLionel Sambuc     DS.SetRangeEnd(CastRange.getEnd());
5672*f4a2713aSLionel Sambuc 
5673*f4a2713aSLionel Sambuc   if (isCastExpr) {
5674*f4a2713aSLionel Sambuc     if (!CastTy) {
5675*f4a2713aSLionel Sambuc       DS.SetTypeSpecError();
5676*f4a2713aSLionel Sambuc       return;
5677*f4a2713aSLionel Sambuc     }
5678*f4a2713aSLionel Sambuc 
5679*f4a2713aSLionel Sambuc     const char *PrevSpec = 0;
5680*f4a2713aSLionel Sambuc     unsigned DiagID;
5681*f4a2713aSLionel Sambuc     // Check for duplicate type specifiers (e.g. "int typeof(int)").
5682*f4a2713aSLionel Sambuc     if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
5683*f4a2713aSLionel Sambuc                            DiagID, CastTy))
5684*f4a2713aSLionel Sambuc       Diag(StartLoc, DiagID) << PrevSpec;
5685*f4a2713aSLionel Sambuc     return;
5686*f4a2713aSLionel Sambuc   }
5687*f4a2713aSLionel Sambuc 
5688*f4a2713aSLionel Sambuc   // If we get here, the operand to the typeof was an expresion.
5689*f4a2713aSLionel Sambuc   if (Operand.isInvalid()) {
5690*f4a2713aSLionel Sambuc     DS.SetTypeSpecError();
5691*f4a2713aSLionel Sambuc     return;
5692*f4a2713aSLionel Sambuc   }
5693*f4a2713aSLionel Sambuc 
5694*f4a2713aSLionel Sambuc   // We might need to transform the operand if it is potentially evaluated.
5695*f4a2713aSLionel Sambuc   Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());
5696*f4a2713aSLionel Sambuc   if (Operand.isInvalid()) {
5697*f4a2713aSLionel Sambuc     DS.SetTypeSpecError();
5698*f4a2713aSLionel Sambuc     return;
5699*f4a2713aSLionel Sambuc   }
5700*f4a2713aSLionel Sambuc 
5701*f4a2713aSLionel Sambuc   const char *PrevSpec = 0;
5702*f4a2713aSLionel Sambuc   unsigned DiagID;
5703*f4a2713aSLionel Sambuc   // Check for duplicate type specifiers (e.g. "int typeof(int)").
5704*f4a2713aSLionel Sambuc   if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
5705*f4a2713aSLionel Sambuc                          DiagID, Operand.get()))
5706*f4a2713aSLionel Sambuc     Diag(StartLoc, DiagID) << PrevSpec;
5707*f4a2713aSLionel Sambuc }
5708*f4a2713aSLionel Sambuc 
5709*f4a2713aSLionel Sambuc /// [C11]   atomic-specifier:
5710*f4a2713aSLionel Sambuc ///           _Atomic ( type-name )
5711*f4a2713aSLionel Sambuc ///
5712*f4a2713aSLionel Sambuc void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
5713*f4a2713aSLionel Sambuc   assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) &&
5714*f4a2713aSLionel Sambuc          "Not an atomic specifier");
5715*f4a2713aSLionel Sambuc 
5716*f4a2713aSLionel Sambuc   SourceLocation StartLoc = ConsumeToken();
5717*f4a2713aSLionel Sambuc   BalancedDelimiterTracker T(*this, tok::l_paren);
5718*f4a2713aSLionel Sambuc   if (T.consumeOpen())
5719*f4a2713aSLionel Sambuc     return;
5720*f4a2713aSLionel Sambuc 
5721*f4a2713aSLionel Sambuc   TypeResult Result = ParseTypeName();
5722*f4a2713aSLionel Sambuc   if (Result.isInvalid()) {
5723*f4a2713aSLionel Sambuc     SkipUntil(tok::r_paren, StopAtSemi);
5724*f4a2713aSLionel Sambuc     return;
5725*f4a2713aSLionel Sambuc   }
5726*f4a2713aSLionel Sambuc 
5727*f4a2713aSLionel Sambuc   // Match the ')'
5728*f4a2713aSLionel Sambuc   T.consumeClose();
5729*f4a2713aSLionel Sambuc 
5730*f4a2713aSLionel Sambuc   if (T.getCloseLocation().isInvalid())
5731*f4a2713aSLionel Sambuc     return;
5732*f4a2713aSLionel Sambuc 
5733*f4a2713aSLionel Sambuc   DS.setTypeofParensRange(T.getRange());
5734*f4a2713aSLionel Sambuc   DS.SetRangeEnd(T.getCloseLocation());
5735*f4a2713aSLionel Sambuc 
5736*f4a2713aSLionel Sambuc   const char *PrevSpec = 0;
5737*f4a2713aSLionel Sambuc   unsigned DiagID;
5738*f4a2713aSLionel Sambuc   if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
5739*f4a2713aSLionel Sambuc                          DiagID, Result.release()))
5740*f4a2713aSLionel Sambuc     Diag(StartLoc, DiagID) << PrevSpec;
5741*f4a2713aSLionel Sambuc }
5742*f4a2713aSLionel Sambuc 
5743*f4a2713aSLionel Sambuc 
5744*f4a2713aSLionel Sambuc /// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
5745*f4a2713aSLionel Sambuc /// from TryAltiVecVectorToken.
5746*f4a2713aSLionel Sambuc bool Parser::TryAltiVecVectorTokenOutOfLine() {
5747*f4a2713aSLionel Sambuc   Token Next = NextToken();
5748*f4a2713aSLionel Sambuc   switch (Next.getKind()) {
5749*f4a2713aSLionel Sambuc   default: return false;
5750*f4a2713aSLionel Sambuc   case tok::kw_short:
5751*f4a2713aSLionel Sambuc   case tok::kw_long:
5752*f4a2713aSLionel Sambuc   case tok::kw_signed:
5753*f4a2713aSLionel Sambuc   case tok::kw_unsigned:
5754*f4a2713aSLionel Sambuc   case tok::kw_void:
5755*f4a2713aSLionel Sambuc   case tok::kw_char:
5756*f4a2713aSLionel Sambuc   case tok::kw_int:
5757*f4a2713aSLionel Sambuc   case tok::kw_float:
5758*f4a2713aSLionel Sambuc   case tok::kw_double:
5759*f4a2713aSLionel Sambuc   case tok::kw_bool:
5760*f4a2713aSLionel Sambuc   case tok::kw___pixel:
5761*f4a2713aSLionel Sambuc     Tok.setKind(tok::kw___vector);
5762*f4a2713aSLionel Sambuc     return true;
5763*f4a2713aSLionel Sambuc   case tok::identifier:
5764*f4a2713aSLionel Sambuc     if (Next.getIdentifierInfo() == Ident_pixel) {
5765*f4a2713aSLionel Sambuc       Tok.setKind(tok::kw___vector);
5766*f4a2713aSLionel Sambuc       return true;
5767*f4a2713aSLionel Sambuc     }
5768*f4a2713aSLionel Sambuc     if (Next.getIdentifierInfo() == Ident_bool) {
5769*f4a2713aSLionel Sambuc       Tok.setKind(tok::kw___vector);
5770*f4a2713aSLionel Sambuc       return true;
5771*f4a2713aSLionel Sambuc     }
5772*f4a2713aSLionel Sambuc     return false;
5773*f4a2713aSLionel Sambuc   }
5774*f4a2713aSLionel Sambuc }
5775*f4a2713aSLionel Sambuc 
5776*f4a2713aSLionel Sambuc bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
5777*f4a2713aSLionel Sambuc                                       const char *&PrevSpec, unsigned &DiagID,
5778*f4a2713aSLionel Sambuc                                       bool &isInvalid) {
5779*f4a2713aSLionel Sambuc   if (Tok.getIdentifierInfo() == Ident_vector) {
5780*f4a2713aSLionel Sambuc     Token Next = NextToken();
5781*f4a2713aSLionel Sambuc     switch (Next.getKind()) {
5782*f4a2713aSLionel Sambuc     case tok::kw_short:
5783*f4a2713aSLionel Sambuc     case tok::kw_long:
5784*f4a2713aSLionel Sambuc     case tok::kw_signed:
5785*f4a2713aSLionel Sambuc     case tok::kw_unsigned:
5786*f4a2713aSLionel Sambuc     case tok::kw_void:
5787*f4a2713aSLionel Sambuc     case tok::kw_char:
5788*f4a2713aSLionel Sambuc     case tok::kw_int:
5789*f4a2713aSLionel Sambuc     case tok::kw_float:
5790*f4a2713aSLionel Sambuc     case tok::kw_double:
5791*f4a2713aSLionel Sambuc     case tok::kw_bool:
5792*f4a2713aSLionel Sambuc     case tok::kw___pixel:
5793*f4a2713aSLionel Sambuc       isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5794*f4a2713aSLionel Sambuc       return true;
5795*f4a2713aSLionel Sambuc     case tok::identifier:
5796*f4a2713aSLionel Sambuc       if (Next.getIdentifierInfo() == Ident_pixel) {
5797*f4a2713aSLionel Sambuc         isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5798*f4a2713aSLionel Sambuc         return true;
5799*f4a2713aSLionel Sambuc       }
5800*f4a2713aSLionel Sambuc       if (Next.getIdentifierInfo() == Ident_bool) {
5801*f4a2713aSLionel Sambuc         isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
5802*f4a2713aSLionel Sambuc         return true;
5803*f4a2713aSLionel Sambuc       }
5804*f4a2713aSLionel Sambuc       break;
5805*f4a2713aSLionel Sambuc     default:
5806*f4a2713aSLionel Sambuc       break;
5807*f4a2713aSLionel Sambuc     }
5808*f4a2713aSLionel Sambuc   } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
5809*f4a2713aSLionel Sambuc              DS.isTypeAltiVecVector()) {
5810*f4a2713aSLionel Sambuc     isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
5811*f4a2713aSLionel Sambuc     return true;
5812*f4a2713aSLionel Sambuc   } else if ((Tok.getIdentifierInfo() == Ident_bool) &&
5813*f4a2713aSLionel Sambuc              DS.isTypeAltiVecVector()) {
5814*f4a2713aSLionel Sambuc     isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID);
5815*f4a2713aSLionel Sambuc     return true;
5816*f4a2713aSLionel Sambuc   }
5817*f4a2713aSLionel Sambuc   return false;
5818*f4a2713aSLionel Sambuc }
5819