1*67e74705SXin Li //===--- ParseDeclCXX.cpp - C++ Declaration Parsing -------------*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements the C++ Declaration portions of the Parser interfaces.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li
14*67e74705SXin Li #include "clang/Parse/Parser.h"
15*67e74705SXin Li #include "RAIIObjectsForParser.h"
16*67e74705SXin Li #include "clang/AST/ASTContext.h"
17*67e74705SXin Li #include "clang/AST/DeclTemplate.h"
18*67e74705SXin Li #include "clang/Basic/Attributes.h"
19*67e74705SXin Li #include "clang/Basic/CharInfo.h"
20*67e74705SXin Li #include "clang/Basic/OperatorKinds.h"
21*67e74705SXin Li #include "clang/Basic/TargetInfo.h"
22*67e74705SXin Li #include "clang/Parse/ParseDiagnostic.h"
23*67e74705SXin Li #include "clang/Sema/DeclSpec.h"
24*67e74705SXin Li #include "clang/Sema/ParsedTemplate.h"
25*67e74705SXin Li #include "clang/Sema/PrettyDeclStackTrace.h"
26*67e74705SXin Li #include "clang/Sema/Scope.h"
27*67e74705SXin Li #include "clang/Sema/SemaDiagnostic.h"
28*67e74705SXin Li #include "llvm/ADT/SmallString.h"
29*67e74705SXin Li
30*67e74705SXin Li using namespace clang;
31*67e74705SXin Li
32*67e74705SXin Li /// ParseNamespace - We know that the current token is a namespace keyword. This
33*67e74705SXin Li /// may either be a top level namespace or a block-level namespace alias. If
34*67e74705SXin Li /// there was an inline keyword, it has already been parsed.
35*67e74705SXin Li ///
36*67e74705SXin Li /// namespace-definition: [C++ 7.3: basic.namespace]
37*67e74705SXin Li /// named-namespace-definition
38*67e74705SXin Li /// unnamed-namespace-definition
39*67e74705SXin Li ///
40*67e74705SXin Li /// unnamed-namespace-definition:
41*67e74705SXin Li /// 'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
42*67e74705SXin Li ///
43*67e74705SXin Li /// named-namespace-definition:
44*67e74705SXin Li /// original-namespace-definition
45*67e74705SXin Li /// extension-namespace-definition
46*67e74705SXin Li ///
47*67e74705SXin Li /// original-namespace-definition:
48*67e74705SXin Li /// 'inline'[opt] 'namespace' identifier attributes[opt]
49*67e74705SXin Li /// '{' namespace-body '}'
50*67e74705SXin Li ///
51*67e74705SXin Li /// extension-namespace-definition:
52*67e74705SXin Li /// 'inline'[opt] 'namespace' original-namespace-name
53*67e74705SXin Li /// '{' namespace-body '}'
54*67e74705SXin Li ///
55*67e74705SXin Li /// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
56*67e74705SXin Li /// 'namespace' identifier '=' qualified-namespace-specifier ';'
57*67e74705SXin Li ///
ParseNamespace(unsigned Context,SourceLocation & DeclEnd,SourceLocation InlineLoc)58*67e74705SXin Li Parser::DeclGroupPtrTy Parser::ParseNamespace(unsigned Context,
59*67e74705SXin Li SourceLocation &DeclEnd,
60*67e74705SXin Li SourceLocation InlineLoc) {
61*67e74705SXin Li assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
62*67e74705SXin Li SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
63*67e74705SXin Li ObjCDeclContextSwitch ObjCDC(*this);
64*67e74705SXin Li
65*67e74705SXin Li if (Tok.is(tok::code_completion)) {
66*67e74705SXin Li Actions.CodeCompleteNamespaceDecl(getCurScope());
67*67e74705SXin Li cutOffParsing();
68*67e74705SXin Li return nullptr;
69*67e74705SXin Li }
70*67e74705SXin Li
71*67e74705SXin Li SourceLocation IdentLoc;
72*67e74705SXin Li IdentifierInfo *Ident = nullptr;
73*67e74705SXin Li std::vector<SourceLocation> ExtraIdentLoc;
74*67e74705SXin Li std::vector<IdentifierInfo*> ExtraIdent;
75*67e74705SXin Li std::vector<SourceLocation> ExtraNamespaceLoc;
76*67e74705SXin Li
77*67e74705SXin Li ParsedAttributesWithRange attrs(AttrFactory);
78*67e74705SXin Li SourceLocation attrLoc;
79*67e74705SXin Li if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
80*67e74705SXin Li if (!getLangOpts().CPlusPlus1z)
81*67e74705SXin Li Diag(Tok.getLocation(), diag::warn_cxx14_compat_attribute)
82*67e74705SXin Li << 0 /*namespace*/;
83*67e74705SXin Li attrLoc = Tok.getLocation();
84*67e74705SXin Li ParseCXX11Attributes(attrs);
85*67e74705SXin Li }
86*67e74705SXin Li
87*67e74705SXin Li if (Tok.is(tok::identifier)) {
88*67e74705SXin Li Ident = Tok.getIdentifierInfo();
89*67e74705SXin Li IdentLoc = ConsumeToken(); // eat the identifier.
90*67e74705SXin Li while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) {
91*67e74705SXin Li ExtraNamespaceLoc.push_back(ConsumeToken());
92*67e74705SXin Li ExtraIdent.push_back(Tok.getIdentifierInfo());
93*67e74705SXin Li ExtraIdentLoc.push_back(ConsumeToken());
94*67e74705SXin Li }
95*67e74705SXin Li }
96*67e74705SXin Li
97*67e74705SXin Li // A nested namespace definition cannot have attributes.
98*67e74705SXin Li if (!ExtraNamespaceLoc.empty() && attrLoc.isValid())
99*67e74705SXin Li Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);
100*67e74705SXin Li
101*67e74705SXin Li // Read label attributes, if present.
102*67e74705SXin Li if (Tok.is(tok::kw___attribute)) {
103*67e74705SXin Li attrLoc = Tok.getLocation();
104*67e74705SXin Li ParseGNUAttributes(attrs);
105*67e74705SXin Li }
106*67e74705SXin Li
107*67e74705SXin Li if (Tok.is(tok::equal)) {
108*67e74705SXin Li if (!Ident) {
109*67e74705SXin Li Diag(Tok, diag::err_expected) << tok::identifier;
110*67e74705SXin Li // Skip to end of the definition and eat the ';'.
111*67e74705SXin Li SkipUntil(tok::semi);
112*67e74705SXin Li return nullptr;
113*67e74705SXin Li }
114*67e74705SXin Li if (attrLoc.isValid())
115*67e74705SXin Li Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);
116*67e74705SXin Li if (InlineLoc.isValid())
117*67e74705SXin Li Diag(InlineLoc, diag::err_inline_namespace_alias)
118*67e74705SXin Li << FixItHint::CreateRemoval(InlineLoc);
119*67e74705SXin Li Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
120*67e74705SXin Li return Actions.ConvertDeclToDeclGroup(NSAlias);
121*67e74705SXin Li }
122*67e74705SXin Li
123*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_brace);
124*67e74705SXin Li if (T.consumeOpen()) {
125*67e74705SXin Li if (Ident)
126*67e74705SXin Li Diag(Tok, diag::err_expected) << tok::l_brace;
127*67e74705SXin Li else
128*67e74705SXin Li Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
129*67e74705SXin Li return nullptr;
130*67e74705SXin Li }
131*67e74705SXin Li
132*67e74705SXin Li if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||
133*67e74705SXin Li getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||
134*67e74705SXin Li getCurScope()->getFnParent()) {
135*67e74705SXin Li Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
136*67e74705SXin Li SkipUntil(tok::r_brace);
137*67e74705SXin Li return nullptr;
138*67e74705SXin Li }
139*67e74705SXin Li
140*67e74705SXin Li if (ExtraIdent.empty()) {
141*67e74705SXin Li // Normal namespace definition, not a nested-namespace-definition.
142*67e74705SXin Li } else if (InlineLoc.isValid()) {
143*67e74705SXin Li Diag(InlineLoc, diag::err_inline_nested_namespace_definition);
144*67e74705SXin Li } else if (getLangOpts().CPlusPlus1z) {
145*67e74705SXin Li Diag(ExtraNamespaceLoc[0],
146*67e74705SXin Li diag::warn_cxx14_compat_nested_namespace_definition);
147*67e74705SXin Li } else {
148*67e74705SXin Li TentativeParsingAction TPA(*this);
149*67e74705SXin Li SkipUntil(tok::r_brace, StopBeforeMatch);
150*67e74705SXin Li Token rBraceToken = Tok;
151*67e74705SXin Li TPA.Revert();
152*67e74705SXin Li
153*67e74705SXin Li if (!rBraceToken.is(tok::r_brace)) {
154*67e74705SXin Li Diag(ExtraNamespaceLoc[0], diag::ext_nested_namespace_definition)
155*67e74705SXin Li << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
156*67e74705SXin Li } else {
157*67e74705SXin Li std::string NamespaceFix;
158*67e74705SXin Li for (std::vector<IdentifierInfo*>::iterator I = ExtraIdent.begin(),
159*67e74705SXin Li E = ExtraIdent.end(); I != E; ++I) {
160*67e74705SXin Li NamespaceFix += " { namespace ";
161*67e74705SXin Li NamespaceFix += (*I)->getName();
162*67e74705SXin Li }
163*67e74705SXin Li
164*67e74705SXin Li std::string RBraces;
165*67e74705SXin Li for (unsigned i = 0, e = ExtraIdent.size(); i != e; ++i)
166*67e74705SXin Li RBraces += "} ";
167*67e74705SXin Li
168*67e74705SXin Li Diag(ExtraNamespaceLoc[0], diag::ext_nested_namespace_definition)
169*67e74705SXin Li << FixItHint::CreateReplacement(SourceRange(ExtraNamespaceLoc.front(),
170*67e74705SXin Li ExtraIdentLoc.back()),
171*67e74705SXin Li NamespaceFix)
172*67e74705SXin Li << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces);
173*67e74705SXin Li }
174*67e74705SXin Li }
175*67e74705SXin Li
176*67e74705SXin Li // If we're still good, complain about inline namespaces in non-C++0x now.
177*67e74705SXin Li if (InlineLoc.isValid())
178*67e74705SXin Li Diag(InlineLoc, getLangOpts().CPlusPlus11 ?
179*67e74705SXin Li diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace);
180*67e74705SXin Li
181*67e74705SXin Li // Enter a scope for the namespace.
182*67e74705SXin Li ParseScope NamespaceScope(this, Scope::DeclScope);
183*67e74705SXin Li
184*67e74705SXin Li UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
185*67e74705SXin Li Decl *NamespcDecl =
186*67e74705SXin Li Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
187*67e74705SXin Li IdentLoc, Ident, T.getOpenLocation(),
188*67e74705SXin Li attrs.getList(), ImplicitUsingDirectiveDecl);
189*67e74705SXin Li
190*67e74705SXin Li PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
191*67e74705SXin Li "parsing namespace");
192*67e74705SXin Li
193*67e74705SXin Li // Parse the contents of the namespace. This includes parsing recovery on
194*67e74705SXin Li // any improperly nested namespaces.
195*67e74705SXin Li ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0,
196*67e74705SXin Li InlineLoc, attrs, T);
197*67e74705SXin Li
198*67e74705SXin Li // Leave the namespace scope.
199*67e74705SXin Li NamespaceScope.Exit();
200*67e74705SXin Li
201*67e74705SXin Li DeclEnd = T.getCloseLocation();
202*67e74705SXin Li Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd);
203*67e74705SXin Li
204*67e74705SXin Li return Actions.ConvertDeclToDeclGroup(NamespcDecl,
205*67e74705SXin Li ImplicitUsingDirectiveDecl);
206*67e74705SXin Li }
207*67e74705SXin Li
208*67e74705SXin Li /// ParseInnerNamespace - Parse the contents of a namespace.
ParseInnerNamespace(std::vector<SourceLocation> & IdentLoc,std::vector<IdentifierInfo * > & Ident,std::vector<SourceLocation> & NamespaceLoc,unsigned int index,SourceLocation & InlineLoc,ParsedAttributes & attrs,BalancedDelimiterTracker & Tracker)209*67e74705SXin Li void Parser::ParseInnerNamespace(std::vector<SourceLocation> &IdentLoc,
210*67e74705SXin Li std::vector<IdentifierInfo *> &Ident,
211*67e74705SXin Li std::vector<SourceLocation> &NamespaceLoc,
212*67e74705SXin Li unsigned int index, SourceLocation &InlineLoc,
213*67e74705SXin Li ParsedAttributes &attrs,
214*67e74705SXin Li BalancedDelimiterTracker &Tracker) {
215*67e74705SXin Li if (index == Ident.size()) {
216*67e74705SXin Li while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
217*67e74705SXin Li Tok.isNot(tok::eof)) {
218*67e74705SXin Li ParsedAttributesWithRange attrs(AttrFactory);
219*67e74705SXin Li MaybeParseCXX11Attributes(attrs);
220*67e74705SXin Li MaybeParseMicrosoftAttributes(attrs);
221*67e74705SXin Li ParseExternalDeclaration(attrs);
222*67e74705SXin Li }
223*67e74705SXin Li
224*67e74705SXin Li // The caller is what called check -- we are simply calling
225*67e74705SXin Li // the close for it.
226*67e74705SXin Li Tracker.consumeClose();
227*67e74705SXin Li
228*67e74705SXin Li return;
229*67e74705SXin Li }
230*67e74705SXin Li
231*67e74705SXin Li // Handle a nested namespace definition.
232*67e74705SXin Li // FIXME: Preserve the source information through to the AST rather than
233*67e74705SXin Li // desugaring it here.
234*67e74705SXin Li ParseScope NamespaceScope(this, Scope::DeclScope);
235*67e74705SXin Li UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
236*67e74705SXin Li Decl *NamespcDecl =
237*67e74705SXin Li Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
238*67e74705SXin Li NamespaceLoc[index], IdentLoc[index],
239*67e74705SXin Li Ident[index], Tracker.getOpenLocation(),
240*67e74705SXin Li attrs.getList(), ImplicitUsingDirectiveDecl);
241*67e74705SXin Li assert(!ImplicitUsingDirectiveDecl &&
242*67e74705SXin Li "nested namespace definition cannot define anonymous namespace");
243*67e74705SXin Li
244*67e74705SXin Li ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc,
245*67e74705SXin Li attrs, Tracker);
246*67e74705SXin Li
247*67e74705SXin Li NamespaceScope.Exit();
248*67e74705SXin Li Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation());
249*67e74705SXin Li }
250*67e74705SXin Li
251*67e74705SXin Li /// ParseNamespaceAlias - Parse the part after the '=' in a namespace
252*67e74705SXin Li /// alias definition.
253*67e74705SXin Li ///
ParseNamespaceAlias(SourceLocation NamespaceLoc,SourceLocation AliasLoc,IdentifierInfo * Alias,SourceLocation & DeclEnd)254*67e74705SXin Li Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
255*67e74705SXin Li SourceLocation AliasLoc,
256*67e74705SXin Li IdentifierInfo *Alias,
257*67e74705SXin Li SourceLocation &DeclEnd) {
258*67e74705SXin Li assert(Tok.is(tok::equal) && "Not equal token");
259*67e74705SXin Li
260*67e74705SXin Li ConsumeToken(); // eat the '='.
261*67e74705SXin Li
262*67e74705SXin Li if (Tok.is(tok::code_completion)) {
263*67e74705SXin Li Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
264*67e74705SXin Li cutOffParsing();
265*67e74705SXin Li return nullptr;
266*67e74705SXin Li }
267*67e74705SXin Li
268*67e74705SXin Li CXXScopeSpec SS;
269*67e74705SXin Li // Parse (optional) nested-name-specifier.
270*67e74705SXin Li ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false);
271*67e74705SXin Li
272*67e74705SXin Li if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
273*67e74705SXin Li Diag(Tok, diag::err_expected_namespace_name);
274*67e74705SXin Li // Skip to end of the definition and eat the ';'.
275*67e74705SXin Li SkipUntil(tok::semi);
276*67e74705SXin Li return nullptr;
277*67e74705SXin Li }
278*67e74705SXin Li
279*67e74705SXin Li // Parse identifier.
280*67e74705SXin Li IdentifierInfo *Ident = Tok.getIdentifierInfo();
281*67e74705SXin Li SourceLocation IdentLoc = ConsumeToken();
282*67e74705SXin Li
283*67e74705SXin Li // Eat the ';'.
284*67e74705SXin Li DeclEnd = Tok.getLocation();
285*67e74705SXin Li if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
286*67e74705SXin Li SkipUntil(tok::semi);
287*67e74705SXin Li
288*67e74705SXin Li return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc,
289*67e74705SXin Li Alias, SS, IdentLoc, Ident);
290*67e74705SXin Li }
291*67e74705SXin Li
292*67e74705SXin Li /// ParseLinkage - We know that the current token is a string_literal
293*67e74705SXin Li /// and just before that, that extern was seen.
294*67e74705SXin Li ///
295*67e74705SXin Li /// linkage-specification: [C++ 7.5p2: dcl.link]
296*67e74705SXin Li /// 'extern' string-literal '{' declaration-seq[opt] '}'
297*67e74705SXin Li /// 'extern' string-literal declaration
298*67e74705SXin Li ///
ParseLinkage(ParsingDeclSpec & DS,unsigned Context)299*67e74705SXin Li Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
300*67e74705SXin Li assert(isTokenStringLiteral() && "Not a string literal!");
301*67e74705SXin Li ExprResult Lang = ParseStringLiteralExpression(false);
302*67e74705SXin Li
303*67e74705SXin Li ParseScope LinkageScope(this, Scope::DeclScope);
304*67e74705SXin Li Decl *LinkageSpec =
305*67e74705SXin Li Lang.isInvalid()
306*67e74705SXin Li ? nullptr
307*67e74705SXin Li : Actions.ActOnStartLinkageSpecification(
308*67e74705SXin Li getCurScope(), DS.getSourceRange().getBegin(), Lang.get(),
309*67e74705SXin Li Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());
310*67e74705SXin Li
311*67e74705SXin Li ParsedAttributesWithRange attrs(AttrFactory);
312*67e74705SXin Li MaybeParseCXX11Attributes(attrs);
313*67e74705SXin Li MaybeParseMicrosoftAttributes(attrs);
314*67e74705SXin Li
315*67e74705SXin Li if (Tok.isNot(tok::l_brace)) {
316*67e74705SXin Li // Reset the source range in DS, as the leading "extern"
317*67e74705SXin Li // does not really belong to the inner declaration ...
318*67e74705SXin Li DS.SetRangeStart(SourceLocation());
319*67e74705SXin Li DS.SetRangeEnd(SourceLocation());
320*67e74705SXin Li // ... but anyway remember that such an "extern" was seen.
321*67e74705SXin Li DS.setExternInLinkageSpec(true);
322*67e74705SXin Li ParseExternalDeclaration(attrs, &DS);
323*67e74705SXin Li return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
324*67e74705SXin Li getCurScope(), LinkageSpec, SourceLocation())
325*67e74705SXin Li : nullptr;
326*67e74705SXin Li }
327*67e74705SXin Li
328*67e74705SXin Li DS.abort();
329*67e74705SXin Li
330*67e74705SXin Li ProhibitAttributes(attrs);
331*67e74705SXin Li
332*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_brace);
333*67e74705SXin Li T.consumeOpen();
334*67e74705SXin Li
335*67e74705SXin Li unsigned NestedModules = 0;
336*67e74705SXin Li while (true) {
337*67e74705SXin Li switch (Tok.getKind()) {
338*67e74705SXin Li case tok::annot_module_begin:
339*67e74705SXin Li ++NestedModules;
340*67e74705SXin Li ParseTopLevelDecl();
341*67e74705SXin Li continue;
342*67e74705SXin Li
343*67e74705SXin Li case tok::annot_module_end:
344*67e74705SXin Li if (!NestedModules)
345*67e74705SXin Li break;
346*67e74705SXin Li --NestedModules;
347*67e74705SXin Li ParseTopLevelDecl();
348*67e74705SXin Li continue;
349*67e74705SXin Li
350*67e74705SXin Li case tok::annot_module_include:
351*67e74705SXin Li ParseTopLevelDecl();
352*67e74705SXin Li continue;
353*67e74705SXin Li
354*67e74705SXin Li case tok::eof:
355*67e74705SXin Li break;
356*67e74705SXin Li
357*67e74705SXin Li case tok::r_brace:
358*67e74705SXin Li if (!NestedModules)
359*67e74705SXin Li break;
360*67e74705SXin Li // Fall through.
361*67e74705SXin Li default:
362*67e74705SXin Li ParsedAttributesWithRange attrs(AttrFactory);
363*67e74705SXin Li MaybeParseCXX11Attributes(attrs);
364*67e74705SXin Li MaybeParseMicrosoftAttributes(attrs);
365*67e74705SXin Li ParseExternalDeclaration(attrs);
366*67e74705SXin Li continue;
367*67e74705SXin Li }
368*67e74705SXin Li
369*67e74705SXin Li break;
370*67e74705SXin Li }
371*67e74705SXin Li
372*67e74705SXin Li T.consumeClose();
373*67e74705SXin Li return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
374*67e74705SXin Li getCurScope(), LinkageSpec, T.getCloseLocation())
375*67e74705SXin Li : nullptr;
376*67e74705SXin Li }
377*67e74705SXin Li
378*67e74705SXin Li /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
379*67e74705SXin Li /// using-directive. Assumes that current token is 'using'.
ParseUsingDirectiveOrDeclaration(unsigned Context,const ParsedTemplateInfo & TemplateInfo,SourceLocation & DeclEnd,ParsedAttributesWithRange & attrs,Decl ** OwnedType)380*67e74705SXin Li Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
381*67e74705SXin Li const ParsedTemplateInfo &TemplateInfo,
382*67e74705SXin Li SourceLocation &DeclEnd,
383*67e74705SXin Li ParsedAttributesWithRange &attrs,
384*67e74705SXin Li Decl **OwnedType) {
385*67e74705SXin Li assert(Tok.is(tok::kw_using) && "Not using token");
386*67e74705SXin Li ObjCDeclContextSwitch ObjCDC(*this);
387*67e74705SXin Li
388*67e74705SXin Li // Eat 'using'.
389*67e74705SXin Li SourceLocation UsingLoc = ConsumeToken();
390*67e74705SXin Li
391*67e74705SXin Li if (Tok.is(tok::code_completion)) {
392*67e74705SXin Li Actions.CodeCompleteUsing(getCurScope());
393*67e74705SXin Li cutOffParsing();
394*67e74705SXin Li return nullptr;
395*67e74705SXin Li }
396*67e74705SXin Li
397*67e74705SXin Li // 'using namespace' means this is a using-directive.
398*67e74705SXin Li if (Tok.is(tok::kw_namespace)) {
399*67e74705SXin Li // Template parameters are always an error here.
400*67e74705SXin Li if (TemplateInfo.Kind) {
401*67e74705SXin Li SourceRange R = TemplateInfo.getSourceRange();
402*67e74705SXin Li Diag(UsingLoc, diag::err_templated_using_directive_declaration)
403*67e74705SXin Li << 0 /* directive */ << R << FixItHint::CreateRemoval(R);
404*67e74705SXin Li }
405*67e74705SXin Li
406*67e74705SXin Li return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
407*67e74705SXin Li }
408*67e74705SXin Li
409*67e74705SXin Li // Otherwise, it must be a using-declaration or an alias-declaration.
410*67e74705SXin Li
411*67e74705SXin Li // Using declarations can't have attributes.
412*67e74705SXin Li ProhibitAttributes(attrs);
413*67e74705SXin Li
414*67e74705SXin Li return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
415*67e74705SXin Li AS_none, OwnedType);
416*67e74705SXin Li }
417*67e74705SXin Li
418*67e74705SXin Li /// ParseUsingDirective - Parse C++ using-directive, assumes
419*67e74705SXin Li /// that current token is 'namespace' and 'using' was already parsed.
420*67e74705SXin Li ///
421*67e74705SXin Li /// using-directive: [C++ 7.3.p4: namespace.udir]
422*67e74705SXin Li /// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
423*67e74705SXin Li /// namespace-name ;
424*67e74705SXin Li /// [GNU] using-directive:
425*67e74705SXin Li /// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
426*67e74705SXin Li /// namespace-name attributes[opt] ;
427*67e74705SXin Li ///
ParseUsingDirective(unsigned Context,SourceLocation UsingLoc,SourceLocation & DeclEnd,ParsedAttributes & attrs)428*67e74705SXin Li Decl *Parser::ParseUsingDirective(unsigned Context,
429*67e74705SXin Li SourceLocation UsingLoc,
430*67e74705SXin Li SourceLocation &DeclEnd,
431*67e74705SXin Li ParsedAttributes &attrs) {
432*67e74705SXin Li assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
433*67e74705SXin Li
434*67e74705SXin Li // Eat 'namespace'.
435*67e74705SXin Li SourceLocation NamespcLoc = ConsumeToken();
436*67e74705SXin Li
437*67e74705SXin Li if (Tok.is(tok::code_completion)) {
438*67e74705SXin Li Actions.CodeCompleteUsingDirective(getCurScope());
439*67e74705SXin Li cutOffParsing();
440*67e74705SXin Li return nullptr;
441*67e74705SXin Li }
442*67e74705SXin Li
443*67e74705SXin Li CXXScopeSpec SS;
444*67e74705SXin Li // Parse (optional) nested-name-specifier.
445*67e74705SXin Li ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false);
446*67e74705SXin Li
447*67e74705SXin Li IdentifierInfo *NamespcName = nullptr;
448*67e74705SXin Li SourceLocation IdentLoc = SourceLocation();
449*67e74705SXin Li
450*67e74705SXin Li // Parse namespace-name.
451*67e74705SXin Li if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
452*67e74705SXin Li Diag(Tok, diag::err_expected_namespace_name);
453*67e74705SXin Li // If there was invalid namespace name, skip to end of decl, and eat ';'.
454*67e74705SXin Li SkipUntil(tok::semi);
455*67e74705SXin Li // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
456*67e74705SXin Li return nullptr;
457*67e74705SXin Li }
458*67e74705SXin Li
459*67e74705SXin Li // Parse identifier.
460*67e74705SXin Li NamespcName = Tok.getIdentifierInfo();
461*67e74705SXin Li IdentLoc = ConsumeToken();
462*67e74705SXin Li
463*67e74705SXin Li // Parse (optional) attributes (most likely GNU strong-using extension).
464*67e74705SXin Li bool GNUAttr = false;
465*67e74705SXin Li if (Tok.is(tok::kw___attribute)) {
466*67e74705SXin Li GNUAttr = true;
467*67e74705SXin Li ParseGNUAttributes(attrs);
468*67e74705SXin Li }
469*67e74705SXin Li
470*67e74705SXin Li // Eat ';'.
471*67e74705SXin Li DeclEnd = Tok.getLocation();
472*67e74705SXin Li if (ExpectAndConsume(tok::semi,
473*67e74705SXin Li GNUAttr ? diag::err_expected_semi_after_attribute_list
474*67e74705SXin Li : diag::err_expected_semi_after_namespace_name))
475*67e74705SXin Li SkipUntil(tok::semi);
476*67e74705SXin Li
477*67e74705SXin Li return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
478*67e74705SXin Li IdentLoc, NamespcName, attrs.getList());
479*67e74705SXin Li }
480*67e74705SXin Li
481*67e74705SXin Li /// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
482*67e74705SXin Li /// Assumes that 'using' was already seen.
483*67e74705SXin Li ///
484*67e74705SXin Li /// using-declaration: [C++ 7.3.p3: namespace.udecl]
485*67e74705SXin Li /// 'using' 'typename'[opt] ::[opt] nested-name-specifier
486*67e74705SXin Li /// unqualified-id
487*67e74705SXin Li /// 'using' :: unqualified-id
488*67e74705SXin Li ///
489*67e74705SXin Li /// alias-declaration: C++11 [dcl.dcl]p1
490*67e74705SXin Li /// 'using' identifier attribute-specifier-seq[opt] = type-id ;
491*67e74705SXin Li ///
ParseUsingDeclaration(unsigned Context,const ParsedTemplateInfo & TemplateInfo,SourceLocation UsingLoc,SourceLocation & DeclEnd,AccessSpecifier AS,Decl ** OwnedType)492*67e74705SXin Li Decl *Parser::ParseUsingDeclaration(unsigned Context,
493*67e74705SXin Li const ParsedTemplateInfo &TemplateInfo,
494*67e74705SXin Li SourceLocation UsingLoc,
495*67e74705SXin Li SourceLocation &DeclEnd,
496*67e74705SXin Li AccessSpecifier AS,
497*67e74705SXin Li Decl **OwnedType) {
498*67e74705SXin Li CXXScopeSpec SS;
499*67e74705SXin Li SourceLocation TypenameLoc;
500*67e74705SXin Li bool HasTypenameKeyword = false;
501*67e74705SXin Li
502*67e74705SXin Li // Check for misplaced attributes before the identifier in an
503*67e74705SXin Li // alias-declaration.
504*67e74705SXin Li ParsedAttributesWithRange MisplacedAttrs(AttrFactory);
505*67e74705SXin Li MaybeParseCXX11Attributes(MisplacedAttrs);
506*67e74705SXin Li
507*67e74705SXin Li // Ignore optional 'typename'.
508*67e74705SXin Li // FIXME: This is wrong; we should parse this as a typename-specifier.
509*67e74705SXin Li if (TryConsumeToken(tok::kw_typename, TypenameLoc))
510*67e74705SXin Li HasTypenameKeyword = true;
511*67e74705SXin Li
512*67e74705SXin Li if (Tok.is(tok::kw___super)) {
513*67e74705SXin Li Diag(Tok.getLocation(), diag::err_super_in_using_declaration);
514*67e74705SXin Li SkipUntil(tok::semi);
515*67e74705SXin Li return nullptr;
516*67e74705SXin Li }
517*67e74705SXin Li
518*67e74705SXin Li // Parse nested-name-specifier.
519*67e74705SXin Li IdentifierInfo *LastII = nullptr;
520*67e74705SXin Li ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false,
521*67e74705SXin Li /*MayBePseudoDtor=*/nullptr,
522*67e74705SXin Li /*IsTypename=*/false,
523*67e74705SXin Li /*LastII=*/&LastII);
524*67e74705SXin Li
525*67e74705SXin Li // Check nested-name specifier.
526*67e74705SXin Li if (SS.isInvalid()) {
527*67e74705SXin Li SkipUntil(tok::semi);
528*67e74705SXin Li return nullptr;
529*67e74705SXin Li }
530*67e74705SXin Li
531*67e74705SXin Li SourceLocation TemplateKWLoc;
532*67e74705SXin Li UnqualifiedId Name;
533*67e74705SXin Li
534*67e74705SXin Li // Parse the unqualified-id. We allow parsing of both constructor and
535*67e74705SXin Li // destructor names and allow the action module to diagnose any semantic
536*67e74705SXin Li // errors.
537*67e74705SXin Li //
538*67e74705SXin Li // C++11 [class.qual]p2:
539*67e74705SXin Li // [...] in a using-declaration that is a member-declaration, if the name
540*67e74705SXin Li // specified after the nested-name-specifier is the same as the identifier
541*67e74705SXin Li // or the simple-template-id's template-name in the last component of the
542*67e74705SXin Li // nested-name-specifier, the name is [...] considered to name the
543*67e74705SXin Li // constructor.
544*67e74705SXin Li if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext &&
545*67e74705SXin Li Tok.is(tok::identifier) && NextToken().is(tok::semi) &&
546*67e74705SXin Li SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&
547*67e74705SXin Li !SS.getScopeRep()->getAsNamespace() &&
548*67e74705SXin Li !SS.getScopeRep()->getAsNamespaceAlias()) {
549*67e74705SXin Li SourceLocation IdLoc = ConsumeToken();
550*67e74705SXin Li ParsedType Type = Actions.getInheritingConstructorName(SS, IdLoc, *LastII);
551*67e74705SXin Li Name.setConstructorName(Type, IdLoc, IdLoc);
552*67e74705SXin Li } else if (ParseUnqualifiedId(
553*67e74705SXin Li SS, /*EnteringContext=*/false,
554*67e74705SXin Li /*AllowDestructorName=*/true,
555*67e74705SXin Li /*AllowConstructorName=*/!(Tok.is(tok::identifier) &&
556*67e74705SXin Li NextToken().is(tok::equal)),
557*67e74705SXin Li nullptr, TemplateKWLoc, Name)) {
558*67e74705SXin Li SkipUntil(tok::semi);
559*67e74705SXin Li return nullptr;
560*67e74705SXin Li }
561*67e74705SXin Li
562*67e74705SXin Li ParsedAttributesWithRange Attrs(AttrFactory);
563*67e74705SXin Li MaybeParseGNUAttributes(Attrs);
564*67e74705SXin Li MaybeParseCXX11Attributes(Attrs);
565*67e74705SXin Li
566*67e74705SXin Li // Maybe this is an alias-declaration.
567*67e74705SXin Li TypeResult TypeAlias;
568*67e74705SXin Li bool IsAliasDecl = Tok.is(tok::equal);
569*67e74705SXin Li Decl *DeclFromDeclSpec = nullptr;
570*67e74705SXin Li if (IsAliasDecl) {
571*67e74705SXin Li // If we had any misplaced attributes from earlier, this is where they
572*67e74705SXin Li // should have been written.
573*67e74705SXin Li if (MisplacedAttrs.Range.isValid()) {
574*67e74705SXin Li Diag(MisplacedAttrs.Range.getBegin(), diag::err_attributes_not_allowed)
575*67e74705SXin Li << FixItHint::CreateInsertionFromRange(
576*67e74705SXin Li Tok.getLocation(),
577*67e74705SXin Li CharSourceRange::getTokenRange(MisplacedAttrs.Range))
578*67e74705SXin Li << FixItHint::CreateRemoval(MisplacedAttrs.Range);
579*67e74705SXin Li Attrs.takeAllFrom(MisplacedAttrs);
580*67e74705SXin Li }
581*67e74705SXin Li
582*67e74705SXin Li ConsumeToken();
583*67e74705SXin Li
584*67e74705SXin Li Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
585*67e74705SXin Li diag::warn_cxx98_compat_alias_declaration :
586*67e74705SXin Li diag::ext_alias_declaration);
587*67e74705SXin Li
588*67e74705SXin Li // Type alias templates cannot be specialized.
589*67e74705SXin Li int SpecKind = -1;
590*67e74705SXin Li if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
591*67e74705SXin Li Name.getKind() == UnqualifiedId::IK_TemplateId)
592*67e74705SXin Li SpecKind = 0;
593*67e74705SXin Li if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
594*67e74705SXin Li SpecKind = 1;
595*67e74705SXin Li if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
596*67e74705SXin Li SpecKind = 2;
597*67e74705SXin Li if (SpecKind != -1) {
598*67e74705SXin Li SourceRange Range;
599*67e74705SXin Li if (SpecKind == 0)
600*67e74705SXin Li Range = SourceRange(Name.TemplateId->LAngleLoc,
601*67e74705SXin Li Name.TemplateId->RAngleLoc);
602*67e74705SXin Li else
603*67e74705SXin Li Range = TemplateInfo.getSourceRange();
604*67e74705SXin Li Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
605*67e74705SXin Li << SpecKind << Range;
606*67e74705SXin Li SkipUntil(tok::semi);
607*67e74705SXin Li return nullptr;
608*67e74705SXin Li }
609*67e74705SXin Li
610*67e74705SXin Li // Name must be an identifier.
611*67e74705SXin Li if (Name.getKind() != UnqualifiedId::IK_Identifier) {
612*67e74705SXin Li Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
613*67e74705SXin Li // No removal fixit: can't recover from this.
614*67e74705SXin Li SkipUntil(tok::semi);
615*67e74705SXin Li return nullptr;
616*67e74705SXin Li } else if (HasTypenameKeyword)
617*67e74705SXin Li Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
618*67e74705SXin Li << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
619*67e74705SXin Li SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
620*67e74705SXin Li else if (SS.isNotEmpty())
621*67e74705SXin Li Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
622*67e74705SXin Li << FixItHint::CreateRemoval(SS.getRange());
623*67e74705SXin Li
624*67e74705SXin Li TypeAlias = ParseTypeName(nullptr, TemplateInfo.Kind
625*67e74705SXin Li ? Declarator::AliasTemplateContext
626*67e74705SXin Li : Declarator::AliasDeclContext,
627*67e74705SXin Li AS, &DeclFromDeclSpec, &Attrs);
628*67e74705SXin Li if (OwnedType)
629*67e74705SXin Li *OwnedType = DeclFromDeclSpec;
630*67e74705SXin Li } else {
631*67e74705SXin Li // C++11 attributes are not allowed on a using-declaration, but GNU ones
632*67e74705SXin Li // are.
633*67e74705SXin Li ProhibitAttributes(MisplacedAttrs);
634*67e74705SXin Li ProhibitAttributes(Attrs);
635*67e74705SXin Li
636*67e74705SXin Li // Parse (optional) attributes (most likely GNU strong-using extension).
637*67e74705SXin Li MaybeParseGNUAttributes(Attrs);
638*67e74705SXin Li }
639*67e74705SXin Li
640*67e74705SXin Li // Eat ';'.
641*67e74705SXin Li DeclEnd = Tok.getLocation();
642*67e74705SXin Li if (ExpectAndConsume(tok::semi, diag::err_expected_after,
643*67e74705SXin Li !Attrs.empty() ? "attributes list"
644*67e74705SXin Li : IsAliasDecl ? "alias declaration"
645*67e74705SXin Li : "using declaration"))
646*67e74705SXin Li SkipUntil(tok::semi);
647*67e74705SXin Li
648*67e74705SXin Li // Diagnose an attempt to declare a templated using-declaration.
649*67e74705SXin Li // In C++11, alias-declarations can be templates:
650*67e74705SXin Li // template <...> using id = type;
651*67e74705SXin Li if (TemplateInfo.Kind && !IsAliasDecl) {
652*67e74705SXin Li SourceRange R = TemplateInfo.getSourceRange();
653*67e74705SXin Li Diag(UsingLoc, diag::err_templated_using_directive_declaration)
654*67e74705SXin Li << 1 /* declaration */ << R << FixItHint::CreateRemoval(R);
655*67e74705SXin Li
656*67e74705SXin Li // Unfortunately, we have to bail out instead of recovering by
657*67e74705SXin Li // ignoring the parameters, just in case the nested name specifier
658*67e74705SXin Li // depends on the parameters.
659*67e74705SXin Li return nullptr;
660*67e74705SXin Li }
661*67e74705SXin Li
662*67e74705SXin Li // "typename" keyword is allowed for identifiers only,
663*67e74705SXin Li // because it may be a type definition.
664*67e74705SXin Li if (HasTypenameKeyword && Name.getKind() != UnqualifiedId::IK_Identifier) {
665*67e74705SXin Li Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only)
666*67e74705SXin Li << FixItHint::CreateRemoval(SourceRange(TypenameLoc));
667*67e74705SXin Li // Proceed parsing, but reset the HasTypenameKeyword flag.
668*67e74705SXin Li HasTypenameKeyword = false;
669*67e74705SXin Li }
670*67e74705SXin Li
671*67e74705SXin Li if (IsAliasDecl) {
672*67e74705SXin Li TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
673*67e74705SXin Li MultiTemplateParamsArg TemplateParamsArg(
674*67e74705SXin Li TemplateParams ? TemplateParams->data() : nullptr,
675*67e74705SXin Li TemplateParams ? TemplateParams->size() : 0);
676*67e74705SXin Li return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
677*67e74705SXin Li UsingLoc, Name, Attrs.getList(),
678*67e74705SXin Li TypeAlias, DeclFromDeclSpec);
679*67e74705SXin Li }
680*67e74705SXin Li
681*67e74705SXin Li return Actions.ActOnUsingDeclaration(getCurScope(), AS,
682*67e74705SXin Li /* HasUsingKeyword */ true, UsingLoc,
683*67e74705SXin Li SS, Name, Attrs.getList(),
684*67e74705SXin Li HasTypenameKeyword, TypenameLoc);
685*67e74705SXin Li }
686*67e74705SXin Li
687*67e74705SXin Li /// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
688*67e74705SXin Li ///
689*67e74705SXin Li /// [C++0x] static_assert-declaration:
690*67e74705SXin Li /// static_assert ( constant-expression , string-literal ) ;
691*67e74705SXin Li ///
692*67e74705SXin Li /// [C11] static_assert-declaration:
693*67e74705SXin Li /// _Static_assert ( constant-expression , string-literal ) ;
694*67e74705SXin Li ///
ParseStaticAssertDeclaration(SourceLocation & DeclEnd)695*67e74705SXin Li Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
696*67e74705SXin Li assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
697*67e74705SXin Li "Not a static_assert declaration");
698*67e74705SXin Li
699*67e74705SXin Li if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
700*67e74705SXin Li Diag(Tok, diag::ext_c11_static_assert);
701*67e74705SXin Li if (Tok.is(tok::kw_static_assert))
702*67e74705SXin Li Diag(Tok, diag::warn_cxx98_compat_static_assert);
703*67e74705SXin Li
704*67e74705SXin Li SourceLocation StaticAssertLoc = ConsumeToken();
705*67e74705SXin Li
706*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_paren);
707*67e74705SXin Li if (T.consumeOpen()) {
708*67e74705SXin Li Diag(Tok, diag::err_expected) << tok::l_paren;
709*67e74705SXin Li SkipMalformedDecl();
710*67e74705SXin Li return nullptr;
711*67e74705SXin Li }
712*67e74705SXin Li
713*67e74705SXin Li ExprResult AssertExpr(ParseConstantExpression());
714*67e74705SXin Li if (AssertExpr.isInvalid()) {
715*67e74705SXin Li SkipMalformedDecl();
716*67e74705SXin Li return nullptr;
717*67e74705SXin Li }
718*67e74705SXin Li
719*67e74705SXin Li ExprResult AssertMessage;
720*67e74705SXin Li if (Tok.is(tok::r_paren)) {
721*67e74705SXin Li Diag(Tok, getLangOpts().CPlusPlus1z
722*67e74705SXin Li ? diag::warn_cxx14_compat_static_assert_no_message
723*67e74705SXin Li : diag::ext_static_assert_no_message)
724*67e74705SXin Li << (getLangOpts().CPlusPlus1z
725*67e74705SXin Li ? FixItHint()
726*67e74705SXin Li : FixItHint::CreateInsertion(Tok.getLocation(), ", \"\""));
727*67e74705SXin Li } else {
728*67e74705SXin Li if (ExpectAndConsume(tok::comma)) {
729*67e74705SXin Li SkipUntil(tok::semi);
730*67e74705SXin Li return nullptr;
731*67e74705SXin Li }
732*67e74705SXin Li
733*67e74705SXin Li if (!isTokenStringLiteral()) {
734*67e74705SXin Li Diag(Tok, diag::err_expected_string_literal)
735*67e74705SXin Li << /*Source='static_assert'*/1;
736*67e74705SXin Li SkipMalformedDecl();
737*67e74705SXin Li return nullptr;
738*67e74705SXin Li }
739*67e74705SXin Li
740*67e74705SXin Li AssertMessage = ParseStringLiteralExpression();
741*67e74705SXin Li if (AssertMessage.isInvalid()) {
742*67e74705SXin Li SkipMalformedDecl();
743*67e74705SXin Li return nullptr;
744*67e74705SXin Li }
745*67e74705SXin Li }
746*67e74705SXin Li
747*67e74705SXin Li T.consumeClose();
748*67e74705SXin Li
749*67e74705SXin Li DeclEnd = Tok.getLocation();
750*67e74705SXin Li ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
751*67e74705SXin Li
752*67e74705SXin Li return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
753*67e74705SXin Li AssertExpr.get(),
754*67e74705SXin Li AssertMessage.get(),
755*67e74705SXin Li T.getCloseLocation());
756*67e74705SXin Li }
757*67e74705SXin Li
758*67e74705SXin Li /// ParseDecltypeSpecifier - Parse a C++11 decltype specifier.
759*67e74705SXin Li ///
760*67e74705SXin Li /// 'decltype' ( expression )
761*67e74705SXin Li /// 'decltype' ( 'auto' ) [C++1y]
762*67e74705SXin Li ///
ParseDecltypeSpecifier(DeclSpec & DS)763*67e74705SXin Li SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
764*67e74705SXin Li assert(Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)
765*67e74705SXin Li && "Not a decltype specifier");
766*67e74705SXin Li
767*67e74705SXin Li ExprResult Result;
768*67e74705SXin Li SourceLocation StartLoc = Tok.getLocation();
769*67e74705SXin Li SourceLocation EndLoc;
770*67e74705SXin Li
771*67e74705SXin Li if (Tok.is(tok::annot_decltype)) {
772*67e74705SXin Li Result = getExprAnnotation(Tok);
773*67e74705SXin Li EndLoc = Tok.getAnnotationEndLoc();
774*67e74705SXin Li ConsumeToken();
775*67e74705SXin Li if (Result.isInvalid()) {
776*67e74705SXin Li DS.SetTypeSpecError();
777*67e74705SXin Li return EndLoc;
778*67e74705SXin Li }
779*67e74705SXin Li } else {
780*67e74705SXin Li if (Tok.getIdentifierInfo()->isStr("decltype"))
781*67e74705SXin Li Diag(Tok, diag::warn_cxx98_compat_decltype);
782*67e74705SXin Li
783*67e74705SXin Li ConsumeToken();
784*67e74705SXin Li
785*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_paren);
786*67e74705SXin Li if (T.expectAndConsume(diag::err_expected_lparen_after,
787*67e74705SXin Li "decltype", tok::r_paren)) {
788*67e74705SXin Li DS.SetTypeSpecError();
789*67e74705SXin Li return T.getOpenLocation() == Tok.getLocation() ?
790*67e74705SXin Li StartLoc : T.getOpenLocation();
791*67e74705SXin Li }
792*67e74705SXin Li
793*67e74705SXin Li // Check for C++1y 'decltype(auto)'.
794*67e74705SXin Li if (Tok.is(tok::kw_auto)) {
795*67e74705SXin Li // No need to disambiguate here: an expression can't start with 'auto',
796*67e74705SXin Li // because the typename-specifier in a function-style cast operation can't
797*67e74705SXin Li // be 'auto'.
798*67e74705SXin Li Diag(Tok.getLocation(),
799*67e74705SXin Li getLangOpts().CPlusPlus14
800*67e74705SXin Li ? diag::warn_cxx11_compat_decltype_auto_type_specifier
801*67e74705SXin Li : diag::ext_decltype_auto_type_specifier);
802*67e74705SXin Li ConsumeToken();
803*67e74705SXin Li } else {
804*67e74705SXin Li // Parse the expression
805*67e74705SXin Li
806*67e74705SXin Li // C++11 [dcl.type.simple]p4:
807*67e74705SXin Li // The operand of the decltype specifier is an unevaluated operand.
808*67e74705SXin Li EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
809*67e74705SXin Li nullptr,/*IsDecltype=*/true);
810*67e74705SXin Li Result =
811*67e74705SXin Li Actions.CorrectDelayedTyposInExpr(ParseExpression(), [](Expr *E) {
812*67e74705SXin Li return E->hasPlaceholderType() ? ExprError() : E;
813*67e74705SXin Li });
814*67e74705SXin Li if (Result.isInvalid()) {
815*67e74705SXin Li DS.SetTypeSpecError();
816*67e74705SXin Li if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
817*67e74705SXin Li EndLoc = ConsumeParen();
818*67e74705SXin Li } else {
819*67e74705SXin Li if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) {
820*67e74705SXin Li // Backtrack to get the location of the last token before the semi.
821*67e74705SXin Li PP.RevertCachedTokens(2);
822*67e74705SXin Li ConsumeToken(); // the semi.
823*67e74705SXin Li EndLoc = ConsumeAnyToken();
824*67e74705SXin Li assert(Tok.is(tok::semi));
825*67e74705SXin Li } else {
826*67e74705SXin Li EndLoc = Tok.getLocation();
827*67e74705SXin Li }
828*67e74705SXin Li }
829*67e74705SXin Li return EndLoc;
830*67e74705SXin Li }
831*67e74705SXin Li
832*67e74705SXin Li Result = Actions.ActOnDecltypeExpression(Result.get());
833*67e74705SXin Li }
834*67e74705SXin Li
835*67e74705SXin Li // Match the ')'
836*67e74705SXin Li T.consumeClose();
837*67e74705SXin Li if (T.getCloseLocation().isInvalid()) {
838*67e74705SXin Li DS.SetTypeSpecError();
839*67e74705SXin Li // FIXME: this should return the location of the last token
840*67e74705SXin Li // that was consumed (by "consumeClose()")
841*67e74705SXin Li return T.getCloseLocation();
842*67e74705SXin Li }
843*67e74705SXin Li
844*67e74705SXin Li if (Result.isInvalid()) {
845*67e74705SXin Li DS.SetTypeSpecError();
846*67e74705SXin Li return T.getCloseLocation();
847*67e74705SXin Li }
848*67e74705SXin Li
849*67e74705SXin Li EndLoc = T.getCloseLocation();
850*67e74705SXin Li }
851*67e74705SXin Li assert(!Result.isInvalid());
852*67e74705SXin Li
853*67e74705SXin Li const char *PrevSpec = nullptr;
854*67e74705SXin Li unsigned DiagID;
855*67e74705SXin Li const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
856*67e74705SXin Li // Check for duplicate type specifiers (e.g. "int decltype(a)").
857*67e74705SXin Li if (Result.get()
858*67e74705SXin Li ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
859*67e74705SXin Li DiagID, Result.get(), Policy)
860*67e74705SXin Li : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc, PrevSpec,
861*67e74705SXin Li DiagID, Policy)) {
862*67e74705SXin Li Diag(StartLoc, DiagID) << PrevSpec;
863*67e74705SXin Li DS.SetTypeSpecError();
864*67e74705SXin Li }
865*67e74705SXin Li return EndLoc;
866*67e74705SXin Li }
867*67e74705SXin Li
AnnotateExistingDecltypeSpecifier(const DeclSpec & DS,SourceLocation StartLoc,SourceLocation EndLoc)868*67e74705SXin Li void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS,
869*67e74705SXin Li SourceLocation StartLoc,
870*67e74705SXin Li SourceLocation EndLoc) {
871*67e74705SXin Li // make sure we have a token we can turn into an annotation token
872*67e74705SXin Li if (PP.isBacktrackEnabled())
873*67e74705SXin Li PP.RevertCachedTokens(1);
874*67e74705SXin Li else
875*67e74705SXin Li PP.EnterToken(Tok);
876*67e74705SXin Li
877*67e74705SXin Li Tok.setKind(tok::annot_decltype);
878*67e74705SXin Li setExprAnnotation(Tok,
879*67e74705SXin Li DS.getTypeSpecType() == TST_decltype ? DS.getRepAsExpr() :
880*67e74705SXin Li DS.getTypeSpecType() == TST_decltype_auto ? ExprResult() :
881*67e74705SXin Li ExprError());
882*67e74705SXin Li Tok.setAnnotationEndLoc(EndLoc);
883*67e74705SXin Li Tok.setLocation(StartLoc);
884*67e74705SXin Li PP.AnnotateCachedTokens(Tok);
885*67e74705SXin Li }
886*67e74705SXin Li
ParseUnderlyingTypeSpecifier(DeclSpec & DS)887*67e74705SXin Li void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
888*67e74705SXin Li assert(Tok.is(tok::kw___underlying_type) &&
889*67e74705SXin Li "Not an underlying type specifier");
890*67e74705SXin Li
891*67e74705SXin Li SourceLocation StartLoc = ConsumeToken();
892*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_paren);
893*67e74705SXin Li if (T.expectAndConsume(diag::err_expected_lparen_after,
894*67e74705SXin Li "__underlying_type", tok::r_paren)) {
895*67e74705SXin Li return;
896*67e74705SXin Li }
897*67e74705SXin Li
898*67e74705SXin Li TypeResult Result = ParseTypeName();
899*67e74705SXin Li if (Result.isInvalid()) {
900*67e74705SXin Li SkipUntil(tok::r_paren, StopAtSemi);
901*67e74705SXin Li return;
902*67e74705SXin Li }
903*67e74705SXin Li
904*67e74705SXin Li // Match the ')'
905*67e74705SXin Li T.consumeClose();
906*67e74705SXin Li if (T.getCloseLocation().isInvalid())
907*67e74705SXin Li return;
908*67e74705SXin Li
909*67e74705SXin Li const char *PrevSpec = nullptr;
910*67e74705SXin Li unsigned DiagID;
911*67e74705SXin Li if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
912*67e74705SXin Li DiagID, Result.get(),
913*67e74705SXin Li Actions.getASTContext().getPrintingPolicy()))
914*67e74705SXin Li Diag(StartLoc, DiagID) << PrevSpec;
915*67e74705SXin Li DS.setTypeofParensRange(T.getRange());
916*67e74705SXin Li }
917*67e74705SXin Li
918*67e74705SXin Li /// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a
919*67e74705SXin Li /// class name or decltype-specifier. Note that we only check that the result
920*67e74705SXin Li /// names a type; semantic analysis will need to verify that the type names a
921*67e74705SXin Li /// class. The result is either a type or null, depending on whether a type
922*67e74705SXin Li /// name was found.
923*67e74705SXin Li ///
924*67e74705SXin Li /// base-type-specifier: [C++11 class.derived]
925*67e74705SXin Li /// class-or-decltype
926*67e74705SXin Li /// class-or-decltype: [C++11 class.derived]
927*67e74705SXin Li /// nested-name-specifier[opt] class-name
928*67e74705SXin Li /// decltype-specifier
929*67e74705SXin Li /// class-name: [C++ class.name]
930*67e74705SXin Li /// identifier
931*67e74705SXin Li /// simple-template-id
932*67e74705SXin Li ///
933*67e74705SXin Li /// In C++98, instead of base-type-specifier, we have:
934*67e74705SXin Li ///
935*67e74705SXin Li /// ::[opt] nested-name-specifier[opt] class-name
ParseBaseTypeSpecifier(SourceLocation & BaseLoc,SourceLocation & EndLocation)936*67e74705SXin Li TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
937*67e74705SXin Li SourceLocation &EndLocation) {
938*67e74705SXin Li // Ignore attempts to use typename
939*67e74705SXin Li if (Tok.is(tok::kw_typename)) {
940*67e74705SXin Li Diag(Tok, diag::err_expected_class_name_not_template)
941*67e74705SXin Li << FixItHint::CreateRemoval(Tok.getLocation());
942*67e74705SXin Li ConsumeToken();
943*67e74705SXin Li }
944*67e74705SXin Li
945*67e74705SXin Li // Parse optional nested-name-specifier
946*67e74705SXin Li CXXScopeSpec SS;
947*67e74705SXin Li ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false);
948*67e74705SXin Li
949*67e74705SXin Li BaseLoc = Tok.getLocation();
950*67e74705SXin Li
951*67e74705SXin Li // Parse decltype-specifier
952*67e74705SXin Li // tok == kw_decltype is just error recovery, it can only happen when SS
953*67e74705SXin Li // isn't empty
954*67e74705SXin Li if (Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {
955*67e74705SXin Li if (SS.isNotEmpty())
956*67e74705SXin Li Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
957*67e74705SXin Li << FixItHint::CreateRemoval(SS.getRange());
958*67e74705SXin Li // Fake up a Declarator to use with ActOnTypeName.
959*67e74705SXin Li DeclSpec DS(AttrFactory);
960*67e74705SXin Li
961*67e74705SXin Li EndLocation = ParseDecltypeSpecifier(DS);
962*67e74705SXin Li
963*67e74705SXin Li Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
964*67e74705SXin Li return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
965*67e74705SXin Li }
966*67e74705SXin Li
967*67e74705SXin Li // Check whether we have a template-id that names a type.
968*67e74705SXin Li if (Tok.is(tok::annot_template_id)) {
969*67e74705SXin Li TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
970*67e74705SXin Li if (TemplateId->Kind == TNK_Type_template ||
971*67e74705SXin Li TemplateId->Kind == TNK_Dependent_template_name) {
972*67e74705SXin Li AnnotateTemplateIdTokenAsType();
973*67e74705SXin Li
974*67e74705SXin Li assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
975*67e74705SXin Li ParsedType Type = getTypeAnnotation(Tok);
976*67e74705SXin Li EndLocation = Tok.getAnnotationEndLoc();
977*67e74705SXin Li ConsumeToken();
978*67e74705SXin Li
979*67e74705SXin Li if (Type)
980*67e74705SXin Li return Type;
981*67e74705SXin Li return true;
982*67e74705SXin Li }
983*67e74705SXin Li
984*67e74705SXin Li // Fall through to produce an error below.
985*67e74705SXin Li }
986*67e74705SXin Li
987*67e74705SXin Li if (Tok.isNot(tok::identifier)) {
988*67e74705SXin Li Diag(Tok, diag::err_expected_class_name);
989*67e74705SXin Li return true;
990*67e74705SXin Li }
991*67e74705SXin Li
992*67e74705SXin Li IdentifierInfo *Id = Tok.getIdentifierInfo();
993*67e74705SXin Li SourceLocation IdLoc = ConsumeToken();
994*67e74705SXin Li
995*67e74705SXin Li if (Tok.is(tok::less)) {
996*67e74705SXin Li // It looks the user intended to write a template-id here, but the
997*67e74705SXin Li // template-name was wrong. Try to fix that.
998*67e74705SXin Li TemplateNameKind TNK = TNK_Type_template;
999*67e74705SXin Li TemplateTy Template;
1000*67e74705SXin Li if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
1001*67e74705SXin Li &SS, Template, TNK)) {
1002*67e74705SXin Li Diag(IdLoc, diag::err_unknown_template_name)
1003*67e74705SXin Li << Id;
1004*67e74705SXin Li }
1005*67e74705SXin Li
1006*67e74705SXin Li if (!Template) {
1007*67e74705SXin Li TemplateArgList TemplateArgs;
1008*67e74705SXin Li SourceLocation LAngleLoc, RAngleLoc;
1009*67e74705SXin Li ParseTemplateIdAfterTemplateName(nullptr, IdLoc, SS, true, LAngleLoc,
1010*67e74705SXin Li TemplateArgs, RAngleLoc);
1011*67e74705SXin Li return true;
1012*67e74705SXin Li }
1013*67e74705SXin Li
1014*67e74705SXin Li // Form the template name
1015*67e74705SXin Li UnqualifiedId TemplateName;
1016*67e74705SXin Li TemplateName.setIdentifier(Id, IdLoc);
1017*67e74705SXin Li
1018*67e74705SXin Li // Parse the full template-id, then turn it into a type.
1019*67e74705SXin Li if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
1020*67e74705SXin Li TemplateName, true))
1021*67e74705SXin Li return true;
1022*67e74705SXin Li if (TNK == TNK_Dependent_template_name)
1023*67e74705SXin Li AnnotateTemplateIdTokenAsType();
1024*67e74705SXin Li
1025*67e74705SXin Li // If we didn't end up with a typename token, there's nothing more we
1026*67e74705SXin Li // can do.
1027*67e74705SXin Li if (Tok.isNot(tok::annot_typename))
1028*67e74705SXin Li return true;
1029*67e74705SXin Li
1030*67e74705SXin Li // Retrieve the type from the annotation token, consume that token, and
1031*67e74705SXin Li // return.
1032*67e74705SXin Li EndLocation = Tok.getAnnotationEndLoc();
1033*67e74705SXin Li ParsedType Type = getTypeAnnotation(Tok);
1034*67e74705SXin Li ConsumeToken();
1035*67e74705SXin Li return Type;
1036*67e74705SXin Li }
1037*67e74705SXin Li
1038*67e74705SXin Li // We have an identifier; check whether it is actually a type.
1039*67e74705SXin Li IdentifierInfo *CorrectedII = nullptr;
1040*67e74705SXin Li ParsedType Type =
1041*67e74705SXin Li Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, false, nullptr,
1042*67e74705SXin Li /*IsCtorOrDtorName=*/false,
1043*67e74705SXin Li /*NonTrivialTypeSourceInfo=*/true, &CorrectedII);
1044*67e74705SXin Li if (!Type) {
1045*67e74705SXin Li Diag(IdLoc, diag::err_expected_class_name);
1046*67e74705SXin Li return true;
1047*67e74705SXin Li }
1048*67e74705SXin Li
1049*67e74705SXin Li // Consume the identifier.
1050*67e74705SXin Li EndLocation = IdLoc;
1051*67e74705SXin Li
1052*67e74705SXin Li // Fake up a Declarator to use with ActOnTypeName.
1053*67e74705SXin Li DeclSpec DS(AttrFactory);
1054*67e74705SXin Li DS.SetRangeStart(IdLoc);
1055*67e74705SXin Li DS.SetRangeEnd(EndLocation);
1056*67e74705SXin Li DS.getTypeSpecScope() = SS;
1057*67e74705SXin Li
1058*67e74705SXin Li const char *PrevSpec = nullptr;
1059*67e74705SXin Li unsigned DiagID;
1060*67e74705SXin Li DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type,
1061*67e74705SXin Li Actions.getASTContext().getPrintingPolicy());
1062*67e74705SXin Li
1063*67e74705SXin Li Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1064*67e74705SXin Li return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
1065*67e74705SXin Li }
1066*67e74705SXin Li
ParseMicrosoftInheritanceClassAttributes(ParsedAttributes & attrs)1067*67e74705SXin Li void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
1068*67e74705SXin Li while (Tok.isOneOf(tok::kw___single_inheritance,
1069*67e74705SXin Li tok::kw___multiple_inheritance,
1070*67e74705SXin Li tok::kw___virtual_inheritance)) {
1071*67e74705SXin Li IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1072*67e74705SXin Li SourceLocation AttrNameLoc = ConsumeToken();
1073*67e74705SXin Li attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
1074*67e74705SXin Li AttributeList::AS_Keyword);
1075*67e74705SXin Li }
1076*67e74705SXin Li }
1077*67e74705SXin Li
1078*67e74705SXin Li /// Determine whether the following tokens are valid after a type-specifier
1079*67e74705SXin Li /// which could be a standalone declaration. This will conservatively return
1080*67e74705SXin Li /// true if there's any doubt, and is appropriate for insert-';' fixits.
isValidAfterTypeSpecifier(bool CouldBeBitfield)1081*67e74705SXin Li bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
1082*67e74705SXin Li // This switch enumerates the valid "follow" set for type-specifiers.
1083*67e74705SXin Li switch (Tok.getKind()) {
1084*67e74705SXin Li default: break;
1085*67e74705SXin Li case tok::semi: // struct foo {...} ;
1086*67e74705SXin Li case tok::star: // struct foo {...} * P;
1087*67e74705SXin Li case tok::amp: // struct foo {...} & R = ...
1088*67e74705SXin Li case tok::ampamp: // struct foo {...} && R = ...
1089*67e74705SXin Li case tok::identifier: // struct foo {...} V ;
1090*67e74705SXin Li case tok::r_paren: //(struct foo {...} ) {4}
1091*67e74705SXin Li case tok::annot_cxxscope: // struct foo {...} a:: b;
1092*67e74705SXin Li case tok::annot_typename: // struct foo {...} a ::b;
1093*67e74705SXin Li case tok::annot_template_id: // struct foo {...} a<int> ::b;
1094*67e74705SXin Li case tok::l_paren: // struct foo {...} ( x);
1095*67e74705SXin Li case tok::comma: // __builtin_offsetof(struct foo{...} ,
1096*67e74705SXin Li case tok::kw_operator: // struct foo operator ++() {...}
1097*67e74705SXin Li case tok::kw___declspec: // struct foo {...} __declspec(...)
1098*67e74705SXin Li case tok::l_square: // void f(struct f [ 3])
1099*67e74705SXin Li case tok::ellipsis: // void f(struct f ... [Ns])
1100*67e74705SXin Li // FIXME: we should emit semantic diagnostic when declaration
1101*67e74705SXin Li // attribute is in type attribute position.
1102*67e74705SXin Li case tok::kw___attribute: // struct foo __attribute__((used)) x;
1103*67e74705SXin Li case tok::annot_pragma_pack: // struct foo {...} _Pragma(pack(pop));
1104*67e74705SXin Li // struct foo {...} _Pragma(section(...));
1105*67e74705SXin Li case tok::annot_pragma_ms_pragma:
1106*67e74705SXin Li // struct foo {...} _Pragma(vtordisp(pop));
1107*67e74705SXin Li case tok::annot_pragma_ms_vtordisp:
1108*67e74705SXin Li // struct foo {...} _Pragma(pointers_to_members(...));
1109*67e74705SXin Li case tok::annot_pragma_ms_pointers_to_members:
1110*67e74705SXin Li return true;
1111*67e74705SXin Li case tok::colon:
1112*67e74705SXin Li return CouldBeBitfield; // enum E { ... } : 2;
1113*67e74705SXin Li // Microsoft compatibility
1114*67e74705SXin Li case tok::kw___cdecl: // struct foo {...} __cdecl x;
1115*67e74705SXin Li case tok::kw___fastcall: // struct foo {...} __fastcall x;
1116*67e74705SXin Li case tok::kw___stdcall: // struct foo {...} __stdcall x;
1117*67e74705SXin Li case tok::kw___thiscall: // struct foo {...} __thiscall x;
1118*67e74705SXin Li case tok::kw___vectorcall: // struct foo {...} __vectorcall x;
1119*67e74705SXin Li // We will diagnose these calling-convention specifiers on non-function
1120*67e74705SXin Li // declarations later, so claim they are valid after a type specifier.
1121*67e74705SXin Li return getLangOpts().MicrosoftExt;
1122*67e74705SXin Li // Type qualifiers
1123*67e74705SXin Li case tok::kw_const: // struct foo {...} const x;
1124*67e74705SXin Li case tok::kw_volatile: // struct foo {...} volatile x;
1125*67e74705SXin Li case tok::kw_restrict: // struct foo {...} restrict x;
1126*67e74705SXin Li case tok::kw__Atomic: // struct foo {...} _Atomic x;
1127*67e74705SXin Li case tok::kw___unaligned: // struct foo {...} __unaligned *x;
1128*67e74705SXin Li // Function specifiers
1129*67e74705SXin Li // Note, no 'explicit'. An explicit function must be either a conversion
1130*67e74705SXin Li // operator or a constructor. Either way, it can't have a return type.
1131*67e74705SXin Li case tok::kw_inline: // struct foo inline f();
1132*67e74705SXin Li case tok::kw_virtual: // struct foo virtual f();
1133*67e74705SXin Li case tok::kw_friend: // struct foo friend f();
1134*67e74705SXin Li // Storage-class specifiers
1135*67e74705SXin Li case tok::kw_static: // struct foo {...} static x;
1136*67e74705SXin Li case tok::kw_extern: // struct foo {...} extern x;
1137*67e74705SXin Li case tok::kw_typedef: // struct foo {...} typedef x;
1138*67e74705SXin Li case tok::kw_register: // struct foo {...} register x;
1139*67e74705SXin Li case tok::kw_auto: // struct foo {...} auto x;
1140*67e74705SXin Li case tok::kw_mutable: // struct foo {...} mutable x;
1141*67e74705SXin Li case tok::kw_thread_local: // struct foo {...} thread_local x;
1142*67e74705SXin Li case tok::kw_constexpr: // struct foo {...} constexpr x;
1143*67e74705SXin Li // As shown above, type qualifiers and storage class specifiers absolutely
1144*67e74705SXin Li // can occur after class specifiers according to the grammar. However,
1145*67e74705SXin Li // almost no one actually writes code like this. If we see one of these,
1146*67e74705SXin Li // it is much more likely that someone missed a semi colon and the
1147*67e74705SXin Li // type/storage class specifier we're seeing is part of the *next*
1148*67e74705SXin Li // intended declaration, as in:
1149*67e74705SXin Li //
1150*67e74705SXin Li // struct foo { ... }
1151*67e74705SXin Li // typedef int X;
1152*67e74705SXin Li //
1153*67e74705SXin Li // We'd really like to emit a missing semicolon error instead of emitting
1154*67e74705SXin Li // an error on the 'int' saying that you can't have two type specifiers in
1155*67e74705SXin Li // the same declaration of X. Because of this, we look ahead past this
1156*67e74705SXin Li // token to see if it's a type specifier. If so, we know the code is
1157*67e74705SXin Li // otherwise invalid, so we can produce the expected semi error.
1158*67e74705SXin Li if (!isKnownToBeTypeSpecifier(NextToken()))
1159*67e74705SXin Li return true;
1160*67e74705SXin Li break;
1161*67e74705SXin Li case tok::r_brace: // struct bar { struct foo {...} }
1162*67e74705SXin Li // Missing ';' at end of struct is accepted as an extension in C mode.
1163*67e74705SXin Li if (!getLangOpts().CPlusPlus)
1164*67e74705SXin Li return true;
1165*67e74705SXin Li break;
1166*67e74705SXin Li case tok::greater:
1167*67e74705SXin Li // template<class T = class X>
1168*67e74705SXin Li return getLangOpts().CPlusPlus;
1169*67e74705SXin Li }
1170*67e74705SXin Li return false;
1171*67e74705SXin Li }
1172*67e74705SXin Li
1173*67e74705SXin Li /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
1174*67e74705SXin Li /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
1175*67e74705SXin Li /// until we reach the start of a definition or see a token that
1176*67e74705SXin Li /// cannot start a definition.
1177*67e74705SXin Li ///
1178*67e74705SXin Li /// class-specifier: [C++ class]
1179*67e74705SXin Li /// class-head '{' member-specification[opt] '}'
1180*67e74705SXin Li /// class-head '{' member-specification[opt] '}' attributes[opt]
1181*67e74705SXin Li /// class-head:
1182*67e74705SXin Li /// class-key identifier[opt] base-clause[opt]
1183*67e74705SXin Li /// class-key nested-name-specifier identifier base-clause[opt]
1184*67e74705SXin Li /// class-key nested-name-specifier[opt] simple-template-id
1185*67e74705SXin Li /// base-clause[opt]
1186*67e74705SXin Li /// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt]
1187*67e74705SXin Li /// [GNU] class-key attributes[opt] nested-name-specifier
1188*67e74705SXin Li /// identifier base-clause[opt]
1189*67e74705SXin Li /// [GNU] class-key attributes[opt] nested-name-specifier[opt]
1190*67e74705SXin Li /// simple-template-id base-clause[opt]
1191*67e74705SXin Li /// class-key:
1192*67e74705SXin Li /// 'class'
1193*67e74705SXin Li /// 'struct'
1194*67e74705SXin Li /// 'union'
1195*67e74705SXin Li ///
1196*67e74705SXin Li /// elaborated-type-specifier: [C++ dcl.type.elab]
1197*67e74705SXin Li /// class-key ::[opt] nested-name-specifier[opt] identifier
1198*67e74705SXin Li /// class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
1199*67e74705SXin Li /// simple-template-id
1200*67e74705SXin Li ///
1201*67e74705SXin Li /// Note that the C++ class-specifier and elaborated-type-specifier,
1202*67e74705SXin Li /// together, subsume the C99 struct-or-union-specifier:
1203*67e74705SXin Li ///
1204*67e74705SXin Li /// struct-or-union-specifier: [C99 6.7.2.1]
1205*67e74705SXin Li /// struct-or-union identifier[opt] '{' struct-contents '}'
1206*67e74705SXin Li /// struct-or-union identifier
1207*67e74705SXin Li /// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents
1208*67e74705SXin Li /// '}' attributes[opt]
1209*67e74705SXin Li /// [GNU] struct-or-union attributes[opt] identifier
1210*67e74705SXin Li /// struct-or-union:
1211*67e74705SXin Li /// 'struct'
1212*67e74705SXin Li /// 'union'
ParseClassSpecifier(tok::TokenKind TagTokKind,SourceLocation StartLoc,DeclSpec & DS,const ParsedTemplateInfo & TemplateInfo,AccessSpecifier AS,bool EnteringContext,DeclSpecContext DSC,ParsedAttributesWithRange & Attributes)1213*67e74705SXin Li void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
1214*67e74705SXin Li SourceLocation StartLoc, DeclSpec &DS,
1215*67e74705SXin Li const ParsedTemplateInfo &TemplateInfo,
1216*67e74705SXin Li AccessSpecifier AS,
1217*67e74705SXin Li bool EnteringContext, DeclSpecContext DSC,
1218*67e74705SXin Li ParsedAttributesWithRange &Attributes) {
1219*67e74705SXin Li DeclSpec::TST TagType;
1220*67e74705SXin Li if (TagTokKind == tok::kw_struct)
1221*67e74705SXin Li TagType = DeclSpec::TST_struct;
1222*67e74705SXin Li else if (TagTokKind == tok::kw___interface)
1223*67e74705SXin Li TagType = DeclSpec::TST_interface;
1224*67e74705SXin Li else if (TagTokKind == tok::kw_class)
1225*67e74705SXin Li TagType = DeclSpec::TST_class;
1226*67e74705SXin Li else {
1227*67e74705SXin Li assert(TagTokKind == tok::kw_union && "Not a class specifier");
1228*67e74705SXin Li TagType = DeclSpec::TST_union;
1229*67e74705SXin Li }
1230*67e74705SXin Li
1231*67e74705SXin Li if (Tok.is(tok::code_completion)) {
1232*67e74705SXin Li // Code completion for a struct, class, or union name.
1233*67e74705SXin Li Actions.CodeCompleteTag(getCurScope(), TagType);
1234*67e74705SXin Li return cutOffParsing();
1235*67e74705SXin Li }
1236*67e74705SXin Li
1237*67e74705SXin Li // C++03 [temp.explicit] 14.7.2/8:
1238*67e74705SXin Li // The usual access checking rules do not apply to names used to specify
1239*67e74705SXin Li // explicit instantiations.
1240*67e74705SXin Li //
1241*67e74705SXin Li // As an extension we do not perform access checking on the names used to
1242*67e74705SXin Li // specify explicit specializations either. This is important to allow
1243*67e74705SXin Li // specializing traits classes for private types.
1244*67e74705SXin Li //
1245*67e74705SXin Li // Note that we don't suppress if this turns out to be an elaborated
1246*67e74705SXin Li // type specifier.
1247*67e74705SXin Li bool shouldDelayDiagsInTag =
1248*67e74705SXin Li (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
1249*67e74705SXin Li TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
1250*67e74705SXin Li SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
1251*67e74705SXin Li
1252*67e74705SXin Li ParsedAttributesWithRange attrs(AttrFactory);
1253*67e74705SXin Li // If attributes exist after tag, parse them.
1254*67e74705SXin Li MaybeParseGNUAttributes(attrs);
1255*67e74705SXin Li MaybeParseMicrosoftDeclSpecs(attrs);
1256*67e74705SXin Li
1257*67e74705SXin Li // Parse inheritance specifiers.
1258*67e74705SXin Li if (Tok.isOneOf(tok::kw___single_inheritance,
1259*67e74705SXin Li tok::kw___multiple_inheritance,
1260*67e74705SXin Li tok::kw___virtual_inheritance))
1261*67e74705SXin Li ParseMicrosoftInheritanceClassAttributes(attrs);
1262*67e74705SXin Li
1263*67e74705SXin Li // If C++0x attributes exist here, parse them.
1264*67e74705SXin Li // FIXME: Are we consistent with the ordering of parsing of different
1265*67e74705SXin Li // styles of attributes?
1266*67e74705SXin Li MaybeParseCXX11Attributes(attrs);
1267*67e74705SXin Li
1268*67e74705SXin Li // Source location used by FIXIT to insert misplaced
1269*67e74705SXin Li // C++11 attributes
1270*67e74705SXin Li SourceLocation AttrFixitLoc = Tok.getLocation();
1271*67e74705SXin Li
1272*67e74705SXin Li if (TagType == DeclSpec::TST_struct &&
1273*67e74705SXin Li Tok.isNot(tok::identifier) &&
1274*67e74705SXin Li !Tok.isAnnotation() &&
1275*67e74705SXin Li Tok.getIdentifierInfo() &&
1276*67e74705SXin Li Tok.isOneOf(tok::kw___is_abstract,
1277*67e74705SXin Li tok::kw___is_arithmetic,
1278*67e74705SXin Li tok::kw___is_array,
1279*67e74705SXin Li tok::kw___is_assignable,
1280*67e74705SXin Li tok::kw___is_base_of,
1281*67e74705SXin Li tok::kw___is_class,
1282*67e74705SXin Li tok::kw___is_complete_type,
1283*67e74705SXin Li tok::kw___is_compound,
1284*67e74705SXin Li tok::kw___is_const,
1285*67e74705SXin Li tok::kw___is_constructible,
1286*67e74705SXin Li tok::kw___is_convertible,
1287*67e74705SXin Li tok::kw___is_convertible_to,
1288*67e74705SXin Li tok::kw___is_destructible,
1289*67e74705SXin Li tok::kw___is_empty,
1290*67e74705SXin Li tok::kw___is_enum,
1291*67e74705SXin Li tok::kw___is_floating_point,
1292*67e74705SXin Li tok::kw___is_final,
1293*67e74705SXin Li tok::kw___is_function,
1294*67e74705SXin Li tok::kw___is_fundamental,
1295*67e74705SXin Li tok::kw___is_integral,
1296*67e74705SXin Li tok::kw___is_interface_class,
1297*67e74705SXin Li tok::kw___is_literal,
1298*67e74705SXin Li tok::kw___is_lvalue_expr,
1299*67e74705SXin Li tok::kw___is_lvalue_reference,
1300*67e74705SXin Li tok::kw___is_member_function_pointer,
1301*67e74705SXin Li tok::kw___is_member_object_pointer,
1302*67e74705SXin Li tok::kw___is_member_pointer,
1303*67e74705SXin Li tok::kw___is_nothrow_assignable,
1304*67e74705SXin Li tok::kw___is_nothrow_constructible,
1305*67e74705SXin Li tok::kw___is_nothrow_destructible,
1306*67e74705SXin Li tok::kw___is_object,
1307*67e74705SXin Li tok::kw___is_pod,
1308*67e74705SXin Li tok::kw___is_pointer,
1309*67e74705SXin Li tok::kw___is_polymorphic,
1310*67e74705SXin Li tok::kw___is_reference,
1311*67e74705SXin Li tok::kw___is_rvalue_expr,
1312*67e74705SXin Li tok::kw___is_rvalue_reference,
1313*67e74705SXin Li tok::kw___is_same,
1314*67e74705SXin Li tok::kw___is_scalar,
1315*67e74705SXin Li tok::kw___is_sealed,
1316*67e74705SXin Li tok::kw___is_signed,
1317*67e74705SXin Li tok::kw___is_standard_layout,
1318*67e74705SXin Li tok::kw___is_trivial,
1319*67e74705SXin Li tok::kw___is_trivially_assignable,
1320*67e74705SXin Li tok::kw___is_trivially_constructible,
1321*67e74705SXin Li tok::kw___is_trivially_copyable,
1322*67e74705SXin Li tok::kw___is_union,
1323*67e74705SXin Li tok::kw___is_unsigned,
1324*67e74705SXin Li tok::kw___is_void,
1325*67e74705SXin Li tok::kw___is_volatile))
1326*67e74705SXin Li // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
1327*67e74705SXin Li // name of struct templates, but some are keywords in GCC >= 4.3
1328*67e74705SXin Li // and Clang. Therefore, when we see the token sequence "struct
1329*67e74705SXin Li // X", make X into a normal identifier rather than a keyword, to
1330*67e74705SXin Li // allow libstdc++ 4.2 and libc++ to work properly.
1331*67e74705SXin Li TryKeywordIdentFallback(true);
1332*67e74705SXin Li
1333*67e74705SXin Li struct PreserveAtomicIdentifierInfoRAII {
1334*67e74705SXin Li PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled)
1335*67e74705SXin Li : AtomicII(nullptr) {
1336*67e74705SXin Li if (!Enabled)
1337*67e74705SXin Li return;
1338*67e74705SXin Li assert(Tok.is(tok::kw__Atomic));
1339*67e74705SXin Li AtomicII = Tok.getIdentifierInfo();
1340*67e74705SXin Li AtomicII->revertTokenIDToIdentifier();
1341*67e74705SXin Li Tok.setKind(tok::identifier);
1342*67e74705SXin Li }
1343*67e74705SXin Li ~PreserveAtomicIdentifierInfoRAII() {
1344*67e74705SXin Li if (!AtomicII)
1345*67e74705SXin Li return;
1346*67e74705SXin Li AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);
1347*67e74705SXin Li }
1348*67e74705SXin Li IdentifierInfo *AtomicII;
1349*67e74705SXin Li };
1350*67e74705SXin Li
1351*67e74705SXin Li // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL
1352*67e74705SXin Li // implementation for VS2013 uses _Atomic as an identifier for one of the
1353*67e74705SXin Li // classes in <atomic>. When we are parsing 'struct _Atomic', don't consider
1354*67e74705SXin Li // '_Atomic' to be a keyword. We are careful to undo this so that clang can
1355*67e74705SXin Li // use '_Atomic' in its own header files.
1356*67e74705SXin Li bool ShouldChangeAtomicToIdentifier = getLangOpts().MSVCCompat &&
1357*67e74705SXin Li Tok.is(tok::kw__Atomic) &&
1358*67e74705SXin Li TagType == DeclSpec::TST_struct;
1359*67e74705SXin Li PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(
1360*67e74705SXin Li Tok, ShouldChangeAtomicToIdentifier);
1361*67e74705SXin Li
1362*67e74705SXin Li // Parse the (optional) nested-name-specifier.
1363*67e74705SXin Li CXXScopeSpec &SS = DS.getTypeSpecScope();
1364*67e74705SXin Li if (getLangOpts().CPlusPlus) {
1365*67e74705SXin Li // "FOO : BAR" is not a potential typo for "FOO::BAR". In this context it
1366*67e74705SXin Li // is a base-specifier-list.
1367*67e74705SXin Li ColonProtectionRAIIObject X(*this);
1368*67e74705SXin Li
1369*67e74705SXin Li CXXScopeSpec Spec;
1370*67e74705SXin Li bool HasValidSpec = true;
1371*67e74705SXin Li if (ParseOptionalCXXScopeSpecifier(Spec, nullptr, EnteringContext)) {
1372*67e74705SXin Li DS.SetTypeSpecError();
1373*67e74705SXin Li HasValidSpec = false;
1374*67e74705SXin Li }
1375*67e74705SXin Li if (Spec.isSet())
1376*67e74705SXin Li if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) {
1377*67e74705SXin Li Diag(Tok, diag::err_expected) << tok::identifier;
1378*67e74705SXin Li HasValidSpec = false;
1379*67e74705SXin Li }
1380*67e74705SXin Li if (HasValidSpec)
1381*67e74705SXin Li SS = Spec;
1382*67e74705SXin Li }
1383*67e74705SXin Li
1384*67e74705SXin Li TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
1385*67e74705SXin Li
1386*67e74705SXin Li // Parse the (optional) class name or simple-template-id.
1387*67e74705SXin Li IdentifierInfo *Name = nullptr;
1388*67e74705SXin Li SourceLocation NameLoc;
1389*67e74705SXin Li TemplateIdAnnotation *TemplateId = nullptr;
1390*67e74705SXin Li if (Tok.is(tok::identifier)) {
1391*67e74705SXin Li Name = Tok.getIdentifierInfo();
1392*67e74705SXin Li NameLoc = ConsumeToken();
1393*67e74705SXin Li
1394*67e74705SXin Li if (Tok.is(tok::less) && getLangOpts().CPlusPlus) {
1395*67e74705SXin Li // The name was supposed to refer to a template, but didn't.
1396*67e74705SXin Li // Eat the template argument list and try to continue parsing this as
1397*67e74705SXin Li // a class (or template thereof).
1398*67e74705SXin Li TemplateArgList TemplateArgs;
1399*67e74705SXin Li SourceLocation LAngleLoc, RAngleLoc;
1400*67e74705SXin Li if (ParseTemplateIdAfterTemplateName(
1401*67e74705SXin Li nullptr, NameLoc, SS, true, LAngleLoc, TemplateArgs, RAngleLoc)) {
1402*67e74705SXin Li // We couldn't parse the template argument list at all, so don't
1403*67e74705SXin Li // try to give any location information for the list.
1404*67e74705SXin Li LAngleLoc = RAngleLoc = SourceLocation();
1405*67e74705SXin Li }
1406*67e74705SXin Li
1407*67e74705SXin Li Diag(NameLoc, diag::err_explicit_spec_non_template)
1408*67e74705SXin Li << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
1409*67e74705SXin Li << TagTokKind << Name << SourceRange(LAngleLoc, RAngleLoc);
1410*67e74705SXin Li
1411*67e74705SXin Li // Strip off the last template parameter list if it was empty, since
1412*67e74705SXin Li // we've removed its template argument list.
1413*67e74705SXin Li if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1414*67e74705SXin Li if (TemplateParams->size() > 1) {
1415*67e74705SXin Li TemplateParams->pop_back();
1416*67e74705SXin Li } else {
1417*67e74705SXin Li TemplateParams = nullptr;
1418*67e74705SXin Li const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
1419*67e74705SXin Li = ParsedTemplateInfo::NonTemplate;
1420*67e74705SXin Li }
1421*67e74705SXin Li } else if (TemplateInfo.Kind
1422*67e74705SXin Li == ParsedTemplateInfo::ExplicitInstantiation) {
1423*67e74705SXin Li // Pretend this is just a forward declaration.
1424*67e74705SXin Li TemplateParams = nullptr;
1425*67e74705SXin Li const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
1426*67e74705SXin Li = ParsedTemplateInfo::NonTemplate;
1427*67e74705SXin Li const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
1428*67e74705SXin Li = SourceLocation();
1429*67e74705SXin Li const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
1430*67e74705SXin Li = SourceLocation();
1431*67e74705SXin Li }
1432*67e74705SXin Li }
1433*67e74705SXin Li } else if (Tok.is(tok::annot_template_id)) {
1434*67e74705SXin Li TemplateId = takeTemplateIdAnnotation(Tok);
1435*67e74705SXin Li NameLoc = ConsumeToken();
1436*67e74705SXin Li
1437*67e74705SXin Li if (TemplateId->Kind != TNK_Type_template &&
1438*67e74705SXin Li TemplateId->Kind != TNK_Dependent_template_name) {
1439*67e74705SXin Li // The template-name in the simple-template-id refers to
1440*67e74705SXin Li // something other than a class template. Give an appropriate
1441*67e74705SXin Li // error message and skip to the ';'.
1442*67e74705SXin Li SourceRange Range(NameLoc);
1443*67e74705SXin Li if (SS.isNotEmpty())
1444*67e74705SXin Li Range.setBegin(SS.getBeginLoc());
1445*67e74705SXin Li
1446*67e74705SXin Li // FIXME: Name may be null here.
1447*67e74705SXin Li Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
1448*67e74705SXin Li << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;
1449*67e74705SXin Li
1450*67e74705SXin Li DS.SetTypeSpecError();
1451*67e74705SXin Li SkipUntil(tok::semi, StopBeforeMatch);
1452*67e74705SXin Li return;
1453*67e74705SXin Li }
1454*67e74705SXin Li }
1455*67e74705SXin Li
1456*67e74705SXin Li // There are four options here.
1457*67e74705SXin Li // - If we are in a trailing return type, this is always just a reference,
1458*67e74705SXin Li // and we must not try to parse a definition. For instance,
1459*67e74705SXin Li // [] () -> struct S { };
1460*67e74705SXin Li // does not define a type.
1461*67e74705SXin Li // - If we have 'struct foo {...', 'struct foo :...',
1462*67e74705SXin Li // 'struct foo final :' or 'struct foo final {', then this is a definition.
1463*67e74705SXin Li // - If we have 'struct foo;', then this is either a forward declaration
1464*67e74705SXin Li // or a friend declaration, which have to be treated differently.
1465*67e74705SXin Li // - Otherwise we have something like 'struct foo xyz', a reference.
1466*67e74705SXin Li //
1467*67e74705SXin Li // We also detect these erroneous cases to provide better diagnostic for
1468*67e74705SXin Li // C++11 attributes parsing.
1469*67e74705SXin Li // - attributes follow class name:
1470*67e74705SXin Li // struct foo [[]] {};
1471*67e74705SXin Li // - attributes appear before or after 'final':
1472*67e74705SXin Li // struct foo [[]] final [[]] {};
1473*67e74705SXin Li //
1474*67e74705SXin Li // However, in type-specifier-seq's, things look like declarations but are
1475*67e74705SXin Li // just references, e.g.
1476*67e74705SXin Li // new struct s;
1477*67e74705SXin Li // or
1478*67e74705SXin Li // &T::operator struct s;
1479*67e74705SXin Li // For these, DSC is DSC_type_specifier or DSC_alias_declaration.
1480*67e74705SXin Li
1481*67e74705SXin Li // If there are attributes after class name, parse them.
1482*67e74705SXin Li MaybeParseCXX11Attributes(Attributes);
1483*67e74705SXin Li
1484*67e74705SXin Li const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
1485*67e74705SXin Li Sema::TagUseKind TUK;
1486*67e74705SXin Li if (DSC == DSC_trailing)
1487*67e74705SXin Li TUK = Sema::TUK_Reference;
1488*67e74705SXin Li else if (Tok.is(tok::l_brace) ||
1489*67e74705SXin Li (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
1490*67e74705SXin Li (isCXX11FinalKeyword() &&
1491*67e74705SXin Li (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) {
1492*67e74705SXin Li if (DS.isFriendSpecified()) {
1493*67e74705SXin Li // C++ [class.friend]p2:
1494*67e74705SXin Li // A class shall not be defined in a friend declaration.
1495*67e74705SXin Li Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
1496*67e74705SXin Li << SourceRange(DS.getFriendSpecLoc());
1497*67e74705SXin Li
1498*67e74705SXin Li // Skip everything up to the semicolon, so that this looks like a proper
1499*67e74705SXin Li // friend class (or template thereof) declaration.
1500*67e74705SXin Li SkipUntil(tok::semi, StopBeforeMatch);
1501*67e74705SXin Li TUK = Sema::TUK_Friend;
1502*67e74705SXin Li } else {
1503*67e74705SXin Li // Okay, this is a class definition.
1504*67e74705SXin Li TUK = Sema::TUK_Definition;
1505*67e74705SXin Li }
1506*67e74705SXin Li } else if (isCXX11FinalKeyword() && (NextToken().is(tok::l_square) ||
1507*67e74705SXin Li NextToken().is(tok::kw_alignas))) {
1508*67e74705SXin Li // We can't tell if this is a definition or reference
1509*67e74705SXin Li // until we skipped the 'final' and C++11 attribute specifiers.
1510*67e74705SXin Li TentativeParsingAction PA(*this);
1511*67e74705SXin Li
1512*67e74705SXin Li // Skip the 'final' keyword.
1513*67e74705SXin Li ConsumeToken();
1514*67e74705SXin Li
1515*67e74705SXin Li // Skip C++11 attribute specifiers.
1516*67e74705SXin Li while (true) {
1517*67e74705SXin Li if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
1518*67e74705SXin Li ConsumeBracket();
1519*67e74705SXin Li if (!SkipUntil(tok::r_square, StopAtSemi))
1520*67e74705SXin Li break;
1521*67e74705SXin Li } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {
1522*67e74705SXin Li ConsumeToken();
1523*67e74705SXin Li ConsumeParen();
1524*67e74705SXin Li if (!SkipUntil(tok::r_paren, StopAtSemi))
1525*67e74705SXin Li break;
1526*67e74705SXin Li } else {
1527*67e74705SXin Li break;
1528*67e74705SXin Li }
1529*67e74705SXin Li }
1530*67e74705SXin Li
1531*67e74705SXin Li if (Tok.isOneOf(tok::l_brace, tok::colon))
1532*67e74705SXin Li TUK = Sema::TUK_Definition;
1533*67e74705SXin Li else
1534*67e74705SXin Li TUK = Sema::TUK_Reference;
1535*67e74705SXin Li
1536*67e74705SXin Li PA.Revert();
1537*67e74705SXin Li } else if (!isTypeSpecifier(DSC) &&
1538*67e74705SXin Li (Tok.is(tok::semi) ||
1539*67e74705SXin Li (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
1540*67e74705SXin Li TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
1541*67e74705SXin Li if (Tok.isNot(tok::semi)) {
1542*67e74705SXin Li const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
1543*67e74705SXin Li // A semicolon was missing after this declaration. Diagnose and recover.
1544*67e74705SXin Li ExpectAndConsume(tok::semi, diag::err_expected_after,
1545*67e74705SXin Li DeclSpec::getSpecifierName(TagType, PPol));
1546*67e74705SXin Li PP.EnterToken(Tok);
1547*67e74705SXin Li Tok.setKind(tok::semi);
1548*67e74705SXin Li }
1549*67e74705SXin Li } else
1550*67e74705SXin Li TUK = Sema::TUK_Reference;
1551*67e74705SXin Li
1552*67e74705SXin Li // Forbid misplaced attributes. In cases of a reference, we pass attributes
1553*67e74705SXin Li // to caller to handle.
1554*67e74705SXin Li if (TUK != Sema::TUK_Reference) {
1555*67e74705SXin Li // If this is not a reference, then the only possible
1556*67e74705SXin Li // valid place for C++11 attributes to appear here
1557*67e74705SXin Li // is between class-key and class-name. If there are
1558*67e74705SXin Li // any attributes after class-name, we try a fixit to move
1559*67e74705SXin Li // them to the right place.
1560*67e74705SXin Li SourceRange AttrRange = Attributes.Range;
1561*67e74705SXin Li if (AttrRange.isValid()) {
1562*67e74705SXin Li Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed)
1563*67e74705SXin Li << AttrRange
1564*67e74705SXin Li << FixItHint::CreateInsertionFromRange(AttrFixitLoc,
1565*67e74705SXin Li CharSourceRange(AttrRange, true))
1566*67e74705SXin Li << FixItHint::CreateRemoval(AttrRange);
1567*67e74705SXin Li
1568*67e74705SXin Li // Recover by adding misplaced attributes to the attribute list
1569*67e74705SXin Li // of the class so they can be applied on the class later.
1570*67e74705SXin Li attrs.takeAllFrom(Attributes);
1571*67e74705SXin Li }
1572*67e74705SXin Li }
1573*67e74705SXin Li
1574*67e74705SXin Li // If this is an elaborated type specifier, and we delayed
1575*67e74705SXin Li // diagnostics before, just merge them into the current pool.
1576*67e74705SXin Li if (shouldDelayDiagsInTag) {
1577*67e74705SXin Li diagsFromTag.done();
1578*67e74705SXin Li if (TUK == Sema::TUK_Reference)
1579*67e74705SXin Li diagsFromTag.redelay();
1580*67e74705SXin Li }
1581*67e74705SXin Li
1582*67e74705SXin Li if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
1583*67e74705SXin Li TUK != Sema::TUK_Definition)) {
1584*67e74705SXin Li if (DS.getTypeSpecType() != DeclSpec::TST_error) {
1585*67e74705SXin Li // We have a declaration or reference to an anonymous class.
1586*67e74705SXin Li Diag(StartLoc, diag::err_anon_type_definition)
1587*67e74705SXin Li << DeclSpec::getSpecifierName(TagType, Policy);
1588*67e74705SXin Li }
1589*67e74705SXin Li
1590*67e74705SXin Li // If we are parsing a definition and stop at a base-clause, continue on
1591*67e74705SXin Li // until the semicolon. Continuing from the comma will just trick us into
1592*67e74705SXin Li // thinking we are seeing a variable declaration.
1593*67e74705SXin Li if (TUK == Sema::TUK_Definition && Tok.is(tok::colon))
1594*67e74705SXin Li SkipUntil(tok::semi, StopBeforeMatch);
1595*67e74705SXin Li else
1596*67e74705SXin Li SkipUntil(tok::comma, StopAtSemi);
1597*67e74705SXin Li return;
1598*67e74705SXin Li }
1599*67e74705SXin Li
1600*67e74705SXin Li // Create the tag portion of the class or class template.
1601*67e74705SXin Li DeclResult TagOrTempResult = true; // invalid
1602*67e74705SXin Li TypeResult TypeResult = true; // invalid
1603*67e74705SXin Li
1604*67e74705SXin Li bool Owned = false;
1605*67e74705SXin Li Sema::SkipBodyInfo SkipBody;
1606*67e74705SXin Li if (TemplateId) {
1607*67e74705SXin Li // Explicit specialization, class template partial specialization,
1608*67e74705SXin Li // or explicit instantiation.
1609*67e74705SXin Li ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
1610*67e74705SXin Li TemplateId->NumArgs);
1611*67e74705SXin Li if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1612*67e74705SXin Li TUK == Sema::TUK_Declaration) {
1613*67e74705SXin Li // This is an explicit instantiation of a class template.
1614*67e74705SXin Li ProhibitAttributes(attrs);
1615*67e74705SXin Li
1616*67e74705SXin Li TagOrTempResult
1617*67e74705SXin Li = Actions.ActOnExplicitInstantiation(getCurScope(),
1618*67e74705SXin Li TemplateInfo.ExternLoc,
1619*67e74705SXin Li TemplateInfo.TemplateLoc,
1620*67e74705SXin Li TagType,
1621*67e74705SXin Li StartLoc,
1622*67e74705SXin Li SS,
1623*67e74705SXin Li TemplateId->Template,
1624*67e74705SXin Li TemplateId->TemplateNameLoc,
1625*67e74705SXin Li TemplateId->LAngleLoc,
1626*67e74705SXin Li TemplateArgsPtr,
1627*67e74705SXin Li TemplateId->RAngleLoc,
1628*67e74705SXin Li attrs.getList());
1629*67e74705SXin Li
1630*67e74705SXin Li // Friend template-ids are treated as references unless
1631*67e74705SXin Li // they have template headers, in which case they're ill-formed
1632*67e74705SXin Li // (FIXME: "template <class T> friend class A<T>::B<int>;").
1633*67e74705SXin Li // We diagnose this error in ActOnClassTemplateSpecialization.
1634*67e74705SXin Li } else if (TUK == Sema::TUK_Reference ||
1635*67e74705SXin Li (TUK == Sema::TUK_Friend &&
1636*67e74705SXin Li TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
1637*67e74705SXin Li ProhibitAttributes(attrs);
1638*67e74705SXin Li TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc,
1639*67e74705SXin Li TemplateId->SS,
1640*67e74705SXin Li TemplateId->TemplateKWLoc,
1641*67e74705SXin Li TemplateId->Template,
1642*67e74705SXin Li TemplateId->TemplateNameLoc,
1643*67e74705SXin Li TemplateId->LAngleLoc,
1644*67e74705SXin Li TemplateArgsPtr,
1645*67e74705SXin Li TemplateId->RAngleLoc);
1646*67e74705SXin Li } else {
1647*67e74705SXin Li // This is an explicit specialization or a class template
1648*67e74705SXin Li // partial specialization.
1649*67e74705SXin Li TemplateParameterLists FakedParamLists;
1650*67e74705SXin Li if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
1651*67e74705SXin Li // This looks like an explicit instantiation, because we have
1652*67e74705SXin Li // something like
1653*67e74705SXin Li //
1654*67e74705SXin Li // template class Foo<X>
1655*67e74705SXin Li //
1656*67e74705SXin Li // but it actually has a definition. Most likely, this was
1657*67e74705SXin Li // meant to be an explicit specialization, but the user forgot
1658*67e74705SXin Li // the '<>' after 'template'.
1659*67e74705SXin Li // It this is friend declaration however, since it cannot have a
1660*67e74705SXin Li // template header, it is most likely that the user meant to
1661*67e74705SXin Li // remove the 'template' keyword.
1662*67e74705SXin Li assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) &&
1663*67e74705SXin Li "Expected a definition here");
1664*67e74705SXin Li
1665*67e74705SXin Li if (TUK == Sema::TUK_Friend) {
1666*67e74705SXin Li Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation);
1667*67e74705SXin Li TemplateParams = nullptr;
1668*67e74705SXin Li } else {
1669*67e74705SXin Li SourceLocation LAngleLoc =
1670*67e74705SXin Li PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
1671*67e74705SXin Li Diag(TemplateId->TemplateNameLoc,
1672*67e74705SXin Li diag::err_explicit_instantiation_with_definition)
1673*67e74705SXin Li << SourceRange(TemplateInfo.TemplateLoc)
1674*67e74705SXin Li << FixItHint::CreateInsertion(LAngleLoc, "<>");
1675*67e74705SXin Li
1676*67e74705SXin Li // Create a fake template parameter list that contains only
1677*67e74705SXin Li // "template<>", so that we treat this construct as a class
1678*67e74705SXin Li // template specialization.
1679*67e74705SXin Li FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
1680*67e74705SXin Li 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None,
1681*67e74705SXin Li LAngleLoc, nullptr));
1682*67e74705SXin Li TemplateParams = &FakedParamLists;
1683*67e74705SXin Li }
1684*67e74705SXin Li }
1685*67e74705SXin Li
1686*67e74705SXin Li // Build the class template specialization.
1687*67e74705SXin Li TagOrTempResult = Actions.ActOnClassTemplateSpecialization(
1688*67e74705SXin Li getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(),
1689*67e74705SXin Li *TemplateId, attrs.getList(),
1690*67e74705SXin Li MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]
1691*67e74705SXin Li : nullptr,
1692*67e74705SXin Li TemplateParams ? TemplateParams->size() : 0),
1693*67e74705SXin Li &SkipBody);
1694*67e74705SXin Li }
1695*67e74705SXin Li } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1696*67e74705SXin Li TUK == Sema::TUK_Declaration) {
1697*67e74705SXin Li // Explicit instantiation of a member of a class template
1698*67e74705SXin Li // specialization, e.g.,
1699*67e74705SXin Li //
1700*67e74705SXin Li // template struct Outer<int>::Inner;
1701*67e74705SXin Li //
1702*67e74705SXin Li ProhibitAttributes(attrs);
1703*67e74705SXin Li
1704*67e74705SXin Li TagOrTempResult
1705*67e74705SXin Li = Actions.ActOnExplicitInstantiation(getCurScope(),
1706*67e74705SXin Li TemplateInfo.ExternLoc,
1707*67e74705SXin Li TemplateInfo.TemplateLoc,
1708*67e74705SXin Li TagType, StartLoc, SS, Name,
1709*67e74705SXin Li NameLoc, attrs.getList());
1710*67e74705SXin Li } else if (TUK == Sema::TUK_Friend &&
1711*67e74705SXin Li TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
1712*67e74705SXin Li ProhibitAttributes(attrs);
1713*67e74705SXin Li
1714*67e74705SXin Li TagOrTempResult =
1715*67e74705SXin Li Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
1716*67e74705SXin Li TagType, StartLoc, SS,
1717*67e74705SXin Li Name, NameLoc, attrs.getList(),
1718*67e74705SXin Li MultiTemplateParamsArg(
1719*67e74705SXin Li TemplateParams? &(*TemplateParams)[0]
1720*67e74705SXin Li : nullptr,
1721*67e74705SXin Li TemplateParams? TemplateParams->size() : 0));
1722*67e74705SXin Li } else {
1723*67e74705SXin Li if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
1724*67e74705SXin Li ProhibitAttributes(attrs);
1725*67e74705SXin Li
1726*67e74705SXin Li if (TUK == Sema::TUK_Definition &&
1727*67e74705SXin Li TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
1728*67e74705SXin Li // If the declarator-id is not a template-id, issue a diagnostic and
1729*67e74705SXin Li // recover by ignoring the 'template' keyword.
1730*67e74705SXin Li Diag(Tok, diag::err_template_defn_explicit_instantiation)
1731*67e74705SXin Li << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
1732*67e74705SXin Li TemplateParams = nullptr;
1733*67e74705SXin Li }
1734*67e74705SXin Li
1735*67e74705SXin Li bool IsDependent = false;
1736*67e74705SXin Li
1737*67e74705SXin Li // Don't pass down template parameter lists if this is just a tag
1738*67e74705SXin Li // reference. For example, we don't need the template parameters here:
1739*67e74705SXin Li // template <class T> class A *makeA(T t);
1740*67e74705SXin Li MultiTemplateParamsArg TParams;
1741*67e74705SXin Li if (TUK != Sema::TUK_Reference && TemplateParams)
1742*67e74705SXin Li TParams =
1743*67e74705SXin Li MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
1744*67e74705SXin Li
1745*67e74705SXin Li handleDeclspecAlignBeforeClassKey(attrs, DS, TUK);
1746*67e74705SXin Li
1747*67e74705SXin Li // Declaration or definition of a class type
1748*67e74705SXin Li TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
1749*67e74705SXin Li SS, Name, NameLoc, attrs.getList(), AS,
1750*67e74705SXin Li DS.getModulePrivateSpecLoc(),
1751*67e74705SXin Li TParams, Owned, IsDependent,
1752*67e74705SXin Li SourceLocation(), false,
1753*67e74705SXin Li clang::TypeResult(),
1754*67e74705SXin Li DSC == DSC_type_specifier,
1755*67e74705SXin Li &SkipBody);
1756*67e74705SXin Li
1757*67e74705SXin Li // If ActOnTag said the type was dependent, try again with the
1758*67e74705SXin Li // less common call.
1759*67e74705SXin Li if (IsDependent) {
1760*67e74705SXin Li assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend);
1761*67e74705SXin Li TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
1762*67e74705SXin Li SS, Name, StartLoc, NameLoc);
1763*67e74705SXin Li }
1764*67e74705SXin Li }
1765*67e74705SXin Li
1766*67e74705SXin Li // If there is a body, parse it and inform the actions module.
1767*67e74705SXin Li if (TUK == Sema::TUK_Definition) {
1768*67e74705SXin Li assert(Tok.is(tok::l_brace) ||
1769*67e74705SXin Li (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
1770*67e74705SXin Li isCXX11FinalKeyword());
1771*67e74705SXin Li if (SkipBody.ShouldSkip)
1772*67e74705SXin Li SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,
1773*67e74705SXin Li TagOrTempResult.get());
1774*67e74705SXin Li else if (getLangOpts().CPlusPlus)
1775*67e74705SXin Li ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
1776*67e74705SXin Li TagOrTempResult.get());
1777*67e74705SXin Li else
1778*67e74705SXin Li ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
1779*67e74705SXin Li }
1780*67e74705SXin Li
1781*67e74705SXin Li const char *PrevSpec = nullptr;
1782*67e74705SXin Li unsigned DiagID;
1783*67e74705SXin Li bool Result;
1784*67e74705SXin Li if (!TypeResult.isInvalid()) {
1785*67e74705SXin Li Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
1786*67e74705SXin Li NameLoc.isValid() ? NameLoc : StartLoc,
1787*67e74705SXin Li PrevSpec, DiagID, TypeResult.get(), Policy);
1788*67e74705SXin Li } else if (!TagOrTempResult.isInvalid()) {
1789*67e74705SXin Li Result = DS.SetTypeSpecType(TagType, StartLoc,
1790*67e74705SXin Li NameLoc.isValid() ? NameLoc : StartLoc,
1791*67e74705SXin Li PrevSpec, DiagID, TagOrTempResult.get(), Owned,
1792*67e74705SXin Li Policy);
1793*67e74705SXin Li } else {
1794*67e74705SXin Li DS.SetTypeSpecError();
1795*67e74705SXin Li return;
1796*67e74705SXin Li }
1797*67e74705SXin Li
1798*67e74705SXin Li if (Result)
1799*67e74705SXin Li Diag(StartLoc, DiagID) << PrevSpec;
1800*67e74705SXin Li
1801*67e74705SXin Li // At this point, we've successfully parsed a class-specifier in 'definition'
1802*67e74705SXin Li // form (e.g. "struct foo { int x; }". While we could just return here, we're
1803*67e74705SXin Li // going to look at what comes after it to improve error recovery. If an
1804*67e74705SXin Li // impossible token occurs next, we assume that the programmer forgot a ; at
1805*67e74705SXin Li // the end of the declaration and recover that way.
1806*67e74705SXin Li //
1807*67e74705SXin Li // Also enforce C++ [temp]p3:
1808*67e74705SXin Li // In a template-declaration which defines a class, no declarator
1809*67e74705SXin Li // is permitted.
1810*67e74705SXin Li //
1811*67e74705SXin Li // After a type-specifier, we don't expect a semicolon. This only happens in
1812*67e74705SXin Li // C, since definitions are not permitted in this context in C++.
1813*67e74705SXin Li if (TUK == Sema::TUK_Definition &&
1814*67e74705SXin Li (getLangOpts().CPlusPlus || !isTypeSpecifier(DSC)) &&
1815*67e74705SXin Li (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
1816*67e74705SXin Li if (Tok.isNot(tok::semi)) {
1817*67e74705SXin Li const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
1818*67e74705SXin Li ExpectAndConsume(tok::semi, diag::err_expected_after,
1819*67e74705SXin Li DeclSpec::getSpecifierName(TagType, PPol));
1820*67e74705SXin Li // Push this token back into the preprocessor and change our current token
1821*67e74705SXin Li // to ';' so that the rest of the code recovers as though there were an
1822*67e74705SXin Li // ';' after the definition.
1823*67e74705SXin Li PP.EnterToken(Tok);
1824*67e74705SXin Li Tok.setKind(tok::semi);
1825*67e74705SXin Li }
1826*67e74705SXin Li }
1827*67e74705SXin Li }
1828*67e74705SXin Li
1829*67e74705SXin Li /// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1830*67e74705SXin Li ///
1831*67e74705SXin Li /// base-clause : [C++ class.derived]
1832*67e74705SXin Li /// ':' base-specifier-list
1833*67e74705SXin Li /// base-specifier-list:
1834*67e74705SXin Li /// base-specifier '...'[opt]
1835*67e74705SXin Li /// base-specifier-list ',' base-specifier '...'[opt]
ParseBaseClause(Decl * ClassDecl)1836*67e74705SXin Li void Parser::ParseBaseClause(Decl *ClassDecl) {
1837*67e74705SXin Li assert(Tok.is(tok::colon) && "Not a base clause");
1838*67e74705SXin Li ConsumeToken();
1839*67e74705SXin Li
1840*67e74705SXin Li // Build up an array of parsed base specifiers.
1841*67e74705SXin Li SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
1842*67e74705SXin Li
1843*67e74705SXin Li while (true) {
1844*67e74705SXin Li // Parse a base-specifier.
1845*67e74705SXin Li BaseResult Result = ParseBaseSpecifier(ClassDecl);
1846*67e74705SXin Li if (Result.isInvalid()) {
1847*67e74705SXin Li // Skip the rest of this base specifier, up until the comma or
1848*67e74705SXin Li // opening brace.
1849*67e74705SXin Li SkipUntil(tok::comma, tok::l_brace, StopAtSemi | StopBeforeMatch);
1850*67e74705SXin Li } else {
1851*67e74705SXin Li // Add this to our array of base specifiers.
1852*67e74705SXin Li BaseInfo.push_back(Result.get());
1853*67e74705SXin Li }
1854*67e74705SXin Li
1855*67e74705SXin Li // If the next token is a comma, consume it and keep reading
1856*67e74705SXin Li // base-specifiers.
1857*67e74705SXin Li if (!TryConsumeToken(tok::comma))
1858*67e74705SXin Li break;
1859*67e74705SXin Li }
1860*67e74705SXin Li
1861*67e74705SXin Li // Attach the base specifiers
1862*67e74705SXin Li Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo);
1863*67e74705SXin Li }
1864*67e74705SXin Li
1865*67e74705SXin Li /// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1866*67e74705SXin Li /// one entry in the base class list of a class specifier, for example:
1867*67e74705SXin Li /// class foo : public bar, virtual private baz {
1868*67e74705SXin Li /// 'public bar' and 'virtual private baz' are each base-specifiers.
1869*67e74705SXin Li ///
1870*67e74705SXin Li /// base-specifier: [C++ class.derived]
1871*67e74705SXin Li /// attribute-specifier-seq[opt] base-type-specifier
1872*67e74705SXin Li /// attribute-specifier-seq[opt] 'virtual' access-specifier[opt]
1873*67e74705SXin Li /// base-type-specifier
1874*67e74705SXin Li /// attribute-specifier-seq[opt] access-specifier 'virtual'[opt]
1875*67e74705SXin Li /// base-type-specifier
ParseBaseSpecifier(Decl * ClassDecl)1876*67e74705SXin Li BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
1877*67e74705SXin Li bool IsVirtual = false;
1878*67e74705SXin Li SourceLocation StartLoc = Tok.getLocation();
1879*67e74705SXin Li
1880*67e74705SXin Li ParsedAttributesWithRange Attributes(AttrFactory);
1881*67e74705SXin Li MaybeParseCXX11Attributes(Attributes);
1882*67e74705SXin Li
1883*67e74705SXin Li // Parse the 'virtual' keyword.
1884*67e74705SXin Li if (TryConsumeToken(tok::kw_virtual))
1885*67e74705SXin Li IsVirtual = true;
1886*67e74705SXin Li
1887*67e74705SXin Li CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1888*67e74705SXin Li
1889*67e74705SXin Li // Parse an (optional) access specifier.
1890*67e74705SXin Li AccessSpecifier Access = getAccessSpecifierIfPresent();
1891*67e74705SXin Li if (Access != AS_none)
1892*67e74705SXin Li ConsumeToken();
1893*67e74705SXin Li
1894*67e74705SXin Li CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1895*67e74705SXin Li
1896*67e74705SXin Li // Parse the 'virtual' keyword (again!), in case it came after the
1897*67e74705SXin Li // access specifier.
1898*67e74705SXin Li if (Tok.is(tok::kw_virtual)) {
1899*67e74705SXin Li SourceLocation VirtualLoc = ConsumeToken();
1900*67e74705SXin Li if (IsVirtual) {
1901*67e74705SXin Li // Complain about duplicate 'virtual'
1902*67e74705SXin Li Diag(VirtualLoc, diag::err_dup_virtual)
1903*67e74705SXin Li << FixItHint::CreateRemoval(VirtualLoc);
1904*67e74705SXin Li }
1905*67e74705SXin Li
1906*67e74705SXin Li IsVirtual = true;
1907*67e74705SXin Li }
1908*67e74705SXin Li
1909*67e74705SXin Li CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1910*67e74705SXin Li
1911*67e74705SXin Li // Parse the class-name.
1912*67e74705SXin Li
1913*67e74705SXin Li // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL
1914*67e74705SXin Li // implementation for VS2013 uses _Atomic as an identifier for one of the
1915*67e74705SXin Li // classes in <atomic>. Treat '_Atomic' to be an identifier when we are
1916*67e74705SXin Li // parsing the class-name for a base specifier.
1917*67e74705SXin Li if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
1918*67e74705SXin Li NextToken().is(tok::less))
1919*67e74705SXin Li Tok.setKind(tok::identifier);
1920*67e74705SXin Li
1921*67e74705SXin Li SourceLocation EndLocation;
1922*67e74705SXin Li SourceLocation BaseLoc;
1923*67e74705SXin Li TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
1924*67e74705SXin Li if (BaseType.isInvalid())
1925*67e74705SXin Li return true;
1926*67e74705SXin Li
1927*67e74705SXin Li // Parse the optional ellipsis (for a pack expansion). The ellipsis is
1928*67e74705SXin Li // actually part of the base-specifier-list grammar productions, but we
1929*67e74705SXin Li // parse it here for convenience.
1930*67e74705SXin Li SourceLocation EllipsisLoc;
1931*67e74705SXin Li TryConsumeToken(tok::ellipsis, EllipsisLoc);
1932*67e74705SXin Li
1933*67e74705SXin Li // Find the complete source range for the base-specifier.
1934*67e74705SXin Li SourceRange Range(StartLoc, EndLocation);
1935*67e74705SXin Li
1936*67e74705SXin Li // Notify semantic analysis that we have parsed a complete
1937*67e74705SXin Li // base-specifier.
1938*67e74705SXin Li return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual,
1939*67e74705SXin Li Access, BaseType.get(), BaseLoc,
1940*67e74705SXin Li EllipsisLoc);
1941*67e74705SXin Li }
1942*67e74705SXin Li
1943*67e74705SXin Li /// getAccessSpecifierIfPresent - Determine whether the next token is
1944*67e74705SXin Li /// a C++ access-specifier.
1945*67e74705SXin Li ///
1946*67e74705SXin Li /// access-specifier: [C++ class.derived]
1947*67e74705SXin Li /// 'private'
1948*67e74705SXin Li /// 'protected'
1949*67e74705SXin Li /// 'public'
getAccessSpecifierIfPresent() const1950*67e74705SXin Li AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1951*67e74705SXin Li switch (Tok.getKind()) {
1952*67e74705SXin Li default: return AS_none;
1953*67e74705SXin Li case tok::kw_private: return AS_private;
1954*67e74705SXin Li case tok::kw_protected: return AS_protected;
1955*67e74705SXin Li case tok::kw_public: return AS_public;
1956*67e74705SXin Li }
1957*67e74705SXin Li }
1958*67e74705SXin Li
1959*67e74705SXin Li /// \brief If the given declarator has any parts for which parsing has to be
1960*67e74705SXin Li /// delayed, e.g., default arguments or an exception-specification, create a
1961*67e74705SXin Li /// late-parsed method declaration record to handle the parsing at the end of
1962*67e74705SXin Li /// the class definition.
HandleMemberFunctionDeclDelays(Declarator & DeclaratorInfo,Decl * ThisDecl)1963*67e74705SXin Li void Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
1964*67e74705SXin Li Decl *ThisDecl) {
1965*67e74705SXin Li DeclaratorChunk::FunctionTypeInfo &FTI
1966*67e74705SXin Li = DeclaratorInfo.getFunctionTypeInfo();
1967*67e74705SXin Li // If there was a late-parsed exception-specification, we'll need a
1968*67e74705SXin Li // late parse
1969*67e74705SXin Li bool NeedLateParse = FTI.getExceptionSpecType() == EST_Unparsed;
1970*67e74705SXin Li
1971*67e74705SXin Li if (!NeedLateParse) {
1972*67e74705SXin Li // Look ahead to see if there are any default args
1973*67e74705SXin Li for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) {
1974*67e74705SXin Li auto Param = cast<ParmVarDecl>(FTI.Params[ParamIdx].Param);
1975*67e74705SXin Li if (Param->hasUnparsedDefaultArg()) {
1976*67e74705SXin Li NeedLateParse = true;
1977*67e74705SXin Li break;
1978*67e74705SXin Li }
1979*67e74705SXin Li }
1980*67e74705SXin Li }
1981*67e74705SXin Li
1982*67e74705SXin Li if (NeedLateParse) {
1983*67e74705SXin Li // Push this method onto the stack of late-parsed method
1984*67e74705SXin Li // declarations.
1985*67e74705SXin Li auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
1986*67e74705SXin Li getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
1987*67e74705SXin Li LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
1988*67e74705SXin Li
1989*67e74705SXin Li // Stash the exception-specification tokens in the late-pased method.
1990*67e74705SXin Li LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens;
1991*67e74705SXin Li FTI.ExceptionSpecTokens = nullptr;
1992*67e74705SXin Li
1993*67e74705SXin Li // Push tokens for each parameter. Those that do not have
1994*67e74705SXin Li // defaults will be NULL.
1995*67e74705SXin Li LateMethod->DefaultArgs.reserve(FTI.NumParams);
1996*67e74705SXin Li for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx)
1997*67e74705SXin Li LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
1998*67e74705SXin Li FTI.Params[ParamIdx].Param, FTI.Params[ParamIdx].DefaultArgTokens));
1999*67e74705SXin Li }
2000*67e74705SXin Li }
2001*67e74705SXin Li
2002*67e74705SXin Li /// isCXX11VirtSpecifier - Determine whether the given token is a C++11
2003*67e74705SXin Li /// virt-specifier.
2004*67e74705SXin Li ///
2005*67e74705SXin Li /// virt-specifier:
2006*67e74705SXin Li /// override
2007*67e74705SXin Li /// final
isCXX11VirtSpecifier(const Token & Tok) const2008*67e74705SXin Li VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
2009*67e74705SXin Li if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier))
2010*67e74705SXin Li return VirtSpecifiers::VS_None;
2011*67e74705SXin Li
2012*67e74705SXin Li IdentifierInfo *II = Tok.getIdentifierInfo();
2013*67e74705SXin Li
2014*67e74705SXin Li // Initialize the contextual keywords.
2015*67e74705SXin Li if (!Ident_final) {
2016*67e74705SXin Li Ident_final = &PP.getIdentifierTable().get("final");
2017*67e74705SXin Li if (getLangOpts().MicrosoftExt)
2018*67e74705SXin Li Ident_sealed = &PP.getIdentifierTable().get("sealed");
2019*67e74705SXin Li Ident_override = &PP.getIdentifierTable().get("override");
2020*67e74705SXin Li }
2021*67e74705SXin Li
2022*67e74705SXin Li if (II == Ident_override)
2023*67e74705SXin Li return VirtSpecifiers::VS_Override;
2024*67e74705SXin Li
2025*67e74705SXin Li if (II == Ident_sealed)
2026*67e74705SXin Li return VirtSpecifiers::VS_Sealed;
2027*67e74705SXin Li
2028*67e74705SXin Li if (II == Ident_final)
2029*67e74705SXin Li return VirtSpecifiers::VS_Final;
2030*67e74705SXin Li
2031*67e74705SXin Li return VirtSpecifiers::VS_None;
2032*67e74705SXin Li }
2033*67e74705SXin Li
2034*67e74705SXin Li /// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq.
2035*67e74705SXin Li ///
2036*67e74705SXin Li /// virt-specifier-seq:
2037*67e74705SXin Li /// virt-specifier
2038*67e74705SXin Li /// virt-specifier-seq virt-specifier
ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers & VS,bool IsInterface,SourceLocation FriendLoc)2039*67e74705SXin Li void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
2040*67e74705SXin Li bool IsInterface,
2041*67e74705SXin Li SourceLocation FriendLoc) {
2042*67e74705SXin Li while (true) {
2043*67e74705SXin Li VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
2044*67e74705SXin Li if (Specifier == VirtSpecifiers::VS_None)
2045*67e74705SXin Li return;
2046*67e74705SXin Li
2047*67e74705SXin Li if (FriendLoc.isValid()) {
2048*67e74705SXin Li Diag(Tok.getLocation(), diag::err_friend_decl_spec)
2049*67e74705SXin Li << VirtSpecifiers::getSpecifierName(Specifier)
2050*67e74705SXin Li << FixItHint::CreateRemoval(Tok.getLocation())
2051*67e74705SXin Li << SourceRange(FriendLoc, FriendLoc);
2052*67e74705SXin Li ConsumeToken();
2053*67e74705SXin Li continue;
2054*67e74705SXin Li }
2055*67e74705SXin Li
2056*67e74705SXin Li // C++ [class.mem]p8:
2057*67e74705SXin Li // A virt-specifier-seq shall contain at most one of each virt-specifier.
2058*67e74705SXin Li const char *PrevSpec = nullptr;
2059*67e74705SXin Li if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
2060*67e74705SXin Li Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
2061*67e74705SXin Li << PrevSpec
2062*67e74705SXin Li << FixItHint::CreateRemoval(Tok.getLocation());
2063*67e74705SXin Li
2064*67e74705SXin Li if (IsInterface && (Specifier == VirtSpecifiers::VS_Final ||
2065*67e74705SXin Li Specifier == VirtSpecifiers::VS_Sealed)) {
2066*67e74705SXin Li Diag(Tok.getLocation(), diag::err_override_control_interface)
2067*67e74705SXin Li << VirtSpecifiers::getSpecifierName(Specifier);
2068*67e74705SXin Li } else if (Specifier == VirtSpecifiers::VS_Sealed) {
2069*67e74705SXin Li Diag(Tok.getLocation(), diag::ext_ms_sealed_keyword);
2070*67e74705SXin Li } else {
2071*67e74705SXin Li Diag(Tok.getLocation(),
2072*67e74705SXin Li getLangOpts().CPlusPlus11
2073*67e74705SXin Li ? diag::warn_cxx98_compat_override_control_keyword
2074*67e74705SXin Li : diag::ext_override_control_keyword)
2075*67e74705SXin Li << VirtSpecifiers::getSpecifierName(Specifier);
2076*67e74705SXin Li }
2077*67e74705SXin Li ConsumeToken();
2078*67e74705SXin Li }
2079*67e74705SXin Li }
2080*67e74705SXin Li
2081*67e74705SXin Li /// isCXX11FinalKeyword - Determine whether the next token is a C++11
2082*67e74705SXin Li /// 'final' or Microsoft 'sealed' contextual keyword.
isCXX11FinalKeyword() const2083*67e74705SXin Li bool Parser::isCXX11FinalKeyword() const {
2084*67e74705SXin Li VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
2085*67e74705SXin Li return Specifier == VirtSpecifiers::VS_Final ||
2086*67e74705SXin Li Specifier == VirtSpecifiers::VS_Sealed;
2087*67e74705SXin Li }
2088*67e74705SXin Li
2089*67e74705SXin Li /// \brief Parse a C++ member-declarator up to, but not including, the optional
2090*67e74705SXin Li /// brace-or-equal-initializer or pure-specifier.
ParseCXXMemberDeclaratorBeforeInitializer(Declarator & DeclaratorInfo,VirtSpecifiers & VS,ExprResult & BitfieldSize,LateParsedAttrList & LateParsedAttrs)2091*67e74705SXin Li bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
2092*67e74705SXin Li Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,
2093*67e74705SXin Li LateParsedAttrList &LateParsedAttrs) {
2094*67e74705SXin Li // member-declarator:
2095*67e74705SXin Li // declarator pure-specifier[opt]
2096*67e74705SXin Li // declarator brace-or-equal-initializer[opt]
2097*67e74705SXin Li // identifier[opt] ':' constant-expression
2098*67e74705SXin Li if (Tok.isNot(tok::colon))
2099*67e74705SXin Li ParseDeclarator(DeclaratorInfo);
2100*67e74705SXin Li else
2101*67e74705SXin Li DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
2102*67e74705SXin Li
2103*67e74705SXin Li if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {
2104*67e74705SXin Li assert(DeclaratorInfo.isPastIdentifier() &&
2105*67e74705SXin Li "don't know where identifier would go yet?");
2106*67e74705SXin Li BitfieldSize = ParseConstantExpression();
2107*67e74705SXin Li if (BitfieldSize.isInvalid())
2108*67e74705SXin Li SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
2109*67e74705SXin Li } else {
2110*67e74705SXin Li ParseOptionalCXX11VirtSpecifierSeq(
2111*67e74705SXin Li VS, getCurrentClass().IsInterface,
2112*67e74705SXin Li DeclaratorInfo.getDeclSpec().getFriendSpecLoc());
2113*67e74705SXin Li if (!VS.isUnset())
2114*67e74705SXin Li MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS);
2115*67e74705SXin Li }
2116*67e74705SXin Li
2117*67e74705SXin Li // If a simple-asm-expr is present, parse it.
2118*67e74705SXin Li if (Tok.is(tok::kw_asm)) {
2119*67e74705SXin Li SourceLocation Loc;
2120*67e74705SXin Li ExprResult AsmLabel(ParseSimpleAsm(&Loc));
2121*67e74705SXin Li if (AsmLabel.isInvalid())
2122*67e74705SXin Li SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
2123*67e74705SXin Li
2124*67e74705SXin Li DeclaratorInfo.setAsmLabel(AsmLabel.get());
2125*67e74705SXin Li DeclaratorInfo.SetRangeEnd(Loc);
2126*67e74705SXin Li }
2127*67e74705SXin Li
2128*67e74705SXin Li // If attributes exist after the declarator, but before an '{', parse them.
2129*67e74705SXin Li MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
2130*67e74705SXin Li
2131*67e74705SXin Li // For compatibility with code written to older Clang, also accept a
2132*67e74705SXin Li // virt-specifier *after* the GNU attributes.
2133*67e74705SXin Li if (BitfieldSize.isUnset() && VS.isUnset()) {
2134*67e74705SXin Li ParseOptionalCXX11VirtSpecifierSeq(
2135*67e74705SXin Li VS, getCurrentClass().IsInterface,
2136*67e74705SXin Li DeclaratorInfo.getDeclSpec().getFriendSpecLoc());
2137*67e74705SXin Li if (!VS.isUnset()) {
2138*67e74705SXin Li // If we saw any GNU-style attributes that are known to GCC followed by a
2139*67e74705SXin Li // virt-specifier, issue a GCC-compat warning.
2140*67e74705SXin Li const AttributeList *Attr = DeclaratorInfo.getAttributes();
2141*67e74705SXin Li while (Attr) {
2142*67e74705SXin Li if (Attr->isKnownToGCC() && !Attr->isCXX11Attribute())
2143*67e74705SXin Li Diag(Attr->getLoc(), diag::warn_gcc_attribute_location);
2144*67e74705SXin Li Attr = Attr->getNext();
2145*67e74705SXin Li }
2146*67e74705SXin Li MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS);
2147*67e74705SXin Li }
2148*67e74705SXin Li }
2149*67e74705SXin Li
2150*67e74705SXin Li // If this has neither a name nor a bit width, something has gone seriously
2151*67e74705SXin Li // wrong. Skip until the semi-colon or }.
2152*67e74705SXin Li if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {
2153*67e74705SXin Li // If so, skip until the semi-colon or a }.
2154*67e74705SXin Li SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
2155*67e74705SXin Li return true;
2156*67e74705SXin Li }
2157*67e74705SXin Li return false;
2158*67e74705SXin Li }
2159*67e74705SXin Li
2160*67e74705SXin Li /// \brief Look for declaration specifiers possibly occurring after C++11
2161*67e74705SXin Li /// virt-specifier-seq and diagnose them.
MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator & D,VirtSpecifiers & VS)2162*67e74705SXin Li void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
2163*67e74705SXin Li Declarator &D,
2164*67e74705SXin Li VirtSpecifiers &VS) {
2165*67e74705SXin Li DeclSpec DS(AttrFactory);
2166*67e74705SXin Li
2167*67e74705SXin Li // GNU-style and C++11 attributes are not allowed here, but they will be
2168*67e74705SXin Li // handled by the caller. Diagnose everything else.
2169*67e74705SXin Li ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed, false);
2170*67e74705SXin Li D.ExtendWithDeclSpec(DS);
2171*67e74705SXin Li
2172*67e74705SXin Li if (D.isFunctionDeclarator()) {
2173*67e74705SXin Li auto &Function = D.getFunctionTypeInfo();
2174*67e74705SXin Li if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
2175*67e74705SXin Li auto DeclSpecCheck = [&] (DeclSpec::TQ TypeQual,
2176*67e74705SXin Li const char *FixItName,
2177*67e74705SXin Li SourceLocation SpecLoc,
2178*67e74705SXin Li unsigned* QualifierLoc) {
2179*67e74705SXin Li FixItHint Insertion;
2180*67e74705SXin Li if (DS.getTypeQualifiers() & TypeQual) {
2181*67e74705SXin Li if (!(Function.TypeQuals & TypeQual)) {
2182*67e74705SXin Li std::string Name(FixItName);
2183*67e74705SXin Li Name += " ";
2184*67e74705SXin Li Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name.c_str());
2185*67e74705SXin Li Function.TypeQuals |= TypeQual;
2186*67e74705SXin Li *QualifierLoc = SpecLoc.getRawEncoding();
2187*67e74705SXin Li }
2188*67e74705SXin Li Diag(SpecLoc, diag::err_declspec_after_virtspec)
2189*67e74705SXin Li << FixItName
2190*67e74705SXin Li << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
2191*67e74705SXin Li << FixItHint::CreateRemoval(SpecLoc)
2192*67e74705SXin Li << Insertion;
2193*67e74705SXin Li }
2194*67e74705SXin Li };
2195*67e74705SXin Li DeclSpecCheck(DeclSpec::TQ_const, "const", DS.getConstSpecLoc(),
2196*67e74705SXin Li &Function.ConstQualifierLoc);
2197*67e74705SXin Li DeclSpecCheck(DeclSpec::TQ_volatile, "volatile", DS.getVolatileSpecLoc(),
2198*67e74705SXin Li &Function.VolatileQualifierLoc);
2199*67e74705SXin Li DeclSpecCheck(DeclSpec::TQ_restrict, "restrict", DS.getRestrictSpecLoc(),
2200*67e74705SXin Li &Function.RestrictQualifierLoc);
2201*67e74705SXin Li }
2202*67e74705SXin Li
2203*67e74705SXin Li // Parse ref-qualifiers.
2204*67e74705SXin Li bool RefQualifierIsLValueRef = true;
2205*67e74705SXin Li SourceLocation RefQualifierLoc;
2206*67e74705SXin Li if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
2207*67e74705SXin Li const char *Name = (RefQualifierIsLValueRef ? "& " : "&& ");
2208*67e74705SXin Li FixItHint Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name);
2209*67e74705SXin Li Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
2210*67e74705SXin Li Function.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
2211*67e74705SXin Li
2212*67e74705SXin Li Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
2213*67e74705SXin Li << (RefQualifierIsLValueRef ? "&" : "&&")
2214*67e74705SXin Li << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
2215*67e74705SXin Li << FixItHint::CreateRemoval(RefQualifierLoc)
2216*67e74705SXin Li << Insertion;
2217*67e74705SXin Li D.SetRangeEnd(RefQualifierLoc);
2218*67e74705SXin Li }
2219*67e74705SXin Li }
2220*67e74705SXin Li }
2221*67e74705SXin Li
2222*67e74705SXin Li /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
2223*67e74705SXin Li ///
2224*67e74705SXin Li /// member-declaration:
2225*67e74705SXin Li /// decl-specifier-seq[opt] member-declarator-list[opt] ';'
2226*67e74705SXin Li /// function-definition ';'[opt]
2227*67e74705SXin Li /// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
2228*67e74705SXin Li /// using-declaration [TODO]
2229*67e74705SXin Li /// [C++0x] static_assert-declaration
2230*67e74705SXin Li /// template-declaration
2231*67e74705SXin Li /// [GNU] '__extension__' member-declaration
2232*67e74705SXin Li ///
2233*67e74705SXin Li /// member-declarator-list:
2234*67e74705SXin Li /// member-declarator
2235*67e74705SXin Li /// member-declarator-list ',' member-declarator
2236*67e74705SXin Li ///
2237*67e74705SXin Li /// member-declarator:
2238*67e74705SXin Li /// declarator virt-specifier-seq[opt] pure-specifier[opt]
2239*67e74705SXin Li /// declarator constant-initializer[opt]
2240*67e74705SXin Li /// [C++11] declarator brace-or-equal-initializer[opt]
2241*67e74705SXin Li /// identifier[opt] ':' constant-expression
2242*67e74705SXin Li ///
2243*67e74705SXin Li /// virt-specifier-seq:
2244*67e74705SXin Li /// virt-specifier
2245*67e74705SXin Li /// virt-specifier-seq virt-specifier
2246*67e74705SXin Li ///
2247*67e74705SXin Li /// virt-specifier:
2248*67e74705SXin Li /// override
2249*67e74705SXin Li /// final
2250*67e74705SXin Li /// [MS] sealed
2251*67e74705SXin Li ///
2252*67e74705SXin Li /// pure-specifier:
2253*67e74705SXin Li /// '= 0'
2254*67e74705SXin Li ///
2255*67e74705SXin Li /// constant-initializer:
2256*67e74705SXin Li /// '=' constant-expression
2257*67e74705SXin Li ///
2258*67e74705SXin Li Parser::DeclGroupPtrTy
ParseCXXClassMemberDeclaration(AccessSpecifier AS,AttributeList * AccessAttrs,const ParsedTemplateInfo & TemplateInfo,ParsingDeclRAIIObject * TemplateDiags)2259*67e74705SXin Li Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
2260*67e74705SXin Li AttributeList *AccessAttrs,
2261*67e74705SXin Li const ParsedTemplateInfo &TemplateInfo,
2262*67e74705SXin Li ParsingDeclRAIIObject *TemplateDiags) {
2263*67e74705SXin Li if (Tok.is(tok::at)) {
2264*67e74705SXin Li if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
2265*67e74705SXin Li Diag(Tok, diag::err_at_defs_cxx);
2266*67e74705SXin Li else
2267*67e74705SXin Li Diag(Tok, diag::err_at_in_class);
2268*67e74705SXin Li
2269*67e74705SXin Li ConsumeToken();
2270*67e74705SXin Li SkipUntil(tok::r_brace, StopAtSemi);
2271*67e74705SXin Li return nullptr;
2272*67e74705SXin Li }
2273*67e74705SXin Li
2274*67e74705SXin Li // Turn on colon protection early, while parsing declspec, although there is
2275*67e74705SXin Li // nothing to protect there. It prevents from false errors if error recovery
2276*67e74705SXin Li // incorrectly determines where the declspec ends, as in the example:
2277*67e74705SXin Li // struct A { enum class B { C }; };
2278*67e74705SXin Li // const int C = 4;
2279*67e74705SXin Li // struct D { A::B : C; };
2280*67e74705SXin Li ColonProtectionRAIIObject X(*this);
2281*67e74705SXin Li
2282*67e74705SXin Li // Access declarations.
2283*67e74705SXin Li bool MalformedTypeSpec = false;
2284*67e74705SXin Li if (!TemplateInfo.Kind &&
2285*67e74705SXin Li Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {
2286*67e74705SXin Li if (TryAnnotateCXXScopeToken())
2287*67e74705SXin Li MalformedTypeSpec = true;
2288*67e74705SXin Li
2289*67e74705SXin Li bool isAccessDecl;
2290*67e74705SXin Li if (Tok.isNot(tok::annot_cxxscope))
2291*67e74705SXin Li isAccessDecl = false;
2292*67e74705SXin Li else if (NextToken().is(tok::identifier))
2293*67e74705SXin Li isAccessDecl = GetLookAheadToken(2).is(tok::semi);
2294*67e74705SXin Li else
2295*67e74705SXin Li isAccessDecl = NextToken().is(tok::kw_operator);
2296*67e74705SXin Li
2297*67e74705SXin Li if (isAccessDecl) {
2298*67e74705SXin Li // Collect the scope specifier token we annotated earlier.
2299*67e74705SXin Li CXXScopeSpec SS;
2300*67e74705SXin Li ParseOptionalCXXScopeSpecifier(SS, nullptr,
2301*67e74705SXin Li /*EnteringContext=*/false);
2302*67e74705SXin Li
2303*67e74705SXin Li if (SS.isInvalid()) {
2304*67e74705SXin Li SkipUntil(tok::semi);
2305*67e74705SXin Li return nullptr;
2306*67e74705SXin Li }
2307*67e74705SXin Li
2308*67e74705SXin Li // Try to parse an unqualified-id.
2309*67e74705SXin Li SourceLocation TemplateKWLoc;
2310*67e74705SXin Li UnqualifiedId Name;
2311*67e74705SXin Li if (ParseUnqualifiedId(SS, false, true, true, nullptr, TemplateKWLoc,
2312*67e74705SXin Li Name)) {
2313*67e74705SXin Li SkipUntil(tok::semi);
2314*67e74705SXin Li return nullptr;
2315*67e74705SXin Li }
2316*67e74705SXin Li
2317*67e74705SXin Li // TODO: recover from mistakenly-qualified operator declarations.
2318*67e74705SXin Li if (ExpectAndConsume(tok::semi, diag::err_expected_after,
2319*67e74705SXin Li "access declaration")) {
2320*67e74705SXin Li SkipUntil(tok::semi);
2321*67e74705SXin Li return nullptr;
2322*67e74705SXin Li }
2323*67e74705SXin Li
2324*67e74705SXin Li return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration(
2325*67e74705SXin Li getCurScope(), AS,
2326*67e74705SXin Li /* HasUsingKeyword */ false, SourceLocation(), SS, Name,
2327*67e74705SXin Li /* AttrList */ nullptr,
2328*67e74705SXin Li /* HasTypenameKeyword */ false, SourceLocation())));
2329*67e74705SXin Li }
2330*67e74705SXin Li }
2331*67e74705SXin Li
2332*67e74705SXin Li // static_assert-declaration. A templated static_assert declaration is
2333*67e74705SXin Li // diagnosed in Parser::ParseSingleDeclarationAfterTemplate.
2334*67e74705SXin Li if (!TemplateInfo.Kind &&
2335*67e74705SXin Li Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2336*67e74705SXin Li SourceLocation DeclEnd;
2337*67e74705SXin Li return DeclGroupPtrTy::make(
2338*67e74705SXin Li DeclGroupRef(ParseStaticAssertDeclaration(DeclEnd)));
2339*67e74705SXin Li }
2340*67e74705SXin Li
2341*67e74705SXin Li if (Tok.is(tok::kw_template)) {
2342*67e74705SXin Li assert(!TemplateInfo.TemplateParams &&
2343*67e74705SXin Li "Nested template improperly parsed?");
2344*67e74705SXin Li SourceLocation DeclEnd;
2345*67e74705SXin Li return DeclGroupPtrTy::make(
2346*67e74705SXin Li DeclGroupRef(ParseDeclarationStartingWithTemplate(
2347*67e74705SXin Li Declarator::MemberContext, DeclEnd, AS, AccessAttrs)));
2348*67e74705SXin Li }
2349*67e74705SXin Li
2350*67e74705SXin Li // Handle: member-declaration ::= '__extension__' member-declaration
2351*67e74705SXin Li if (Tok.is(tok::kw___extension__)) {
2352*67e74705SXin Li // __extension__ silences extension warnings in the subexpression.
2353*67e74705SXin Li ExtensionRAIIObject O(Diags); // Use RAII to do this.
2354*67e74705SXin Li ConsumeToken();
2355*67e74705SXin Li return ParseCXXClassMemberDeclaration(AS, AccessAttrs,
2356*67e74705SXin Li TemplateInfo, TemplateDiags);
2357*67e74705SXin Li }
2358*67e74705SXin Li
2359*67e74705SXin Li ParsedAttributesWithRange attrs(AttrFactory);
2360*67e74705SXin Li ParsedAttributesWithRange FnAttrs(AttrFactory);
2361*67e74705SXin Li // Optional C++11 attribute-specifier
2362*67e74705SXin Li MaybeParseCXX11Attributes(attrs);
2363*67e74705SXin Li // We need to keep these attributes for future diagnostic
2364*67e74705SXin Li // before they are taken over by declaration specifier.
2365*67e74705SXin Li FnAttrs.addAll(attrs.getList());
2366*67e74705SXin Li FnAttrs.Range = attrs.Range;
2367*67e74705SXin Li
2368*67e74705SXin Li MaybeParseMicrosoftAttributes(attrs);
2369*67e74705SXin Li
2370*67e74705SXin Li if (Tok.is(tok::kw_using)) {
2371*67e74705SXin Li ProhibitAttributes(attrs);
2372*67e74705SXin Li
2373*67e74705SXin Li // Eat 'using'.
2374*67e74705SXin Li SourceLocation UsingLoc = ConsumeToken();
2375*67e74705SXin Li
2376*67e74705SXin Li if (Tok.is(tok::kw_namespace)) {
2377*67e74705SXin Li Diag(UsingLoc, diag::err_using_namespace_in_class);
2378*67e74705SXin Li SkipUntil(tok::semi, StopBeforeMatch);
2379*67e74705SXin Li return nullptr;
2380*67e74705SXin Li }
2381*67e74705SXin Li SourceLocation DeclEnd;
2382*67e74705SXin Li // Otherwise, it must be a using-declaration or an alias-declaration.
2383*67e74705SXin Li return DeclGroupPtrTy::make(DeclGroupRef(ParseUsingDeclaration(
2384*67e74705SXin Li Declarator::MemberContext, TemplateInfo, UsingLoc, DeclEnd, AS)));
2385*67e74705SXin Li }
2386*67e74705SXin Li
2387*67e74705SXin Li // Hold late-parsed attributes so we can attach a Decl to them later.
2388*67e74705SXin Li LateParsedAttrList CommonLateParsedAttrs;
2389*67e74705SXin Li
2390*67e74705SXin Li // decl-specifier-seq:
2391*67e74705SXin Li // Parse the common declaration-specifiers piece.
2392*67e74705SXin Li ParsingDeclSpec DS(*this, TemplateDiags);
2393*67e74705SXin Li DS.takeAttributesFrom(attrs);
2394*67e74705SXin Li if (MalformedTypeSpec)
2395*67e74705SXin Li DS.SetTypeSpecError();
2396*67e74705SXin Li
2397*67e74705SXin Li ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
2398*67e74705SXin Li &CommonLateParsedAttrs);
2399*67e74705SXin Li
2400*67e74705SXin Li // Turn off colon protection that was set for declspec.
2401*67e74705SXin Li X.restore();
2402*67e74705SXin Li
2403*67e74705SXin Li // If we had a free-standing type definition with a missing semicolon, we
2404*67e74705SXin Li // may get this far before the problem becomes obvious.
2405*67e74705SXin Li if (DS.hasTagDefinition() &&
2406*67e74705SXin Li TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
2407*67e74705SXin Li DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_class,
2408*67e74705SXin Li &CommonLateParsedAttrs))
2409*67e74705SXin Li return nullptr;
2410*67e74705SXin Li
2411*67e74705SXin Li MultiTemplateParamsArg TemplateParams(
2412*67e74705SXin Li TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data()
2413*67e74705SXin Li : nullptr,
2414*67e74705SXin Li TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
2415*67e74705SXin Li
2416*67e74705SXin Li if (TryConsumeToken(tok::semi)) {
2417*67e74705SXin Li if (DS.isFriendSpecified())
2418*67e74705SXin Li ProhibitAttributes(FnAttrs);
2419*67e74705SXin Li
2420*67e74705SXin Li RecordDecl *AnonRecord = nullptr;
2421*67e74705SXin Li Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
2422*67e74705SXin Li getCurScope(), AS, DS, TemplateParams, false, AnonRecord);
2423*67e74705SXin Li DS.complete(TheDecl);
2424*67e74705SXin Li if (AnonRecord) {
2425*67e74705SXin Li Decl* decls[] = {AnonRecord, TheDecl};
2426*67e74705SXin Li return Actions.BuildDeclaratorGroup(decls, /*TypeMayContainAuto=*/false);
2427*67e74705SXin Li }
2428*67e74705SXin Li return Actions.ConvertDeclToDeclGroup(TheDecl);
2429*67e74705SXin Li }
2430*67e74705SXin Li
2431*67e74705SXin Li ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
2432*67e74705SXin Li VirtSpecifiers VS;
2433*67e74705SXin Li
2434*67e74705SXin Li // Hold late-parsed attributes so we can attach a Decl to them later.
2435*67e74705SXin Li LateParsedAttrList LateParsedAttrs;
2436*67e74705SXin Li
2437*67e74705SXin Li SourceLocation EqualLoc;
2438*67e74705SXin Li SourceLocation PureSpecLoc;
2439*67e74705SXin Li
2440*67e74705SXin Li auto TryConsumePureSpecifier = [&] (bool AllowDefinition) {
2441*67e74705SXin Li if (Tok.isNot(tok::equal))
2442*67e74705SXin Li return false;
2443*67e74705SXin Li
2444*67e74705SXin Li auto &Zero = NextToken();
2445*67e74705SXin Li SmallString<8> Buffer;
2446*67e74705SXin Li if (Zero.isNot(tok::numeric_constant) || Zero.getLength() != 1 ||
2447*67e74705SXin Li PP.getSpelling(Zero, Buffer) != "0")
2448*67e74705SXin Li return false;
2449*67e74705SXin Li
2450*67e74705SXin Li auto &After = GetLookAheadToken(2);
2451*67e74705SXin Li if (!After.isOneOf(tok::semi, tok::comma) &&
2452*67e74705SXin Li !(AllowDefinition &&
2453*67e74705SXin Li After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))
2454*67e74705SXin Li return false;
2455*67e74705SXin Li
2456*67e74705SXin Li EqualLoc = ConsumeToken();
2457*67e74705SXin Li PureSpecLoc = ConsumeToken();
2458*67e74705SXin Li return true;
2459*67e74705SXin Li };
2460*67e74705SXin Li
2461*67e74705SXin Li SmallVector<Decl *, 8> DeclsInGroup;
2462*67e74705SXin Li ExprResult BitfieldSize;
2463*67e74705SXin Li bool ExpectSemi = true;
2464*67e74705SXin Li
2465*67e74705SXin Li // Parse the first declarator.
2466*67e74705SXin Li if (ParseCXXMemberDeclaratorBeforeInitializer(
2467*67e74705SXin Li DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {
2468*67e74705SXin Li TryConsumeToken(tok::semi);
2469*67e74705SXin Li return nullptr;
2470*67e74705SXin Li }
2471*67e74705SXin Li
2472*67e74705SXin Li // Check for a member function definition.
2473*67e74705SXin Li if (BitfieldSize.isUnset()) {
2474*67e74705SXin Li // MSVC permits pure specifier on inline functions defined at class scope.
2475*67e74705SXin Li // Hence check for =0 before checking for function definition.
2476*67e74705SXin Li if (getLangOpts().MicrosoftExt && DeclaratorInfo.isDeclarationOfFunction())
2477*67e74705SXin Li TryConsumePureSpecifier(/*AllowDefinition*/ true);
2478*67e74705SXin Li
2479*67e74705SXin Li FunctionDefinitionKind DefinitionKind = FDK_Declaration;
2480*67e74705SXin Li // function-definition:
2481*67e74705SXin Li //
2482*67e74705SXin Li // In C++11, a non-function declarator followed by an open brace is a
2483*67e74705SXin Li // braced-init-list for an in-class member initialization, not an
2484*67e74705SXin Li // erroneous function definition.
2485*67e74705SXin Li if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) {
2486*67e74705SXin Li DefinitionKind = FDK_Definition;
2487*67e74705SXin Li } else if (DeclaratorInfo.isFunctionDeclarator()) {
2488*67e74705SXin Li if (Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {
2489*67e74705SXin Li DefinitionKind = FDK_Definition;
2490*67e74705SXin Li } else if (Tok.is(tok::equal)) {
2491*67e74705SXin Li const Token &KW = NextToken();
2492*67e74705SXin Li if (KW.is(tok::kw_default))
2493*67e74705SXin Li DefinitionKind = FDK_Defaulted;
2494*67e74705SXin Li else if (KW.is(tok::kw_delete))
2495*67e74705SXin Li DefinitionKind = FDK_Deleted;
2496*67e74705SXin Li }
2497*67e74705SXin Li }
2498*67e74705SXin Li DeclaratorInfo.setFunctionDefinitionKind(DefinitionKind);
2499*67e74705SXin Li
2500*67e74705SXin Li // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
2501*67e74705SXin Li // to a friend declaration, that declaration shall be a definition.
2502*67e74705SXin Li if (DeclaratorInfo.isFunctionDeclarator() &&
2503*67e74705SXin Li DefinitionKind != FDK_Definition && DS.isFriendSpecified()) {
2504*67e74705SXin Li // Diagnose attributes that appear before decl specifier:
2505*67e74705SXin Li // [[]] friend int foo();
2506*67e74705SXin Li ProhibitAttributes(FnAttrs);
2507*67e74705SXin Li }
2508*67e74705SXin Li
2509*67e74705SXin Li if (DefinitionKind != FDK_Declaration) {
2510*67e74705SXin Li if (!DeclaratorInfo.isFunctionDeclarator()) {
2511*67e74705SXin Li Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
2512*67e74705SXin Li ConsumeBrace();
2513*67e74705SXin Li SkipUntil(tok::r_brace);
2514*67e74705SXin Li
2515*67e74705SXin Li // Consume the optional ';'
2516*67e74705SXin Li TryConsumeToken(tok::semi);
2517*67e74705SXin Li
2518*67e74705SXin Li return nullptr;
2519*67e74705SXin Li }
2520*67e74705SXin Li
2521*67e74705SXin Li if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
2522*67e74705SXin Li Diag(DeclaratorInfo.getIdentifierLoc(),
2523*67e74705SXin Li diag::err_function_declared_typedef);
2524*67e74705SXin Li
2525*67e74705SXin Li // Recover by treating the 'typedef' as spurious.
2526*67e74705SXin Li DS.ClearStorageClassSpecs();
2527*67e74705SXin Li }
2528*67e74705SXin Li
2529*67e74705SXin Li Decl *FunDecl =
2530*67e74705SXin Li ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo,
2531*67e74705SXin Li VS, PureSpecLoc);
2532*67e74705SXin Li
2533*67e74705SXin Li if (FunDecl) {
2534*67e74705SXin Li for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
2535*67e74705SXin Li CommonLateParsedAttrs[i]->addDecl(FunDecl);
2536*67e74705SXin Li }
2537*67e74705SXin Li for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
2538*67e74705SXin Li LateParsedAttrs[i]->addDecl(FunDecl);
2539*67e74705SXin Li }
2540*67e74705SXin Li }
2541*67e74705SXin Li LateParsedAttrs.clear();
2542*67e74705SXin Li
2543*67e74705SXin Li // Consume the ';' - it's optional unless we have a delete or default
2544*67e74705SXin Li if (Tok.is(tok::semi))
2545*67e74705SXin Li ConsumeExtraSemi(AfterMemberFunctionDefinition);
2546*67e74705SXin Li
2547*67e74705SXin Li return DeclGroupPtrTy::make(DeclGroupRef(FunDecl));
2548*67e74705SXin Li }
2549*67e74705SXin Li }
2550*67e74705SXin Li
2551*67e74705SXin Li // member-declarator-list:
2552*67e74705SXin Li // member-declarator
2553*67e74705SXin Li // member-declarator-list ',' member-declarator
2554*67e74705SXin Li
2555*67e74705SXin Li while (1) {
2556*67e74705SXin Li InClassInitStyle HasInClassInit = ICIS_NoInit;
2557*67e74705SXin Li bool HasStaticInitializer = false;
2558*67e74705SXin Li if (Tok.isOneOf(tok::equal, tok::l_brace) && PureSpecLoc.isInvalid()) {
2559*67e74705SXin Li if (BitfieldSize.get()) {
2560*67e74705SXin Li Diag(Tok, diag::err_bitfield_member_init);
2561*67e74705SXin Li SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
2562*67e74705SXin Li } else if (DeclaratorInfo.isDeclarationOfFunction()) {
2563*67e74705SXin Li // It's a pure-specifier.
2564*67e74705SXin Li if (!TryConsumePureSpecifier(/*AllowFunctionDefinition*/ false))
2565*67e74705SXin Li // Parse it as an expression so that Sema can diagnose it.
2566*67e74705SXin Li HasStaticInitializer = true;
2567*67e74705SXin Li } else if (DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
2568*67e74705SXin Li DeclSpec::SCS_static &&
2569*67e74705SXin Li DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
2570*67e74705SXin Li DeclSpec::SCS_typedef &&
2571*67e74705SXin Li !DS.isFriendSpecified()) {
2572*67e74705SXin Li // It's a default member initializer.
2573*67e74705SXin Li HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit;
2574*67e74705SXin Li } else {
2575*67e74705SXin Li HasStaticInitializer = true;
2576*67e74705SXin Li }
2577*67e74705SXin Li }
2578*67e74705SXin Li
2579*67e74705SXin Li // NOTE: If Sema is the Action module and declarator is an instance field,
2580*67e74705SXin Li // this call will *not* return the created decl; It will return null.
2581*67e74705SXin Li // See Sema::ActOnCXXMemberDeclarator for details.
2582*67e74705SXin Li
2583*67e74705SXin Li NamedDecl *ThisDecl = nullptr;
2584*67e74705SXin Li if (DS.isFriendSpecified()) {
2585*67e74705SXin Li // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
2586*67e74705SXin Li // to a friend declaration, that declaration shall be a definition.
2587*67e74705SXin Li //
2588*67e74705SXin Li // Diagnose attributes that appear in a friend member function declarator:
2589*67e74705SXin Li // friend int foo [[]] ();
2590*67e74705SXin Li SmallVector<SourceRange, 4> Ranges;
2591*67e74705SXin Li DeclaratorInfo.getCXX11AttributeRanges(Ranges);
2592*67e74705SXin Li for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(),
2593*67e74705SXin Li E = Ranges.end(); I != E; ++I)
2594*67e74705SXin Li Diag((*I).getBegin(), diag::err_attributes_not_allowed) << *I;
2595*67e74705SXin Li
2596*67e74705SXin Li ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
2597*67e74705SXin Li TemplateParams);
2598*67e74705SXin Li } else {
2599*67e74705SXin Li ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
2600*67e74705SXin Li DeclaratorInfo,
2601*67e74705SXin Li TemplateParams,
2602*67e74705SXin Li BitfieldSize.get(),
2603*67e74705SXin Li VS, HasInClassInit);
2604*67e74705SXin Li
2605*67e74705SXin Li if (VarTemplateDecl *VT =
2606*67e74705SXin Li ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : nullptr)
2607*67e74705SXin Li // Re-direct this decl to refer to the templated decl so that we can
2608*67e74705SXin Li // initialize it.
2609*67e74705SXin Li ThisDecl = VT->getTemplatedDecl();
2610*67e74705SXin Li
2611*67e74705SXin Li if (ThisDecl && AccessAttrs)
2612*67e74705SXin Li Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
2613*67e74705SXin Li }
2614*67e74705SXin Li
2615*67e74705SXin Li // Error recovery might have converted a non-static member into a static
2616*67e74705SXin Li // member.
2617*67e74705SXin Li if (HasInClassInit != ICIS_NoInit &&
2618*67e74705SXin Li DeclaratorInfo.getDeclSpec().getStorageClassSpec() ==
2619*67e74705SXin Li DeclSpec::SCS_static) {
2620*67e74705SXin Li HasInClassInit = ICIS_NoInit;
2621*67e74705SXin Li HasStaticInitializer = true;
2622*67e74705SXin Li }
2623*67e74705SXin Li
2624*67e74705SXin Li if (ThisDecl && PureSpecLoc.isValid())
2625*67e74705SXin Li Actions.ActOnPureSpecifier(ThisDecl, PureSpecLoc);
2626*67e74705SXin Li
2627*67e74705SXin Li // Handle the initializer.
2628*67e74705SXin Li if (HasInClassInit != ICIS_NoInit) {
2629*67e74705SXin Li // The initializer was deferred; parse it and cache the tokens.
2630*67e74705SXin Li Diag(Tok, getLangOpts().CPlusPlus11
2631*67e74705SXin Li ? diag::warn_cxx98_compat_nonstatic_member_init
2632*67e74705SXin Li : diag::ext_nonstatic_member_init);
2633*67e74705SXin Li
2634*67e74705SXin Li if (DeclaratorInfo.isArrayOfUnknownBound()) {
2635*67e74705SXin Li // C++11 [dcl.array]p3: An array bound may also be omitted when the
2636*67e74705SXin Li // declarator is followed by an initializer.
2637*67e74705SXin Li //
2638*67e74705SXin Li // A brace-or-equal-initializer for a member-declarator is not an
2639*67e74705SXin Li // initializer in the grammar, so this is ill-formed.
2640*67e74705SXin Li Diag(Tok, diag::err_incomplete_array_member_init);
2641*67e74705SXin Li SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
2642*67e74705SXin Li
2643*67e74705SXin Li // Avoid later warnings about a class member of incomplete type.
2644*67e74705SXin Li if (ThisDecl)
2645*67e74705SXin Li ThisDecl->setInvalidDecl();
2646*67e74705SXin Li } else
2647*67e74705SXin Li ParseCXXNonStaticMemberInitializer(ThisDecl);
2648*67e74705SXin Li } else if (HasStaticInitializer) {
2649*67e74705SXin Li // Normal initializer.
2650*67e74705SXin Li ExprResult Init = ParseCXXMemberInitializer(
2651*67e74705SXin Li ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
2652*67e74705SXin Li
2653*67e74705SXin Li if (Init.isInvalid())
2654*67e74705SXin Li SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
2655*67e74705SXin Li else if (ThisDecl)
2656*67e74705SXin Li Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
2657*67e74705SXin Li DS.containsPlaceholderType());
2658*67e74705SXin Li } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static)
2659*67e74705SXin Li // No initializer.
2660*67e74705SXin Li Actions.ActOnUninitializedDecl(ThisDecl, DS.containsPlaceholderType());
2661*67e74705SXin Li
2662*67e74705SXin Li if (ThisDecl) {
2663*67e74705SXin Li if (!ThisDecl->isInvalidDecl()) {
2664*67e74705SXin Li // Set the Decl for any late parsed attributes
2665*67e74705SXin Li for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
2666*67e74705SXin Li CommonLateParsedAttrs[i]->addDecl(ThisDecl);
2667*67e74705SXin Li
2668*67e74705SXin Li for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
2669*67e74705SXin Li LateParsedAttrs[i]->addDecl(ThisDecl);
2670*67e74705SXin Li }
2671*67e74705SXin Li Actions.FinalizeDeclaration(ThisDecl);
2672*67e74705SXin Li DeclsInGroup.push_back(ThisDecl);
2673*67e74705SXin Li
2674*67e74705SXin Li if (DeclaratorInfo.isFunctionDeclarator() &&
2675*67e74705SXin Li DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
2676*67e74705SXin Li DeclSpec::SCS_typedef)
2677*67e74705SXin Li HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
2678*67e74705SXin Li }
2679*67e74705SXin Li LateParsedAttrs.clear();
2680*67e74705SXin Li
2681*67e74705SXin Li DeclaratorInfo.complete(ThisDecl);
2682*67e74705SXin Li
2683*67e74705SXin Li // If we don't have a comma, it is either the end of the list (a ';')
2684*67e74705SXin Li // or an error, bail out.
2685*67e74705SXin Li SourceLocation CommaLoc;
2686*67e74705SXin Li if (!TryConsumeToken(tok::comma, CommaLoc))
2687*67e74705SXin Li break;
2688*67e74705SXin Li
2689*67e74705SXin Li if (Tok.isAtStartOfLine() &&
2690*67e74705SXin Li !MightBeDeclarator(Declarator::MemberContext)) {
2691*67e74705SXin Li // This comma was followed by a line-break and something which can't be
2692*67e74705SXin Li // the start of a declarator. The comma was probably a typo for a
2693*67e74705SXin Li // semicolon.
2694*67e74705SXin Li Diag(CommaLoc, diag::err_expected_semi_declaration)
2695*67e74705SXin Li << FixItHint::CreateReplacement(CommaLoc, ";");
2696*67e74705SXin Li ExpectSemi = false;
2697*67e74705SXin Li break;
2698*67e74705SXin Li }
2699*67e74705SXin Li
2700*67e74705SXin Li // Parse the next declarator.
2701*67e74705SXin Li DeclaratorInfo.clear();
2702*67e74705SXin Li VS.clear();
2703*67e74705SXin Li BitfieldSize = ExprResult(/*Invalid=*/false);
2704*67e74705SXin Li EqualLoc = PureSpecLoc = SourceLocation();
2705*67e74705SXin Li DeclaratorInfo.setCommaLoc(CommaLoc);
2706*67e74705SXin Li
2707*67e74705SXin Li // GNU attributes are allowed before the second and subsequent declarator.
2708*67e74705SXin Li MaybeParseGNUAttributes(DeclaratorInfo);
2709*67e74705SXin Li
2710*67e74705SXin Li if (ParseCXXMemberDeclaratorBeforeInitializer(
2711*67e74705SXin Li DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))
2712*67e74705SXin Li break;
2713*67e74705SXin Li }
2714*67e74705SXin Li
2715*67e74705SXin Li if (ExpectSemi &&
2716*67e74705SXin Li ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
2717*67e74705SXin Li // Skip to end of block or statement.
2718*67e74705SXin Li SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
2719*67e74705SXin Li // If we stopped at a ';', eat it.
2720*67e74705SXin Li TryConsumeToken(tok::semi);
2721*67e74705SXin Li return nullptr;
2722*67e74705SXin Li }
2723*67e74705SXin Li
2724*67e74705SXin Li return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
2725*67e74705SXin Li }
2726*67e74705SXin Li
2727*67e74705SXin Li /// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer.
2728*67e74705SXin Li /// Also detect and reject any attempted defaulted/deleted function definition.
2729*67e74705SXin Li /// The location of the '=', if any, will be placed in EqualLoc.
2730*67e74705SXin Li ///
2731*67e74705SXin Li /// This does not check for a pure-specifier; that's handled elsewhere.
2732*67e74705SXin Li ///
2733*67e74705SXin Li /// brace-or-equal-initializer:
2734*67e74705SXin Li /// '=' initializer-expression
2735*67e74705SXin Li /// braced-init-list
2736*67e74705SXin Li ///
2737*67e74705SXin Li /// initializer-clause:
2738*67e74705SXin Li /// assignment-expression
2739*67e74705SXin Li /// braced-init-list
2740*67e74705SXin Li ///
2741*67e74705SXin Li /// defaulted/deleted function-definition:
2742*67e74705SXin Li /// '=' 'default'
2743*67e74705SXin Li /// '=' 'delete'
2744*67e74705SXin Li ///
2745*67e74705SXin Li /// Prior to C++0x, the assignment-expression in an initializer-clause must
2746*67e74705SXin Li /// be a constant-expression.
ParseCXXMemberInitializer(Decl * D,bool IsFunction,SourceLocation & EqualLoc)2747*67e74705SXin Li ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
2748*67e74705SXin Li SourceLocation &EqualLoc) {
2749*67e74705SXin Li assert(Tok.isOneOf(tok::equal, tok::l_brace)
2750*67e74705SXin Li && "Data member initializer not starting with '=' or '{'");
2751*67e74705SXin Li
2752*67e74705SXin Li EnterExpressionEvaluationContext Context(Actions,
2753*67e74705SXin Li Sema::PotentiallyEvaluated,
2754*67e74705SXin Li D);
2755*67e74705SXin Li if (TryConsumeToken(tok::equal, EqualLoc)) {
2756*67e74705SXin Li if (Tok.is(tok::kw_delete)) {
2757*67e74705SXin Li // In principle, an initializer of '= delete p;' is legal, but it will
2758*67e74705SXin Li // never type-check. It's better to diagnose it as an ill-formed expression
2759*67e74705SXin Li // than as an ill-formed deleted non-function member.
2760*67e74705SXin Li // An initializer of '= delete p, foo' will never be parsed, because
2761*67e74705SXin Li // a top-level comma always ends the initializer expression.
2762*67e74705SXin Li const Token &Next = NextToken();
2763*67e74705SXin Li if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {
2764*67e74705SXin Li if (IsFunction)
2765*67e74705SXin Li Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2766*67e74705SXin Li << 1 /* delete */;
2767*67e74705SXin Li else
2768*67e74705SXin Li Diag(ConsumeToken(), diag::err_deleted_non_function);
2769*67e74705SXin Li return ExprError();
2770*67e74705SXin Li }
2771*67e74705SXin Li } else if (Tok.is(tok::kw_default)) {
2772*67e74705SXin Li if (IsFunction)
2773*67e74705SXin Li Diag(Tok, diag::err_default_delete_in_multiple_declaration)
2774*67e74705SXin Li << 0 /* default */;
2775*67e74705SXin Li else
2776*67e74705SXin Li Diag(ConsumeToken(), diag::err_default_special_members);
2777*67e74705SXin Li return ExprError();
2778*67e74705SXin Li }
2779*67e74705SXin Li }
2780*67e74705SXin Li if (const auto *PD = dyn_cast_or_null<MSPropertyDecl>(D)) {
2781*67e74705SXin Li Diag(Tok, diag::err_ms_property_initializer) << PD;
2782*67e74705SXin Li return ExprError();
2783*67e74705SXin Li }
2784*67e74705SXin Li return ParseInitializer();
2785*67e74705SXin Li }
2786*67e74705SXin Li
SkipCXXMemberSpecification(SourceLocation RecordLoc,SourceLocation AttrFixitLoc,unsigned TagType,Decl * TagDecl)2787*67e74705SXin Li void Parser::SkipCXXMemberSpecification(SourceLocation RecordLoc,
2788*67e74705SXin Li SourceLocation AttrFixitLoc,
2789*67e74705SXin Li unsigned TagType, Decl *TagDecl) {
2790*67e74705SXin Li // Skip the optional 'final' keyword.
2791*67e74705SXin Li if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
2792*67e74705SXin Li assert(isCXX11FinalKeyword() && "not a class definition");
2793*67e74705SXin Li ConsumeToken();
2794*67e74705SXin Li
2795*67e74705SXin Li // Diagnose any C++11 attributes after 'final' keyword.
2796*67e74705SXin Li // We deliberately discard these attributes.
2797*67e74705SXin Li ParsedAttributesWithRange Attrs(AttrFactory);
2798*67e74705SXin Li CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
2799*67e74705SXin Li
2800*67e74705SXin Li // This can only happen if we had malformed misplaced attributes;
2801*67e74705SXin Li // we only get called if there is a colon or left-brace after the
2802*67e74705SXin Li // attributes.
2803*67e74705SXin Li if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_brace))
2804*67e74705SXin Li return;
2805*67e74705SXin Li }
2806*67e74705SXin Li
2807*67e74705SXin Li // Skip the base clauses. This requires actually parsing them, because
2808*67e74705SXin Li // otherwise we can't be sure where they end (a left brace may appear
2809*67e74705SXin Li // within a template argument).
2810*67e74705SXin Li if (Tok.is(tok::colon)) {
2811*67e74705SXin Li // Enter the scope of the class so that we can correctly parse its bases.
2812*67e74705SXin Li ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
2813*67e74705SXin Li ParsingClassDefinition ParsingDef(*this, TagDecl, /*NonNestedClass*/ true,
2814*67e74705SXin Li TagType == DeclSpec::TST_interface);
2815*67e74705SXin Li auto OldContext =
2816*67e74705SXin Li Actions.ActOnTagStartSkippedDefinition(getCurScope(), TagDecl);
2817*67e74705SXin Li
2818*67e74705SXin Li // Parse the bases but don't attach them to the class.
2819*67e74705SXin Li ParseBaseClause(nullptr);
2820*67e74705SXin Li
2821*67e74705SXin Li Actions.ActOnTagFinishSkippedDefinition(OldContext);
2822*67e74705SXin Li
2823*67e74705SXin Li if (!Tok.is(tok::l_brace)) {
2824*67e74705SXin Li Diag(PP.getLocForEndOfToken(PrevTokLocation),
2825*67e74705SXin Li diag::err_expected_lbrace_after_base_specifiers);
2826*67e74705SXin Li return;
2827*67e74705SXin Li }
2828*67e74705SXin Li }
2829*67e74705SXin Li
2830*67e74705SXin Li // Skip the body.
2831*67e74705SXin Li assert(Tok.is(tok::l_brace));
2832*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_brace);
2833*67e74705SXin Li T.consumeOpen();
2834*67e74705SXin Li T.skipToEnd();
2835*67e74705SXin Li
2836*67e74705SXin Li // Parse and discard any trailing attributes.
2837*67e74705SXin Li ParsedAttributes Attrs(AttrFactory);
2838*67e74705SXin Li if (Tok.is(tok::kw___attribute))
2839*67e74705SXin Li MaybeParseGNUAttributes(Attrs);
2840*67e74705SXin Li }
2841*67e74705SXin Li
ParseCXXClassMemberDeclarationWithPragmas(AccessSpecifier & AS,ParsedAttributesWithRange & AccessAttrs,DeclSpec::TST TagType,Decl * TagDecl)2842*67e74705SXin Li Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
2843*67e74705SXin Li AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs,
2844*67e74705SXin Li DeclSpec::TST TagType, Decl *TagDecl) {
2845*67e74705SXin Li if (getLangOpts().MicrosoftExt &&
2846*67e74705SXin Li Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
2847*67e74705SXin Li ParseMicrosoftIfExistsClassDeclaration(TagType, AS);
2848*67e74705SXin Li return nullptr;
2849*67e74705SXin Li }
2850*67e74705SXin Li
2851*67e74705SXin Li // Check for extraneous top-level semicolon.
2852*67e74705SXin Li if (Tok.is(tok::semi)) {
2853*67e74705SXin Li ConsumeExtraSemi(InsideStruct, TagType);
2854*67e74705SXin Li return nullptr;
2855*67e74705SXin Li }
2856*67e74705SXin Li
2857*67e74705SXin Li if (Tok.is(tok::annot_pragma_vis)) {
2858*67e74705SXin Li HandlePragmaVisibility();
2859*67e74705SXin Li return nullptr;
2860*67e74705SXin Li }
2861*67e74705SXin Li
2862*67e74705SXin Li if (Tok.is(tok::annot_pragma_pack)) {
2863*67e74705SXin Li HandlePragmaPack();
2864*67e74705SXin Li return nullptr;
2865*67e74705SXin Li }
2866*67e74705SXin Li
2867*67e74705SXin Li if (Tok.is(tok::annot_pragma_align)) {
2868*67e74705SXin Li HandlePragmaAlign();
2869*67e74705SXin Li return nullptr;
2870*67e74705SXin Li }
2871*67e74705SXin Li
2872*67e74705SXin Li if (Tok.is(tok::annot_pragma_ms_pointers_to_members)) {
2873*67e74705SXin Li HandlePragmaMSPointersToMembers();
2874*67e74705SXin Li return nullptr;
2875*67e74705SXin Li }
2876*67e74705SXin Li
2877*67e74705SXin Li if (Tok.is(tok::annot_pragma_ms_pragma)) {
2878*67e74705SXin Li HandlePragmaMSPragma();
2879*67e74705SXin Li return nullptr;
2880*67e74705SXin Li }
2881*67e74705SXin Li
2882*67e74705SXin Li if (Tok.is(tok::annot_pragma_ms_vtordisp)) {
2883*67e74705SXin Li HandlePragmaMSVtorDisp();
2884*67e74705SXin Li return nullptr;
2885*67e74705SXin Li }
2886*67e74705SXin Li
2887*67e74705SXin Li // If we see a namespace here, a close brace was missing somewhere.
2888*67e74705SXin Li if (Tok.is(tok::kw_namespace)) {
2889*67e74705SXin Li DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
2890*67e74705SXin Li return nullptr;
2891*67e74705SXin Li }
2892*67e74705SXin Li
2893*67e74705SXin Li AccessSpecifier NewAS = getAccessSpecifierIfPresent();
2894*67e74705SXin Li if (NewAS != AS_none) {
2895*67e74705SXin Li // Current token is a C++ access specifier.
2896*67e74705SXin Li AS = NewAS;
2897*67e74705SXin Li SourceLocation ASLoc = Tok.getLocation();
2898*67e74705SXin Li unsigned TokLength = Tok.getLength();
2899*67e74705SXin Li ConsumeToken();
2900*67e74705SXin Li AccessAttrs.clear();
2901*67e74705SXin Li MaybeParseGNUAttributes(AccessAttrs);
2902*67e74705SXin Li
2903*67e74705SXin Li SourceLocation EndLoc;
2904*67e74705SXin Li if (TryConsumeToken(tok::colon, EndLoc)) {
2905*67e74705SXin Li } else if (TryConsumeToken(tok::semi, EndLoc)) {
2906*67e74705SXin Li Diag(EndLoc, diag::err_expected)
2907*67e74705SXin Li << tok::colon << FixItHint::CreateReplacement(EndLoc, ":");
2908*67e74705SXin Li } else {
2909*67e74705SXin Li EndLoc = ASLoc.getLocWithOffset(TokLength);
2910*67e74705SXin Li Diag(EndLoc, diag::err_expected)
2911*67e74705SXin Li << tok::colon << FixItHint::CreateInsertion(EndLoc, ":");
2912*67e74705SXin Li }
2913*67e74705SXin Li
2914*67e74705SXin Li // The Microsoft extension __interface does not permit non-public
2915*67e74705SXin Li // access specifiers.
2916*67e74705SXin Li if (TagType == DeclSpec::TST_interface && AS != AS_public) {
2917*67e74705SXin Li Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);
2918*67e74705SXin Li }
2919*67e74705SXin Li
2920*67e74705SXin Li if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc,
2921*67e74705SXin Li AccessAttrs.getList())) {
2922*67e74705SXin Li // found another attribute than only annotations
2923*67e74705SXin Li AccessAttrs.clear();
2924*67e74705SXin Li }
2925*67e74705SXin Li
2926*67e74705SXin Li return nullptr;
2927*67e74705SXin Li }
2928*67e74705SXin Li
2929*67e74705SXin Li if (Tok.is(tok::annot_pragma_openmp))
2930*67e74705SXin Li return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, AccessAttrs, TagType,
2931*67e74705SXin Li TagDecl);
2932*67e74705SXin Li
2933*67e74705SXin Li // Parse all the comma separated declarators.
2934*67e74705SXin Li return ParseCXXClassMemberDeclaration(AS, AccessAttrs.getList());
2935*67e74705SXin Li }
2936*67e74705SXin Li
2937*67e74705SXin Li /// ParseCXXMemberSpecification - Parse the class definition.
2938*67e74705SXin Li ///
2939*67e74705SXin Li /// member-specification:
2940*67e74705SXin Li /// member-declaration member-specification[opt]
2941*67e74705SXin Li /// access-specifier ':' member-specification[opt]
2942*67e74705SXin Li ///
ParseCXXMemberSpecification(SourceLocation RecordLoc,SourceLocation AttrFixitLoc,ParsedAttributesWithRange & Attrs,unsigned TagType,Decl * TagDecl)2943*67e74705SXin Li void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
2944*67e74705SXin Li SourceLocation AttrFixitLoc,
2945*67e74705SXin Li ParsedAttributesWithRange &Attrs,
2946*67e74705SXin Li unsigned TagType, Decl *TagDecl) {
2947*67e74705SXin Li assert((TagType == DeclSpec::TST_struct ||
2948*67e74705SXin Li TagType == DeclSpec::TST_interface ||
2949*67e74705SXin Li TagType == DeclSpec::TST_union ||
2950*67e74705SXin Li TagType == DeclSpec::TST_class) && "Invalid TagType!");
2951*67e74705SXin Li
2952*67e74705SXin Li PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2953*67e74705SXin Li "parsing struct/union/class body");
2954*67e74705SXin Li
2955*67e74705SXin Li // Determine whether this is a non-nested class. Note that local
2956*67e74705SXin Li // classes are *not* considered to be nested classes.
2957*67e74705SXin Li bool NonNestedClass = true;
2958*67e74705SXin Li if (!ClassStack.empty()) {
2959*67e74705SXin Li for (const Scope *S = getCurScope(); S; S = S->getParent()) {
2960*67e74705SXin Li if (S->isClassScope()) {
2961*67e74705SXin Li // We're inside a class scope, so this is a nested class.
2962*67e74705SXin Li NonNestedClass = false;
2963*67e74705SXin Li
2964*67e74705SXin Li // The Microsoft extension __interface does not permit nested classes.
2965*67e74705SXin Li if (getCurrentClass().IsInterface) {
2966*67e74705SXin Li Diag(RecordLoc, diag::err_invalid_member_in_interface)
2967*67e74705SXin Li << /*ErrorType=*/6
2968*67e74705SXin Li << (isa<NamedDecl>(TagDecl)
2969*67e74705SXin Li ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString()
2970*67e74705SXin Li : "(anonymous)");
2971*67e74705SXin Li }
2972*67e74705SXin Li break;
2973*67e74705SXin Li }
2974*67e74705SXin Li
2975*67e74705SXin Li if ((S->getFlags() & Scope::FnScope))
2976*67e74705SXin Li // If we're in a function or function template then this is a local
2977*67e74705SXin Li // class rather than a nested class.
2978*67e74705SXin Li break;
2979*67e74705SXin Li }
2980*67e74705SXin Li }
2981*67e74705SXin Li
2982*67e74705SXin Li // Enter a scope for the class.
2983*67e74705SXin Li ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
2984*67e74705SXin Li
2985*67e74705SXin Li // Note that we are parsing a new (potentially-nested) class definition.
2986*67e74705SXin Li ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass,
2987*67e74705SXin Li TagType == DeclSpec::TST_interface);
2988*67e74705SXin Li
2989*67e74705SXin Li if (TagDecl)
2990*67e74705SXin Li Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
2991*67e74705SXin Li
2992*67e74705SXin Li SourceLocation FinalLoc;
2993*67e74705SXin Li bool IsFinalSpelledSealed = false;
2994*67e74705SXin Li
2995*67e74705SXin Li // Parse the optional 'final' keyword.
2996*67e74705SXin Li if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
2997*67e74705SXin Li VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);
2998*67e74705SXin Li assert((Specifier == VirtSpecifiers::VS_Final ||
2999*67e74705SXin Li Specifier == VirtSpecifiers::VS_Sealed) &&
3000*67e74705SXin Li "not a class definition");
3001*67e74705SXin Li FinalLoc = ConsumeToken();
3002*67e74705SXin Li IsFinalSpelledSealed = Specifier == VirtSpecifiers::VS_Sealed;
3003*67e74705SXin Li
3004*67e74705SXin Li if (TagType == DeclSpec::TST_interface)
3005*67e74705SXin Li Diag(FinalLoc, diag::err_override_control_interface)
3006*67e74705SXin Li << VirtSpecifiers::getSpecifierName(Specifier);
3007*67e74705SXin Li else if (Specifier == VirtSpecifiers::VS_Final)
3008*67e74705SXin Li Diag(FinalLoc, getLangOpts().CPlusPlus11
3009*67e74705SXin Li ? diag::warn_cxx98_compat_override_control_keyword
3010*67e74705SXin Li : diag::ext_override_control_keyword)
3011*67e74705SXin Li << VirtSpecifiers::getSpecifierName(Specifier);
3012*67e74705SXin Li else if (Specifier == VirtSpecifiers::VS_Sealed)
3013*67e74705SXin Li Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3014*67e74705SXin Li
3015*67e74705SXin Li // Parse any C++11 attributes after 'final' keyword.
3016*67e74705SXin Li // These attributes are not allowed to appear here,
3017*67e74705SXin Li // and the only possible place for them to appertain
3018*67e74705SXin Li // to the class would be between class-key and class-name.
3019*67e74705SXin Li CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3020*67e74705SXin Li
3021*67e74705SXin Li // ParseClassSpecifier() does only a superficial check for attributes before
3022*67e74705SXin Li // deciding to call this method. For example, for
3023*67e74705SXin Li // `class C final alignas ([l) {` it will decide that this looks like a
3024*67e74705SXin Li // misplaced attribute since it sees `alignas '(' ')'`. But the actual
3025*67e74705SXin Li // attribute parsing code will try to parse the '[' as a constexpr lambda
3026*67e74705SXin Li // and consume enough tokens that the alignas parsing code will eat the
3027*67e74705SXin Li // opening '{'. So bail out if the next token isn't one we expect.
3028*67e74705SXin Li if (!Tok.is(tok::colon) && !Tok.is(tok::l_brace)) {
3029*67e74705SXin Li if (TagDecl)
3030*67e74705SXin Li Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
3031*67e74705SXin Li return;
3032*67e74705SXin Li }
3033*67e74705SXin Li }
3034*67e74705SXin Li
3035*67e74705SXin Li if (Tok.is(tok::colon)) {
3036*67e74705SXin Li ParseBaseClause(TagDecl);
3037*67e74705SXin Li if (!Tok.is(tok::l_brace)) {
3038*67e74705SXin Li bool SuggestFixIt = false;
3039*67e74705SXin Li SourceLocation BraceLoc = PP.getLocForEndOfToken(PrevTokLocation);
3040*67e74705SXin Li if (Tok.isAtStartOfLine()) {
3041*67e74705SXin Li switch (Tok.getKind()) {
3042*67e74705SXin Li case tok::kw_private:
3043*67e74705SXin Li case tok::kw_protected:
3044*67e74705SXin Li case tok::kw_public:
3045*67e74705SXin Li SuggestFixIt = NextToken().getKind() == tok::colon;
3046*67e74705SXin Li break;
3047*67e74705SXin Li case tok::kw_static_assert:
3048*67e74705SXin Li case tok::r_brace:
3049*67e74705SXin Li case tok::kw_using:
3050*67e74705SXin Li // base-clause can have simple-template-id; 'template' can't be there
3051*67e74705SXin Li case tok::kw_template:
3052*67e74705SXin Li SuggestFixIt = true;
3053*67e74705SXin Li break;
3054*67e74705SXin Li case tok::identifier:
3055*67e74705SXin Li SuggestFixIt = isConstructorDeclarator(true);
3056*67e74705SXin Li break;
3057*67e74705SXin Li default:
3058*67e74705SXin Li SuggestFixIt = isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
3059*67e74705SXin Li break;
3060*67e74705SXin Li }
3061*67e74705SXin Li }
3062*67e74705SXin Li DiagnosticBuilder LBraceDiag =
3063*67e74705SXin Li Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);
3064*67e74705SXin Li if (SuggestFixIt) {
3065*67e74705SXin Li LBraceDiag << FixItHint::CreateInsertion(BraceLoc, " {");
3066*67e74705SXin Li // Try recovering from missing { after base-clause.
3067*67e74705SXin Li PP.EnterToken(Tok);
3068*67e74705SXin Li Tok.setKind(tok::l_brace);
3069*67e74705SXin Li } else {
3070*67e74705SXin Li if (TagDecl)
3071*67e74705SXin Li Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
3072*67e74705SXin Li return;
3073*67e74705SXin Li }
3074*67e74705SXin Li }
3075*67e74705SXin Li }
3076*67e74705SXin Li
3077*67e74705SXin Li assert(Tok.is(tok::l_brace));
3078*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_brace);
3079*67e74705SXin Li T.consumeOpen();
3080*67e74705SXin Li
3081*67e74705SXin Li if (TagDecl)
3082*67e74705SXin Li Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
3083*67e74705SXin Li IsFinalSpelledSealed,
3084*67e74705SXin Li T.getOpenLocation());
3085*67e74705SXin Li
3086*67e74705SXin Li // C++ 11p3: Members of a class defined with the keyword class are private
3087*67e74705SXin Li // by default. Members of a class defined with the keywords struct or union
3088*67e74705SXin Li // are public by default.
3089*67e74705SXin Li AccessSpecifier CurAS;
3090*67e74705SXin Li if (TagType == DeclSpec::TST_class)
3091*67e74705SXin Li CurAS = AS_private;
3092*67e74705SXin Li else
3093*67e74705SXin Li CurAS = AS_public;
3094*67e74705SXin Li ParsedAttributesWithRange AccessAttrs(AttrFactory);
3095*67e74705SXin Li
3096*67e74705SXin Li if (TagDecl) {
3097*67e74705SXin Li // While we still have something to read, read the member-declarations.
3098*67e74705SXin Li while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
3099*67e74705SXin Li Tok.isNot(tok::eof)) {
3100*67e74705SXin Li // Each iteration of this loop reads one member-declaration.
3101*67e74705SXin Li ParseCXXClassMemberDeclarationWithPragmas(
3102*67e74705SXin Li CurAS, AccessAttrs, static_cast<DeclSpec::TST>(TagType), TagDecl);
3103*67e74705SXin Li }
3104*67e74705SXin Li T.consumeClose();
3105*67e74705SXin Li } else {
3106*67e74705SXin Li SkipUntil(tok::r_brace);
3107*67e74705SXin Li }
3108*67e74705SXin Li
3109*67e74705SXin Li // If attributes exist after class contents, parse them.
3110*67e74705SXin Li ParsedAttributes attrs(AttrFactory);
3111*67e74705SXin Li MaybeParseGNUAttributes(attrs);
3112*67e74705SXin Li
3113*67e74705SXin Li if (TagDecl)
3114*67e74705SXin Li Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
3115*67e74705SXin Li T.getOpenLocation(),
3116*67e74705SXin Li T.getCloseLocation(),
3117*67e74705SXin Li attrs.getList());
3118*67e74705SXin Li
3119*67e74705SXin Li // C++11 [class.mem]p2:
3120*67e74705SXin Li // Within the class member-specification, the class is regarded as complete
3121*67e74705SXin Li // within function bodies, default arguments, exception-specifications, and
3122*67e74705SXin Li // brace-or-equal-initializers for non-static data members (including such
3123*67e74705SXin Li // things in nested classes).
3124*67e74705SXin Li if (TagDecl && NonNestedClass) {
3125*67e74705SXin Li // We are not inside a nested class. This class and its nested classes
3126*67e74705SXin Li // are complete and we can parse the delayed portions of method
3127*67e74705SXin Li // declarations and the lexed inline method definitions, along with any
3128*67e74705SXin Li // delayed attributes.
3129*67e74705SXin Li SourceLocation SavedPrevTokLocation = PrevTokLocation;
3130*67e74705SXin Li ParseLexedAttributes(getCurrentClass());
3131*67e74705SXin Li ParseLexedMethodDeclarations(getCurrentClass());
3132*67e74705SXin Li
3133*67e74705SXin Li // We've finished with all pending member declarations.
3134*67e74705SXin Li Actions.ActOnFinishCXXMemberDecls();
3135*67e74705SXin Li
3136*67e74705SXin Li ParseLexedMemberInitializers(getCurrentClass());
3137*67e74705SXin Li ParseLexedMethodDefs(getCurrentClass());
3138*67e74705SXin Li PrevTokLocation = SavedPrevTokLocation;
3139*67e74705SXin Li
3140*67e74705SXin Li // We've finished parsing everything, including default argument
3141*67e74705SXin Li // initializers.
3142*67e74705SXin Li Actions.ActOnFinishCXXNonNestedClass(TagDecl);
3143*67e74705SXin Li }
3144*67e74705SXin Li
3145*67e74705SXin Li if (TagDecl)
3146*67e74705SXin Li Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
3147*67e74705SXin Li T.getCloseLocation());
3148*67e74705SXin Li
3149*67e74705SXin Li // Leave the class scope.
3150*67e74705SXin Li ParsingDef.Pop();
3151*67e74705SXin Li ClassScope.Exit();
3152*67e74705SXin Li }
3153*67e74705SXin Li
DiagnoseUnexpectedNamespace(NamedDecl * D)3154*67e74705SXin Li void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {
3155*67e74705SXin Li assert(Tok.is(tok::kw_namespace));
3156*67e74705SXin Li
3157*67e74705SXin Li // FIXME: Suggest where the close brace should have gone by looking
3158*67e74705SXin Li // at indentation changes within the definition body.
3159*67e74705SXin Li Diag(D->getLocation(),
3160*67e74705SXin Li diag::err_missing_end_of_definition) << D;
3161*67e74705SXin Li Diag(Tok.getLocation(),
3162*67e74705SXin Li diag::note_missing_end_of_definition_before) << D;
3163*67e74705SXin Li
3164*67e74705SXin Li // Push '};' onto the token stream to recover.
3165*67e74705SXin Li PP.EnterToken(Tok);
3166*67e74705SXin Li
3167*67e74705SXin Li Tok.startToken();
3168*67e74705SXin Li Tok.setLocation(PP.getLocForEndOfToken(PrevTokLocation));
3169*67e74705SXin Li Tok.setKind(tok::semi);
3170*67e74705SXin Li PP.EnterToken(Tok);
3171*67e74705SXin Li
3172*67e74705SXin Li Tok.setKind(tok::r_brace);
3173*67e74705SXin Li }
3174*67e74705SXin Li
3175*67e74705SXin Li /// ParseConstructorInitializer - Parse a C++ constructor initializer,
3176*67e74705SXin Li /// which explicitly initializes the members or base classes of a
3177*67e74705SXin Li /// class (C++ [class.base.init]). For example, the three initializers
3178*67e74705SXin Li /// after the ':' in the Derived constructor below:
3179*67e74705SXin Li ///
3180*67e74705SXin Li /// @code
3181*67e74705SXin Li /// class Base { };
3182*67e74705SXin Li /// class Derived : Base {
3183*67e74705SXin Li /// int x;
3184*67e74705SXin Li /// float f;
3185*67e74705SXin Li /// public:
3186*67e74705SXin Li /// Derived(float f) : Base(), x(17), f(f) { }
3187*67e74705SXin Li /// };
3188*67e74705SXin Li /// @endcode
3189*67e74705SXin Li ///
3190*67e74705SXin Li /// [C++] ctor-initializer:
3191*67e74705SXin Li /// ':' mem-initializer-list
3192*67e74705SXin Li ///
3193*67e74705SXin Li /// [C++] mem-initializer-list:
3194*67e74705SXin Li /// mem-initializer ...[opt]
3195*67e74705SXin Li /// mem-initializer ...[opt] , mem-initializer-list
ParseConstructorInitializer(Decl * ConstructorDecl)3196*67e74705SXin Li void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
3197*67e74705SXin Li assert(Tok.is(tok::colon) &&
3198*67e74705SXin Li "Constructor initializer always starts with ':'");
3199*67e74705SXin Li
3200*67e74705SXin Li // Poison the SEH identifiers so they are flagged as illegal in constructor
3201*67e74705SXin Li // initializers.
3202*67e74705SXin Li PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
3203*67e74705SXin Li SourceLocation ColonLoc = ConsumeToken();
3204*67e74705SXin Li
3205*67e74705SXin Li SmallVector<CXXCtorInitializer*, 4> MemInitializers;
3206*67e74705SXin Li bool AnyErrors = false;
3207*67e74705SXin Li
3208*67e74705SXin Li do {
3209*67e74705SXin Li if (Tok.is(tok::code_completion)) {
3210*67e74705SXin Li Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
3211*67e74705SXin Li MemInitializers);
3212*67e74705SXin Li return cutOffParsing();
3213*67e74705SXin Li }
3214*67e74705SXin Li
3215*67e74705SXin Li MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
3216*67e74705SXin Li if (!MemInit.isInvalid())
3217*67e74705SXin Li MemInitializers.push_back(MemInit.get());
3218*67e74705SXin Li else
3219*67e74705SXin Li AnyErrors = true;
3220*67e74705SXin Li
3221*67e74705SXin Li if (Tok.is(tok::comma))
3222*67e74705SXin Li ConsumeToken();
3223*67e74705SXin Li else if (Tok.is(tok::l_brace))
3224*67e74705SXin Li break;
3225*67e74705SXin Li // If the previous initializer was valid and the next token looks like a
3226*67e74705SXin Li // base or member initializer, assume that we're just missing a comma.
3227*67e74705SXin Li else if (!MemInit.isInvalid() &&
3228*67e74705SXin Li Tok.isOneOf(tok::identifier, tok::coloncolon)) {
3229*67e74705SXin Li SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
3230*67e74705SXin Li Diag(Loc, diag::err_ctor_init_missing_comma)
3231*67e74705SXin Li << FixItHint::CreateInsertion(Loc, ", ");
3232*67e74705SXin Li } else {
3233*67e74705SXin Li // Skip over garbage, until we get to '{'. Don't eat the '{'.
3234*67e74705SXin Li if (!MemInit.isInvalid())
3235*67e74705SXin Li Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace
3236*67e74705SXin Li << tok::comma;
3237*67e74705SXin Li SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
3238*67e74705SXin Li break;
3239*67e74705SXin Li }
3240*67e74705SXin Li } while (true);
3241*67e74705SXin Li
3242*67e74705SXin Li Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers,
3243*67e74705SXin Li AnyErrors);
3244*67e74705SXin Li }
3245*67e74705SXin Li
3246*67e74705SXin Li /// ParseMemInitializer - Parse a C++ member initializer, which is
3247*67e74705SXin Li /// part of a constructor initializer that explicitly initializes one
3248*67e74705SXin Li /// member or base class (C++ [class.base.init]). See
3249*67e74705SXin Li /// ParseConstructorInitializer for an example.
3250*67e74705SXin Li ///
3251*67e74705SXin Li /// [C++] mem-initializer:
3252*67e74705SXin Li /// mem-initializer-id '(' expression-list[opt] ')'
3253*67e74705SXin Li /// [C++0x] mem-initializer-id braced-init-list
3254*67e74705SXin Li ///
3255*67e74705SXin Li /// [C++] mem-initializer-id:
3256*67e74705SXin Li /// '::'[opt] nested-name-specifier[opt] class-name
3257*67e74705SXin Li /// identifier
ParseMemInitializer(Decl * ConstructorDecl)3258*67e74705SXin Li MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
3259*67e74705SXin Li // parse '::'[opt] nested-name-specifier[opt]
3260*67e74705SXin Li CXXScopeSpec SS;
3261*67e74705SXin Li ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false);
3262*67e74705SXin Li ParsedType TemplateTypeTy;
3263*67e74705SXin Li if (Tok.is(tok::annot_template_id)) {
3264*67e74705SXin Li TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3265*67e74705SXin Li if (TemplateId->Kind == TNK_Type_template ||
3266*67e74705SXin Li TemplateId->Kind == TNK_Dependent_template_name) {
3267*67e74705SXin Li AnnotateTemplateIdTokenAsType();
3268*67e74705SXin Li assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
3269*67e74705SXin Li TemplateTypeTy = getTypeAnnotation(Tok);
3270*67e74705SXin Li }
3271*67e74705SXin Li }
3272*67e74705SXin Li // Uses of decltype will already have been converted to annot_decltype by
3273*67e74705SXin Li // ParseOptionalCXXScopeSpecifier at this point.
3274*67e74705SXin Li if (!TemplateTypeTy && Tok.isNot(tok::identifier)
3275*67e74705SXin Li && Tok.isNot(tok::annot_decltype)) {
3276*67e74705SXin Li Diag(Tok, diag::err_expected_member_or_base_name);
3277*67e74705SXin Li return true;
3278*67e74705SXin Li }
3279*67e74705SXin Li
3280*67e74705SXin Li IdentifierInfo *II = nullptr;
3281*67e74705SXin Li DeclSpec DS(AttrFactory);
3282*67e74705SXin Li SourceLocation IdLoc = Tok.getLocation();
3283*67e74705SXin Li if (Tok.is(tok::annot_decltype)) {
3284*67e74705SXin Li // Get the decltype expression, if there is one.
3285*67e74705SXin Li ParseDecltypeSpecifier(DS);
3286*67e74705SXin Li } else {
3287*67e74705SXin Li if (Tok.is(tok::identifier))
3288*67e74705SXin Li // Get the identifier. This may be a member name or a class name,
3289*67e74705SXin Li // but we'll let the semantic analysis determine which it is.
3290*67e74705SXin Li II = Tok.getIdentifierInfo();
3291*67e74705SXin Li ConsumeToken();
3292*67e74705SXin Li }
3293*67e74705SXin Li
3294*67e74705SXin Li
3295*67e74705SXin Li // Parse the '('.
3296*67e74705SXin Li if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
3297*67e74705SXin Li Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3298*67e74705SXin Li
3299*67e74705SXin Li ExprResult InitList = ParseBraceInitializer();
3300*67e74705SXin Li if (InitList.isInvalid())
3301*67e74705SXin Li return true;
3302*67e74705SXin Li
3303*67e74705SXin Li SourceLocation EllipsisLoc;
3304*67e74705SXin Li TryConsumeToken(tok::ellipsis, EllipsisLoc);
3305*67e74705SXin Li
3306*67e74705SXin Li return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
3307*67e74705SXin Li TemplateTypeTy, DS, IdLoc,
3308*67e74705SXin Li InitList.get(), EllipsisLoc);
3309*67e74705SXin Li } else if(Tok.is(tok::l_paren)) {
3310*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_paren);
3311*67e74705SXin Li T.consumeOpen();
3312*67e74705SXin Li
3313*67e74705SXin Li // Parse the optional expression-list.
3314*67e74705SXin Li ExprVector ArgExprs;
3315*67e74705SXin Li CommaLocsTy CommaLocs;
3316*67e74705SXin Li if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
3317*67e74705SXin Li SkipUntil(tok::r_paren, StopAtSemi);
3318*67e74705SXin Li return true;
3319*67e74705SXin Li }
3320*67e74705SXin Li
3321*67e74705SXin Li T.consumeClose();
3322*67e74705SXin Li
3323*67e74705SXin Li SourceLocation EllipsisLoc;
3324*67e74705SXin Li TryConsumeToken(tok::ellipsis, EllipsisLoc);
3325*67e74705SXin Li
3326*67e74705SXin Li return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
3327*67e74705SXin Li TemplateTypeTy, DS, IdLoc,
3328*67e74705SXin Li T.getOpenLocation(), ArgExprs,
3329*67e74705SXin Li T.getCloseLocation(), EllipsisLoc);
3330*67e74705SXin Li }
3331*67e74705SXin Li
3332*67e74705SXin Li if (getLangOpts().CPlusPlus11)
3333*67e74705SXin Li return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
3334*67e74705SXin Li else
3335*67e74705SXin Li return Diag(Tok, diag::err_expected) << tok::l_paren;
3336*67e74705SXin Li }
3337*67e74705SXin Li
3338*67e74705SXin Li /// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
3339*67e74705SXin Li ///
3340*67e74705SXin Li /// exception-specification:
3341*67e74705SXin Li /// dynamic-exception-specification
3342*67e74705SXin Li /// noexcept-specification
3343*67e74705SXin Li ///
3344*67e74705SXin Li /// noexcept-specification:
3345*67e74705SXin Li /// 'noexcept'
3346*67e74705SXin Li /// 'noexcept' '(' constant-expression ')'
3347*67e74705SXin Li ExceptionSpecificationType
tryParseExceptionSpecification(bool Delayed,SourceRange & SpecificationRange,SmallVectorImpl<ParsedType> & DynamicExceptions,SmallVectorImpl<SourceRange> & DynamicExceptionRanges,ExprResult & NoexceptExpr,CachedTokens * & ExceptionSpecTokens)3348*67e74705SXin Li Parser::tryParseExceptionSpecification(bool Delayed,
3349*67e74705SXin Li SourceRange &SpecificationRange,
3350*67e74705SXin Li SmallVectorImpl<ParsedType> &DynamicExceptions,
3351*67e74705SXin Li SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
3352*67e74705SXin Li ExprResult &NoexceptExpr,
3353*67e74705SXin Li CachedTokens *&ExceptionSpecTokens) {
3354*67e74705SXin Li ExceptionSpecificationType Result = EST_None;
3355*67e74705SXin Li ExceptionSpecTokens = nullptr;
3356*67e74705SXin Li
3357*67e74705SXin Li // Handle delayed parsing of exception-specifications.
3358*67e74705SXin Li if (Delayed) {
3359*67e74705SXin Li if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))
3360*67e74705SXin Li return EST_None;
3361*67e74705SXin Li
3362*67e74705SXin Li // Consume and cache the starting token.
3363*67e74705SXin Li bool IsNoexcept = Tok.is(tok::kw_noexcept);
3364*67e74705SXin Li Token StartTok = Tok;
3365*67e74705SXin Li SpecificationRange = SourceRange(ConsumeToken());
3366*67e74705SXin Li
3367*67e74705SXin Li // Check for a '('.
3368*67e74705SXin Li if (!Tok.is(tok::l_paren)) {
3369*67e74705SXin Li // If this is a bare 'noexcept', we're done.
3370*67e74705SXin Li if (IsNoexcept) {
3371*67e74705SXin Li Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3372*67e74705SXin Li NoexceptExpr = nullptr;
3373*67e74705SXin Li return EST_BasicNoexcept;
3374*67e74705SXin Li }
3375*67e74705SXin Li
3376*67e74705SXin Li Diag(Tok, diag::err_expected_lparen_after) << "throw";
3377*67e74705SXin Li return EST_DynamicNone;
3378*67e74705SXin Li }
3379*67e74705SXin Li
3380*67e74705SXin Li // Cache the tokens for the exception-specification.
3381*67e74705SXin Li ExceptionSpecTokens = new CachedTokens;
3382*67e74705SXin Li ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept'
3383*67e74705SXin Li ExceptionSpecTokens->push_back(Tok); // '('
3384*67e74705SXin Li SpecificationRange.setEnd(ConsumeParen()); // '('
3385*67e74705SXin Li
3386*67e74705SXin Li ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
3387*67e74705SXin Li /*StopAtSemi=*/true,
3388*67e74705SXin Li /*ConsumeFinalToken=*/true);
3389*67e74705SXin Li SpecificationRange.setEnd(ExceptionSpecTokens->back().getLocation());
3390*67e74705SXin Li
3391*67e74705SXin Li return EST_Unparsed;
3392*67e74705SXin Li }
3393*67e74705SXin Li
3394*67e74705SXin Li // See if there's a dynamic specification.
3395*67e74705SXin Li if (Tok.is(tok::kw_throw)) {
3396*67e74705SXin Li Result = ParseDynamicExceptionSpecification(SpecificationRange,
3397*67e74705SXin Li DynamicExceptions,
3398*67e74705SXin Li DynamicExceptionRanges);
3399*67e74705SXin Li assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
3400*67e74705SXin Li "Produced different number of exception types and ranges.");
3401*67e74705SXin Li }
3402*67e74705SXin Li
3403*67e74705SXin Li // If there's no noexcept specification, we're done.
3404*67e74705SXin Li if (Tok.isNot(tok::kw_noexcept))
3405*67e74705SXin Li return Result;
3406*67e74705SXin Li
3407*67e74705SXin Li Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3408*67e74705SXin Li
3409*67e74705SXin Li // If we already had a dynamic specification, parse the noexcept for,
3410*67e74705SXin Li // recovery, but emit a diagnostic and don't store the results.
3411*67e74705SXin Li SourceRange NoexceptRange;
3412*67e74705SXin Li ExceptionSpecificationType NoexceptType = EST_None;
3413*67e74705SXin Li
3414*67e74705SXin Li SourceLocation KeywordLoc = ConsumeToken();
3415*67e74705SXin Li if (Tok.is(tok::l_paren)) {
3416*67e74705SXin Li // There is an argument.
3417*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_paren);
3418*67e74705SXin Li T.consumeOpen();
3419*67e74705SXin Li NoexceptType = EST_ComputedNoexcept;
3420*67e74705SXin Li NoexceptExpr = ParseConstantExpression();
3421*67e74705SXin Li T.consumeClose();
3422*67e74705SXin Li // The argument must be contextually convertible to bool. We use
3423*67e74705SXin Li // CheckBooleanCondition for this purpose.
3424*67e74705SXin Li // FIXME: Add a proper Sema entry point for this.
3425*67e74705SXin Li if (!NoexceptExpr.isInvalid()) {
3426*67e74705SXin Li NoexceptExpr =
3427*67e74705SXin Li Actions.CheckBooleanCondition(KeywordLoc, NoexceptExpr.get());
3428*67e74705SXin Li NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
3429*67e74705SXin Li } else {
3430*67e74705SXin Li NoexceptType = EST_None;
3431*67e74705SXin Li }
3432*67e74705SXin Li } else {
3433*67e74705SXin Li // There is no argument.
3434*67e74705SXin Li NoexceptType = EST_BasicNoexcept;
3435*67e74705SXin Li NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
3436*67e74705SXin Li }
3437*67e74705SXin Li
3438*67e74705SXin Li if (Result == EST_None) {
3439*67e74705SXin Li SpecificationRange = NoexceptRange;
3440*67e74705SXin Li Result = NoexceptType;
3441*67e74705SXin Li
3442*67e74705SXin Li // If there's a dynamic specification after a noexcept specification,
3443*67e74705SXin Li // parse that and ignore the results.
3444*67e74705SXin Li if (Tok.is(tok::kw_throw)) {
3445*67e74705SXin Li Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
3446*67e74705SXin Li ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
3447*67e74705SXin Li DynamicExceptionRanges);
3448*67e74705SXin Li }
3449*67e74705SXin Li } else {
3450*67e74705SXin Li Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
3451*67e74705SXin Li }
3452*67e74705SXin Li
3453*67e74705SXin Li return Result;
3454*67e74705SXin Li }
3455*67e74705SXin Li
diagnoseDynamicExceptionSpecification(Parser & P,SourceRange Range,bool IsNoexcept)3456*67e74705SXin Li static void diagnoseDynamicExceptionSpecification(
3457*67e74705SXin Li Parser &P, SourceRange Range, bool IsNoexcept) {
3458*67e74705SXin Li if (P.getLangOpts().CPlusPlus11) {
3459*67e74705SXin Li const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";
3460*67e74705SXin Li P.Diag(Range.getBegin(), diag::warn_exception_spec_deprecated) << Range;
3461*67e74705SXin Li P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
3462*67e74705SXin Li << Replacement << FixItHint::CreateReplacement(Range, Replacement);
3463*67e74705SXin Li }
3464*67e74705SXin Li }
3465*67e74705SXin Li
3466*67e74705SXin Li /// ParseDynamicExceptionSpecification - Parse a C++
3467*67e74705SXin Li /// dynamic-exception-specification (C++ [except.spec]).
3468*67e74705SXin Li ///
3469*67e74705SXin Li /// dynamic-exception-specification:
3470*67e74705SXin Li /// 'throw' '(' type-id-list [opt] ')'
3471*67e74705SXin Li /// [MS] 'throw' '(' '...' ')'
3472*67e74705SXin Li ///
3473*67e74705SXin Li /// type-id-list:
3474*67e74705SXin Li /// type-id ... [opt]
3475*67e74705SXin Li /// type-id-list ',' type-id ... [opt]
3476*67e74705SXin Li ///
ParseDynamicExceptionSpecification(SourceRange & SpecificationRange,SmallVectorImpl<ParsedType> & Exceptions,SmallVectorImpl<SourceRange> & Ranges)3477*67e74705SXin Li ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
3478*67e74705SXin Li SourceRange &SpecificationRange,
3479*67e74705SXin Li SmallVectorImpl<ParsedType> &Exceptions,
3480*67e74705SXin Li SmallVectorImpl<SourceRange> &Ranges) {
3481*67e74705SXin Li assert(Tok.is(tok::kw_throw) && "expected throw");
3482*67e74705SXin Li
3483*67e74705SXin Li SpecificationRange.setBegin(ConsumeToken());
3484*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_paren);
3485*67e74705SXin Li if (T.consumeOpen()) {
3486*67e74705SXin Li Diag(Tok, diag::err_expected_lparen_after) << "throw";
3487*67e74705SXin Li SpecificationRange.setEnd(SpecificationRange.getBegin());
3488*67e74705SXin Li return EST_DynamicNone;
3489*67e74705SXin Li }
3490*67e74705SXin Li
3491*67e74705SXin Li // Parse throw(...), a Microsoft extension that means "this function
3492*67e74705SXin Li // can throw anything".
3493*67e74705SXin Li if (Tok.is(tok::ellipsis)) {
3494*67e74705SXin Li SourceLocation EllipsisLoc = ConsumeToken();
3495*67e74705SXin Li if (!getLangOpts().MicrosoftExt)
3496*67e74705SXin Li Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
3497*67e74705SXin Li T.consumeClose();
3498*67e74705SXin Li SpecificationRange.setEnd(T.getCloseLocation());
3499*67e74705SXin Li diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false);
3500*67e74705SXin Li return EST_MSAny;
3501*67e74705SXin Li }
3502*67e74705SXin Li
3503*67e74705SXin Li // Parse the sequence of type-ids.
3504*67e74705SXin Li SourceRange Range;
3505*67e74705SXin Li while (Tok.isNot(tok::r_paren)) {
3506*67e74705SXin Li TypeResult Res(ParseTypeName(&Range));
3507*67e74705SXin Li
3508*67e74705SXin Li if (Tok.is(tok::ellipsis)) {
3509*67e74705SXin Li // C++0x [temp.variadic]p5:
3510*67e74705SXin Li // - In a dynamic-exception-specification (15.4); the pattern is a
3511*67e74705SXin Li // type-id.
3512*67e74705SXin Li SourceLocation Ellipsis = ConsumeToken();
3513*67e74705SXin Li Range.setEnd(Ellipsis);
3514*67e74705SXin Li if (!Res.isInvalid())
3515*67e74705SXin Li Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);
3516*67e74705SXin Li }
3517*67e74705SXin Li
3518*67e74705SXin Li if (!Res.isInvalid()) {
3519*67e74705SXin Li Exceptions.push_back(Res.get());
3520*67e74705SXin Li Ranges.push_back(Range);
3521*67e74705SXin Li }
3522*67e74705SXin Li
3523*67e74705SXin Li if (!TryConsumeToken(tok::comma))
3524*67e74705SXin Li break;
3525*67e74705SXin Li }
3526*67e74705SXin Li
3527*67e74705SXin Li T.consumeClose();
3528*67e74705SXin Li SpecificationRange.setEnd(T.getCloseLocation());
3529*67e74705SXin Li diagnoseDynamicExceptionSpecification(*this, SpecificationRange,
3530*67e74705SXin Li Exceptions.empty());
3531*67e74705SXin Li return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
3532*67e74705SXin Li }
3533*67e74705SXin Li
3534*67e74705SXin Li /// ParseTrailingReturnType - Parse a trailing return type on a new-style
3535*67e74705SXin Li /// function declaration.
ParseTrailingReturnType(SourceRange & Range)3536*67e74705SXin Li TypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
3537*67e74705SXin Li assert(Tok.is(tok::arrow) && "expected arrow");
3538*67e74705SXin Li
3539*67e74705SXin Li ConsumeToken();
3540*67e74705SXin Li
3541*67e74705SXin Li return ParseTypeName(&Range, Declarator::TrailingReturnContext);
3542*67e74705SXin Li }
3543*67e74705SXin Li
3544*67e74705SXin Li /// \brief We have just started parsing the definition of a new class,
3545*67e74705SXin Li /// so push that class onto our stack of classes that is currently
3546*67e74705SXin Li /// being parsed.
3547*67e74705SXin Li Sema::ParsingClassState
PushParsingClass(Decl * ClassDecl,bool NonNestedClass,bool IsInterface)3548*67e74705SXin Li Parser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass,
3549*67e74705SXin Li bool IsInterface) {
3550*67e74705SXin Li assert((NonNestedClass || !ClassStack.empty()) &&
3551*67e74705SXin Li "Nested class without outer class");
3552*67e74705SXin Li ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
3553*67e74705SXin Li return Actions.PushParsingClass();
3554*67e74705SXin Li }
3555*67e74705SXin Li
3556*67e74705SXin Li /// \brief Deallocate the given parsed class and all of its nested
3557*67e74705SXin Li /// classes.
DeallocateParsedClasses(Parser::ParsingClass * Class)3558*67e74705SXin Li void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
3559*67e74705SXin Li for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
3560*67e74705SXin Li delete Class->LateParsedDeclarations[I];
3561*67e74705SXin Li delete Class;
3562*67e74705SXin Li }
3563*67e74705SXin Li
3564*67e74705SXin Li /// \brief Pop the top class of the stack of classes that are
3565*67e74705SXin Li /// currently being parsed.
3566*67e74705SXin Li ///
3567*67e74705SXin Li /// This routine should be called when we have finished parsing the
3568*67e74705SXin Li /// definition of a class, but have not yet popped the Scope
3569*67e74705SXin Li /// associated with the class's definition.
PopParsingClass(Sema::ParsingClassState state)3570*67e74705SXin Li void Parser::PopParsingClass(Sema::ParsingClassState state) {
3571*67e74705SXin Li assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
3572*67e74705SXin Li
3573*67e74705SXin Li Actions.PopParsingClass(state);
3574*67e74705SXin Li
3575*67e74705SXin Li ParsingClass *Victim = ClassStack.top();
3576*67e74705SXin Li ClassStack.pop();
3577*67e74705SXin Li if (Victim->TopLevelClass) {
3578*67e74705SXin Li // Deallocate all of the nested classes of this class,
3579*67e74705SXin Li // recursively: we don't need to keep any of this information.
3580*67e74705SXin Li DeallocateParsedClasses(Victim);
3581*67e74705SXin Li return;
3582*67e74705SXin Li }
3583*67e74705SXin Li assert(!ClassStack.empty() && "Missing top-level class?");
3584*67e74705SXin Li
3585*67e74705SXin Li if (Victim->LateParsedDeclarations.empty()) {
3586*67e74705SXin Li // The victim is a nested class, but we will not need to perform
3587*67e74705SXin Li // any processing after the definition of this class since it has
3588*67e74705SXin Li // no members whose handling was delayed. Therefore, we can just
3589*67e74705SXin Li // remove this nested class.
3590*67e74705SXin Li DeallocateParsedClasses(Victim);
3591*67e74705SXin Li return;
3592*67e74705SXin Li }
3593*67e74705SXin Li
3594*67e74705SXin Li // This nested class has some members that will need to be processed
3595*67e74705SXin Li // after the top-level class is completely defined. Therefore, add
3596*67e74705SXin Li // it to the list of nested classes within its parent.
3597*67e74705SXin Li assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
3598*67e74705SXin Li ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim));
3599*67e74705SXin Li Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
3600*67e74705SXin Li }
3601*67e74705SXin Li
3602*67e74705SXin Li /// \brief Try to parse an 'identifier' which appears within an attribute-token.
3603*67e74705SXin Li ///
3604*67e74705SXin Li /// \return the parsed identifier on success, and 0 if the next token is not an
3605*67e74705SXin Li /// attribute-token.
3606*67e74705SXin Li ///
3607*67e74705SXin Li /// C++11 [dcl.attr.grammar]p3:
3608*67e74705SXin Li /// If a keyword or an alternative token that satisfies the syntactic
3609*67e74705SXin Li /// requirements of an identifier is contained in an attribute-token,
3610*67e74705SXin Li /// it is considered an identifier.
TryParseCXX11AttributeIdentifier(SourceLocation & Loc)3611*67e74705SXin Li IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) {
3612*67e74705SXin Li switch (Tok.getKind()) {
3613*67e74705SXin Li default:
3614*67e74705SXin Li // Identifiers and keywords have identifier info attached.
3615*67e74705SXin Li if (!Tok.isAnnotation()) {
3616*67e74705SXin Li if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
3617*67e74705SXin Li Loc = ConsumeToken();
3618*67e74705SXin Li return II;
3619*67e74705SXin Li }
3620*67e74705SXin Li }
3621*67e74705SXin Li return nullptr;
3622*67e74705SXin Li
3623*67e74705SXin Li case tok::ampamp: // 'and'
3624*67e74705SXin Li case tok::pipe: // 'bitor'
3625*67e74705SXin Li case tok::pipepipe: // 'or'
3626*67e74705SXin Li case tok::caret: // 'xor'
3627*67e74705SXin Li case tok::tilde: // 'compl'
3628*67e74705SXin Li case tok::amp: // 'bitand'
3629*67e74705SXin Li case tok::ampequal: // 'and_eq'
3630*67e74705SXin Li case tok::pipeequal: // 'or_eq'
3631*67e74705SXin Li case tok::caretequal: // 'xor_eq'
3632*67e74705SXin Li case tok::exclaim: // 'not'
3633*67e74705SXin Li case tok::exclaimequal: // 'not_eq'
3634*67e74705SXin Li // Alternative tokens do not have identifier info, but their spelling
3635*67e74705SXin Li // starts with an alphabetical character.
3636*67e74705SXin Li SmallString<8> SpellingBuf;
3637*67e74705SXin Li SourceLocation SpellingLoc =
3638*67e74705SXin Li PP.getSourceManager().getSpellingLoc(Tok.getLocation());
3639*67e74705SXin Li StringRef Spelling = PP.getSpelling(SpellingLoc, SpellingBuf);
3640*67e74705SXin Li if (isLetter(Spelling[0])) {
3641*67e74705SXin Li Loc = ConsumeToken();
3642*67e74705SXin Li return &PP.getIdentifierTable().get(Spelling);
3643*67e74705SXin Li }
3644*67e74705SXin Li return nullptr;
3645*67e74705SXin Li }
3646*67e74705SXin Li }
3647*67e74705SXin Li
IsBuiltInOrStandardCXX11Attribute(IdentifierInfo * AttrName,IdentifierInfo * ScopeName)3648*67e74705SXin Li static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
3649*67e74705SXin Li IdentifierInfo *ScopeName) {
3650*67e74705SXin Li switch (AttributeList::getKind(AttrName, ScopeName,
3651*67e74705SXin Li AttributeList::AS_CXX11)) {
3652*67e74705SXin Li case AttributeList::AT_CarriesDependency:
3653*67e74705SXin Li case AttributeList::AT_Deprecated:
3654*67e74705SXin Li case AttributeList::AT_FallThrough:
3655*67e74705SXin Li case AttributeList::AT_CXX11NoReturn:
3656*67e74705SXin Li return true;
3657*67e74705SXin Li case AttributeList::AT_WarnUnusedResult:
3658*67e74705SXin Li return !ScopeName && AttrName->getName().equals("nodiscard");
3659*67e74705SXin Li case AttributeList::AT_Unused:
3660*67e74705SXin Li return !ScopeName && AttrName->getName().equals("maybe_unused");
3661*67e74705SXin Li default:
3662*67e74705SXin Li return false;
3663*67e74705SXin Li }
3664*67e74705SXin Li }
3665*67e74705SXin Li
3666*67e74705SXin Li /// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause.
3667*67e74705SXin Li ///
3668*67e74705SXin Li /// [C++11] attribute-argument-clause:
3669*67e74705SXin Li /// '(' balanced-token-seq ')'
3670*67e74705SXin Li ///
3671*67e74705SXin Li /// [C++11] balanced-token-seq:
3672*67e74705SXin Li /// balanced-token
3673*67e74705SXin Li /// balanced-token-seq balanced-token
3674*67e74705SXin Li ///
3675*67e74705SXin Li /// [C++11] balanced-token:
3676*67e74705SXin Li /// '(' balanced-token-seq ')'
3677*67e74705SXin Li /// '[' balanced-token-seq ']'
3678*67e74705SXin Li /// '{' balanced-token-seq '}'
3679*67e74705SXin Li /// any token but '(', ')', '[', ']', '{', or '}'
ParseCXX11AttributeArgs(IdentifierInfo * AttrName,SourceLocation AttrNameLoc,ParsedAttributes & Attrs,SourceLocation * EndLoc,IdentifierInfo * ScopeName,SourceLocation ScopeLoc)3680*67e74705SXin Li bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
3681*67e74705SXin Li SourceLocation AttrNameLoc,
3682*67e74705SXin Li ParsedAttributes &Attrs,
3683*67e74705SXin Li SourceLocation *EndLoc,
3684*67e74705SXin Li IdentifierInfo *ScopeName,
3685*67e74705SXin Li SourceLocation ScopeLoc) {
3686*67e74705SXin Li assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
3687*67e74705SXin Li SourceLocation LParenLoc = Tok.getLocation();
3688*67e74705SXin Li
3689*67e74705SXin Li // If the attribute isn't known, we will not attempt to parse any
3690*67e74705SXin Li // arguments.
3691*67e74705SXin Li if (!hasAttribute(AttrSyntax::CXX, ScopeName, AttrName,
3692*67e74705SXin Li getTargetInfo(), getLangOpts())) {
3693*67e74705SXin Li // Eat the left paren, then skip to the ending right paren.
3694*67e74705SXin Li ConsumeParen();
3695*67e74705SXin Li SkipUntil(tok::r_paren);
3696*67e74705SXin Li return false;
3697*67e74705SXin Li }
3698*67e74705SXin Li
3699*67e74705SXin Li if (ScopeName && ScopeName->getName() == "gnu")
3700*67e74705SXin Li // GNU-scoped attributes have some special cases to handle GNU-specific
3701*67e74705SXin Li // behaviors.
3702*67e74705SXin Li ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
3703*67e74705SXin Li ScopeLoc, AttributeList::AS_CXX11, nullptr);
3704*67e74705SXin Li else {
3705*67e74705SXin Li unsigned NumArgs =
3706*67e74705SXin Li ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
3707*67e74705SXin Li ScopeName, ScopeLoc, AttributeList::AS_CXX11);
3708*67e74705SXin Li
3709*67e74705SXin Li const AttributeList *Attr = Attrs.getList();
3710*67e74705SXin Li if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
3711*67e74705SXin Li // If the attribute is a standard or built-in attribute and we are
3712*67e74705SXin Li // parsing an argument list, we need to determine whether this attribute
3713*67e74705SXin Li // was allowed to have an argument list (such as [[deprecated]]), and how
3714*67e74705SXin Li // many arguments were parsed (so we can diagnose on [[deprecated()]]).
3715*67e74705SXin Li if (Attr->getMaxArgs() && !NumArgs) {
3716*67e74705SXin Li // The attribute was allowed to have arguments, but none were provided
3717*67e74705SXin Li // even though the attribute parsed successfully. This is an error.
3718*67e74705SXin Li Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
3719*67e74705SXin Li Attr->setInvalid(true);
3720*67e74705SXin Li } else if (!Attr->getMaxArgs()) {
3721*67e74705SXin Li // The attribute parsed successfully, but was not allowed to have any
3722*67e74705SXin Li // arguments. It doesn't matter whether any were provided -- the
3723*67e74705SXin Li // presence of the argument list (even if empty) is diagnosed.
3724*67e74705SXin Li Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
3725*67e74705SXin Li << AttrName
3726*67e74705SXin Li << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
3727*67e74705SXin Li Attr->setInvalid(true);
3728*67e74705SXin Li }
3729*67e74705SXin Li }
3730*67e74705SXin Li }
3731*67e74705SXin Li return true;
3732*67e74705SXin Li }
3733*67e74705SXin Li
3734*67e74705SXin Li /// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier.
3735*67e74705SXin Li ///
3736*67e74705SXin Li /// [C++11] attribute-specifier:
3737*67e74705SXin Li /// '[' '[' attribute-list ']' ']'
3738*67e74705SXin Li /// alignment-specifier
3739*67e74705SXin Li ///
3740*67e74705SXin Li /// [C++11] attribute-list:
3741*67e74705SXin Li /// attribute[opt]
3742*67e74705SXin Li /// attribute-list ',' attribute[opt]
3743*67e74705SXin Li /// attribute '...'
3744*67e74705SXin Li /// attribute-list ',' attribute '...'
3745*67e74705SXin Li ///
3746*67e74705SXin Li /// [C++11] attribute:
3747*67e74705SXin Li /// attribute-token attribute-argument-clause[opt]
3748*67e74705SXin Li ///
3749*67e74705SXin Li /// [C++11] attribute-token:
3750*67e74705SXin Li /// identifier
3751*67e74705SXin Li /// attribute-scoped-token
3752*67e74705SXin Li ///
3753*67e74705SXin Li /// [C++11] attribute-scoped-token:
3754*67e74705SXin Li /// attribute-namespace '::' identifier
3755*67e74705SXin Li ///
3756*67e74705SXin Li /// [C++11] attribute-namespace:
3757*67e74705SXin Li /// identifier
ParseCXX11AttributeSpecifier(ParsedAttributes & attrs,SourceLocation * endLoc)3758*67e74705SXin Li void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
3759*67e74705SXin Li SourceLocation *endLoc) {
3760*67e74705SXin Li if (Tok.is(tok::kw_alignas)) {
3761*67e74705SXin Li Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);
3762*67e74705SXin Li ParseAlignmentSpecifier(attrs, endLoc);
3763*67e74705SXin Li return;
3764*67e74705SXin Li }
3765*67e74705SXin Li
3766*67e74705SXin Li assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
3767*67e74705SXin Li && "Not a C++11 attribute list");
3768*67e74705SXin Li
3769*67e74705SXin Li Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute);
3770*67e74705SXin Li
3771*67e74705SXin Li ConsumeBracket();
3772*67e74705SXin Li ConsumeBracket();
3773*67e74705SXin Li
3774*67e74705SXin Li SourceLocation CommonScopeLoc;
3775*67e74705SXin Li IdentifierInfo *CommonScopeName = nullptr;
3776*67e74705SXin Li if (Tok.is(tok::kw_using)) {
3777*67e74705SXin Li Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z
3778*67e74705SXin Li ? diag::warn_cxx14_compat_using_attribute_ns
3779*67e74705SXin Li : diag::ext_using_attribute_ns);
3780*67e74705SXin Li ConsumeToken();
3781*67e74705SXin Li
3782*67e74705SXin Li CommonScopeName = TryParseCXX11AttributeIdentifier(CommonScopeLoc);
3783*67e74705SXin Li if (!CommonScopeName) {
3784*67e74705SXin Li Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
3785*67e74705SXin Li SkipUntil(tok::r_square, tok::colon, StopBeforeMatch);
3786*67e74705SXin Li }
3787*67e74705SXin Li if (!TryConsumeToken(tok::colon) && CommonScopeName)
3788*67e74705SXin Li Diag(Tok.getLocation(), diag::err_expected) << tok::colon;
3789*67e74705SXin Li }
3790*67e74705SXin Li
3791*67e74705SXin Li llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs;
3792*67e74705SXin Li
3793*67e74705SXin Li while (Tok.isNot(tok::r_square)) {
3794*67e74705SXin Li // attribute not present
3795*67e74705SXin Li if (TryConsumeToken(tok::comma))
3796*67e74705SXin Li continue;
3797*67e74705SXin Li
3798*67e74705SXin Li SourceLocation ScopeLoc, AttrLoc;
3799*67e74705SXin Li IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr;
3800*67e74705SXin Li
3801*67e74705SXin Li AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
3802*67e74705SXin Li if (!AttrName)
3803*67e74705SXin Li // Break out to the "expected ']'" diagnostic.
3804*67e74705SXin Li break;
3805*67e74705SXin Li
3806*67e74705SXin Li // scoped attribute
3807*67e74705SXin Li if (TryConsumeToken(tok::coloncolon)) {
3808*67e74705SXin Li ScopeName = AttrName;
3809*67e74705SXin Li ScopeLoc = AttrLoc;
3810*67e74705SXin Li
3811*67e74705SXin Li AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
3812*67e74705SXin Li if (!AttrName) {
3813*67e74705SXin Li Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
3814*67e74705SXin Li SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch);
3815*67e74705SXin Li continue;
3816*67e74705SXin Li }
3817*67e74705SXin Li }
3818*67e74705SXin Li
3819*67e74705SXin Li if (CommonScopeName) {
3820*67e74705SXin Li if (ScopeName) {
3821*67e74705SXin Li Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)
3822*67e74705SXin Li << SourceRange(CommonScopeLoc);
3823*67e74705SXin Li } else {
3824*67e74705SXin Li ScopeName = CommonScopeName;
3825*67e74705SXin Li ScopeLoc = CommonScopeLoc;
3826*67e74705SXin Li }
3827*67e74705SXin Li }
3828*67e74705SXin Li
3829*67e74705SXin Li bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName);
3830*67e74705SXin Li bool AttrParsed = false;
3831*67e74705SXin Li
3832*67e74705SXin Li if (StandardAttr &&
3833*67e74705SXin Li !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second)
3834*67e74705SXin Li Diag(AttrLoc, diag::err_cxx11_attribute_repeated)
3835*67e74705SXin Li << AttrName << SourceRange(SeenAttrs[AttrName]);
3836*67e74705SXin Li
3837*67e74705SXin Li // Parse attribute arguments
3838*67e74705SXin Li if (Tok.is(tok::l_paren))
3839*67e74705SXin Li AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, attrs, endLoc,
3840*67e74705SXin Li ScopeName, ScopeLoc);
3841*67e74705SXin Li
3842*67e74705SXin Li if (!AttrParsed)
3843*67e74705SXin Li attrs.addNew(AttrName,
3844*67e74705SXin Li SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
3845*67e74705SXin Li AttrLoc),
3846*67e74705SXin Li ScopeName, ScopeLoc, nullptr, 0, AttributeList::AS_CXX11);
3847*67e74705SXin Li
3848*67e74705SXin Li if (TryConsumeToken(tok::ellipsis))
3849*67e74705SXin Li Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
3850*67e74705SXin Li << AttrName->getName();
3851*67e74705SXin Li }
3852*67e74705SXin Li
3853*67e74705SXin Li if (ExpectAndConsume(tok::r_square))
3854*67e74705SXin Li SkipUntil(tok::r_square);
3855*67e74705SXin Li if (endLoc)
3856*67e74705SXin Li *endLoc = Tok.getLocation();
3857*67e74705SXin Li if (ExpectAndConsume(tok::r_square))
3858*67e74705SXin Li SkipUntil(tok::r_square);
3859*67e74705SXin Li }
3860*67e74705SXin Li
3861*67e74705SXin Li /// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq.
3862*67e74705SXin Li ///
3863*67e74705SXin Li /// attribute-specifier-seq:
3864*67e74705SXin Li /// attribute-specifier-seq[opt] attribute-specifier
ParseCXX11Attributes(ParsedAttributesWithRange & attrs,SourceLocation * endLoc)3865*67e74705SXin Li void Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
3866*67e74705SXin Li SourceLocation *endLoc) {
3867*67e74705SXin Li assert(getLangOpts().CPlusPlus11);
3868*67e74705SXin Li
3869*67e74705SXin Li SourceLocation StartLoc = Tok.getLocation(), Loc;
3870*67e74705SXin Li if (!endLoc)
3871*67e74705SXin Li endLoc = &Loc;
3872*67e74705SXin Li
3873*67e74705SXin Li do {
3874*67e74705SXin Li ParseCXX11AttributeSpecifier(attrs, endLoc);
3875*67e74705SXin Li } while (isCXX11AttributeSpecifier());
3876*67e74705SXin Li
3877*67e74705SXin Li attrs.Range = SourceRange(StartLoc, *endLoc);
3878*67e74705SXin Li }
3879*67e74705SXin Li
DiagnoseAndSkipCXX11Attributes()3880*67e74705SXin Li void Parser::DiagnoseAndSkipCXX11Attributes() {
3881*67e74705SXin Li // Start and end location of an attribute or an attribute list.
3882*67e74705SXin Li SourceLocation StartLoc = Tok.getLocation();
3883*67e74705SXin Li SourceLocation EndLoc = SkipCXX11Attributes();
3884*67e74705SXin Li
3885*67e74705SXin Li if (EndLoc.isValid()) {
3886*67e74705SXin Li SourceRange Range(StartLoc, EndLoc);
3887*67e74705SXin Li Diag(StartLoc, diag::err_attributes_not_allowed)
3888*67e74705SXin Li << Range;
3889*67e74705SXin Li }
3890*67e74705SXin Li }
3891*67e74705SXin Li
SkipCXX11Attributes()3892*67e74705SXin Li SourceLocation Parser::SkipCXX11Attributes() {
3893*67e74705SXin Li SourceLocation EndLoc;
3894*67e74705SXin Li
3895*67e74705SXin Li if (!isCXX11AttributeSpecifier())
3896*67e74705SXin Li return EndLoc;
3897*67e74705SXin Li
3898*67e74705SXin Li do {
3899*67e74705SXin Li if (Tok.is(tok::l_square)) {
3900*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_square);
3901*67e74705SXin Li T.consumeOpen();
3902*67e74705SXin Li T.skipToEnd();
3903*67e74705SXin Li EndLoc = T.getCloseLocation();
3904*67e74705SXin Li } else {
3905*67e74705SXin Li assert(Tok.is(tok::kw_alignas) && "not an attribute specifier");
3906*67e74705SXin Li ConsumeToken();
3907*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_paren);
3908*67e74705SXin Li if (!T.consumeOpen())
3909*67e74705SXin Li T.skipToEnd();
3910*67e74705SXin Li EndLoc = T.getCloseLocation();
3911*67e74705SXin Li }
3912*67e74705SXin Li } while (isCXX11AttributeSpecifier());
3913*67e74705SXin Li
3914*67e74705SXin Li return EndLoc;
3915*67e74705SXin Li }
3916*67e74705SXin Li
3917*67e74705SXin Li /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr]
3918*67e74705SXin Li ///
3919*67e74705SXin Li /// [MS] ms-attribute:
3920*67e74705SXin Li /// '[' token-seq ']'
3921*67e74705SXin Li ///
3922*67e74705SXin Li /// [MS] ms-attribute-seq:
3923*67e74705SXin Li /// ms-attribute[opt]
3924*67e74705SXin Li /// ms-attribute ms-attribute-seq
ParseMicrosoftAttributes(ParsedAttributes & attrs,SourceLocation * endLoc)3925*67e74705SXin Li void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
3926*67e74705SXin Li SourceLocation *endLoc) {
3927*67e74705SXin Li assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
3928*67e74705SXin Li
3929*67e74705SXin Li do {
3930*67e74705SXin Li // FIXME: If this is actually a C++11 attribute, parse it as one.
3931*67e74705SXin Li BalancedDelimiterTracker T(*this, tok::l_square);
3932*67e74705SXin Li T.consumeOpen();
3933*67e74705SXin Li SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch);
3934*67e74705SXin Li T.consumeClose();
3935*67e74705SXin Li if (endLoc)
3936*67e74705SXin Li *endLoc = T.getCloseLocation();
3937*67e74705SXin Li } while (Tok.is(tok::l_square));
3938*67e74705SXin Li }
3939*67e74705SXin Li
ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,AccessSpecifier & CurAS)3940*67e74705SXin Li void Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
3941*67e74705SXin Li AccessSpecifier& CurAS) {
3942*67e74705SXin Li IfExistsCondition Result;
3943*67e74705SXin Li if (ParseMicrosoftIfExistsCondition(Result))
3944*67e74705SXin Li return;
3945*67e74705SXin Li
3946*67e74705SXin Li BalancedDelimiterTracker Braces(*this, tok::l_brace);
3947*67e74705SXin Li if (Braces.consumeOpen()) {
3948*67e74705SXin Li Diag(Tok, diag::err_expected) << tok::l_brace;
3949*67e74705SXin Li return;
3950*67e74705SXin Li }
3951*67e74705SXin Li
3952*67e74705SXin Li switch (Result.Behavior) {
3953*67e74705SXin Li case IEB_Parse:
3954*67e74705SXin Li // Parse the declarations below.
3955*67e74705SXin Li break;
3956*67e74705SXin Li
3957*67e74705SXin Li case IEB_Dependent:
3958*67e74705SXin Li Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
3959*67e74705SXin Li << Result.IsIfExists;
3960*67e74705SXin Li // Fall through to skip.
3961*67e74705SXin Li
3962*67e74705SXin Li case IEB_Skip:
3963*67e74705SXin Li Braces.skipToEnd();
3964*67e74705SXin Li return;
3965*67e74705SXin Li }
3966*67e74705SXin Li
3967*67e74705SXin Li while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
3968*67e74705SXin Li // __if_exists, __if_not_exists can nest.
3969*67e74705SXin Li if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
3970*67e74705SXin Li ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
3971*67e74705SXin Li continue;
3972*67e74705SXin Li }
3973*67e74705SXin Li
3974*67e74705SXin Li // Check for extraneous top-level semicolon.
3975*67e74705SXin Li if (Tok.is(tok::semi)) {
3976*67e74705SXin Li ConsumeExtraSemi(InsideStruct, TagType);
3977*67e74705SXin Li continue;
3978*67e74705SXin Li }
3979*67e74705SXin Li
3980*67e74705SXin Li AccessSpecifier AS = getAccessSpecifierIfPresent();
3981*67e74705SXin Li if (AS != AS_none) {
3982*67e74705SXin Li // Current token is a C++ access specifier.
3983*67e74705SXin Li CurAS = AS;
3984*67e74705SXin Li SourceLocation ASLoc = Tok.getLocation();
3985*67e74705SXin Li ConsumeToken();
3986*67e74705SXin Li if (Tok.is(tok::colon))
3987*67e74705SXin Li Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
3988*67e74705SXin Li else
3989*67e74705SXin Li Diag(Tok, diag::err_expected) << tok::colon;
3990*67e74705SXin Li ConsumeToken();
3991*67e74705SXin Li continue;
3992*67e74705SXin Li }
3993*67e74705SXin Li
3994*67e74705SXin Li // Parse all the comma separated declarators.
3995*67e74705SXin Li ParseCXXClassMemberDeclaration(CurAS, nullptr);
3996*67e74705SXin Li }
3997*67e74705SXin Li
3998*67e74705SXin Li Braces.consumeClose();
3999*67e74705SXin Li }
4000