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