File: | src/gnu/usr.bin/clang/libclangParse/../../../llvm/clang/lib/Parse/ParseDeclCXX.cpp |
Warning: | line 633, column 9 Forming reference to null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- ParseDeclCXX.cpp - C++ Declaration Parsing -------------*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // This file implements the C++ Declaration portions of the Parser interfaces. | |||
10 | // | |||
11 | //===----------------------------------------------------------------------===// | |||
12 | ||||
13 | #include "clang/Parse/Parser.h" | |||
14 | #include "clang/AST/ASTContext.h" | |||
15 | #include "clang/AST/DeclTemplate.h" | |||
16 | #include "clang/AST/PrettyDeclStackTrace.h" | |||
17 | #include "clang/Basic/Attributes.h" | |||
18 | #include "clang/Basic/CharInfo.h" | |||
19 | #include "clang/Basic/OperatorKinds.h" | |||
20 | #include "clang/Basic/TargetInfo.h" | |||
21 | #include "clang/Parse/ParseDiagnostic.h" | |||
22 | #include "clang/Parse/RAIIObjectsForParser.h" | |||
23 | #include "clang/Sema/DeclSpec.h" | |||
24 | #include "clang/Sema/ParsedTemplate.h" | |||
25 | #include "clang/Sema/Scope.h" | |||
26 | #include "llvm/ADT/SmallString.h" | |||
27 | #include "llvm/Support/TimeProfiler.h" | |||
28 | ||||
29 | using namespace clang; | |||
30 | ||||
31 | /// ParseNamespace - We know that the current token is a namespace keyword. This | |||
32 | /// may either be a top level namespace or a block-level namespace alias. If | |||
33 | /// there was an inline keyword, it has already been parsed. | |||
34 | /// | |||
35 | /// namespace-definition: [C++: namespace.def] | |||
36 | /// named-namespace-definition | |||
37 | /// unnamed-namespace-definition | |||
38 | /// nested-namespace-definition | |||
39 | /// | |||
40 | /// named-namespace-definition: | |||
41 | /// 'inline'[opt] 'namespace' attributes[opt] identifier '{' | |||
42 | /// namespace-body '}' | |||
43 | /// | |||
44 | /// unnamed-namespace-definition: | |||
45 | /// 'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}' | |||
46 | /// | |||
47 | /// nested-namespace-definition: | |||
48 | /// 'namespace' enclosing-namespace-specifier '::' 'inline'[opt] | |||
49 | /// identifier '{' namespace-body '}' | |||
50 | /// | |||
51 | /// enclosing-namespace-specifier: | |||
52 | /// identifier | |||
53 | /// enclosing-namespace-specifier '::' 'inline'[opt] identifier | |||
54 | /// | |||
55 | /// namespace-alias-definition: [C++ 7.3.2: namespace.alias] | |||
56 | /// 'namespace' identifier '=' qualified-namespace-specifier ';' | |||
57 | /// | |||
58 | Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context, | |||
59 | SourceLocation &DeclEnd, | |||
60 | SourceLocation InlineLoc) { | |||
61 | assert(Tok.is(tok::kw_namespace) && "Not a namespace!")((void)0); | |||
62 | SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. | |||
63 | ObjCDeclContextSwitch ObjCDC(*this); | |||
64 | ||||
65 | if (Tok.is(tok::code_completion)) { | |||
66 | cutOffParsing(); | |||
67 | Actions.CodeCompleteNamespaceDecl(getCurScope()); | |||
68 | return nullptr; | |||
69 | } | |||
70 | ||||
71 | SourceLocation IdentLoc; | |||
72 | IdentifierInfo *Ident = nullptr; | |||
73 | InnerNamespaceInfoList ExtraNSs; | |||
74 | SourceLocation FirstNestedInlineLoc; | |||
75 | ||||
76 | ParsedAttributesWithRange attrs(AttrFactory); | |||
77 | SourceLocation attrLoc; | |||
78 | if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { | |||
79 | Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 | |||
80 | ? diag::warn_cxx14_compat_ns_enum_attribute | |||
81 | : diag::ext_ns_enum_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) && | |||
91 | (NextToken().is(tok::identifier) || | |||
92 | (NextToken().is(tok::kw_inline) && | |||
93 | GetLookAheadToken(2).is(tok::identifier)))) { | |||
94 | ||||
95 | InnerNamespaceInfo Info; | |||
96 | Info.NamespaceLoc = ConsumeToken(); | |||
97 | ||||
98 | if (Tok.is(tok::kw_inline)) { | |||
99 | Info.InlineLoc = ConsumeToken(); | |||
100 | if (FirstNestedInlineLoc.isInvalid()) | |||
101 | FirstNestedInlineLoc = Info.InlineLoc; | |||
102 | } | |||
103 | ||||
104 | Info.Ident = Tok.getIdentifierInfo(); | |||
105 | Info.IdentLoc = ConsumeToken(); | |||
106 | ||||
107 | ExtraNSs.push_back(Info); | |||
108 | } | |||
109 | } | |||
110 | ||||
111 | // A nested namespace definition cannot have attributes. | |||
112 | if (!ExtraNSs.empty() && attrLoc.isValid()) | |||
113 | Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute); | |||
114 | ||||
115 | // Read label attributes, if present. | |||
116 | if (Tok.is(tok::kw___attribute)) { | |||
117 | attrLoc = Tok.getLocation(); | |||
118 | ParseGNUAttributes(attrs); | |||
119 | } | |||
120 | ||||
121 | if (Tok.is(tok::equal)) { | |||
122 | if (!Ident) { | |||
123 | Diag(Tok, diag::err_expected) << tok::identifier; | |||
124 | // Skip to end of the definition and eat the ';'. | |||
125 | SkipUntil(tok::semi); | |||
126 | return nullptr; | |||
127 | } | |||
128 | if (attrLoc.isValid()) | |||
129 | Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias); | |||
130 | if (InlineLoc.isValid()) | |||
131 | Diag(InlineLoc, diag::err_inline_namespace_alias) | |||
132 | << FixItHint::CreateRemoval(InlineLoc); | |||
133 | Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); | |||
134 | return Actions.ConvertDeclToDeclGroup(NSAlias); | |||
135 | } | |||
136 | ||||
137 | BalancedDelimiterTracker T(*this, tok::l_brace); | |||
138 | if (T.consumeOpen()) { | |||
139 | if (Ident) | |||
140 | Diag(Tok, diag::err_expected) << tok::l_brace; | |||
141 | else | |||
142 | Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace; | |||
143 | return nullptr; | |||
144 | } | |||
145 | ||||
146 | if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() || | |||
147 | getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() || | |||
148 | getCurScope()->getFnParent()) { | |||
149 | Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope); | |||
150 | SkipUntil(tok::r_brace); | |||
151 | return nullptr; | |||
152 | } | |||
153 | ||||
154 | if (ExtraNSs.empty()) { | |||
155 | // Normal namespace definition, not a nested-namespace-definition. | |||
156 | } else if (InlineLoc.isValid()) { | |||
157 | Diag(InlineLoc, diag::err_inline_nested_namespace_definition); | |||
158 | } else if (getLangOpts().CPlusPlus20) { | |||
159 | Diag(ExtraNSs[0].NamespaceLoc, | |||
160 | diag::warn_cxx14_compat_nested_namespace_definition); | |||
161 | if (FirstNestedInlineLoc.isValid()) | |||
162 | Diag(FirstNestedInlineLoc, | |||
163 | diag::warn_cxx17_compat_inline_nested_namespace_definition); | |||
164 | } else if (getLangOpts().CPlusPlus17) { | |||
165 | Diag(ExtraNSs[0].NamespaceLoc, | |||
166 | diag::warn_cxx14_compat_nested_namespace_definition); | |||
167 | if (FirstNestedInlineLoc.isValid()) | |||
168 | Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition); | |||
169 | } else { | |||
170 | TentativeParsingAction TPA(*this); | |||
171 | SkipUntil(tok::r_brace, StopBeforeMatch); | |||
172 | Token rBraceToken = Tok; | |||
173 | TPA.Revert(); | |||
174 | ||||
175 | if (!rBraceToken.is(tok::r_brace)) { | |||
176 | Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition) | |||
177 | << SourceRange(ExtraNSs.front().NamespaceLoc, | |||
178 | ExtraNSs.back().IdentLoc); | |||
179 | } else { | |||
180 | std::string NamespaceFix; | |||
181 | for (const auto &ExtraNS : ExtraNSs) { | |||
182 | NamespaceFix += " { "; | |||
183 | if (ExtraNS.InlineLoc.isValid()) | |||
184 | NamespaceFix += "inline "; | |||
185 | NamespaceFix += "namespace "; | |||
186 | NamespaceFix += ExtraNS.Ident->getName(); | |||
187 | } | |||
188 | ||||
189 | std::string RBraces; | |||
190 | for (unsigned i = 0, e = ExtraNSs.size(); i != e; ++i) | |||
191 | RBraces += "} "; | |||
192 | ||||
193 | Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition) | |||
194 | << FixItHint::CreateReplacement( | |||
195 | SourceRange(ExtraNSs.front().NamespaceLoc, | |||
196 | ExtraNSs.back().IdentLoc), | |||
197 | NamespaceFix) | |||
198 | << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces); | |||
199 | } | |||
200 | ||||
201 | // Warn about nested inline namespaces. | |||
202 | if (FirstNestedInlineLoc.isValid()) | |||
203 | Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition); | |||
204 | } | |||
205 | ||||
206 | // If we're still good, complain about inline namespaces in non-C++0x now. | |||
207 | if (InlineLoc.isValid()) | |||
208 | Diag(InlineLoc, getLangOpts().CPlusPlus11 ? | |||
209 | diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace); | |||
210 | ||||
211 | // Enter a scope for the namespace. | |||
212 | ParseScope NamespaceScope(this, Scope::DeclScope); | |||
213 | ||||
214 | UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; | |||
215 | Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( | |||
216 | getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident, | |||
217 | T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl); | |||
218 | ||||
219 | PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl, | |||
220 | NamespaceLoc, "parsing namespace"); | |||
221 | ||||
222 | // Parse the contents of the namespace. This includes parsing recovery on | |||
223 | // any improperly nested namespaces. | |||
224 | ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T); | |||
225 | ||||
226 | // Leave the namespace scope. | |||
227 | NamespaceScope.Exit(); | |||
228 | ||||
229 | DeclEnd = T.getCloseLocation(); | |||
230 | Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd); | |||
231 | ||||
232 | return Actions.ConvertDeclToDeclGroup(NamespcDecl, | |||
233 | ImplicitUsingDirectiveDecl); | |||
234 | } | |||
235 | ||||
236 | /// ParseInnerNamespace - Parse the contents of a namespace. | |||
237 | void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs, | |||
238 | unsigned int index, SourceLocation &InlineLoc, | |||
239 | ParsedAttributes &attrs, | |||
240 | BalancedDelimiterTracker &Tracker) { | |||
241 | if (index == InnerNSs.size()) { | |||
242 | while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && | |||
243 | Tok.isNot(tok::eof)) { | |||
244 | ParsedAttributesWithRange attrs(AttrFactory); | |||
245 | MaybeParseCXX11Attributes(attrs); | |||
246 | ParseExternalDeclaration(attrs); | |||
247 | } | |||
248 | ||||
249 | // The caller is what called check -- we are simply calling | |||
250 | // the close for it. | |||
251 | Tracker.consumeClose(); | |||
252 | ||||
253 | return; | |||
254 | } | |||
255 | ||||
256 | // Handle a nested namespace definition. | |||
257 | // FIXME: Preserve the source information through to the AST rather than | |||
258 | // desugaring it here. | |||
259 | ParseScope NamespaceScope(this, Scope::DeclScope); | |||
260 | UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; | |||
261 | Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( | |||
262 | getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc, | |||
263 | InnerNSs[index].IdentLoc, InnerNSs[index].Ident, | |||
264 | Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl); | |||
265 | assert(!ImplicitUsingDirectiveDecl &&((void)0) | |||
266 | "nested namespace definition cannot define anonymous namespace")((void)0); | |||
267 | ||||
268 | ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker); | |||
269 | ||||
270 | NamespaceScope.Exit(); | |||
271 | Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation()); | |||
272 | } | |||
273 | ||||
274 | /// ParseNamespaceAlias - Parse the part after the '=' in a namespace | |||
275 | /// alias definition. | |||
276 | /// | |||
277 | Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, | |||
278 | SourceLocation AliasLoc, | |||
279 | IdentifierInfo *Alias, | |||
280 | SourceLocation &DeclEnd) { | |||
281 | assert(Tok.is(tok::equal) && "Not equal token")((void)0); | |||
282 | ||||
283 | ConsumeToken(); // eat the '='. | |||
284 | ||||
285 | if (Tok.is(tok::code_completion)) { | |||
286 | cutOffParsing(); | |||
287 | Actions.CodeCompleteNamespaceAliasDecl(getCurScope()); | |||
288 | return nullptr; | |||
289 | } | |||
290 | ||||
291 | CXXScopeSpec SS; | |||
292 | // Parse (optional) nested-name-specifier. | |||
293 | ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, | |||
294 | /*ObjectHadErrors=*/false, | |||
295 | /*EnteringContext=*/false, | |||
296 | /*MayBePseudoDestructor=*/nullptr, | |||
297 | /*IsTypename=*/false, | |||
298 | /*LastII=*/nullptr, | |||
299 | /*OnlyNamespace=*/true); | |||
300 | ||||
301 | if (Tok.isNot(tok::identifier)) { | |||
302 | Diag(Tok, diag::err_expected_namespace_name); | |||
303 | // Skip to end of the definition and eat the ';'. | |||
304 | SkipUntil(tok::semi); | |||
305 | return nullptr; | |||
306 | } | |||
307 | ||||
308 | if (SS.isInvalid()) { | |||
309 | // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier. | |||
310 | // Skip to end of the definition and eat the ';'. | |||
311 | SkipUntil(tok::semi); | |||
312 | return nullptr; | |||
313 | } | |||
314 | ||||
315 | // Parse identifier. | |||
316 | IdentifierInfo *Ident = Tok.getIdentifierInfo(); | |||
317 | SourceLocation IdentLoc = ConsumeToken(); | |||
318 | ||||
319 | // Eat the ';'. | |||
320 | DeclEnd = Tok.getLocation(); | |||
321 | if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name)) | |||
322 | SkipUntil(tok::semi); | |||
323 | ||||
324 | return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, | |||
325 | Alias, SS, IdentLoc, Ident); | |||
326 | } | |||
327 | ||||
328 | /// ParseLinkage - We know that the current token is a string_literal | |||
329 | /// and just before that, that extern was seen. | |||
330 | /// | |||
331 | /// linkage-specification: [C++ 7.5p2: dcl.link] | |||
332 | /// 'extern' string-literal '{' declaration-seq[opt] '}' | |||
333 | /// 'extern' string-literal declaration | |||
334 | /// | |||
335 | Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) { | |||
336 | assert(isTokenStringLiteral() && "Not a string literal!")((void)0); | |||
337 | ExprResult Lang = ParseStringLiteralExpression(false); | |||
338 | ||||
339 | ParseScope LinkageScope(this, Scope::DeclScope); | |||
340 | Decl *LinkageSpec = | |||
341 | Lang.isInvalid() | |||
342 | ? nullptr | |||
343 | : Actions.ActOnStartLinkageSpecification( | |||
344 | getCurScope(), DS.getSourceRange().getBegin(), Lang.get(), | |||
345 | Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation()); | |||
346 | ||||
347 | ParsedAttributesWithRange attrs(AttrFactory); | |||
348 | MaybeParseCXX11Attributes(attrs); | |||
349 | ||||
350 | if (Tok.isNot(tok::l_brace)) { | |||
351 | // Reset the source range in DS, as the leading "extern" | |||
352 | // does not really belong to the inner declaration ... | |||
353 | DS.SetRangeStart(SourceLocation()); | |||
354 | DS.SetRangeEnd(SourceLocation()); | |||
355 | // ... but anyway remember that such an "extern" was seen. | |||
356 | DS.setExternInLinkageSpec(true); | |||
357 | ParseExternalDeclaration(attrs, &DS); | |||
358 | return LinkageSpec ? Actions.ActOnFinishLinkageSpecification( | |||
359 | getCurScope(), LinkageSpec, SourceLocation()) | |||
360 | : nullptr; | |||
361 | } | |||
362 | ||||
363 | DS.abort(); | |||
364 | ||||
365 | ProhibitAttributes(attrs); | |||
366 | ||||
367 | BalancedDelimiterTracker T(*this, tok::l_brace); | |||
368 | T.consumeOpen(); | |||
369 | ||||
370 | unsigned NestedModules = 0; | |||
371 | while (true) { | |||
372 | switch (Tok.getKind()) { | |||
373 | case tok::annot_module_begin: | |||
374 | ++NestedModules; | |||
375 | ParseTopLevelDecl(); | |||
376 | continue; | |||
377 | ||||
378 | case tok::annot_module_end: | |||
379 | if (!NestedModules) | |||
380 | break; | |||
381 | --NestedModules; | |||
382 | ParseTopLevelDecl(); | |||
383 | continue; | |||
384 | ||||
385 | case tok::annot_module_include: | |||
386 | ParseTopLevelDecl(); | |||
387 | continue; | |||
388 | ||||
389 | case tok::eof: | |||
390 | break; | |||
391 | ||||
392 | case tok::r_brace: | |||
393 | if (!NestedModules) | |||
394 | break; | |||
395 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | |||
396 | default: | |||
397 | ParsedAttributesWithRange attrs(AttrFactory); | |||
398 | MaybeParseCXX11Attributes(attrs); | |||
399 | ParseExternalDeclaration(attrs); | |||
400 | continue; | |||
401 | } | |||
402 | ||||
403 | break; | |||
404 | } | |||
405 | ||||
406 | T.consumeClose(); | |||
407 | return LinkageSpec ? Actions.ActOnFinishLinkageSpecification( | |||
408 | getCurScope(), LinkageSpec, T.getCloseLocation()) | |||
409 | : nullptr; | |||
410 | } | |||
411 | ||||
412 | /// Parse a C++ Modules TS export-declaration. | |||
413 | /// | |||
414 | /// export-declaration: | |||
415 | /// 'export' declaration | |||
416 | /// 'export' '{' declaration-seq[opt] '}' | |||
417 | /// | |||
418 | Decl *Parser::ParseExportDeclaration() { | |||
419 | assert(Tok.is(tok::kw_export))((void)0); | |||
420 | SourceLocation ExportLoc = ConsumeToken(); | |||
421 | ||||
422 | ParseScope ExportScope(this, Scope::DeclScope); | |||
423 | Decl *ExportDecl = Actions.ActOnStartExportDecl( | |||
424 | getCurScope(), ExportLoc, | |||
425 | Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation()); | |||
426 | ||||
427 | if (Tok.isNot(tok::l_brace)) { | |||
428 | // FIXME: Factor out a ParseExternalDeclarationWithAttrs. | |||
429 | ParsedAttributesWithRange Attrs(AttrFactory); | |||
430 | MaybeParseCXX11Attributes(Attrs); | |||
431 | MaybeParseMicrosoftAttributes(Attrs); | |||
432 | ParseExternalDeclaration(Attrs); | |||
433 | return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl, | |||
434 | SourceLocation()); | |||
435 | } | |||
436 | ||||
437 | BalancedDelimiterTracker T(*this, tok::l_brace); | |||
438 | T.consumeOpen(); | |||
439 | ||||
440 | // The Modules TS draft says "An export-declaration shall declare at least one | |||
441 | // entity", but the intent is that it shall contain at least one declaration. | |||
442 | if (Tok.is(tok::r_brace) && getLangOpts().ModulesTS) { | |||
443 | Diag(ExportLoc, diag::err_export_empty) | |||
444 | << SourceRange(ExportLoc, Tok.getLocation()); | |||
445 | } | |||
446 | ||||
447 | while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && | |||
448 | Tok.isNot(tok::eof)) { | |||
449 | ParsedAttributesWithRange Attrs(AttrFactory); | |||
450 | MaybeParseCXX11Attributes(Attrs); | |||
451 | MaybeParseMicrosoftAttributes(Attrs); | |||
452 | ParseExternalDeclaration(Attrs); | |||
453 | } | |||
454 | ||||
455 | T.consumeClose(); | |||
456 | return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl, | |||
457 | T.getCloseLocation()); | |||
458 | } | |||
459 | ||||
460 | /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or | |||
461 | /// using-directive. Assumes that current token is 'using'. | |||
462 | Parser::DeclGroupPtrTy | |||
463 | Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context, | |||
464 | const ParsedTemplateInfo &TemplateInfo, | |||
465 | SourceLocation &DeclEnd, | |||
466 | ParsedAttributesWithRange &attrs) { | |||
467 | assert(Tok.is(tok::kw_using) && "Not using token")((void)0); | |||
468 | ObjCDeclContextSwitch ObjCDC(*this); | |||
469 | ||||
470 | // Eat 'using'. | |||
471 | SourceLocation UsingLoc = ConsumeToken(); | |||
472 | ||||
473 | if (Tok.is(tok::code_completion)) { | |||
| ||||
474 | cutOffParsing(); | |||
475 | Actions.CodeCompleteUsing(getCurScope()); | |||
476 | return nullptr; | |||
477 | } | |||
478 | ||||
479 | // Consume unexpected 'template' keywords. | |||
480 | while (Tok.is(tok::kw_template)) { | |||
481 | SourceLocation TemplateLoc = ConsumeToken(); | |||
482 | Diag(TemplateLoc, diag::err_unexpected_template_after_using) | |||
483 | << FixItHint::CreateRemoval(TemplateLoc); | |||
484 | } | |||
485 | ||||
486 | // 'using namespace' means this is a using-directive. | |||
487 | if (Tok.is(tok::kw_namespace)) { | |||
488 | // Template parameters are always an error here. | |||
489 | if (TemplateInfo.Kind) { | |||
490 | SourceRange R = TemplateInfo.getSourceRange(); | |||
491 | Diag(UsingLoc, diag::err_templated_using_directive_declaration) | |||
492 | << 0 /* directive */ << R << FixItHint::CreateRemoval(R); | |||
493 | } | |||
494 | ||||
495 | Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs); | |||
496 | return Actions.ConvertDeclToDeclGroup(UsingDir); | |||
497 | } | |||
498 | ||||
499 | // Otherwise, it must be a using-declaration or an alias-declaration. | |||
500 | return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, attrs, | |||
501 | AS_none); | |||
502 | } | |||
503 | ||||
504 | /// ParseUsingDirective - Parse C++ using-directive, assumes | |||
505 | /// that current token is 'namespace' and 'using' was already parsed. | |||
506 | /// | |||
507 | /// using-directive: [C++ 7.3.p4: namespace.udir] | |||
508 | /// 'using' 'namespace' ::[opt] nested-name-specifier[opt] | |||
509 | /// namespace-name ; | |||
510 | /// [GNU] using-directive: | |||
511 | /// 'using' 'namespace' ::[opt] nested-name-specifier[opt] | |||
512 | /// namespace-name attributes[opt] ; | |||
513 | /// | |||
514 | Decl *Parser::ParseUsingDirective(DeclaratorContext Context, | |||
515 | SourceLocation UsingLoc, | |||
516 | SourceLocation &DeclEnd, | |||
517 | ParsedAttributes &attrs) { | |||
518 | assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token")((void)0); | |||
519 | ||||
520 | // Eat 'namespace'. | |||
521 | SourceLocation NamespcLoc = ConsumeToken(); | |||
522 | ||||
523 | if (Tok.is(tok::code_completion)) { | |||
524 | cutOffParsing(); | |||
525 | Actions.CodeCompleteUsingDirective(getCurScope()); | |||
526 | return nullptr; | |||
527 | } | |||
528 | ||||
529 | CXXScopeSpec SS; | |||
530 | // Parse (optional) nested-name-specifier. | |||
531 | ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, | |||
532 | /*ObjectHadErrors=*/false, | |||
533 | /*EnteringContext=*/false, | |||
534 | /*MayBePseudoDestructor=*/nullptr, | |||
535 | /*IsTypename=*/false, | |||
536 | /*LastII=*/nullptr, | |||
537 | /*OnlyNamespace=*/true); | |||
538 | ||||
539 | IdentifierInfo *NamespcName = nullptr; | |||
540 | SourceLocation IdentLoc = SourceLocation(); | |||
541 | ||||
542 | // Parse namespace-name. | |||
543 | if (Tok.isNot(tok::identifier)) { | |||
544 | Diag(Tok, diag::err_expected_namespace_name); | |||
545 | // If there was invalid namespace name, skip to end of decl, and eat ';'. | |||
546 | SkipUntil(tok::semi); | |||
547 | // FIXME: Are there cases, when we would like to call ActOnUsingDirective? | |||
548 | return nullptr; | |||
549 | } | |||
550 | ||||
551 | if (SS.isInvalid()) { | |||
552 | // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier. | |||
553 | // Skip to end of the definition and eat the ';'. | |||
554 | SkipUntil(tok::semi); | |||
555 | return nullptr; | |||
556 | } | |||
557 | ||||
558 | // Parse identifier. | |||
559 | NamespcName = Tok.getIdentifierInfo(); | |||
560 | IdentLoc = ConsumeToken(); | |||
561 | ||||
562 | // Parse (optional) attributes (most likely GNU strong-using extension). | |||
563 | bool GNUAttr = false; | |||
564 | if (Tok.is(tok::kw___attribute)) { | |||
565 | GNUAttr = true; | |||
566 | ParseGNUAttributes(attrs); | |||
567 | } | |||
568 | ||||
569 | // Eat ';'. | |||
570 | DeclEnd = Tok.getLocation(); | |||
571 | if (ExpectAndConsume(tok::semi, | |||
572 | GNUAttr ? diag::err_expected_semi_after_attribute_list | |||
573 | : diag::err_expected_semi_after_namespace_name)) | |||
574 | SkipUntil(tok::semi); | |||
575 | ||||
576 | return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS, | |||
577 | IdentLoc, NamespcName, attrs); | |||
578 | } | |||
579 | ||||
580 | /// Parse a using-declarator (or the identifier in a C++11 alias-declaration). | |||
581 | /// | |||
582 | /// using-declarator: | |||
583 | /// 'typename'[opt] nested-name-specifier unqualified-id | |||
584 | /// | |||
585 | bool Parser::ParseUsingDeclarator(DeclaratorContext Context, | |||
586 | UsingDeclarator &D) { | |||
587 | D.clear(); | |||
588 | ||||
589 | // Ignore optional 'typename'. | |||
590 | // FIXME: This is wrong; we should parse this as a typename-specifier. | |||
591 | TryConsumeToken(tok::kw_typename, D.TypenameLoc); | |||
592 | ||||
593 | if (Tok.is(tok::kw___super)) { | |||
594 | Diag(Tok.getLocation(), diag::err_super_in_using_declaration); | |||
595 | return true; | |||
596 | } | |||
597 | ||||
598 | // Parse nested-name-specifier. | |||
599 | IdentifierInfo *LastII = nullptr; | |||
600 | if (ParseOptionalCXXScopeSpecifier(D.SS, /*ObjectType=*/nullptr, | |||
601 | /*ObjectHadErrors=*/false, | |||
602 | /*EnteringContext=*/false, | |||
603 | /*MayBePseudoDtor=*/nullptr, | |||
604 | /*IsTypename=*/false, | |||
605 | /*LastII=*/&LastII, | |||
606 | /*OnlyNamespace=*/false, | |||
607 | /*InUsingDeclaration=*/true)) | |||
608 | ||||
609 | return true; | |||
610 | if (D.SS.isInvalid()) | |||
611 | return true; | |||
612 | ||||
613 | // Parse the unqualified-id. We allow parsing of both constructor and | |||
614 | // destructor names and allow the action module to diagnose any semantic | |||
615 | // errors. | |||
616 | // | |||
617 | // C++11 [class.qual]p2: | |||
618 | // [...] in a using-declaration that is a member-declaration, if the name | |||
619 | // specified after the nested-name-specifier is the same as the identifier | |||
620 | // or the simple-template-id's template-name in the last component of the | |||
621 | // nested-name-specifier, the name is [...] considered to name the | |||
622 | // constructor. | |||
623 | if (getLangOpts().CPlusPlus11 && Context == DeclaratorContext::Member && | |||
624 | Tok.is(tok::identifier) && | |||
625 | (NextToken().is(tok::semi) || NextToken().is(tok::comma) || | |||
626 | NextToken().is(tok::ellipsis) || NextToken().is(tok::l_square) || | |||
627 | NextToken().is(tok::kw___attribute)) && | |||
628 | D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() && | |||
629 | !D.SS.getScopeRep()->getAsNamespace() && | |||
630 | !D.SS.getScopeRep()->getAsNamespaceAlias()) { | |||
631 | SourceLocation IdLoc = ConsumeToken(); | |||
632 | ParsedType Type = | |||
633 | Actions.getInheritingConstructorName(D.SS, IdLoc, *LastII); | |||
| ||||
634 | D.Name.setConstructorName(Type, IdLoc, IdLoc); | |||
635 | } else { | |||
636 | if (ParseUnqualifiedId( | |||
637 | D.SS, /*ObjectType=*/nullptr, | |||
638 | /*ObjectHadErrors=*/false, /*EnteringContext=*/false, | |||
639 | /*AllowDestructorName=*/true, | |||
640 | /*AllowConstructorName=*/ | |||
641 | !(Tok.is(tok::identifier) && NextToken().is(tok::equal)), | |||
642 | /*AllowDeductionGuide=*/false, nullptr, D.Name)) | |||
643 | return true; | |||
644 | } | |||
645 | ||||
646 | if (TryConsumeToken(tok::ellipsis, D.EllipsisLoc)) | |||
647 | Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 ? | |||
648 | diag::warn_cxx17_compat_using_declaration_pack : | |||
649 | diag::ext_using_declaration_pack); | |||
650 | ||||
651 | return false; | |||
652 | } | |||
653 | ||||
654 | /// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration. | |||
655 | /// Assumes that 'using' was already seen. | |||
656 | /// | |||
657 | /// using-declaration: [C++ 7.3.p3: namespace.udecl] | |||
658 | /// 'using' using-declarator-list[opt] ; | |||
659 | /// | |||
660 | /// using-declarator-list: [C++1z] | |||
661 | /// using-declarator '...'[opt] | |||
662 | /// using-declarator-list ',' using-declarator '...'[opt] | |||
663 | /// | |||
664 | /// using-declarator-list: [C++98-14] | |||
665 | /// using-declarator | |||
666 | /// | |||
667 | /// alias-declaration: C++11 [dcl.dcl]p1 | |||
668 | /// 'using' identifier attribute-specifier-seq[opt] = type-id ; | |||
669 | /// | |||
670 | /// using-enum-declaration: [C++20, dcl.enum] | |||
671 | /// 'using' elaborated-enum-specifier ; | |||
672 | /// | |||
673 | /// elaborated-enum-specifier: | |||
674 | /// 'enum' nested-name-specifier[opt] identifier | |||
675 | Parser::DeclGroupPtrTy | |||
676 | Parser::ParseUsingDeclaration( | |||
677 | DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo, | |||
678 | SourceLocation UsingLoc, SourceLocation &DeclEnd, | |||
679 | ParsedAttributesWithRange &PrefixAttrs, AccessSpecifier AS) { | |||
680 | SourceLocation UELoc; | |||
681 | if (TryConsumeToken(tok::kw_enum, UELoc)) { | |||
682 | // C++20 using-enum | |||
683 | Diag(UELoc, getLangOpts().CPlusPlus20 | |||
684 | ? diag::warn_cxx17_compat_using_enum_declaration | |||
685 | : diag::ext_using_enum_declaration); | |||
686 | ||||
687 | DiagnoseCXX11AttributeExtension(PrefixAttrs); | |||
688 | ||||
689 | DeclSpec DS(AttrFactory); | |||
690 | ParseEnumSpecifier(UELoc, DS, TemplateInfo, AS, | |||
691 | // DSC_trailing has the semantics we desire | |||
692 | DeclSpecContext::DSC_trailing); | |||
693 | ||||
694 | if (TemplateInfo.Kind) { | |||
695 | SourceRange R = TemplateInfo.getSourceRange(); | |||
696 | Diag(UsingLoc, diag::err_templated_using_directive_declaration) | |||
697 | << 1 /* declaration */ << R << FixItHint::CreateRemoval(R); | |||
698 | ||||
699 | return nullptr; | |||
700 | } | |||
701 | ||||
702 | Decl *UED = Actions.ActOnUsingEnumDeclaration(getCurScope(), AS, UsingLoc, | |||
703 | UELoc, DS); | |||
704 | DeclEnd = Tok.getLocation(); | |||
705 | if (ExpectAndConsume(tok::semi, diag::err_expected_after, | |||
706 | "using-enum declaration")) | |||
707 | SkipUntil(tok::semi); | |||
708 | ||||
709 | return Actions.ConvertDeclToDeclGroup(UED); | |||
710 | } | |||
711 | ||||
712 | // Check for misplaced attributes before the identifier in an | |||
713 | // alias-declaration. | |||
714 | ParsedAttributesWithRange MisplacedAttrs(AttrFactory); | |||
715 | MaybeParseCXX11Attributes(MisplacedAttrs); | |||
716 | ||||
717 | UsingDeclarator D; | |||
718 | bool InvalidDeclarator = ParseUsingDeclarator(Context, D); | |||
719 | ||||
720 | ParsedAttributesWithRange Attrs(AttrFactory); | |||
721 | MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs); | |||
722 | ||||
723 | // If we had any misplaced attributes from earlier, this is where they | |||
724 | // should have been written. | |||
725 | if (MisplacedAttrs.Range.isValid()) { | |||
726 | Diag(MisplacedAttrs.Range.getBegin(), diag::err_attributes_not_allowed) | |||
727 | << FixItHint::CreateInsertionFromRange( | |||
728 | Tok.getLocation(), | |||
729 | CharSourceRange::getTokenRange(MisplacedAttrs.Range)) | |||
730 | << FixItHint::CreateRemoval(MisplacedAttrs.Range); | |||
731 | Attrs.takeAllFrom(MisplacedAttrs); | |||
732 | } | |||
733 | ||||
734 | // Maybe this is an alias-declaration. | |||
735 | if (Tok.is(tok::equal)) { | |||
736 | if (InvalidDeclarator) { | |||
737 | SkipUntil(tok::semi); | |||
738 | return nullptr; | |||
739 | } | |||
740 | ||||
741 | ProhibitAttributes(PrefixAttrs); | |||
742 | ||||
743 | Decl *DeclFromDeclSpec = nullptr; | |||
744 | Decl *AD = ParseAliasDeclarationAfterDeclarator( | |||
745 | TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec); | |||
746 | return Actions.ConvertDeclToDeclGroup(AD, DeclFromDeclSpec); | |||
747 | } | |||
748 | ||||
749 | DiagnoseCXX11AttributeExtension(PrefixAttrs); | |||
750 | ||||
751 | // Diagnose an attempt to declare a templated using-declaration. | |||
752 | // In C++11, alias-declarations can be templates: | |||
753 | // template <...> using id = type; | |||
754 | if (TemplateInfo.Kind) { | |||
755 | SourceRange R = TemplateInfo.getSourceRange(); | |||
756 | Diag(UsingLoc, diag::err_templated_using_directive_declaration) | |||
757 | << 1 /* declaration */ << R << FixItHint::CreateRemoval(R); | |||
758 | ||||
759 | // Unfortunately, we have to bail out instead of recovering by | |||
760 | // ignoring the parameters, just in case the nested name specifier | |||
761 | // depends on the parameters. | |||
762 | return nullptr; | |||
763 | } | |||
764 | ||||
765 | SmallVector<Decl *, 8> DeclsInGroup; | |||
766 | while (true) { | |||
767 | // Parse (optional) attributes. | |||
768 | MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs); | |||
769 | DiagnoseCXX11AttributeExtension(Attrs); | |||
770 | Attrs.addAll(PrefixAttrs.begin(), PrefixAttrs.end()); | |||
771 | ||||
772 | if (InvalidDeclarator) | |||
773 | SkipUntil(tok::comma, tok::semi, StopBeforeMatch); | |||
774 | else { | |||
775 | // "typename" keyword is allowed for identifiers only, | |||
776 | // because it may be a type definition. | |||
777 | if (D.TypenameLoc.isValid() && | |||
778 | D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) { | |||
779 | Diag(D.Name.getSourceRange().getBegin(), | |||
780 | diag::err_typename_identifiers_only) | |||
781 | << FixItHint::CreateRemoval(SourceRange(D.TypenameLoc)); | |||
782 | // Proceed parsing, but discard the typename keyword. | |||
783 | D.TypenameLoc = SourceLocation(); | |||
784 | } | |||
785 | ||||
786 | Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc, | |||
787 | D.TypenameLoc, D.SS, D.Name, | |||
788 | D.EllipsisLoc, Attrs); | |||
789 | if (UD) | |||
790 | DeclsInGroup.push_back(UD); | |||
791 | } | |||
792 | ||||
793 | if (!TryConsumeToken(tok::comma)) | |||
794 | break; | |||
795 | ||||
796 | // Parse another using-declarator. | |||
797 | Attrs.clear(); | |||
798 | InvalidDeclarator = ParseUsingDeclarator(Context, D); | |||
799 | } | |||
800 | ||||
801 | if (DeclsInGroup.size() > 1) | |||
802 | Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 ? | |||
803 | diag::warn_cxx17_compat_multi_using_declaration : | |||
804 | diag::ext_multi_using_declaration); | |||
805 | ||||
806 | // Eat ';'. | |||
807 | DeclEnd = Tok.getLocation(); | |||
808 | if (ExpectAndConsume(tok::semi, diag::err_expected_after, | |||
809 | !Attrs.empty() ? "attributes list" | |||
810 | : UELoc.isValid() ? "using-enum declaration" | |||
811 | : "using declaration")) | |||
812 | SkipUntil(tok::semi); | |||
813 | ||||
814 | return Actions.BuildDeclaratorGroup(DeclsInGroup); | |||
815 | } | |||
816 | ||||
817 | Decl *Parser::ParseAliasDeclarationAfterDeclarator( | |||
818 | const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc, | |||
819 | UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS, | |||
820 | ParsedAttributes &Attrs, Decl **OwnedType) { | |||
821 | if (ExpectAndConsume(tok::equal)) { | |||
822 | SkipUntil(tok::semi); | |||
823 | return nullptr; | |||
824 | } | |||
825 | ||||
826 | Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ? | |||
827 | diag::warn_cxx98_compat_alias_declaration : | |||
828 | diag::ext_alias_declaration); | |||
829 | ||||
830 | // Type alias templates cannot be specialized. | |||
831 | int SpecKind = -1; | |||
832 | if (TemplateInfo.Kind == ParsedTemplateInfo::Template && | |||
833 | D.Name.getKind() == UnqualifiedIdKind::IK_TemplateId) | |||
834 | SpecKind = 0; | |||
835 | if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) | |||
836 | SpecKind = 1; | |||
837 | if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) | |||
838 | SpecKind = 2; | |||
839 | if (SpecKind != -1) { | |||
840 | SourceRange Range; | |||
841 | if (SpecKind == 0) | |||
842 | Range = SourceRange(D.Name.TemplateId->LAngleLoc, | |||
843 | D.Name.TemplateId->RAngleLoc); | |||
844 | else | |||
845 | Range = TemplateInfo.getSourceRange(); | |||
846 | Diag(Range.getBegin(), diag::err_alias_declaration_specialization) | |||
847 | << SpecKind << Range; | |||
848 | SkipUntil(tok::semi); | |||
849 | return nullptr; | |||
850 | } | |||
851 | ||||
852 | // Name must be an identifier. | |||
853 | if (D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) { | |||
854 | Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier); | |||
855 | // No removal fixit: can't recover from this. | |||
856 | SkipUntil(tok::semi); | |||
857 | return nullptr; | |||
858 | } else if (D.TypenameLoc.isValid()) | |||
859 | Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier) | |||
860 | << FixItHint::CreateRemoval(SourceRange( | |||
861 | D.TypenameLoc, | |||
862 | D.SS.isNotEmpty() ? D.SS.getEndLoc() : D.TypenameLoc)); | |||
863 | else if (D.SS.isNotEmpty()) | |||
864 | Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier) | |||
865 | << FixItHint::CreateRemoval(D.SS.getRange()); | |||
866 | if (D.EllipsisLoc.isValid()) | |||
867 | Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion) | |||
868 | << FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc)); | |||
869 | ||||
870 | Decl *DeclFromDeclSpec = nullptr; | |||
871 | TypeResult TypeAlias = | |||
872 | ParseTypeName(nullptr, | |||
873 | TemplateInfo.Kind ? DeclaratorContext::AliasTemplate | |||
874 | : DeclaratorContext::AliasDecl, | |||
875 | AS, &DeclFromDeclSpec, &Attrs); | |||
876 | if (OwnedType) | |||
877 | *OwnedType = DeclFromDeclSpec; | |||
878 | ||||
879 | // Eat ';'. | |||
880 | DeclEnd = Tok.getLocation(); | |||
881 | if (ExpectAndConsume(tok::semi, diag::err_expected_after, | |||
882 | !Attrs.empty() ? "attributes list" | |||
883 | : "alias declaration")) | |||
884 | SkipUntil(tok::semi); | |||
885 | ||||
886 | TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; | |||
887 | MultiTemplateParamsArg TemplateParamsArg( | |||
888 | TemplateParams ? TemplateParams->data() : nullptr, | |||
889 | TemplateParams ? TemplateParams->size() : 0); | |||
890 | return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg, | |||
891 | UsingLoc, D.Name, Attrs, TypeAlias, | |||
892 | DeclFromDeclSpec); | |||
893 | } | |||
894 | ||||
895 | static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr, | |||
896 | SourceLocation EndExprLoc) { | |||
897 | if (const auto *BO = dyn_cast_or_null<BinaryOperator>(AssertExpr)) { | |||
898 | if (BO->getOpcode() == BO_LAnd && | |||
899 | isa<StringLiteral>(BO->getRHS()->IgnoreImpCasts())) | |||
900 | return FixItHint::CreateReplacement(BO->getOperatorLoc(), ","); | |||
901 | } | |||
902 | return FixItHint::CreateInsertion(EndExprLoc, ", \"\""); | |||
903 | } | |||
904 | ||||
905 | /// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration. | |||
906 | /// | |||
907 | /// [C++0x] static_assert-declaration: | |||
908 | /// static_assert ( constant-expression , string-literal ) ; | |||
909 | /// | |||
910 | /// [C11] static_assert-declaration: | |||
911 | /// _Static_assert ( constant-expression , string-literal ) ; | |||
912 | /// | |||
913 | Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ | |||
914 | assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&((void)0) | |||
915 | "Not a static_assert declaration")((void)0); | |||
916 | ||||
917 | if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) | |||
918 | Diag(Tok, diag::ext_c11_feature) << Tok.getName(); | |||
919 | if (Tok.is(tok::kw_static_assert)) { | |||
920 | if (!getLangOpts().CPlusPlus) | |||
921 | Diag(Tok, diag::ext_ms_static_assert) | |||
922 | << FixItHint::CreateReplacement(Tok.getLocation(), "_Static_assert"); | |||
923 | else | |||
924 | Diag(Tok, diag::warn_cxx98_compat_static_assert); | |||
925 | } | |||
926 | ||||
927 | SourceLocation StaticAssertLoc = ConsumeToken(); | |||
928 | ||||
929 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
930 | if (T.consumeOpen()) { | |||
931 | Diag(Tok, diag::err_expected) << tok::l_paren; | |||
932 | SkipMalformedDecl(); | |||
933 | return nullptr; | |||
934 | } | |||
935 | ||||
936 | EnterExpressionEvaluationContext ConstantEvaluated( | |||
937 | Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); | |||
938 | ExprResult AssertExpr(ParseConstantExpressionInExprEvalContext()); | |||
939 | if (AssertExpr.isInvalid()) { | |||
940 | SkipMalformedDecl(); | |||
941 | return nullptr; | |||
942 | } | |||
943 | ||||
944 | ExprResult AssertMessage; | |||
945 | if (Tok.is(tok::r_paren)) { | |||
946 | unsigned DiagVal; | |||
947 | if (getLangOpts().CPlusPlus17) | |||
948 | DiagVal = diag::warn_cxx14_compat_static_assert_no_message; | |||
949 | else if (getLangOpts().CPlusPlus) | |||
950 | DiagVal = diag::ext_cxx_static_assert_no_message; | |||
951 | else if (getLangOpts().C2x) | |||
952 | DiagVal = diag::warn_c17_compat_static_assert_no_message; | |||
953 | else | |||
954 | DiagVal = diag::ext_c_static_assert_no_message; | |||
955 | Diag(Tok, DiagVal) << getStaticAssertNoMessageFixIt(AssertExpr.get(), | |||
956 | Tok.getLocation()); | |||
957 | } else { | |||
958 | if (ExpectAndConsume(tok::comma)) { | |||
959 | SkipUntil(tok::semi); | |||
960 | return nullptr; | |||
961 | } | |||
962 | ||||
963 | if (!isTokenStringLiteral()) { | |||
964 | Diag(Tok, diag::err_expected_string_literal) | |||
965 | << /*Source='static_assert'*/1; | |||
966 | SkipMalformedDecl(); | |||
967 | return nullptr; | |||
968 | } | |||
969 | ||||
970 | AssertMessage = ParseStringLiteralExpression(); | |||
971 | if (AssertMessage.isInvalid()) { | |||
972 | SkipMalformedDecl(); | |||
973 | return nullptr; | |||
974 | } | |||
975 | } | |||
976 | ||||
977 | T.consumeClose(); | |||
978 | ||||
979 | DeclEnd = Tok.getLocation(); | |||
980 | ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); | |||
981 | ||||
982 | return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, | |||
983 | AssertExpr.get(), | |||
984 | AssertMessage.get(), | |||
985 | T.getCloseLocation()); | |||
986 | } | |||
987 | ||||
988 | /// ParseDecltypeSpecifier - Parse a C++11 decltype specifier. | |||
989 | /// | |||
990 | /// 'decltype' ( expression ) | |||
991 | /// 'decltype' ( 'auto' ) [C++1y] | |||
992 | /// | |||
993 | SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { | |||
994 | assert(Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)((void)0) | |||
995 | && "Not a decltype specifier")((void)0); | |||
996 | ||||
997 | ExprResult Result; | |||
998 | SourceLocation StartLoc = Tok.getLocation(); | |||
999 | SourceLocation EndLoc; | |||
1000 | ||||
1001 | if (Tok.is(tok::annot_decltype)) { | |||
1002 | Result = getExprAnnotation(Tok); | |||
1003 | EndLoc = Tok.getAnnotationEndLoc(); | |||
1004 | ConsumeAnnotationToken(); | |||
1005 | if (Result.isInvalid()) { | |||
1006 | DS.SetTypeSpecError(); | |||
1007 | return EndLoc; | |||
1008 | } | |||
1009 | } else { | |||
1010 | if (Tok.getIdentifierInfo()->isStr("decltype")) | |||
1011 | Diag(Tok, diag::warn_cxx98_compat_decltype); | |||
1012 | ||||
1013 | ConsumeToken(); | |||
1014 | ||||
1015 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
1016 | if (T.expectAndConsume(diag::err_expected_lparen_after, | |||
1017 | "decltype", tok::r_paren)) { | |||
1018 | DS.SetTypeSpecError(); | |||
1019 | return T.getOpenLocation() == Tok.getLocation() ? | |||
1020 | StartLoc : T.getOpenLocation(); | |||
1021 | } | |||
1022 | ||||
1023 | // Check for C++1y 'decltype(auto)'. | |||
1024 | if (Tok.is(tok::kw_auto)) { | |||
1025 | // No need to disambiguate here: an expression can't start with 'auto', | |||
1026 | // because the typename-specifier in a function-style cast operation can't | |||
1027 | // be 'auto'. | |||
1028 | Diag(Tok.getLocation(), | |||
1029 | getLangOpts().CPlusPlus14 | |||
1030 | ? diag::warn_cxx11_compat_decltype_auto_type_specifier | |||
1031 | : diag::ext_decltype_auto_type_specifier); | |||
1032 | ConsumeToken(); | |||
1033 | } else { | |||
1034 | // Parse the expression | |||
1035 | ||||
1036 | // C++11 [dcl.type.simple]p4: | |||
1037 | // The operand of the decltype specifier is an unevaluated operand. | |||
1038 | EnterExpressionEvaluationContext Unevaluated( | |||
1039 | Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, | |||
1040 | Sema::ExpressionEvaluationContextRecord::EK_Decltype); | |||
1041 | Result = Actions.CorrectDelayedTyposInExpr( | |||
1042 | ParseExpression(), /*InitDecl=*/nullptr, | |||
1043 | /*RecoverUncorrectedTypos=*/false, | |||
1044 | [](Expr *E) { return E->hasPlaceholderType() ? ExprError() : E; }); | |||
1045 | if (Result.isInvalid()) { | |||
1046 | DS.SetTypeSpecError(); | |||
1047 | if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) { | |||
1048 | EndLoc = ConsumeParen(); | |||
1049 | } else { | |||
1050 | if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) { | |||
1051 | // Backtrack to get the location of the last token before the semi. | |||
1052 | PP.RevertCachedTokens(2); | |||
1053 | ConsumeToken(); // the semi. | |||
1054 | EndLoc = ConsumeAnyToken(); | |||
1055 | assert(Tok.is(tok::semi))((void)0); | |||
1056 | } else { | |||
1057 | EndLoc = Tok.getLocation(); | |||
1058 | } | |||
1059 | } | |||
1060 | return EndLoc; | |||
1061 | } | |||
1062 | ||||
1063 | Result = Actions.ActOnDecltypeExpression(Result.get()); | |||
1064 | } | |||
1065 | ||||
1066 | // Match the ')' | |||
1067 | T.consumeClose(); | |||
1068 | if (T.getCloseLocation().isInvalid()) { | |||
1069 | DS.SetTypeSpecError(); | |||
1070 | // FIXME: this should return the location of the last token | |||
1071 | // that was consumed (by "consumeClose()") | |||
1072 | return T.getCloseLocation(); | |||
1073 | } | |||
1074 | ||||
1075 | if (Result.isInvalid()) { | |||
1076 | DS.SetTypeSpecError(); | |||
1077 | return T.getCloseLocation(); | |||
1078 | } | |||
1079 | ||||
1080 | EndLoc = T.getCloseLocation(); | |||
1081 | } | |||
1082 | assert(!Result.isInvalid())((void)0); | |||
1083 | ||||
1084 | const char *PrevSpec = nullptr; | |||
1085 | unsigned DiagID; | |||
1086 | const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy(); | |||
1087 | // Check for duplicate type specifiers (e.g. "int decltype(a)"). | |||
1088 | if (Result.get() | |||
1089 | ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec, | |||
1090 | DiagID, Result.get(), Policy) | |||
1091 | : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc, PrevSpec, | |||
1092 | DiagID, Policy)) { | |||
1093 | Diag(StartLoc, DiagID) << PrevSpec; | |||
1094 | DS.SetTypeSpecError(); | |||
1095 | } | |||
1096 | return EndLoc; | |||
1097 | } | |||
1098 | ||||
1099 | void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS, | |||
1100 | SourceLocation StartLoc, | |||
1101 | SourceLocation EndLoc) { | |||
1102 | // make sure we have a token we can turn into an annotation token | |||
1103 | if (PP.isBacktrackEnabled()) { | |||
1104 | PP.RevertCachedTokens(1); | |||
1105 | if (DS.getTypeSpecType() == TST_error) { | |||
1106 | // We encountered an error in parsing 'decltype(...)' so lets annotate all | |||
1107 | // the tokens in the backtracking cache - that we likely had to skip over | |||
1108 | // to get to a token that allows us to resume parsing, such as a | |||
1109 | // semi-colon. | |||
1110 | EndLoc = PP.getLastCachedTokenLocation(); | |||
1111 | } | |||
1112 | } | |||
1113 | else | |||
1114 | PP.EnterToken(Tok, /*IsReinject*/true); | |||
1115 | ||||
1116 | Tok.setKind(tok::annot_decltype); | |||
1117 | setExprAnnotation(Tok, | |||
1118 | DS.getTypeSpecType() == TST_decltype ? DS.getRepAsExpr() : | |||
1119 | DS.getTypeSpecType() == TST_decltype_auto ? ExprResult() : | |||
1120 | ExprError()); | |||
1121 | Tok.setAnnotationEndLoc(EndLoc); | |||
1122 | Tok.setLocation(StartLoc); | |||
1123 | PP.AnnotateCachedTokens(Tok); | |||
1124 | } | |||
1125 | ||||
1126 | void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { | |||
1127 | assert(Tok.is(tok::kw___underlying_type) &&((void)0) | |||
1128 | "Not an underlying type specifier")((void)0); | |||
1129 | ||||
1130 | SourceLocation StartLoc = ConsumeToken(); | |||
1131 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
1132 | if (T.expectAndConsume(diag::err_expected_lparen_after, | |||
1133 | "__underlying_type", tok::r_paren)) { | |||
1134 | return; | |||
1135 | } | |||
1136 | ||||
1137 | TypeResult Result = ParseTypeName(); | |||
1138 | if (Result.isInvalid()) { | |||
1139 | SkipUntil(tok::r_paren, StopAtSemi); | |||
1140 | return; | |||
1141 | } | |||
1142 | ||||
1143 | // Match the ')' | |||
1144 | T.consumeClose(); | |||
1145 | if (T.getCloseLocation().isInvalid()) | |||
1146 | return; | |||
1147 | ||||
1148 | const char *PrevSpec = nullptr; | |||
1149 | unsigned DiagID; | |||
1150 | if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec, | |||
1151 | DiagID, Result.get(), | |||
1152 | Actions.getASTContext().getPrintingPolicy())) | |||
1153 | Diag(StartLoc, DiagID) << PrevSpec; | |||
1154 | DS.setTypeofParensRange(T.getRange()); | |||
1155 | } | |||
1156 | ||||
1157 | /// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a | |||
1158 | /// class name or decltype-specifier. Note that we only check that the result | |||
1159 | /// names a type; semantic analysis will need to verify that the type names a | |||
1160 | /// class. The result is either a type or null, depending on whether a type | |||
1161 | /// name was found. | |||
1162 | /// | |||
1163 | /// base-type-specifier: [C++11 class.derived] | |||
1164 | /// class-or-decltype | |||
1165 | /// class-or-decltype: [C++11 class.derived] | |||
1166 | /// nested-name-specifier[opt] class-name | |||
1167 | /// decltype-specifier | |||
1168 | /// class-name: [C++ class.name] | |||
1169 | /// identifier | |||
1170 | /// simple-template-id | |||
1171 | /// | |||
1172 | /// In C++98, instead of base-type-specifier, we have: | |||
1173 | /// | |||
1174 | /// ::[opt] nested-name-specifier[opt] class-name | |||
1175 | TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, | |||
1176 | SourceLocation &EndLocation) { | |||
1177 | // Ignore attempts to use typename | |||
1178 | if (Tok.is(tok::kw_typename)) { | |||
1179 | Diag(Tok, diag::err_expected_class_name_not_template) | |||
1180 | << FixItHint::CreateRemoval(Tok.getLocation()); | |||
1181 | ConsumeToken(); | |||
1182 | } | |||
1183 | ||||
1184 | // Parse optional nested-name-specifier | |||
1185 | CXXScopeSpec SS; | |||
1186 | if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, | |||
1187 | /*ObjectHadErrors=*/false, | |||
1188 | /*EnteringContext=*/false)) | |||
1189 | return true; | |||
1190 | ||||
1191 | BaseLoc = Tok.getLocation(); | |||
1192 | ||||
1193 | // Parse decltype-specifier | |||
1194 | // tok == kw_decltype is just error recovery, it can only happen when SS | |||
1195 | // isn't empty | |||
1196 | if (Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) { | |||
1197 | if (SS.isNotEmpty()) | |||
1198 | Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype) | |||
1199 | << FixItHint::CreateRemoval(SS.getRange()); | |||
1200 | // Fake up a Declarator to use with ActOnTypeName. | |||
1201 | DeclSpec DS(AttrFactory); | |||
1202 | ||||
1203 | EndLocation = ParseDecltypeSpecifier(DS); | |||
1204 | ||||
1205 | Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); | |||
1206 | return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); | |||
1207 | } | |||
1208 | ||||
1209 | // Check whether we have a template-id that names a type. | |||
1210 | if (Tok.is(tok::annot_template_id)) { | |||
1211 | TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); | |||
1212 | if (TemplateId->mightBeType()) { | |||
1213 | AnnotateTemplateIdTokenAsType(SS, /*IsClassName*/true); | |||
1214 | ||||
1215 | assert(Tok.is(tok::annot_typename) && "template-id -> type failed")((void)0); | |||
1216 | TypeResult Type = getTypeAnnotation(Tok); | |||
1217 | EndLocation = Tok.getAnnotationEndLoc(); | |||
1218 | ConsumeAnnotationToken(); | |||
1219 | return Type; | |||
1220 | } | |||
1221 | ||||
1222 | // Fall through to produce an error below. | |||
1223 | } | |||
1224 | ||||
1225 | if (Tok.isNot(tok::identifier)) { | |||
1226 | Diag(Tok, diag::err_expected_class_name); | |||
1227 | return true; | |||
1228 | } | |||
1229 | ||||
1230 | IdentifierInfo *Id = Tok.getIdentifierInfo(); | |||
1231 | SourceLocation IdLoc = ConsumeToken(); | |||
1232 | ||||
1233 | if (Tok.is(tok::less)) { | |||
1234 | // It looks the user intended to write a template-id here, but the | |||
1235 | // template-name was wrong. Try to fix that. | |||
1236 | // FIXME: Invoke ParseOptionalCXXScopeSpecifier in a "'template' is neither | |||
1237 | // required nor permitted" mode, and do this there. | |||
1238 | TemplateNameKind TNK = TNK_Non_template; | |||
1239 | TemplateTy Template; | |||
1240 | if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(), | |||
1241 | &SS, Template, TNK)) { | |||
1242 | Diag(IdLoc, diag::err_unknown_template_name) | |||
1243 | << Id; | |||
1244 | } | |||
1245 | ||||
1246 | // Form the template name | |||
1247 | UnqualifiedId TemplateName; | |||
1248 | TemplateName.setIdentifier(Id, IdLoc); | |||
1249 | ||||
1250 | // Parse the full template-id, then turn it into a type. | |||
1251 | if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), | |||
1252 | TemplateName)) | |||
1253 | return true; | |||
1254 | if (Tok.is(tok::annot_template_id) && | |||
1255 | takeTemplateIdAnnotation(Tok)->mightBeType()) | |||
1256 | AnnotateTemplateIdTokenAsType(SS, /*IsClassName*/true); | |||
1257 | ||||
1258 | // If we didn't end up with a typename token, there's nothing more we | |||
1259 | // can do. | |||
1260 | if (Tok.isNot(tok::annot_typename)) | |||
1261 | return true; | |||
1262 | ||||
1263 | // Retrieve the type from the annotation token, consume that token, and | |||
1264 | // return. | |||
1265 | EndLocation = Tok.getAnnotationEndLoc(); | |||
1266 | TypeResult Type = getTypeAnnotation(Tok); | |||
1267 | ConsumeAnnotationToken(); | |||
1268 | return Type; | |||
1269 | } | |||
1270 | ||||
1271 | // We have an identifier; check whether it is actually a type. | |||
1272 | IdentifierInfo *CorrectedII = nullptr; | |||
1273 | ParsedType Type = Actions.getTypeName( | |||
1274 | *Id, IdLoc, getCurScope(), &SS, /*isClassName=*/true, false, nullptr, | |||
1275 | /*IsCtorOrDtorName=*/false, | |||
1276 | /*WantNontrivialTypeSourceInfo=*/true, | |||
1277 | /*IsClassTemplateDeductionContext*/ false, &CorrectedII); | |||
1278 | if (!Type) { | |||
1279 | Diag(IdLoc, diag::err_expected_class_name); | |||
1280 | return true; | |||
1281 | } | |||
1282 | ||||
1283 | // Consume the identifier. | |||
1284 | EndLocation = IdLoc; | |||
1285 | ||||
1286 | // Fake up a Declarator to use with ActOnTypeName. | |||
1287 | DeclSpec DS(AttrFactory); | |||
1288 | DS.SetRangeStart(IdLoc); | |||
1289 | DS.SetRangeEnd(EndLocation); | |||
1290 | DS.getTypeSpecScope() = SS; | |||
1291 | ||||
1292 | const char *PrevSpec = nullptr; | |||
1293 | unsigned DiagID; | |||
1294 | DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type, | |||
1295 | Actions.getASTContext().getPrintingPolicy()); | |||
1296 | ||||
1297 | Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); | |||
1298 | return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); | |||
1299 | } | |||
1300 | ||||
1301 | void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) { | |||
1302 | while (Tok.isOneOf(tok::kw___single_inheritance, | |||
1303 | tok::kw___multiple_inheritance, | |||
1304 | tok::kw___virtual_inheritance)) { | |||
1305 | IdentifierInfo *AttrName = Tok.getIdentifierInfo(); | |||
1306 | SourceLocation AttrNameLoc = ConsumeToken(); | |||
1307 | attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, | |||
1308 | ParsedAttr::AS_Keyword); | |||
1309 | } | |||
1310 | } | |||
1311 | ||||
1312 | /// Determine whether the following tokens are valid after a type-specifier | |||
1313 | /// which could be a standalone declaration. This will conservatively return | |||
1314 | /// true if there's any doubt, and is appropriate for insert-';' fixits. | |||
1315 | bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) { | |||
1316 | // This switch enumerates the valid "follow" set for type-specifiers. | |||
1317 | switch (Tok.getKind()) { | |||
1318 | default: break; | |||
1319 | case tok::semi: // struct foo {...} ; | |||
1320 | case tok::star: // struct foo {...} * P; | |||
1321 | case tok::amp: // struct foo {...} & R = ... | |||
1322 | case tok::ampamp: // struct foo {...} && R = ... | |||
1323 | case tok::identifier: // struct foo {...} V ; | |||
1324 | case tok::r_paren: //(struct foo {...} ) {4} | |||
1325 | case tok::coloncolon: // struct foo {...} :: a::b; | |||
1326 | case tok::annot_cxxscope: // struct foo {...} a:: b; | |||
1327 | case tok::annot_typename: // struct foo {...} a ::b; | |||
1328 | case tok::annot_template_id: // struct foo {...} a<int> ::b; | |||
1329 | case tok::kw_decltype: // struct foo {...} decltype (a)::b; | |||
1330 | case tok::l_paren: // struct foo {...} ( x); | |||
1331 | case tok::comma: // __builtin_offsetof(struct foo{...} , | |||
1332 | case tok::kw_operator: // struct foo operator ++() {...} | |||
1333 | case tok::kw___declspec: // struct foo {...} __declspec(...) | |||
1334 | case tok::l_square: // void f(struct f [ 3]) | |||
1335 | case tok::ellipsis: // void f(struct f ... [Ns]) | |||
1336 | // FIXME: we should emit semantic diagnostic when declaration | |||
1337 | // attribute is in type attribute position. | |||
1338 | case tok::kw___attribute: // struct foo __attribute__((used)) x; | |||
1339 | case tok::annot_pragma_pack: // struct foo {...} _Pragma(pack(pop)); | |||
1340 | // struct foo {...} _Pragma(section(...)); | |||
1341 | case tok::annot_pragma_ms_pragma: | |||
1342 | // struct foo {...} _Pragma(vtordisp(pop)); | |||
1343 | case tok::annot_pragma_ms_vtordisp: | |||
1344 | // struct foo {...} _Pragma(pointers_to_members(...)); | |||
1345 | case tok::annot_pragma_ms_pointers_to_members: | |||
1346 | return true; | |||
1347 | case tok::colon: | |||
1348 | return CouldBeBitfield || // enum E { ... } : 2; | |||
1349 | ColonIsSacred; // _Generic(..., enum E : 2); | |||
1350 | // Microsoft compatibility | |||
1351 | case tok::kw___cdecl: // struct foo {...} __cdecl x; | |||
1352 | case tok::kw___fastcall: // struct foo {...} __fastcall x; | |||
1353 | case tok::kw___stdcall: // struct foo {...} __stdcall x; | |||
1354 | case tok::kw___thiscall: // struct foo {...} __thiscall x; | |||
1355 | case tok::kw___vectorcall: // struct foo {...} __vectorcall x; | |||
1356 | // We will diagnose these calling-convention specifiers on non-function | |||
1357 | // declarations later, so claim they are valid after a type specifier. | |||
1358 | return getLangOpts().MicrosoftExt; | |||
1359 | // Type qualifiers | |||
1360 | case tok::kw_const: // struct foo {...} const x; | |||
1361 | case tok::kw_volatile: // struct foo {...} volatile x; | |||
1362 | case tok::kw_restrict: // struct foo {...} restrict x; | |||
1363 | case tok::kw__Atomic: // struct foo {...} _Atomic x; | |||
1364 | case tok::kw___unaligned: // struct foo {...} __unaligned *x; | |||
1365 | // Function specifiers | |||
1366 | // Note, no 'explicit'. An explicit function must be either a conversion | |||
1367 | // operator or a constructor. Either way, it can't have a return type. | |||
1368 | case tok::kw_inline: // struct foo inline f(); | |||
1369 | case tok::kw_virtual: // struct foo virtual f(); | |||
1370 | case tok::kw_friend: // struct foo friend f(); | |||
1371 | // Storage-class specifiers | |||
1372 | case tok::kw_static: // struct foo {...} static x; | |||
1373 | case tok::kw_extern: // struct foo {...} extern x; | |||
1374 | case tok::kw_typedef: // struct foo {...} typedef x; | |||
1375 | case tok::kw_register: // struct foo {...} register x; | |||
1376 | case tok::kw_auto: // struct foo {...} auto x; | |||
1377 | case tok::kw_mutable: // struct foo {...} mutable x; | |||
1378 | case tok::kw_thread_local: // struct foo {...} thread_local x; | |||
1379 | case tok::kw_constexpr: // struct foo {...} constexpr x; | |||
1380 | case tok::kw_consteval: // struct foo {...} consteval x; | |||
1381 | case tok::kw_constinit: // struct foo {...} constinit x; | |||
1382 | // As shown above, type qualifiers and storage class specifiers absolutely | |||
1383 | // can occur after class specifiers according to the grammar. However, | |||
1384 | // almost no one actually writes code like this. If we see one of these, | |||
1385 | // it is much more likely that someone missed a semi colon and the | |||
1386 | // type/storage class specifier we're seeing is part of the *next* | |||
1387 | // intended declaration, as in: | |||
1388 | // | |||
1389 | // struct foo { ... } | |||
1390 | // typedef int X; | |||
1391 | // | |||
1392 | // We'd really like to emit a missing semicolon error instead of emitting | |||
1393 | // an error on the 'int' saying that you can't have two type specifiers in | |||
1394 | // the same declaration of X. Because of this, we look ahead past this | |||
1395 | // token to see if it's a type specifier. If so, we know the code is | |||
1396 | // otherwise invalid, so we can produce the expected semi error. | |||
1397 | if (!isKnownToBeTypeSpecifier(NextToken())) | |||
1398 | return true; | |||
1399 | break; | |||
1400 | case tok::r_brace: // struct bar { struct foo {...} } | |||
1401 | // Missing ';' at end of struct is accepted as an extension in C mode. | |||
1402 | if (!getLangOpts().CPlusPlus) | |||
1403 | return true; | |||
1404 | break; | |||
1405 | case tok::greater: | |||
1406 | // template<class T = class X> | |||
1407 | return getLangOpts().CPlusPlus; | |||
1408 | } | |||
1409 | return false; | |||
1410 | } | |||
1411 | ||||
1412 | /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or | |||
1413 | /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which | |||
1414 | /// until we reach the start of a definition or see a token that | |||
1415 | /// cannot start a definition. | |||
1416 | /// | |||
1417 | /// class-specifier: [C++ class] | |||
1418 | /// class-head '{' member-specification[opt] '}' | |||
1419 | /// class-head '{' member-specification[opt] '}' attributes[opt] | |||
1420 | /// class-head: | |||
1421 | /// class-key identifier[opt] base-clause[opt] | |||
1422 | /// class-key nested-name-specifier identifier base-clause[opt] | |||
1423 | /// class-key nested-name-specifier[opt] simple-template-id | |||
1424 | /// base-clause[opt] | |||
1425 | /// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] | |||
1426 | /// [GNU] class-key attributes[opt] nested-name-specifier | |||
1427 | /// identifier base-clause[opt] | |||
1428 | /// [GNU] class-key attributes[opt] nested-name-specifier[opt] | |||
1429 | /// simple-template-id base-clause[opt] | |||
1430 | /// class-key: | |||
1431 | /// 'class' | |||
1432 | /// 'struct' | |||
1433 | /// 'union' | |||
1434 | /// | |||
1435 | /// elaborated-type-specifier: [C++ dcl.type.elab] | |||
1436 | /// class-key ::[opt] nested-name-specifier[opt] identifier | |||
1437 | /// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] | |||
1438 | /// simple-template-id | |||
1439 | /// | |||
1440 | /// Note that the C++ class-specifier and elaborated-type-specifier, | |||
1441 | /// together, subsume the C99 struct-or-union-specifier: | |||
1442 | /// | |||
1443 | /// struct-or-union-specifier: [C99 6.7.2.1] | |||
1444 | /// struct-or-union identifier[opt] '{' struct-contents '}' | |||
1445 | /// struct-or-union identifier | |||
1446 | /// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents | |||
1447 | /// '}' attributes[opt] | |||
1448 | /// [GNU] struct-or-union attributes[opt] identifier | |||
1449 | /// struct-or-union: | |||
1450 | /// 'struct' | |||
1451 | /// 'union' | |||
1452 | void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, | |||
1453 | SourceLocation StartLoc, DeclSpec &DS, | |||
1454 | const ParsedTemplateInfo &TemplateInfo, | |||
1455 | AccessSpecifier AS, | |||
1456 | bool EnteringContext, DeclSpecContext DSC, | |||
1457 | ParsedAttributesWithRange &Attributes) { | |||
1458 | DeclSpec::TST TagType; | |||
1459 | if (TagTokKind == tok::kw_struct) | |||
1460 | TagType = DeclSpec::TST_struct; | |||
1461 | else if (TagTokKind == tok::kw___interface) | |||
1462 | TagType = DeclSpec::TST_interface; | |||
1463 | else if (TagTokKind == tok::kw_class) | |||
1464 | TagType = DeclSpec::TST_class; | |||
1465 | else { | |||
1466 | assert(TagTokKind == tok::kw_union && "Not a class specifier")((void)0); | |||
1467 | TagType = DeclSpec::TST_union; | |||
1468 | } | |||
1469 | ||||
1470 | if (Tok.is(tok::code_completion)) { | |||
1471 | // Code completion for a struct, class, or union name. | |||
1472 | cutOffParsing(); | |||
1473 | Actions.CodeCompleteTag(getCurScope(), TagType); | |||
1474 | return; | |||
1475 | } | |||
1476 | ||||
1477 | // C++03 [temp.explicit] 14.7.2/8: | |||
1478 | // The usual access checking rules do not apply to names used to specify | |||
1479 | // explicit instantiations. | |||
1480 | // | |||
1481 | // As an extension we do not perform access checking on the names used to | |||
1482 | // specify explicit specializations either. This is important to allow | |||
1483 | // specializing traits classes for private types. | |||
1484 | // | |||
1485 | // Note that we don't suppress if this turns out to be an elaborated | |||
1486 | // type specifier. | |||
1487 | bool shouldDelayDiagsInTag = | |||
1488 | (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || | |||
1489 | TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); | |||
1490 | SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); | |||
1491 | ||||
1492 | ParsedAttributesWithRange attrs(AttrFactory); | |||
1493 | // If attributes exist after tag, parse them. | |||
1494 | MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs); | |||
1495 | ||||
1496 | // Parse inheritance specifiers. | |||
1497 | if (Tok.isOneOf(tok::kw___single_inheritance, | |||
1498 | tok::kw___multiple_inheritance, | |||
1499 | tok::kw___virtual_inheritance)) | |||
1500 | ParseMicrosoftInheritanceClassAttributes(attrs); | |||
1501 | ||||
1502 | // Allow attributes to precede or succeed the inheritance specifiers. | |||
1503 | MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs); | |||
1504 | ||||
1505 | // Source location used by FIXIT to insert misplaced | |||
1506 | // C++11 attributes | |||
1507 | SourceLocation AttrFixitLoc = Tok.getLocation(); | |||
1508 | ||||
1509 | if (TagType == DeclSpec::TST_struct && | |||
1510 | Tok.isNot(tok::identifier) && | |||
1511 | !Tok.isAnnotation() && | |||
1512 | Tok.getIdentifierInfo() && | |||
1513 | Tok.isOneOf(tok::kw___is_abstract, | |||
1514 | tok::kw___is_aggregate, | |||
1515 | tok::kw___is_arithmetic, | |||
1516 | tok::kw___is_array, | |||
1517 | tok::kw___is_assignable, | |||
1518 | tok::kw___is_base_of, | |||
1519 | tok::kw___is_class, | |||
1520 | tok::kw___is_complete_type, | |||
1521 | tok::kw___is_compound, | |||
1522 | tok::kw___is_const, | |||
1523 | tok::kw___is_constructible, | |||
1524 | tok::kw___is_convertible, | |||
1525 | tok::kw___is_convertible_to, | |||
1526 | tok::kw___is_destructible, | |||
1527 | tok::kw___is_empty, | |||
1528 | tok::kw___is_enum, | |||
1529 | tok::kw___is_floating_point, | |||
1530 | tok::kw___is_final, | |||
1531 | tok::kw___is_function, | |||
1532 | tok::kw___is_fundamental, | |||
1533 | tok::kw___is_integral, | |||
1534 | tok::kw___is_interface_class, | |||
1535 | tok::kw___is_literal, | |||
1536 | tok::kw___is_lvalue_expr, | |||
1537 | tok::kw___is_lvalue_reference, | |||
1538 | tok::kw___is_member_function_pointer, | |||
1539 | tok::kw___is_member_object_pointer, | |||
1540 | tok::kw___is_member_pointer, | |||
1541 | tok::kw___is_nothrow_assignable, | |||
1542 | tok::kw___is_nothrow_constructible, | |||
1543 | tok::kw___is_nothrow_destructible, | |||
1544 | tok::kw___is_object, | |||
1545 | tok::kw___is_pod, | |||
1546 | tok::kw___is_pointer, | |||
1547 | tok::kw___is_polymorphic, | |||
1548 | tok::kw___is_reference, | |||
1549 | tok::kw___is_rvalue_expr, | |||
1550 | tok::kw___is_rvalue_reference, | |||
1551 | tok::kw___is_same, | |||
1552 | tok::kw___is_scalar, | |||
1553 | tok::kw___is_sealed, | |||
1554 | tok::kw___is_signed, | |||
1555 | tok::kw___is_standard_layout, | |||
1556 | tok::kw___is_trivial, | |||
1557 | tok::kw___is_trivially_assignable, | |||
1558 | tok::kw___is_trivially_constructible, | |||
1559 | tok::kw___is_trivially_copyable, | |||
1560 | tok::kw___is_union, | |||
1561 | tok::kw___is_unsigned, | |||
1562 | tok::kw___is_void, | |||
1563 | tok::kw___is_volatile)) | |||
1564 | // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the | |||
1565 | // name of struct templates, but some are keywords in GCC >= 4.3 | |||
1566 | // and Clang. Therefore, when we see the token sequence "struct | |||
1567 | // X", make X into a normal identifier rather than a keyword, to | |||
1568 | // allow libstdc++ 4.2 and libc++ to work properly. | |||
1569 | TryKeywordIdentFallback(true); | |||
1570 | ||||
1571 | struct PreserveAtomicIdentifierInfoRAII { | |||
1572 | PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled) | |||
1573 | : AtomicII(nullptr) { | |||
1574 | if (!Enabled) | |||
1575 | return; | |||
1576 | assert(Tok.is(tok::kw__Atomic))((void)0); | |||
1577 | AtomicII = Tok.getIdentifierInfo(); | |||
1578 | AtomicII->revertTokenIDToIdentifier(); | |||
1579 | Tok.setKind(tok::identifier); | |||
1580 | } | |||
1581 | ~PreserveAtomicIdentifierInfoRAII() { | |||
1582 | if (!AtomicII) | |||
1583 | return; | |||
1584 | AtomicII->revertIdentifierToTokenID(tok::kw__Atomic); | |||
1585 | } | |||
1586 | IdentifierInfo *AtomicII; | |||
1587 | }; | |||
1588 | ||||
1589 | // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL | |||
1590 | // implementation for VS2013 uses _Atomic as an identifier for one of the | |||
1591 | // classes in <atomic>. When we are parsing 'struct _Atomic', don't consider | |||
1592 | // '_Atomic' to be a keyword. We are careful to undo this so that clang can | |||
1593 | // use '_Atomic' in its own header files. | |||
1594 | bool ShouldChangeAtomicToIdentifier = getLangOpts().MSVCCompat && | |||
1595 | Tok.is(tok::kw__Atomic) && | |||
1596 | TagType == DeclSpec::TST_struct; | |||
1597 | PreserveAtomicIdentifierInfoRAII AtomicTokenGuard( | |||
1598 | Tok, ShouldChangeAtomicToIdentifier); | |||
1599 | ||||
1600 | // Parse the (optional) nested-name-specifier. | |||
1601 | CXXScopeSpec &SS = DS.getTypeSpecScope(); | |||
1602 | if (getLangOpts().CPlusPlus) { | |||
1603 | // "FOO : BAR" is not a potential typo for "FOO::BAR". In this context it | |||
1604 | // is a base-specifier-list. | |||
1605 | ColonProtectionRAIIObject X(*this); | |||
1606 | ||||
1607 | CXXScopeSpec Spec; | |||
1608 | bool HasValidSpec = true; | |||
1609 | if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr, | |||
1610 | /*ObjectHadErrors=*/false, | |||
1611 | EnteringContext)) { | |||
1612 | DS.SetTypeSpecError(); | |||
1613 | HasValidSpec = false; | |||
1614 | } | |||
1615 | if (Spec.isSet()) | |||
1616 | if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) { | |||
1617 | Diag(Tok, diag::err_expected) << tok::identifier; | |||
1618 | HasValidSpec = false; | |||
1619 | } | |||
1620 | if (HasValidSpec) | |||
1621 | SS = Spec; | |||
1622 | } | |||
1623 | ||||
1624 | TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; | |||
1625 | ||||
1626 | auto RecoverFromUndeclaredTemplateName = [&](IdentifierInfo *Name, | |||
1627 | SourceLocation NameLoc, | |||
1628 | SourceRange TemplateArgRange, | |||
1629 | bool KnownUndeclared) { | |||
1630 | Diag(NameLoc, diag::err_explicit_spec_non_template) | |||
1631 | << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) | |||
1632 | << TagTokKind << Name << TemplateArgRange << KnownUndeclared; | |||
1633 | ||||
1634 | // Strip off the last template parameter list if it was empty, since | |||
1635 | // we've removed its template argument list. | |||
1636 | if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) { | |||
1637 | if (TemplateParams->size() > 1) { | |||
1638 | TemplateParams->pop_back(); | |||
1639 | } else { | |||
1640 | TemplateParams = nullptr; | |||
1641 | const_cast<ParsedTemplateInfo &>(TemplateInfo).Kind = | |||
1642 | ParsedTemplateInfo::NonTemplate; | |||
1643 | } | |||
1644 | } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { | |||
1645 | // Pretend this is just a forward declaration. | |||
1646 | TemplateParams = nullptr; | |||
1647 | const_cast<ParsedTemplateInfo &>(TemplateInfo).Kind = | |||
1648 | ParsedTemplateInfo::NonTemplate; | |||
1649 | const_cast<ParsedTemplateInfo &>(TemplateInfo).TemplateLoc = | |||
1650 | SourceLocation(); | |||
1651 | const_cast<ParsedTemplateInfo &>(TemplateInfo).ExternLoc = | |||
1652 | SourceLocation(); | |||
1653 | } | |||
1654 | }; | |||
1655 | ||||
1656 | // Parse the (optional) class name or simple-template-id. | |||
1657 | IdentifierInfo *Name = nullptr; | |||
1658 | SourceLocation NameLoc; | |||
1659 | TemplateIdAnnotation *TemplateId = nullptr; | |||
1660 | if (Tok.is(tok::identifier)) { | |||
1661 | Name = Tok.getIdentifierInfo(); | |||
1662 | NameLoc = ConsumeToken(); | |||
1663 | ||||
1664 | if (Tok.is(tok::less) && getLangOpts().CPlusPlus) { | |||
1665 | // The name was supposed to refer to a template, but didn't. | |||
1666 | // Eat the template argument list and try to continue parsing this as | |||
1667 | // a class (or template thereof). | |||
1668 | TemplateArgList TemplateArgs; | |||
1669 | SourceLocation LAngleLoc, RAngleLoc; | |||
1670 | if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, | |||
1671 | RAngleLoc)) { | |||
1672 | // We couldn't parse the template argument list at all, so don't | |||
1673 | // try to give any location information for the list. | |||
1674 | LAngleLoc = RAngleLoc = SourceLocation(); | |||
1675 | } | |||
1676 | RecoverFromUndeclaredTemplateName( | |||
1677 | Name, NameLoc, SourceRange(LAngleLoc, RAngleLoc), false); | |||
1678 | } | |||
1679 | } else if (Tok.is(tok::annot_template_id)) { | |||
1680 | TemplateId = takeTemplateIdAnnotation(Tok); | |||
1681 | NameLoc = ConsumeAnnotationToken(); | |||
1682 | ||||
1683 | if (TemplateId->Kind == TNK_Undeclared_template) { | |||
1684 | // Try to resolve the template name to a type template. May update Kind. | |||
1685 | Actions.ActOnUndeclaredTypeTemplateName( | |||
1686 | getCurScope(), TemplateId->Template, TemplateId->Kind, NameLoc, Name); | |||
1687 | if (TemplateId->Kind == TNK_Undeclared_template) { | |||
1688 | RecoverFromUndeclaredTemplateName( | |||
1689 | Name, NameLoc, | |||
1690 | SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc), true); | |||
1691 | TemplateId = nullptr; | |||
1692 | } | |||
1693 | } | |||
1694 | ||||
1695 | if (TemplateId && !TemplateId->mightBeType()) { | |||
1696 | // The template-name in the simple-template-id refers to | |||
1697 | // something other than a type template. Give an appropriate | |||
1698 | // error message and skip to the ';'. | |||
1699 | SourceRange Range(NameLoc); | |||
1700 | if (SS.isNotEmpty()) | |||
1701 | Range.setBegin(SS.getBeginLoc()); | |||
1702 | ||||
1703 | // FIXME: Name may be null here. | |||
1704 | Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) | |||
1705 | << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range; | |||
1706 | ||||
1707 | DS.SetTypeSpecError(); | |||
1708 | SkipUntil(tok::semi, StopBeforeMatch); | |||
1709 | return; | |||
1710 | } | |||
1711 | } | |||
1712 | ||||
1713 | // There are four options here. | |||
1714 | // - If we are in a trailing return type, this is always just a reference, | |||
1715 | // and we must not try to parse a definition. For instance, | |||
1716 | // [] () -> struct S { }; | |||
1717 | // does not define a type. | |||
1718 | // - If we have 'struct foo {...', 'struct foo :...', | |||
1719 | // 'struct foo final :' or 'struct foo final {', then this is a definition. | |||
1720 | // - If we have 'struct foo;', then this is either a forward declaration | |||
1721 | // or a friend declaration, which have to be treated differently. | |||
1722 | // - Otherwise we have something like 'struct foo xyz', a reference. | |||
1723 | // | |||
1724 | // We also detect these erroneous cases to provide better diagnostic for | |||
1725 | // C++11 attributes parsing. | |||
1726 | // - attributes follow class name: | |||
1727 | // struct foo [[]] {}; | |||
1728 | // - attributes appear before or after 'final': | |||
1729 | // struct foo [[]] final [[]] {}; | |||
1730 | // | |||
1731 | // However, in type-specifier-seq's, things look like declarations but are | |||
1732 | // just references, e.g. | |||
1733 | // new struct s; | |||
1734 | // or | |||
1735 | // &T::operator struct s; | |||
1736 | // For these, DSC is DeclSpecContext::DSC_type_specifier or | |||
1737 | // DeclSpecContext::DSC_alias_declaration. | |||
1738 | ||||
1739 | // If there are attributes after class name, parse them. | |||
1740 | MaybeParseCXX11Attributes(Attributes); | |||
1741 | ||||
1742 | const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy(); | |||
1743 | Sema::TagUseKind TUK; | |||
1744 | if (isDefiningTypeSpecifierContext(DSC) == AllowDefiningTypeSpec::No || | |||
1745 | (getLangOpts().OpenMP && OpenMPDirectiveParsing)) | |||
1746 | TUK = Sema::TUK_Reference; | |||
1747 | else if (Tok.is(tok::l_brace) || | |||
1748 | (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || | |||
1749 | (isClassCompatibleKeyword() && | |||
1750 | (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) { | |||
1751 | if (DS.isFriendSpecified()) { | |||
1752 | // C++ [class.friend]p2: | |||
1753 | // A class shall not be defined in a friend declaration. | |||
1754 | Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) | |||
1755 | << SourceRange(DS.getFriendSpecLoc()); | |||
1756 | ||||
1757 | // Skip everything up to the semicolon, so that this looks like a proper | |||
1758 | // friend class (or template thereof) declaration. | |||
1759 | SkipUntil(tok::semi, StopBeforeMatch); | |||
1760 | TUK = Sema::TUK_Friend; | |||
1761 | } else { | |||
1762 | // Okay, this is a class definition. | |||
1763 | TUK = Sema::TUK_Definition; | |||
1764 | } | |||
1765 | } else if (isClassCompatibleKeyword() && | |||
1766 | (NextToken().is(tok::l_square) || | |||
1767 | NextToken().is(tok::kw_alignas) || | |||
1768 | isCXX11VirtSpecifier(NextToken()) != VirtSpecifiers::VS_None)) { | |||
1769 | // We can't tell if this is a definition or reference | |||
1770 | // until we skipped the 'final' and C++11 attribute specifiers. | |||
1771 | TentativeParsingAction PA(*this); | |||
1772 | ||||
1773 | // Skip the 'final', abstract'... keywords. | |||
1774 | while (isClassCompatibleKeyword()) { | |||
1775 | ConsumeToken(); | |||
1776 | } | |||
1777 | ||||
1778 | // Skip C++11 attribute specifiers. | |||
1779 | while (true) { | |||
1780 | if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) { | |||
1781 | ConsumeBracket(); | |||
1782 | if (!SkipUntil(tok::r_square, StopAtSemi)) | |||
1783 | break; | |||
1784 | } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) { | |||
1785 | ConsumeToken(); | |||
1786 | ConsumeParen(); | |||
1787 | if (!SkipUntil(tok::r_paren, StopAtSemi)) | |||
1788 | break; | |||
1789 | } else { | |||
1790 | break; | |||
1791 | } | |||
1792 | } | |||
1793 | ||||
1794 | if (Tok.isOneOf(tok::l_brace, tok::colon)) | |||
1795 | TUK = Sema::TUK_Definition; | |||
1796 | else | |||
1797 | TUK = Sema::TUK_Reference; | |||
1798 | ||||
1799 | PA.Revert(); | |||
1800 | } else if (!isTypeSpecifier(DSC) && | |||
1801 | (Tok.is(tok::semi) || | |||
1802 | (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) { | |||
1803 | TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; | |||
1804 | if (Tok.isNot(tok::semi)) { | |||
1805 | const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy(); | |||
1806 | // A semicolon was missing after this declaration. Diagnose and recover. | |||
1807 | ExpectAndConsume(tok::semi, diag::err_expected_after, | |||
1808 | DeclSpec::getSpecifierName(TagType, PPol)); | |||
1809 | PP.EnterToken(Tok, /*IsReinject*/true); | |||
1810 | Tok.setKind(tok::semi); | |||
1811 | } | |||
1812 | } else | |||
1813 | TUK = Sema::TUK_Reference; | |||
1814 | ||||
1815 | // Forbid misplaced attributes. In cases of a reference, we pass attributes | |||
1816 | // to caller to handle. | |||
1817 | if (TUK != Sema::TUK_Reference) { | |||
1818 | // If this is not a reference, then the only possible | |||
1819 | // valid place for C++11 attributes to appear here | |||
1820 | // is between class-key and class-name. If there are | |||
1821 | // any attributes after class-name, we try a fixit to move | |||
1822 | // them to the right place. | |||
1823 | SourceRange AttrRange = Attributes.Range; | |||
1824 | if (AttrRange.isValid()) { | |||
1825 | Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) | |||
1826 | << AttrRange | |||
1827 | << FixItHint::CreateInsertionFromRange(AttrFixitLoc, | |||
1828 | CharSourceRange(AttrRange, true)) | |||
1829 | << FixItHint::CreateRemoval(AttrRange); | |||
1830 | ||||
1831 | // Recover by adding misplaced attributes to the attribute list | |||
1832 | // of the class so they can be applied on the class later. | |||
1833 | attrs.takeAllFrom(Attributes); | |||
1834 | } | |||
1835 | } | |||
1836 | ||||
1837 | // If this is an elaborated type specifier, and we delayed | |||
1838 | // diagnostics before, just merge them into the current pool. | |||
1839 | if (shouldDelayDiagsInTag) { | |||
1840 | diagsFromTag.done(); | |||
1841 | if (TUK == Sema::TUK_Reference) | |||
1842 | diagsFromTag.redelay(); | |||
1843 | } | |||
1844 | ||||
1845 | if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || | |||
1846 | TUK != Sema::TUK_Definition)) { | |||
1847 | if (DS.getTypeSpecType() != DeclSpec::TST_error) { | |||
1848 | // We have a declaration or reference to an anonymous class. | |||
1849 | Diag(StartLoc, diag::err_anon_type_definition) | |||
1850 | << DeclSpec::getSpecifierName(TagType, Policy); | |||
1851 | } | |||
1852 | ||||
1853 | // If we are parsing a definition and stop at a base-clause, continue on | |||
1854 | // until the semicolon. Continuing from the comma will just trick us into | |||
1855 | // thinking we are seeing a variable declaration. | |||
1856 | if (TUK == Sema::TUK_Definition && Tok.is(tok::colon)) | |||
1857 | SkipUntil(tok::semi, StopBeforeMatch); | |||
1858 | else | |||
1859 | SkipUntil(tok::comma, StopAtSemi); | |||
1860 | return; | |||
1861 | } | |||
1862 | ||||
1863 | // Create the tag portion of the class or class template. | |||
1864 | DeclResult TagOrTempResult = true; // invalid | |||
1865 | TypeResult TypeResult = true; // invalid | |||
1866 | ||||
1867 | bool Owned = false; | |||
1868 | Sema::SkipBodyInfo SkipBody; | |||
1869 | if (TemplateId) { | |||
1870 | // Explicit specialization, class template partial specialization, | |||
1871 | // or explicit instantiation. | |||
1872 | ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), | |||
1873 | TemplateId->NumArgs); | |||
1874 | if (TemplateId->isInvalid()) { | |||
1875 | // Can't build the declaration. | |||
1876 | } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && | |||
1877 | TUK == Sema::TUK_Declaration) { | |||
1878 | // This is an explicit instantiation of a class template. | |||
1879 | ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | |||
1880 | /*DiagnoseEmptyAttrs=*/true); | |||
1881 | ||||
1882 | TagOrTempResult = Actions.ActOnExplicitInstantiation( | |||
1883 | getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, | |||
1884 | TagType, StartLoc, SS, TemplateId->Template, | |||
1885 | TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, | |||
1886 | TemplateId->RAngleLoc, attrs); | |||
1887 | ||||
1888 | // Friend template-ids are treated as references unless | |||
1889 | // they have template headers, in which case they're ill-formed | |||
1890 | // (FIXME: "template <class T> friend class A<T>::B<int>;"). | |||
1891 | // We diagnose this error in ActOnClassTemplateSpecialization. | |||
1892 | } else if (TUK == Sema::TUK_Reference || | |||
1893 | (TUK == Sema::TUK_Friend && | |||
1894 | TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { | |||
1895 | ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | |||
1896 | /*DiagnoseEmptyAttrs=*/true); | |||
1897 | TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc, | |||
1898 | SS, | |||
1899 | TemplateId->TemplateKWLoc, | |||
1900 | TemplateId->Template, | |||
1901 | TemplateId->TemplateNameLoc, | |||
1902 | TemplateId->LAngleLoc, | |||
1903 | TemplateArgsPtr, | |||
1904 | TemplateId->RAngleLoc); | |||
1905 | } else { | |||
1906 | // This is an explicit specialization or a class template | |||
1907 | // partial specialization. | |||
1908 | TemplateParameterLists FakedParamLists; | |||
1909 | if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { | |||
1910 | // This looks like an explicit instantiation, because we have | |||
1911 | // something like | |||
1912 | // | |||
1913 | // template class Foo<X> | |||
1914 | // | |||
1915 | // but it actually has a definition. Most likely, this was | |||
1916 | // meant to be an explicit specialization, but the user forgot | |||
1917 | // the '<>' after 'template'. | |||
1918 | // It this is friend declaration however, since it cannot have a | |||
1919 | // template header, it is most likely that the user meant to | |||
1920 | // remove the 'template' keyword. | |||
1921 | assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) &&((void)0) | |||
1922 | "Expected a definition here")((void)0); | |||
1923 | ||||
1924 | if (TUK == Sema::TUK_Friend) { | |||
1925 | Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation); | |||
1926 | TemplateParams = nullptr; | |||
1927 | } else { | |||
1928 | SourceLocation LAngleLoc = | |||
1929 | PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); | |||
1930 | Diag(TemplateId->TemplateNameLoc, | |||
1931 | diag::err_explicit_instantiation_with_definition) | |||
1932 | << SourceRange(TemplateInfo.TemplateLoc) | |||
1933 | << FixItHint::CreateInsertion(LAngleLoc, "<>"); | |||
1934 | ||||
1935 | // Create a fake template parameter list that contains only | |||
1936 | // "template<>", so that we treat this construct as a class | |||
1937 | // template specialization. | |||
1938 | FakedParamLists.push_back(Actions.ActOnTemplateParameterList( | |||
1939 | 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, | |||
1940 | LAngleLoc, nullptr)); | |||
1941 | TemplateParams = &FakedParamLists; | |||
1942 | } | |||
1943 | } | |||
1944 | ||||
1945 | // Build the class template specialization. | |||
1946 | TagOrTempResult = Actions.ActOnClassTemplateSpecialization( | |||
1947 | getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(), | |||
1948 | SS, *TemplateId, attrs, | |||
1949 | MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] | |||
1950 | : nullptr, | |||
1951 | TemplateParams ? TemplateParams->size() : 0), | |||
1952 | &SkipBody); | |||
1953 | } | |||
1954 | } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && | |||
1955 | TUK == Sema::TUK_Declaration) { | |||
1956 | // Explicit instantiation of a member of a class template | |||
1957 | // specialization, e.g., | |||
1958 | // | |||
1959 | // template struct Outer<int>::Inner; | |||
1960 | // | |||
1961 | ProhibitAttributes(attrs); | |||
1962 | ||||
1963 | TagOrTempResult = Actions.ActOnExplicitInstantiation( | |||
1964 | getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, | |||
1965 | TagType, StartLoc, SS, Name, NameLoc, attrs); | |||
1966 | } else if (TUK == Sema::TUK_Friend && | |||
1967 | TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { | |||
1968 | ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | |||
1969 | /*DiagnoseEmptyAttrs=*/true); | |||
1970 | ||||
1971 | TagOrTempResult = Actions.ActOnTemplatedFriendTag( | |||
1972 | getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name, | |||
1973 | NameLoc, attrs, | |||
1974 | MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr, | |||
1975 | TemplateParams ? TemplateParams->size() : 0)); | |||
1976 | } else { | |||
1977 | if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) | |||
1978 | ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed, | |||
1979 | /* DiagnoseEmptyAttrs=*/true); | |||
1980 | ||||
1981 | if (TUK == Sema::TUK_Definition && | |||
1982 | TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { | |||
1983 | // If the declarator-id is not a template-id, issue a diagnostic and | |||
1984 | // recover by ignoring the 'template' keyword. | |||
1985 | Diag(Tok, diag::err_template_defn_explicit_instantiation) | |||
1986 | << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc); | |||
1987 | TemplateParams = nullptr; | |||
1988 | } | |||
1989 | ||||
1990 | bool IsDependent = false; | |||
1991 | ||||
1992 | // Don't pass down template parameter lists if this is just a tag | |||
1993 | // reference. For example, we don't need the template parameters here: | |||
1994 | // template <class T> class A *makeA(T t); | |||
1995 | MultiTemplateParamsArg TParams; | |||
1996 | if (TUK != Sema::TUK_Reference && TemplateParams) | |||
1997 | TParams = | |||
1998 | MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size()); | |||
1999 | ||||
2000 | stripTypeAttributesOffDeclSpec(attrs, DS, TUK); | |||
2001 | ||||
2002 | // Declaration or definition of a class type | |||
2003 | TagOrTempResult = Actions.ActOnTag( | |||
2004 | getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS, | |||
2005 | DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, | |||
2006 | SourceLocation(), false, clang::TypeResult(), | |||
2007 | DSC == DeclSpecContext::DSC_type_specifier, | |||
2008 | DSC == DeclSpecContext::DSC_template_param || | |||
2009 | DSC == DeclSpecContext::DSC_template_type_arg, | |||
2010 | &SkipBody); | |||
2011 | ||||
2012 | // If ActOnTag said the type was dependent, try again with the | |||
2013 | // less common call. | |||
2014 | if (IsDependent) { | |||
2015 | assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend)((void)0); | |||
2016 | TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, | |||
2017 | SS, Name, StartLoc, NameLoc); | |||
2018 | } | |||
2019 | } | |||
2020 | ||||
2021 | // If there is a body, parse it and inform the actions module. | |||
2022 | if (TUK == Sema::TUK_Definition) { | |||
2023 | assert(Tok.is(tok::l_brace) ||((void)0) | |||
2024 | (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||((void)0) | |||
2025 | isClassCompatibleKeyword())((void)0); | |||
2026 | if (SkipBody.ShouldSkip) | |||
2027 | SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType, | |||
2028 | TagOrTempResult.get()); | |||
2029 | else if (getLangOpts().CPlusPlus) | |||
2030 | ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType, | |||
2031 | TagOrTempResult.get()); | |||
2032 | else { | |||
2033 | Decl *D = | |||
2034 | SkipBody.CheckSameAsPrevious ? SkipBody.New : TagOrTempResult.get(); | |||
2035 | // Parse the definition body. | |||
2036 | ParseStructUnionBody(StartLoc, TagType, cast<RecordDecl>(D)); | |||
2037 | if (SkipBody.CheckSameAsPrevious && | |||
2038 | !Actions.ActOnDuplicateDefinition(DS, TagOrTempResult.get(), | |||
2039 | SkipBody)) { | |||
2040 | DS.SetTypeSpecError(); | |||
2041 | return; | |||
2042 | } | |||
2043 | } | |||
2044 | } | |||
2045 | ||||
2046 | if (!TagOrTempResult.isInvalid()) | |||
2047 | // Delayed processing of attributes. | |||
2048 | Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs); | |||
2049 | ||||
2050 | const char *PrevSpec = nullptr; | |||
2051 | unsigned DiagID; | |||
2052 | bool Result; | |||
2053 | if (!TypeResult.isInvalid()) { | |||
2054 | Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, | |||
2055 | NameLoc.isValid() ? NameLoc : StartLoc, | |||
2056 | PrevSpec, DiagID, TypeResult.get(), Policy); | |||
2057 | } else if (!TagOrTempResult.isInvalid()) { | |||
2058 | Result = DS.SetTypeSpecType(TagType, StartLoc, | |||
2059 | NameLoc.isValid() ? NameLoc : StartLoc, | |||
2060 | PrevSpec, DiagID, TagOrTempResult.get(), Owned, | |||
2061 | Policy); | |||
2062 | } else { | |||
2063 | DS.SetTypeSpecError(); | |||
2064 | return; | |||
2065 | } | |||
2066 | ||||
2067 | if (Result) | |||
2068 | Diag(StartLoc, DiagID) << PrevSpec; | |||
2069 | ||||
2070 | // At this point, we've successfully parsed a class-specifier in 'definition' | |||
2071 | // form (e.g. "struct foo { int x; }". While we could just return here, we're | |||
2072 | // going to look at what comes after it to improve error recovery. If an | |||
2073 | // impossible token occurs next, we assume that the programmer forgot a ; at | |||
2074 | // the end of the declaration and recover that way. | |||
2075 | // | |||
2076 | // Also enforce C++ [temp]p3: | |||
2077 | // In a template-declaration which defines a class, no declarator | |||
2078 | // is permitted. | |||
2079 | // | |||
2080 | // After a type-specifier, we don't expect a semicolon. This only happens in | |||
2081 | // C, since definitions are not permitted in this context in C++. | |||
2082 | if (TUK == Sema::TUK_Definition && | |||
2083 | (getLangOpts().CPlusPlus || !isTypeSpecifier(DSC)) && | |||
2084 | (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) { | |||
2085 | if (Tok.isNot(tok::semi)) { | |||
2086 | const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy(); | |||
2087 | ExpectAndConsume(tok::semi, diag::err_expected_after, | |||
2088 | DeclSpec::getSpecifierName(TagType, PPol)); | |||
2089 | // Push this token back into the preprocessor and change our current token | |||
2090 | // to ';' so that the rest of the code recovers as though there were an | |||
2091 | // ';' after the definition. | |||
2092 | PP.EnterToken(Tok, /*IsReinject=*/true); | |||
2093 | Tok.setKind(tok::semi); | |||
2094 | } | |||
2095 | } | |||
2096 | } | |||
2097 | ||||
2098 | /// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. | |||
2099 | /// | |||
2100 | /// base-clause : [C++ class.derived] | |||
2101 | /// ':' base-specifier-list | |||
2102 | /// base-specifier-list: | |||
2103 | /// base-specifier '...'[opt] | |||
2104 | /// base-specifier-list ',' base-specifier '...'[opt] | |||
2105 | void Parser::ParseBaseClause(Decl *ClassDecl) { | |||
2106 | assert(Tok.is(tok::colon) && "Not a base clause")((void)0); | |||
2107 | ConsumeToken(); | |||
2108 | ||||
2109 | // Build up an array of parsed base specifiers. | |||
2110 | SmallVector<CXXBaseSpecifier *, 8> BaseInfo; | |||
2111 | ||||
2112 | while (true) { | |||
2113 | // Parse a base-specifier. | |||
2114 | BaseResult Result = ParseBaseSpecifier(ClassDecl); | |||
2115 | if (Result.isInvalid()) { | |||
2116 | // Skip the rest of this base specifier, up until the comma or | |||
2117 | // opening brace. | |||
2118 | SkipUntil(tok::comma, tok::l_brace, StopAtSemi | StopBeforeMatch); | |||
2119 | } else { | |||
2120 | // Add this to our array of base specifiers. | |||
2121 | BaseInfo.push_back(Result.get()); | |||
2122 | } | |||
2123 | ||||
2124 | // If the next token is a comma, consume it and keep reading | |||
2125 | // base-specifiers. | |||
2126 | if (!TryConsumeToken(tok::comma)) | |||
2127 | break; | |||
2128 | } | |||
2129 | ||||
2130 | // Attach the base specifiers | |||
2131 | Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo); | |||
2132 | } | |||
2133 | ||||
2134 | /// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is | |||
2135 | /// one entry in the base class list of a class specifier, for example: | |||
2136 | /// class foo : public bar, virtual private baz { | |||
2137 | /// 'public bar' and 'virtual private baz' are each base-specifiers. | |||
2138 | /// | |||
2139 | /// base-specifier: [C++ class.derived] | |||
2140 | /// attribute-specifier-seq[opt] base-type-specifier | |||
2141 | /// attribute-specifier-seq[opt] 'virtual' access-specifier[opt] | |||
2142 | /// base-type-specifier | |||
2143 | /// attribute-specifier-seq[opt] access-specifier 'virtual'[opt] | |||
2144 | /// base-type-specifier | |||
2145 | BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { | |||
2146 | bool IsVirtual = false; | |||
2147 | SourceLocation StartLoc = Tok.getLocation(); | |||
2148 | ||||
2149 | ParsedAttributesWithRange Attributes(AttrFactory); | |||
2150 | MaybeParseCXX11Attributes(Attributes); | |||
2151 | ||||
2152 | // Parse the 'virtual' keyword. | |||
2153 | if (TryConsumeToken(tok::kw_virtual)) | |||
2154 | IsVirtual = true; | |||
2155 | ||||
2156 | CheckMisplacedCXX11Attribute(Attributes, StartLoc); | |||
2157 | ||||
2158 | // Parse an (optional) access specifier. | |||
2159 | AccessSpecifier Access = getAccessSpecifierIfPresent(); | |||
2160 | if (Access != AS_none) | |||
2161 | ConsumeToken(); | |||
2162 | ||||
2163 | CheckMisplacedCXX11Attribute(Attributes, StartLoc); | |||
2164 | ||||
2165 | // Parse the 'virtual' keyword (again!), in case it came after the | |||
2166 | // access specifier. | |||
2167 | if (Tok.is(tok::kw_virtual)) { | |||
2168 | SourceLocation VirtualLoc = ConsumeToken(); | |||
2169 | if (IsVirtual) { | |||
2170 | // Complain about duplicate 'virtual' | |||
2171 | Diag(VirtualLoc, diag::err_dup_virtual) | |||
2172 | << FixItHint::CreateRemoval(VirtualLoc); | |||
2173 | } | |||
2174 | ||||
2175 | IsVirtual = true; | |||
2176 | } | |||
2177 | ||||
2178 | CheckMisplacedCXX11Attribute(Attributes, StartLoc); | |||
2179 | ||||
2180 | // Parse the class-name. | |||
2181 | ||||
2182 | // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL | |||
2183 | // implementation for VS2013 uses _Atomic as an identifier for one of the | |||
2184 | // classes in <atomic>. Treat '_Atomic' to be an identifier when we are | |||
2185 | // parsing the class-name for a base specifier. | |||
2186 | if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) && | |||
2187 | NextToken().is(tok::less)) | |||
2188 | Tok.setKind(tok::identifier); | |||
2189 | ||||
2190 | SourceLocation EndLocation; | |||
2191 | SourceLocation BaseLoc; | |||
2192 | TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation); | |||
2193 | if (BaseType.isInvalid()) | |||
2194 | return true; | |||
2195 | ||||
2196 | // Parse the optional ellipsis (for a pack expansion). The ellipsis is | |||
2197 | // actually part of the base-specifier-list grammar productions, but we | |||
2198 | // parse it here for convenience. | |||
2199 | SourceLocation EllipsisLoc; | |||
2200 | TryConsumeToken(tok::ellipsis, EllipsisLoc); | |||
2201 | ||||
2202 | // Find the complete source range for the base-specifier. | |||
2203 | SourceRange Range(StartLoc, EndLocation); | |||
2204 | ||||
2205 | // Notify semantic analysis that we have parsed a complete | |||
2206 | // base-specifier. | |||
2207 | return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual, | |||
2208 | Access, BaseType.get(), BaseLoc, | |||
2209 | EllipsisLoc); | |||
2210 | } | |||
2211 | ||||
2212 | /// getAccessSpecifierIfPresent - Determine whether the next token is | |||
2213 | /// a C++ access-specifier. | |||
2214 | /// | |||
2215 | /// access-specifier: [C++ class.derived] | |||
2216 | /// 'private' | |||
2217 | /// 'protected' | |||
2218 | /// 'public' | |||
2219 | AccessSpecifier Parser::getAccessSpecifierIfPresent() const { | |||
2220 | switch (Tok.getKind()) { | |||
2221 | default: return AS_none; | |||
2222 | case tok::kw_private: return AS_private; | |||
2223 | case tok::kw_protected: return AS_protected; | |||
2224 | case tok::kw_public: return AS_public; | |||
2225 | } | |||
2226 | } | |||
2227 | ||||
2228 | /// If the given declarator has any parts for which parsing has to be | |||
2229 | /// delayed, e.g., default arguments or an exception-specification, create a | |||
2230 | /// late-parsed method declaration record to handle the parsing at the end of | |||
2231 | /// the class definition. | |||
2232 | void Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, | |||
2233 | Decl *ThisDecl) { | |||
2234 | DeclaratorChunk::FunctionTypeInfo &FTI | |||
2235 | = DeclaratorInfo.getFunctionTypeInfo(); | |||
2236 | // If there was a late-parsed exception-specification, we'll need a | |||
2237 | // late parse | |||
2238 | bool NeedLateParse = FTI.getExceptionSpecType() == EST_Unparsed; | |||
2239 | ||||
2240 | if (!NeedLateParse) { | |||
2241 | // Look ahead to see if there are any default args | |||
2242 | for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) { | |||
2243 | auto Param = cast<ParmVarDecl>(FTI.Params[ParamIdx].Param); | |||
2244 | if (Param->hasUnparsedDefaultArg()) { | |||
2245 | NeedLateParse = true; | |||
2246 | break; | |||
2247 | } | |||
2248 | } | |||
2249 | } | |||
2250 | ||||
2251 | if (NeedLateParse) { | |||
2252 | // Push this method onto the stack of late-parsed method | |||
2253 | // declarations. | |||
2254 | auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); | |||
2255 | getCurrentClass().LateParsedDeclarations.push_back(LateMethod); | |||
2256 | ||||
2257 | // Push tokens for each parameter. Those that do not have defaults will be | |||
2258 | // NULL. We need to track all the parameters so that we can push them into | |||
2259 | // scope for later parameters and perhaps for the exception specification. | |||
2260 | LateMethod->DefaultArgs.reserve(FTI.NumParams); | |||
2261 | for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) | |||
2262 | LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument( | |||
2263 | FTI.Params[ParamIdx].Param, | |||
2264 | std::move(FTI.Params[ParamIdx].DefaultArgTokens))); | |||
2265 | ||||
2266 | // Stash the exception-specification tokens in the late-pased method. | |||
2267 | if (FTI.getExceptionSpecType() == EST_Unparsed) { | |||
2268 | LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; | |||
2269 | FTI.ExceptionSpecTokens = nullptr; | |||
2270 | } | |||
2271 | } | |||
2272 | } | |||
2273 | ||||
2274 | /// isCXX11VirtSpecifier - Determine whether the given token is a C++11 | |||
2275 | /// virt-specifier. | |||
2276 | /// | |||
2277 | /// virt-specifier: | |||
2278 | /// override | |||
2279 | /// final | |||
2280 | /// __final | |||
2281 | VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const { | |||
2282 | if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier)) | |||
2283 | return VirtSpecifiers::VS_None; | |||
2284 | ||||
2285 | IdentifierInfo *II = Tok.getIdentifierInfo(); | |||
2286 | ||||
2287 | // Initialize the contextual keywords. | |||
2288 | if (!Ident_final) { | |||
2289 | Ident_final = &PP.getIdentifierTable().get("final"); | |||
2290 | if (getLangOpts().GNUKeywords) | |||
2291 | Ident_GNU_final = &PP.getIdentifierTable().get("__final"); | |||
2292 | if (getLangOpts().MicrosoftExt) { | |||
2293 | Ident_sealed = &PP.getIdentifierTable().get("sealed"); | |||
2294 | Ident_abstract = &PP.getIdentifierTable().get("abstract"); | |||
2295 | } | |||
2296 | Ident_override = &PP.getIdentifierTable().get("override"); | |||
2297 | } | |||
2298 | ||||
2299 | if (II == Ident_override) | |||
2300 | return VirtSpecifiers::VS_Override; | |||
2301 | ||||
2302 | if (II == Ident_sealed) | |||
2303 | return VirtSpecifiers::VS_Sealed; | |||
2304 | ||||
2305 | if (II == Ident_abstract) | |||
2306 | return VirtSpecifiers::VS_Abstract; | |||
2307 | ||||
2308 | if (II == Ident_final) | |||
2309 | return VirtSpecifiers::VS_Final; | |||
2310 | ||||
2311 | if (II == Ident_GNU_final) | |||
2312 | return VirtSpecifiers::VS_GNU_Final; | |||
2313 | ||||
2314 | return VirtSpecifiers::VS_None; | |||
2315 | } | |||
2316 | ||||
2317 | /// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq. | |||
2318 | /// | |||
2319 | /// virt-specifier-seq: | |||
2320 | /// virt-specifier | |||
2321 | /// virt-specifier-seq virt-specifier | |||
2322 | void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, | |||
2323 | bool IsInterface, | |||
2324 | SourceLocation FriendLoc) { | |||
2325 | while (true) { | |||
2326 | VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(); | |||
2327 | if (Specifier == VirtSpecifiers::VS_None) | |||
2328 | return; | |||
2329 | ||||
2330 | if (FriendLoc.isValid()) { | |||
2331 | Diag(Tok.getLocation(), diag::err_friend_decl_spec) | |||
2332 | << VirtSpecifiers::getSpecifierName(Specifier) | |||
2333 | << FixItHint::CreateRemoval(Tok.getLocation()) | |||
2334 | << SourceRange(FriendLoc, FriendLoc); | |||
2335 | ConsumeToken(); | |||
2336 | continue; | |||
2337 | } | |||
2338 | ||||
2339 | // C++ [class.mem]p8: | |||
2340 | // A virt-specifier-seq shall contain at most one of each virt-specifier. | |||
2341 | const char *PrevSpec = nullptr; | |||
2342 | if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec)) | |||
2343 | Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier) | |||
2344 | << PrevSpec | |||
2345 | << FixItHint::CreateRemoval(Tok.getLocation()); | |||
2346 | ||||
2347 | if (IsInterface && (Specifier == VirtSpecifiers::VS_Final || | |||
2348 | Specifier == VirtSpecifiers::VS_Sealed)) { | |||
2349 | Diag(Tok.getLocation(), diag::err_override_control_interface) | |||
2350 | << VirtSpecifiers::getSpecifierName(Specifier); | |||
2351 | } else if (Specifier == VirtSpecifiers::VS_Sealed) { | |||
2352 | Diag(Tok.getLocation(), diag::ext_ms_sealed_keyword); | |||
2353 | } else if (Specifier == VirtSpecifiers::VS_Abstract) { | |||
2354 | Diag(Tok.getLocation(), diag::ext_ms_abstract_keyword); | |||
2355 | } else if (Specifier == VirtSpecifiers::VS_GNU_Final) { | |||
2356 | Diag(Tok.getLocation(), diag::ext_warn_gnu_final); | |||
2357 | } else { | |||
2358 | Diag(Tok.getLocation(), | |||
2359 | getLangOpts().CPlusPlus11 | |||
2360 | ? diag::warn_cxx98_compat_override_control_keyword | |||
2361 | : diag::ext_override_control_keyword) | |||
2362 | << VirtSpecifiers::getSpecifierName(Specifier); | |||
2363 | } | |||
2364 | ConsumeToken(); | |||
2365 | } | |||
2366 | } | |||
2367 | ||||
2368 | /// isCXX11FinalKeyword - Determine whether the next token is a C++11 | |||
2369 | /// 'final' or Microsoft 'sealed' contextual keyword. | |||
2370 | bool Parser::isCXX11FinalKeyword() const { | |||
2371 | VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(); | |||
2372 | return Specifier == VirtSpecifiers::VS_Final || | |||
2373 | Specifier == VirtSpecifiers::VS_GNU_Final || | |||
2374 | Specifier == VirtSpecifiers::VS_Sealed; | |||
2375 | } | |||
2376 | ||||
2377 | /// isClassCompatibleKeyword - Determine whether the next token is a C++11 | |||
2378 | /// 'final' or Microsoft 'sealed' or 'abstract' contextual keywords. | |||
2379 | bool Parser::isClassCompatibleKeyword() const { | |||
2380 | VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(); | |||
2381 | return Specifier == VirtSpecifiers::VS_Final || | |||
2382 | Specifier == VirtSpecifiers::VS_GNU_Final || | |||
2383 | Specifier == VirtSpecifiers::VS_Sealed || | |||
2384 | Specifier == VirtSpecifiers::VS_Abstract; | |||
2385 | } | |||
2386 | ||||
2387 | /// Parse a C++ member-declarator up to, but not including, the optional | |||
2388 | /// brace-or-equal-initializer or pure-specifier. | |||
2389 | bool Parser::ParseCXXMemberDeclaratorBeforeInitializer( | |||
2390 | Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize, | |||
2391 | LateParsedAttrList &LateParsedAttrs) { | |||
2392 | // member-declarator: | |||
2393 | // declarator virt-specifier-seq[opt] pure-specifier[opt] | |||
2394 | // declarator requires-clause | |||
2395 | // declarator brace-or-equal-initializer[opt] | |||
2396 | // identifier attribute-specifier-seq[opt] ':' constant-expression | |||
2397 | // brace-or-equal-initializer[opt] | |||
2398 | // ':' constant-expression | |||
2399 | // | |||
2400 | // NOTE: the latter two productions are a proposed bugfix rather than the | |||
2401 | // current grammar rules as of C++20. | |||
2402 | if (Tok.isNot(tok::colon)) | |||
2403 | ParseDeclarator(DeclaratorInfo); | |||
2404 | else | |||
2405 | DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation()); | |||
2406 | ||||
2407 | if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) { | |||
2408 | assert(DeclaratorInfo.isPastIdentifier() &&((void)0) | |||
2409 | "don't know where identifier would go yet?")((void)0); | |||
2410 | BitfieldSize = ParseConstantExpression(); | |||
2411 | if (BitfieldSize.isInvalid()) | |||
2412 | SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); | |||
2413 | } else if (Tok.is(tok::kw_requires)) { | |||
2414 | ParseTrailingRequiresClause(DeclaratorInfo); | |||
2415 | } else { | |||
2416 | ParseOptionalCXX11VirtSpecifierSeq( | |||
2417 | VS, getCurrentClass().IsInterface, | |||
2418 | DeclaratorInfo.getDeclSpec().getFriendSpecLoc()); | |||
2419 | if (!VS.isUnset()) | |||
2420 | MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS); | |||
2421 | } | |||
2422 | ||||
2423 | // If a simple-asm-expr is present, parse it. | |||
2424 | if (Tok.is(tok::kw_asm)) { | |||
2425 | SourceLocation Loc; | |||
2426 | ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, &Loc)); | |||
2427 | if (AsmLabel.isInvalid()) | |||
2428 | SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); | |||
2429 | ||||
2430 | DeclaratorInfo.setAsmLabel(AsmLabel.get()); | |||
2431 | DeclaratorInfo.SetRangeEnd(Loc); | |||
2432 | } | |||
2433 | ||||
2434 | // If attributes exist after the declarator, but before an '{', parse them. | |||
2435 | // However, this does not apply for [[]] attributes (which could show up | |||
2436 | // before or after the __attribute__ attributes). | |||
2437 | DiagnoseAndSkipCXX11Attributes(); | |||
2438 | MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); | |||
2439 | DiagnoseAndSkipCXX11Attributes(); | |||
2440 | ||||
2441 | // For compatibility with code written to older Clang, also accept a | |||
2442 | // virt-specifier *after* the GNU attributes. | |||
2443 | if (BitfieldSize.isUnset() && VS.isUnset()) { | |||
2444 | ParseOptionalCXX11VirtSpecifierSeq( | |||
2445 | VS, getCurrentClass().IsInterface, | |||
2446 | DeclaratorInfo.getDeclSpec().getFriendSpecLoc()); | |||
2447 | if (!VS.isUnset()) { | |||
2448 | // If we saw any GNU-style attributes that are known to GCC followed by a | |||
2449 | // virt-specifier, issue a GCC-compat warning. | |||
2450 | for (const ParsedAttr &AL : DeclaratorInfo.getAttributes()) | |||
2451 | if (AL.isKnownToGCC() && !AL.isCXX11Attribute()) | |||
2452 | Diag(AL.getLoc(), diag::warn_gcc_attribute_location); | |||
2453 | ||||
2454 | MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo, VS); | |||
2455 | } | |||
2456 | } | |||
2457 | ||||
2458 | // If this has neither a name nor a bit width, something has gone seriously | |||
2459 | // wrong. Skip until the semi-colon or }. | |||
2460 | if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) { | |||
2461 | // If so, skip until the semi-colon or a }. | |||
2462 | SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); | |||
2463 | return true; | |||
2464 | } | |||
2465 | return false; | |||
2466 | } | |||
2467 | ||||
2468 | /// Look for declaration specifiers possibly occurring after C++11 | |||
2469 | /// virt-specifier-seq and diagnose them. | |||
2470 | void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq( | |||
2471 | Declarator &D, | |||
2472 | VirtSpecifiers &VS) { | |||
2473 | DeclSpec DS(AttrFactory); | |||
2474 | ||||
2475 | // GNU-style and C++11 attributes are not allowed here, but they will be | |||
2476 | // handled by the caller. Diagnose everything else. | |||
2477 | ParseTypeQualifierListOpt( | |||
2478 | DS, AR_NoAttributesParsed, false, | |||
2479 | /*IdentifierRequired=*/false, llvm::function_ref<void()>([&]() { | |||
2480 | Actions.CodeCompleteFunctionQualifiers(DS, D, &VS); | |||
2481 | })); | |||
2482 | D.ExtendWithDeclSpec(DS); | |||
2483 | ||||
2484 | if (D.isFunctionDeclarator()) { | |||
2485 | auto &Function = D.getFunctionTypeInfo(); | |||
2486 | if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) { | |||
2487 | auto DeclSpecCheck = [&](DeclSpec::TQ TypeQual, StringRef FixItName, | |||
2488 | SourceLocation SpecLoc) { | |||
2489 | FixItHint Insertion; | |||
2490 | auto &MQ = Function.getOrCreateMethodQualifiers(); | |||
2491 | if (!(MQ.getTypeQualifiers() & TypeQual)) { | |||
2492 | std::string Name(FixItName.data()); | |||
2493 | Name += " "; | |||
2494 | Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name); | |||
2495 | MQ.SetTypeQual(TypeQual, SpecLoc); | |||
2496 | } | |||
2497 | Diag(SpecLoc, diag::err_declspec_after_virtspec) | |||
2498 | << FixItName | |||
2499 | << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier()) | |||
2500 | << FixItHint::CreateRemoval(SpecLoc) << Insertion; | |||
2501 | }; | |||
2502 | DS.forEachQualifier(DeclSpecCheck); | |||
2503 | } | |||
2504 | ||||
2505 | // Parse ref-qualifiers. | |||
2506 | bool RefQualifierIsLValueRef = true; | |||
2507 | SourceLocation RefQualifierLoc; | |||
2508 | if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) { | |||
2509 | const char *Name = (RefQualifierIsLValueRef ? "& " : "&& "); | |||
2510 | FixItHint Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name); | |||
2511 | Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef; | |||
2512 | Function.RefQualifierLoc = RefQualifierLoc; | |||
2513 | ||||
2514 | Diag(RefQualifierLoc, diag::err_declspec_after_virtspec) | |||
2515 | << (RefQualifierIsLValueRef ? "&" : "&&") | |||
2516 | << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier()) | |||
2517 | << FixItHint::CreateRemoval(RefQualifierLoc) | |||
2518 | << Insertion; | |||
2519 | D.SetRangeEnd(RefQualifierLoc); | |||
2520 | } | |||
2521 | } | |||
2522 | } | |||
2523 | ||||
2524 | /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. | |||
2525 | /// | |||
2526 | /// member-declaration: | |||
2527 | /// decl-specifier-seq[opt] member-declarator-list[opt] ';' | |||
2528 | /// function-definition ';'[opt] | |||
2529 | /// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] | |||
2530 | /// using-declaration [TODO] | |||
2531 | /// [C++0x] static_assert-declaration | |||
2532 | /// template-declaration | |||
2533 | /// [GNU] '__extension__' member-declaration | |||
2534 | /// | |||
2535 | /// member-declarator-list: | |||
2536 | /// member-declarator | |||
2537 | /// member-declarator-list ',' member-declarator | |||
2538 | /// | |||
2539 | /// member-declarator: | |||
2540 | /// declarator virt-specifier-seq[opt] pure-specifier[opt] | |||
2541 | /// [C++2a] declarator requires-clause | |||
2542 | /// declarator constant-initializer[opt] | |||
2543 | /// [C++11] declarator brace-or-equal-initializer[opt] | |||
2544 | /// identifier[opt] ':' constant-expression | |||
2545 | /// | |||
2546 | /// virt-specifier-seq: | |||
2547 | /// virt-specifier | |||
2548 | /// virt-specifier-seq virt-specifier | |||
2549 | /// | |||
2550 | /// virt-specifier: | |||
2551 | /// override | |||
2552 | /// final | |||
2553 | /// [MS] sealed | |||
2554 | /// | |||
2555 | /// pure-specifier: | |||
2556 | /// '= 0' | |||
2557 | /// | |||
2558 | /// constant-initializer: | |||
2559 | /// '=' constant-expression | |||
2560 | /// | |||
2561 | Parser::DeclGroupPtrTy | |||
2562 | Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, | |||
2563 | ParsedAttributes &AccessAttrs, | |||
2564 | const ParsedTemplateInfo &TemplateInfo, | |||
2565 | ParsingDeclRAIIObject *TemplateDiags) { | |||
2566 | if (Tok.is(tok::at)) { | |||
2567 | if (getLangOpts().ObjC && NextToken().isObjCAtKeyword(tok::objc_defs)) | |||
2568 | Diag(Tok, diag::err_at_defs_cxx); | |||
2569 | else | |||
2570 | Diag(Tok, diag::err_at_in_class); | |||
2571 | ||||
2572 | ConsumeToken(); | |||
2573 | SkipUntil(tok::r_brace, StopAtSemi); | |||
2574 | return nullptr; | |||
2575 | } | |||
2576 | ||||
2577 | // Turn on colon protection early, while parsing declspec, although there is | |||
2578 | // nothing to protect there. It prevents from false errors if error recovery | |||
2579 | // incorrectly determines where the declspec ends, as in the example: | |||
2580 | // struct A { enum class B { C }; }; | |||
2581 | // const int C = 4; | |||
2582 | // struct D { A::B : C; }; | |||
2583 | ColonProtectionRAIIObject X(*this); | |||
2584 | ||||
2585 | // Access declarations. | |||
2586 | bool MalformedTypeSpec = false; | |||
2587 | if (!TemplateInfo.Kind && | |||
2588 | Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) { | |||
2589 | if (TryAnnotateCXXScopeToken()) | |||
2590 | MalformedTypeSpec = true; | |||
2591 | ||||
2592 | bool isAccessDecl; | |||
2593 | if (Tok.isNot(tok::annot_cxxscope)) | |||
2594 | isAccessDecl = false; | |||
2595 | else if (NextToken().is(tok::identifier)) | |||
2596 | isAccessDecl = GetLookAheadToken(2).is(tok::semi); | |||
2597 | else | |||
2598 | isAccessDecl = NextToken().is(tok::kw_operator); | |||
2599 | ||||
2600 | if (isAccessDecl) { | |||
2601 | // Collect the scope specifier token we annotated earlier. | |||
2602 | CXXScopeSpec SS; | |||
2603 | ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, | |||
2604 | /*ObjectHadErrors=*/false, | |||
2605 | /*EnteringContext=*/false); | |||
2606 | ||||
2607 | if (SS.isInvalid()) { | |||
2608 | SkipUntil(tok::semi); | |||
2609 | return nullptr; | |||
2610 | } | |||
2611 | ||||
2612 | // Try to parse an unqualified-id. | |||
2613 | SourceLocation TemplateKWLoc; | |||
2614 | UnqualifiedId Name; | |||
2615 | if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr, | |||
2616 | /*ObjectHadErrors=*/false, false, true, true, | |||
2617 | false, &TemplateKWLoc, Name)) { | |||
2618 | SkipUntil(tok::semi); | |||
2619 | return nullptr; | |||
2620 | } | |||
2621 | ||||
2622 | // TODO: recover from mistakenly-qualified operator declarations. | |||
2623 | if (ExpectAndConsume(tok::semi, diag::err_expected_after, | |||
2624 | "access declaration")) { | |||
2625 | SkipUntil(tok::semi); | |||
2626 | return nullptr; | |||
2627 | } | |||
2628 | ||||
2629 | // FIXME: We should do something with the 'template' keyword here. | |||
2630 | return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration( | |||
2631 | getCurScope(), AS, /*UsingLoc*/ SourceLocation(), | |||
2632 | /*TypenameLoc*/ SourceLocation(), SS, Name, | |||
2633 | /*EllipsisLoc*/ SourceLocation(), | |||
2634 | /*AttrList*/ ParsedAttributesView()))); | |||
2635 | } | |||
2636 | } | |||
2637 | ||||
2638 | // static_assert-declaration. A templated static_assert declaration is | |||
2639 | // diagnosed in Parser::ParseSingleDeclarationAfterTemplate. | |||
2640 | if (!TemplateInfo.Kind && | |||
2641 | Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) { | |||
2642 | SourceLocation DeclEnd; | |||
2643 | return DeclGroupPtrTy::make( | |||
2644 | DeclGroupRef(ParseStaticAssertDeclaration(DeclEnd))); | |||
2645 | } | |||
2646 | ||||
2647 | if (Tok.is(tok::kw_template)) { | |||
2648 | assert(!TemplateInfo.TemplateParams &&((void)0) | |||
2649 | "Nested template improperly parsed?")((void)0); | |||
2650 | ObjCDeclContextSwitch ObjCDC(*this); | |||
2651 | SourceLocation DeclEnd; | |||
2652 | return DeclGroupPtrTy::make( | |||
2653 | DeclGroupRef(ParseTemplateDeclarationOrSpecialization( | |||
2654 | DeclaratorContext::Member, DeclEnd, AccessAttrs, AS))); | |||
2655 | } | |||
2656 | ||||
2657 | // Handle: member-declaration ::= '__extension__' member-declaration | |||
2658 | if (Tok.is(tok::kw___extension__)) { | |||
2659 | // __extension__ silences extension warnings in the subexpression. | |||
2660 | ExtensionRAIIObject O(Diags); // Use RAII to do this. | |||
2661 | ConsumeToken(); | |||
2662 | return ParseCXXClassMemberDeclaration(AS, AccessAttrs, | |||
2663 | TemplateInfo, TemplateDiags); | |||
2664 | } | |||
2665 | ||||
2666 | ParsedAttributesWithRange attrs(AttrFactory); | |||
2667 | ParsedAttributesViewWithRange FnAttrs; | |||
2668 | // Optional C++11 attribute-specifier | |||
2669 | MaybeParseCXX11Attributes(attrs); | |||
2670 | ||||
2671 | // The next token may be an OpenMP pragma annotation token. That would | |||
2672 | // normally be handled from ParseCXXClassMemberDeclarationWithPragmas, but in | |||
2673 | // this case, it came from an *attribute* rather than a pragma. Handle it now. | |||
2674 | if (Tok.is(tok::annot_attr_openmp)) | |||
2675 | return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, attrs); | |||
2676 | ||||
2677 | // We need to keep these attributes for future diagnostic | |||
2678 | // before they are taken over by declaration specifier. | |||
2679 | FnAttrs.addAll(attrs.begin(), attrs.end()); | |||
2680 | FnAttrs.Range = attrs.Range; | |||
2681 | ||||
2682 | MaybeParseMicrosoftAttributes(attrs); | |||
2683 | ||||
2684 | if (Tok.is(tok::kw_using)) { | |||
2685 | // Eat 'using'. | |||
2686 | SourceLocation UsingLoc = ConsumeToken(); | |||
2687 | ||||
2688 | // Consume unexpected 'template' keywords. | |||
2689 | while (Tok.is(tok::kw_template)) { | |||
2690 | SourceLocation TemplateLoc = ConsumeToken(); | |||
2691 | Diag(TemplateLoc, diag::err_unexpected_template_after_using) | |||
2692 | << FixItHint::CreateRemoval(TemplateLoc); | |||
2693 | } | |||
2694 | ||||
2695 | if (Tok.is(tok::kw_namespace)) { | |||
2696 | Diag(UsingLoc, diag::err_using_namespace_in_class); | |||
2697 | SkipUntil(tok::semi, StopBeforeMatch); | |||
2698 | return nullptr; | |||
2699 | } | |||
2700 | SourceLocation DeclEnd; | |||
2701 | // Otherwise, it must be a using-declaration or an alias-declaration. | |||
2702 | return ParseUsingDeclaration(DeclaratorContext::Member, TemplateInfo, | |||
2703 | UsingLoc, DeclEnd, attrs, AS); | |||
2704 | } | |||
2705 | ||||
2706 | // Hold late-parsed attributes so we can attach a Decl to them later. | |||
2707 | LateParsedAttrList CommonLateParsedAttrs; | |||
2708 | ||||
2709 | // decl-specifier-seq: | |||
2710 | // Parse the common declaration-specifiers piece. | |||
2711 | ParsingDeclSpec DS(*this, TemplateDiags); | |||
2712 | DS.takeAttributesFrom(attrs); | |||
2713 | if (MalformedTypeSpec) | |||
2714 | DS.SetTypeSpecError(); | |||
2715 | ||||
2716 | ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class, | |||
2717 | &CommonLateParsedAttrs); | |||
2718 | ||||
2719 | // Turn off colon protection that was set for declspec. | |||
2720 | X.restore(); | |||
2721 | ||||
2722 | // If we had a free-standing type definition with a missing semicolon, we | |||
2723 | // may get this far before the problem becomes obvious. | |||
2724 | if (DS.hasTagDefinition() && | |||
2725 | TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate && | |||
2726 | DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class, | |||
2727 | &CommonLateParsedAttrs)) | |||
2728 | return nullptr; | |||
2729 | ||||
2730 | MultiTemplateParamsArg TemplateParams( | |||
2731 | TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() | |||
2732 | : nullptr, | |||
2733 | TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); | |||
2734 | ||||
2735 | if (TryConsumeToken(tok::semi)) { | |||
2736 | if (DS.isFriendSpecified()) | |||
2737 | ProhibitAttributes(FnAttrs); | |||
2738 | ||||
2739 | RecordDecl *AnonRecord = nullptr; | |||
2740 | Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec( | |||
2741 | getCurScope(), AS, DS, TemplateParams, false, AnonRecord); | |||
2742 | DS.complete(TheDecl); | |||
2743 | if (AnonRecord) { | |||
2744 | Decl* decls[] = {AnonRecord, TheDecl}; | |||
2745 | return Actions.BuildDeclaratorGroup(decls); | |||
2746 | } | |||
2747 | return Actions.ConvertDeclToDeclGroup(TheDecl); | |||
2748 | } | |||
2749 | ||||
2750 | ParsingDeclarator DeclaratorInfo(*this, DS, DeclaratorContext::Member); | |||
2751 | if (TemplateInfo.TemplateParams) | |||
2752 | DeclaratorInfo.setTemplateParameterLists(TemplateParams); | |||
2753 | VirtSpecifiers VS; | |||
2754 | ||||
2755 | // Hold late-parsed attributes so we can attach a Decl to them later. | |||
2756 | LateParsedAttrList LateParsedAttrs; | |||
2757 | ||||
2758 | SourceLocation EqualLoc; | |||
2759 | SourceLocation PureSpecLoc; | |||
2760 | ||||
2761 | auto TryConsumePureSpecifier = [&] (bool AllowDefinition) { | |||
2762 | if (Tok.isNot(tok::equal)) | |||
2763 | return false; | |||
2764 | ||||
2765 | auto &Zero = NextToken(); | |||
2766 | SmallString<8> Buffer; | |||
2767 | if (Zero.isNot(tok::numeric_constant) || | |||
2768 | PP.getSpelling(Zero, Buffer) != "0") | |||
2769 | return false; | |||
2770 | ||||
2771 | auto &After = GetLookAheadToken(2); | |||
2772 | if (!After.isOneOf(tok::semi, tok::comma) && | |||
2773 | !(AllowDefinition && | |||
2774 | After.isOneOf(tok::l_brace, tok::colon, tok::kw_try))) | |||
2775 | return false; | |||
2776 | ||||
2777 | EqualLoc = ConsumeToken(); | |||
2778 | PureSpecLoc = ConsumeToken(); | |||
2779 | return true; | |||
2780 | }; | |||
2781 | ||||
2782 | SmallVector<Decl *, 8> DeclsInGroup; | |||
2783 | ExprResult BitfieldSize; | |||
2784 | ExprResult TrailingRequiresClause; | |||
2785 | bool ExpectSemi = true; | |||
2786 | ||||
2787 | // Parse the first declarator. | |||
2788 | if (ParseCXXMemberDeclaratorBeforeInitializer( | |||
2789 | DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) { | |||
2790 | TryConsumeToken(tok::semi); | |||
2791 | return nullptr; | |||
2792 | } | |||
2793 | ||||
2794 | // Check for a member function definition. | |||
2795 | if (BitfieldSize.isUnset()) { | |||
2796 | // MSVC permits pure specifier on inline functions defined at class scope. | |||
2797 | // Hence check for =0 before checking for function definition. | |||
2798 | if (getLangOpts().MicrosoftExt && DeclaratorInfo.isDeclarationOfFunction()) | |||
2799 | TryConsumePureSpecifier(/*AllowDefinition*/ true); | |||
2800 | ||||
2801 | FunctionDefinitionKind DefinitionKind = FunctionDefinitionKind::Declaration; | |||
2802 | // function-definition: | |||
2803 | // | |||
2804 | // In C++11, a non-function declarator followed by an open brace is a | |||
2805 | // braced-init-list for an in-class member initialization, not an | |||
2806 | // erroneous function definition. | |||
2807 | if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) { | |||
2808 | DefinitionKind = FunctionDefinitionKind::Definition; | |||
2809 | } else if (DeclaratorInfo.isFunctionDeclarator()) { | |||
2810 | if (Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)) { | |||
2811 | DefinitionKind = FunctionDefinitionKind::Definition; | |||
2812 | } else if (Tok.is(tok::equal)) { | |||
2813 | const Token &KW = NextToken(); | |||
2814 | if (KW.is(tok::kw_default)) | |||
2815 | DefinitionKind = FunctionDefinitionKind::Defaulted; | |||
2816 | else if (KW.is(tok::kw_delete)) | |||
2817 | DefinitionKind = FunctionDefinitionKind::Deleted; | |||
2818 | else if (KW.is(tok::code_completion)) { | |||
2819 | cutOffParsing(); | |||
2820 | Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo); | |||
2821 | return nullptr; | |||
2822 | } | |||
2823 | } | |||
2824 | } | |||
2825 | DeclaratorInfo.setFunctionDefinitionKind(DefinitionKind); | |||
2826 | ||||
2827 | // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains | |||
2828 | // to a friend declaration, that declaration shall be a definition. | |||
2829 | if (DeclaratorInfo.isFunctionDeclarator() && | |||
2830 | DefinitionKind == FunctionDefinitionKind::Declaration && | |||
2831 | DS.isFriendSpecified()) { | |||
2832 | // Diagnose attributes that appear before decl specifier: | |||
2833 | // [[]] friend int foo(); | |||
2834 | ProhibitAttributes(FnAttrs); | |||
2835 | } | |||
2836 | ||||
2837 | if (DefinitionKind != FunctionDefinitionKind::Declaration) { | |||
2838 | if (!DeclaratorInfo.isFunctionDeclarator()) { | |||
2839 | Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params); | |||
2840 | ConsumeBrace(); | |||
2841 | SkipUntil(tok::r_brace); | |||
2842 | ||||
2843 | // Consume the optional ';' | |||
2844 | TryConsumeToken(tok::semi); | |||
2845 | ||||
2846 | return nullptr; | |||
2847 | } | |||
2848 | ||||
2849 | if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { | |||
2850 | Diag(DeclaratorInfo.getIdentifierLoc(), | |||
2851 | diag::err_function_declared_typedef); | |||
2852 | ||||
2853 | // Recover by treating the 'typedef' as spurious. | |||
2854 | DS.ClearStorageClassSpecs(); | |||
2855 | } | |||
2856 | ||||
2857 | Decl *FunDecl = | |||
2858 | ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo, | |||
2859 | VS, PureSpecLoc); | |||
2860 | ||||
2861 | if (FunDecl) { | |||
2862 | for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { | |||
2863 | CommonLateParsedAttrs[i]->addDecl(FunDecl); | |||
2864 | } | |||
2865 | for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { | |||
2866 | LateParsedAttrs[i]->addDecl(FunDecl); | |||
2867 | } | |||
2868 | } | |||
2869 | LateParsedAttrs.clear(); | |||
2870 | ||||
2871 | // Consume the ';' - it's optional unless we have a delete or default | |||
2872 | if (Tok.is(tok::semi)) | |||
2873 | ConsumeExtraSemi(AfterMemberFunctionDefinition); | |||
2874 | ||||
2875 | return DeclGroupPtrTy::make(DeclGroupRef(FunDecl)); | |||
2876 | } | |||
2877 | } | |||
2878 | ||||
2879 | // member-declarator-list: | |||
2880 | // member-declarator | |||
2881 | // member-declarator-list ',' member-declarator | |||
2882 | ||||
2883 | while (1) { | |||
2884 | InClassInitStyle HasInClassInit = ICIS_NoInit; | |||
2885 | bool HasStaticInitializer = false; | |||
2886 | if (Tok.isOneOf(tok::equal, tok::l_brace) && PureSpecLoc.isInvalid()) { | |||
2887 | // DRXXXX: Anonymous bit-fields cannot have a brace-or-equal-initializer. | |||
2888 | if (BitfieldSize.isUsable() && !DeclaratorInfo.hasName()) { | |||
2889 | // Diagnose the error and pretend there is no in-class initializer. | |||
2890 | Diag(Tok, diag::err_anon_bitfield_member_init); | |||
2891 | SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); | |||
2892 | } else if (DeclaratorInfo.isDeclarationOfFunction()) { | |||
2893 | // It's a pure-specifier. | |||
2894 | if (!TryConsumePureSpecifier(/*AllowFunctionDefinition*/ false)) | |||
2895 | // Parse it as an expression so that Sema can diagnose it. | |||
2896 | HasStaticInitializer = true; | |||
2897 | } else if (DeclaratorInfo.getDeclSpec().getStorageClassSpec() != | |||
2898 | DeclSpec::SCS_static && | |||
2899 | DeclaratorInfo.getDeclSpec().getStorageClassSpec() != | |||
2900 | DeclSpec::SCS_typedef && | |||
2901 | !DS.isFriendSpecified()) { | |||
2902 | // It's a default member initializer. | |||
2903 | if (BitfieldSize.get()) | |||
2904 | Diag(Tok, getLangOpts().CPlusPlus20 | |||
2905 | ? diag::warn_cxx17_compat_bitfield_member_init | |||
2906 | : diag::ext_bitfield_member_init); | |||
2907 | HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit; | |||
2908 | } else { | |||
2909 | HasStaticInitializer = true; | |||
2910 | } | |||
2911 | } | |||
2912 | ||||
2913 | // NOTE: If Sema is the Action module and declarator is an instance field, | |||
2914 | // this call will *not* return the created decl; It will return null. | |||
2915 | // See Sema::ActOnCXXMemberDeclarator for details. | |||
2916 | ||||
2917 | NamedDecl *ThisDecl = nullptr; | |||
2918 | if (DS.isFriendSpecified()) { | |||
2919 | // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains | |||
2920 | // to a friend declaration, that declaration shall be a definition. | |||
2921 | // | |||
2922 | // Diagnose attributes that appear in a friend member function declarator: | |||
2923 | // friend int foo [[]] (); | |||
2924 | SmallVector<SourceRange, 4> Ranges; | |||
2925 | DeclaratorInfo.getCXX11AttributeRanges(Ranges); | |||
2926 | for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(), | |||
2927 | E = Ranges.end(); I != E; ++I) | |||
2928 | Diag((*I).getBegin(), diag::err_attributes_not_allowed) << *I; | |||
2929 | ||||
2930 | ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, | |||
2931 | TemplateParams); | |||
2932 | } else { | |||
2933 | ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, | |||
2934 | DeclaratorInfo, | |||
2935 | TemplateParams, | |||
2936 | BitfieldSize.get(), | |||
2937 | VS, HasInClassInit); | |||
2938 | ||||
2939 | if (VarTemplateDecl *VT = | |||
2940 | ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : nullptr) | |||
2941 | // Re-direct this decl to refer to the templated decl so that we can | |||
2942 | // initialize it. | |||
2943 | ThisDecl = VT->getTemplatedDecl(); | |||
2944 | ||||
2945 | if (ThisDecl) | |||
2946 | Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs); | |||
2947 | } | |||
2948 | ||||
2949 | // Error recovery might have converted a non-static member into a static | |||
2950 | // member. | |||
2951 | if (HasInClassInit != ICIS_NoInit && | |||
2952 | DeclaratorInfo.getDeclSpec().getStorageClassSpec() == | |||
2953 | DeclSpec::SCS_static) { | |||
2954 | HasInClassInit = ICIS_NoInit; | |||
2955 | HasStaticInitializer = true; | |||
2956 | } | |||
2957 | ||||
2958 | if (PureSpecLoc.isValid() && VS.getAbstractLoc().isValid()) { | |||
2959 | Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) << "abstract"; | |||
2960 | } | |||
2961 | if (ThisDecl && PureSpecLoc.isValid()) | |||
2962 | Actions.ActOnPureSpecifier(ThisDecl, PureSpecLoc); | |||
2963 | else if (ThisDecl && VS.getAbstractLoc().isValid()) | |||
2964 | Actions.ActOnPureSpecifier(ThisDecl, VS.getAbstractLoc()); | |||
2965 | ||||
2966 | // Handle the initializer. | |||
2967 | if (HasInClassInit != ICIS_NoInit) { | |||
2968 | // The initializer was deferred; parse it and cache the tokens. | |||
2969 | Diag(Tok, getLangOpts().CPlusPlus11 | |||
2970 | ? diag::warn_cxx98_compat_nonstatic_member_init | |||
2971 | : diag::ext_nonstatic_member_init); | |||
2972 | ||||
2973 | if (DeclaratorInfo.isArrayOfUnknownBound()) { | |||
2974 | // C++11 [dcl.array]p3: An array bound may also be omitted when the | |||
2975 | // declarator is followed by an initializer. | |||
2976 | // | |||
2977 | // A brace-or-equal-initializer for a member-declarator is not an | |||
2978 | // initializer in the grammar, so this is ill-formed. | |||
2979 | Diag(Tok, diag::err_incomplete_array_member_init); | |||
2980 | SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); | |||
2981 | ||||
2982 | // Avoid later warnings about a class member of incomplete type. | |||
2983 | if (ThisDecl) | |||
2984 | ThisDecl->setInvalidDecl(); | |||
2985 | } else | |||
2986 | ParseCXXNonStaticMemberInitializer(ThisDecl); | |||
2987 | } else if (HasStaticInitializer) { | |||
2988 | // Normal initializer. | |||
2989 | ExprResult Init = ParseCXXMemberInitializer( | |||
2990 | ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc); | |||
2991 | ||||
2992 | if (Init.isInvalid()) | |||
2993 | SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch); | |||
2994 | else if (ThisDecl) | |||
2995 | Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid()); | |||
2996 | } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) | |||
2997 | // No initializer. | |||
2998 | Actions.ActOnUninitializedDecl(ThisDecl); | |||
2999 | ||||
3000 | if (ThisDecl) { | |||
3001 | if (!ThisDecl->isInvalidDecl()) { | |||
3002 | // Set the Decl for any late parsed attributes | |||
3003 | for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) | |||
3004 | CommonLateParsedAttrs[i]->addDecl(ThisDecl); | |||
3005 | ||||
3006 | for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) | |||
3007 | LateParsedAttrs[i]->addDecl(ThisDecl); | |||
3008 | } | |||
3009 | Actions.FinalizeDeclaration(ThisDecl); | |||
3010 | DeclsInGroup.push_back(ThisDecl); | |||
3011 | ||||
3012 | if (DeclaratorInfo.isFunctionDeclarator() && | |||
3013 | DeclaratorInfo.getDeclSpec().getStorageClassSpec() != | |||
3014 | DeclSpec::SCS_typedef) | |||
3015 | HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl); | |||
3016 | } | |||
3017 | LateParsedAttrs.clear(); | |||
3018 | ||||
3019 | DeclaratorInfo.complete(ThisDecl); | |||
3020 | ||||
3021 | // If we don't have a comma, it is either the end of the list (a ';') | |||
3022 | // or an error, bail out. | |||
3023 | SourceLocation CommaLoc; | |||
3024 | if (!TryConsumeToken(tok::comma, CommaLoc)) | |||
3025 | break; | |||
3026 | ||||
3027 | if (Tok.isAtStartOfLine() && | |||
3028 | !MightBeDeclarator(DeclaratorContext::Member)) { | |||
3029 | // This comma was followed by a line-break and something which can't be | |||
3030 | // the start of a declarator. The comma was probably a typo for a | |||
3031 | // semicolon. | |||
3032 | Diag(CommaLoc, diag::err_expected_semi_declaration) | |||
3033 | << FixItHint::CreateReplacement(CommaLoc, ";"); | |||
3034 | ExpectSemi = false; | |||
3035 | break; | |||
3036 | } | |||
3037 | ||||
3038 | // Parse the next declarator. | |||
3039 | DeclaratorInfo.clear(); | |||
3040 | VS.clear(); | |||
3041 | BitfieldSize = ExprResult(/*Invalid=*/false); | |||
3042 | EqualLoc = PureSpecLoc = SourceLocation(); | |||
3043 | DeclaratorInfo.setCommaLoc(CommaLoc); | |||
3044 | ||||
3045 | // GNU attributes are allowed before the second and subsequent declarator. | |||
3046 | // However, this does not apply for [[]] attributes (which could show up | |||
3047 | // before or after the __attribute__ attributes). | |||
3048 | DiagnoseAndSkipCXX11Attributes(); | |||
3049 | MaybeParseGNUAttributes(DeclaratorInfo); | |||
3050 | DiagnoseAndSkipCXX11Attributes(); | |||
3051 | ||||
3052 | if (ParseCXXMemberDeclaratorBeforeInitializer( | |||
3053 | DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) | |||
3054 | break; | |||
3055 | } | |||
3056 | ||||
3057 | if (ExpectSemi && | |||
3058 | ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) { | |||
3059 | // Skip to end of block or statement. | |||
3060 | SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); | |||
3061 | // If we stopped at a ';', eat it. | |||
3062 | TryConsumeToken(tok::semi); | |||
3063 | return nullptr; | |||
3064 | } | |||
3065 | ||||
3066 | return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); | |||
3067 | } | |||
3068 | ||||
3069 | /// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer. | |||
3070 | /// Also detect and reject any attempted defaulted/deleted function definition. | |||
3071 | /// The location of the '=', if any, will be placed in EqualLoc. | |||
3072 | /// | |||
3073 | /// This does not check for a pure-specifier; that's handled elsewhere. | |||
3074 | /// | |||
3075 | /// brace-or-equal-initializer: | |||
3076 | /// '=' initializer-expression | |||
3077 | /// braced-init-list | |||
3078 | /// | |||
3079 | /// initializer-clause: | |||
3080 | /// assignment-expression | |||
3081 | /// braced-init-list | |||
3082 | /// | |||
3083 | /// defaulted/deleted function-definition: | |||
3084 | /// '=' 'default' | |||
3085 | /// '=' 'delete' | |||
3086 | /// | |||
3087 | /// Prior to C++0x, the assignment-expression in an initializer-clause must | |||
3088 | /// be a constant-expression. | |||
3089 | ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction, | |||
3090 | SourceLocation &EqualLoc) { | |||
3091 | assert(Tok.isOneOf(tok::equal, tok::l_brace)((void)0) | |||
3092 | && "Data member initializer not starting with '=' or '{'")((void)0); | |||
3093 | ||||
3094 | EnterExpressionEvaluationContext Context( | |||
3095 | Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, D); | |||
3096 | if (TryConsumeToken(tok::equal, EqualLoc)) { | |||
3097 | if (Tok.is(tok::kw_delete)) { | |||
3098 | // In principle, an initializer of '= delete p;' is legal, but it will | |||
3099 | // never type-check. It's better to diagnose it as an ill-formed expression | |||
3100 | // than as an ill-formed deleted non-function member. | |||
3101 | // An initializer of '= delete p, foo' will never be parsed, because | |||
3102 | // a top-level comma always ends the initializer expression. | |||
3103 | const Token &Next = NextToken(); | |||
3104 | if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) { | |||
3105 | if (IsFunction) | |||
3106 | Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) | |||
3107 | << 1 /* delete */; | |||
3108 | else | |||
3109 | Diag(ConsumeToken(), diag::err_deleted_non_function); | |||
3110 | return ExprError(); | |||
3111 | } | |||
3112 | } else if (Tok.is(tok::kw_default)) { | |||
3113 | if (IsFunction) | |||
3114 | Diag(Tok, diag::err_default_delete_in_multiple_declaration) | |||
3115 | << 0 /* default */; | |||
3116 | else | |||
3117 | Diag(ConsumeToken(), diag::err_default_special_members) | |||
3118 | << getLangOpts().CPlusPlus20; | |||
3119 | return ExprError(); | |||
3120 | } | |||
3121 | } | |||
3122 | if (const auto *PD = dyn_cast_or_null<MSPropertyDecl>(D)) { | |||
3123 | Diag(Tok, diag::err_ms_property_initializer) << PD; | |||
3124 | return ExprError(); | |||
3125 | } | |||
3126 | return ParseInitializer(); | |||
3127 | } | |||
3128 | ||||
3129 | void Parser::SkipCXXMemberSpecification(SourceLocation RecordLoc, | |||
3130 | SourceLocation AttrFixitLoc, | |||
3131 | unsigned TagType, Decl *TagDecl) { | |||
3132 | // Skip the optional 'final' keyword. | |||
3133 | if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) { | |||
3134 | assert(isCXX11FinalKeyword() && "not a class definition")((void)0); | |||
3135 | ConsumeToken(); | |||
3136 | ||||
3137 | // Diagnose any C++11 attributes after 'final' keyword. | |||
3138 | // We deliberately discard these attributes. | |||
3139 | ParsedAttributesWithRange Attrs(AttrFactory); | |||
3140 | CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc); | |||
3141 | ||||
3142 | // This can only happen if we had malformed misplaced attributes; | |||
3143 | // we only get called if there is a colon or left-brace after the | |||
3144 | // attributes. | |||
3145 | if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_brace)) | |||
3146 | return; | |||
3147 | } | |||
3148 | ||||
3149 | // Skip the base clauses. This requires actually parsing them, because | |||
3150 | // otherwise we can't be sure where they end (a left brace may appear | |||
3151 | // within a template argument). | |||
3152 | if (Tok.is(tok::colon)) { | |||
3153 | // Enter the scope of the class so that we can correctly parse its bases. | |||
3154 | ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); | |||
3155 | ParsingClassDefinition ParsingDef(*this, TagDecl, /*NonNestedClass*/ true, | |||
3156 | TagType == DeclSpec::TST_interface); | |||
3157 | auto OldContext = | |||
3158 | Actions.ActOnTagStartSkippedDefinition(getCurScope(), TagDecl); | |||
3159 | ||||
3160 | // Parse the bases but don't attach them to the class. | |||
3161 | ParseBaseClause(nullptr); | |||
3162 | ||||
3163 | Actions.ActOnTagFinishSkippedDefinition(OldContext); | |||
3164 | ||||
3165 | if (!Tok.is(tok::l_brace)) { | |||
3166 | Diag(PP.getLocForEndOfToken(PrevTokLocation), | |||
3167 | diag::err_expected_lbrace_after_base_specifiers); | |||
3168 | return; | |||
3169 | } | |||
3170 | } | |||
3171 | ||||
3172 | // Skip the body. | |||
3173 | assert(Tok.is(tok::l_brace))((void)0); | |||
3174 | BalancedDelimiterTracker T(*this, tok::l_brace); | |||
3175 | T.consumeOpen(); | |||
3176 | T.skipToEnd(); | |||
3177 | ||||
3178 | // Parse and discard any trailing attributes. | |||
3179 | ParsedAttributes Attrs(AttrFactory); | |||
3180 | if (Tok.is(tok::kw___attribute)) | |||
3181 | MaybeParseGNUAttributes(Attrs); | |||
3182 | } | |||
3183 | ||||
3184 | Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas( | |||
3185 | AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs, | |||
3186 | DeclSpec::TST TagType, Decl *TagDecl) { | |||
3187 | ParenBraceBracketBalancer BalancerRAIIObj(*this); | |||
3188 | ||||
3189 | switch (Tok.getKind()) { | |||
3190 | case tok::kw___if_exists: | |||
3191 | case tok::kw___if_not_exists: | |||
3192 | ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS); | |||
3193 | return nullptr; | |||
3194 | ||||
3195 | case tok::semi: | |||
3196 | // Check for extraneous top-level semicolon. | |||
3197 | ConsumeExtraSemi(InsideStruct, TagType); | |||
3198 | return nullptr; | |||
3199 | ||||
3200 | // Handle pragmas that can appear as member declarations. | |||
3201 | case tok::annot_pragma_vis: | |||
3202 | HandlePragmaVisibility(); | |||
3203 | return nullptr; | |||
3204 | case tok::annot_pragma_pack: | |||
3205 | HandlePragmaPack(); | |||
3206 | return nullptr; | |||
3207 | case tok::annot_pragma_align: | |||
3208 | HandlePragmaAlign(); | |||
3209 | return nullptr; | |||
3210 | case tok::annot_pragma_ms_pointers_to_members: | |||
3211 | HandlePragmaMSPointersToMembers(); | |||
3212 | return nullptr; | |||
3213 | case tok::annot_pragma_ms_pragma: | |||
3214 | HandlePragmaMSPragma(); | |||
3215 | return nullptr; | |||
3216 | case tok::annot_pragma_ms_vtordisp: | |||
3217 | HandlePragmaMSVtorDisp(); | |||
3218 | return nullptr; | |||
3219 | case tok::annot_pragma_dump: | |||
3220 | HandlePragmaDump(); | |||
3221 | return nullptr; | |||
3222 | ||||
3223 | case tok::kw_namespace: | |||
3224 | // If we see a namespace here, a close brace was missing somewhere. | |||
3225 | DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl)); | |||
3226 | return nullptr; | |||
3227 | ||||
3228 | case tok::kw_private: | |||
3229 | // FIXME: We don't accept GNU attributes on access specifiers in OpenCL mode | |||
3230 | // yet. | |||
3231 | if (getLangOpts().OpenCL && !NextToken().is(tok::colon)) | |||
3232 | return ParseCXXClassMemberDeclaration(AS, AccessAttrs); | |||
3233 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | |||
3234 | case tok::kw_public: | |||
3235 | case tok::kw_protected: { | |||
3236 | AccessSpecifier NewAS = getAccessSpecifierIfPresent(); | |||
3237 | assert(NewAS != AS_none)((void)0); | |||
3238 | // Current token is a C++ access specifier. | |||
3239 | AS = NewAS; | |||
3240 | SourceLocation ASLoc = Tok.getLocation(); | |||
3241 | unsigned TokLength = Tok.getLength(); | |||
3242 | ConsumeToken(); | |||
3243 | AccessAttrs.clear(); | |||
3244 | MaybeParseGNUAttributes(AccessAttrs); | |||
3245 | ||||
3246 | SourceLocation EndLoc; | |||
3247 | if (TryConsumeToken(tok::colon, EndLoc)) { | |||
3248 | } else if (TryConsumeToken(tok::semi, EndLoc)) { | |||
3249 | Diag(EndLoc, diag::err_expected) | |||
3250 | << tok::colon << FixItHint::CreateReplacement(EndLoc, ":"); | |||
3251 | } else { | |||
3252 | EndLoc = ASLoc.getLocWithOffset(TokLength); | |||
3253 | Diag(EndLoc, diag::err_expected) | |||
3254 | << tok::colon << FixItHint::CreateInsertion(EndLoc, ":"); | |||
3255 | } | |||
3256 | ||||
3257 | // The Microsoft extension __interface does not permit non-public | |||
3258 | // access specifiers. | |||
3259 | if (TagType == DeclSpec::TST_interface && AS != AS_public) { | |||
3260 | Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected); | |||
3261 | } | |||
3262 | ||||
3263 | if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, AccessAttrs)) { | |||
3264 | // found another attribute than only annotations | |||
3265 | AccessAttrs.clear(); | |||
3266 | } | |||
3267 | ||||
3268 | return nullptr; | |||
3269 | } | |||
3270 | ||||
3271 | case tok::annot_attr_openmp: | |||
3272 | case tok::annot_pragma_openmp: | |||
3273 | return ParseOpenMPDeclarativeDirectiveWithExtDecl( | |||
3274 | AS, AccessAttrs, /*Delayed=*/true, TagType, TagDecl); | |||
3275 | ||||
3276 | default: | |||
3277 | if (tok::isPragmaAnnotation(Tok.getKind())) { | |||
3278 | Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl) | |||
3279 | << DeclSpec::getSpecifierName(TagType, | |||
3280 | Actions.getASTContext().getPrintingPolicy()); | |||
3281 | ConsumeAnnotationToken(); | |||
3282 | return nullptr; | |||
3283 | } | |||
3284 | return ParseCXXClassMemberDeclaration(AS, AccessAttrs); | |||
3285 | } | |||
3286 | } | |||
3287 | ||||
3288 | /// ParseCXXMemberSpecification - Parse the class definition. | |||
3289 | /// | |||
3290 | /// member-specification: | |||
3291 | /// member-declaration member-specification[opt] | |||
3292 | /// access-specifier ':' member-specification[opt] | |||
3293 | /// | |||
3294 | void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, | |||
3295 | SourceLocation AttrFixitLoc, | |||
3296 | ParsedAttributesWithRange &Attrs, | |||
3297 | unsigned TagType, Decl *TagDecl) { | |||
3298 | assert((TagType == DeclSpec::TST_struct ||((void)0) | |||
3299 | TagType == DeclSpec::TST_interface ||((void)0) | |||
3300 | TagType == DeclSpec::TST_union ||((void)0) | |||
3301 | TagType == DeclSpec::TST_class) && "Invalid TagType!")((void)0); | |||
3302 | ||||
3303 | llvm::TimeTraceScope TimeScope("ParseClass", [&]() { | |||
3304 | if (auto *TD = dyn_cast_or_null<NamedDecl>(TagDecl)) | |||
3305 | return TD->getQualifiedNameAsString(); | |||
3306 | return std::string("<anonymous>"); | |||
3307 | }); | |||
3308 | ||||
3309 | PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc, | |||
3310 | "parsing struct/union/class body"); | |||
3311 | ||||
3312 | // Determine whether this is a non-nested class. Note that local | |||
3313 | // classes are *not* considered to be nested classes. | |||
3314 | bool NonNestedClass = true; | |||
3315 | if (!ClassStack.empty()) { | |||
3316 | for (const Scope *S = getCurScope(); S; S = S->getParent()) { | |||
3317 | if (S->isClassScope()) { | |||
3318 | // We're inside a class scope, so this is a nested class. | |||
3319 | NonNestedClass = false; | |||
3320 | ||||
3321 | // The Microsoft extension __interface does not permit nested classes. | |||
3322 | if (getCurrentClass().IsInterface) { | |||
3323 | Diag(RecordLoc, diag::err_invalid_member_in_interface) | |||
3324 | << /*ErrorType=*/6 | |||
3325 | << (isa<NamedDecl>(TagDecl) | |||
3326 | ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString() | |||
3327 | : "(anonymous)"); | |||
3328 | } | |||
3329 | break; | |||
3330 | } | |||
3331 | ||||
3332 | if ((S->getFlags() & Scope::FnScope)) | |||
3333 | // If we're in a function or function template then this is a local | |||
3334 | // class rather than a nested class. | |||
3335 | break; | |||
3336 | } | |||
3337 | } | |||
3338 | ||||
3339 | // Enter a scope for the class. | |||
3340 | ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); | |||
3341 | ||||
3342 | // Note that we are parsing a new (potentially-nested) class definition. | |||
3343 | ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass, | |||
3344 | TagType == DeclSpec::TST_interface); | |||
3345 | ||||
3346 | if (TagDecl) | |||
3347 | Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); | |||
3348 | ||||
3349 | SourceLocation FinalLoc; | |||
3350 | SourceLocation AbstractLoc; | |||
3351 | bool IsFinalSpelledSealed = false; | |||
3352 | bool IsAbstract = false; | |||
3353 | ||||
3354 | // Parse the optional 'final' keyword. | |||
3355 | if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) { | |||
3356 | while (true) { | |||
3357 | VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok); | |||
3358 | if (Specifier == VirtSpecifiers::VS_None) | |||
3359 | break; | |||
3360 | if (isCXX11FinalKeyword()) { | |||
3361 | if (FinalLoc.isValid()) { | |||
3362 | auto Skipped = ConsumeToken(); | |||
3363 | Diag(Skipped, diag::err_duplicate_class_virt_specifier) | |||
3364 | << VirtSpecifiers::getSpecifierName(Specifier); | |||
3365 | } else { | |||
3366 | FinalLoc = ConsumeToken(); | |||
3367 | if (Specifier == VirtSpecifiers::VS_Sealed) | |||
3368 | IsFinalSpelledSealed = true; | |||
3369 | } | |||
3370 | } else { | |||
3371 | if (AbstractLoc.isValid()) { | |||
3372 | auto Skipped = ConsumeToken(); | |||
3373 | Diag(Skipped, diag::err_duplicate_class_virt_specifier) | |||
3374 | << VirtSpecifiers::getSpecifierName(Specifier); | |||
3375 | } else { | |||
3376 | AbstractLoc = ConsumeToken(); | |||
3377 | IsAbstract = true; | |||
3378 | } | |||
3379 | } | |||
3380 | if (TagType == DeclSpec::TST_interface) | |||
3381 | Diag(FinalLoc, diag::err_override_control_interface) | |||
3382 | << VirtSpecifiers::getSpecifierName(Specifier); | |||
3383 | else if (Specifier == VirtSpecifiers::VS_Final) | |||
3384 | Diag(FinalLoc, getLangOpts().CPlusPlus11 | |||
3385 | ? diag::warn_cxx98_compat_override_control_keyword | |||
3386 | : diag::ext_override_control_keyword) | |||
3387 | << VirtSpecifiers::getSpecifierName(Specifier); | |||
3388 | else if (Specifier == VirtSpecifiers::VS_Sealed) | |||
3389 | Diag(FinalLoc, diag::ext_ms_sealed_keyword); | |||
3390 | else if (Specifier == VirtSpecifiers::VS_Abstract) | |||
3391 | Diag(AbstractLoc, diag::ext_ms_abstract_keyword); | |||
3392 | else if (Specifier == VirtSpecifiers::VS_GNU_Final) | |||
3393 | Diag(FinalLoc, diag::ext_warn_gnu_final); | |||
3394 | } | |||
3395 | assert((FinalLoc.isValid() || AbstractLoc.isValid()) &&((void)0) | |||
3396 | "not a class definition")((void)0); | |||
3397 | ||||
3398 | // Parse any C++11 attributes after 'final' keyword. | |||
3399 | // These attributes are not allowed to appear here, | |||
3400 | // and the only possible place for them to appertain | |||
3401 | // to the class would be between class-key and class-name. | |||
3402 | CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc); | |||
3403 | ||||
3404 | // ParseClassSpecifier() does only a superficial check for attributes before | |||
3405 | // deciding to call this method. For example, for | |||
3406 | // `class C final alignas ([l) {` it will decide that this looks like a | |||
3407 | // misplaced attribute since it sees `alignas '(' ')'`. But the actual | |||
3408 | // attribute parsing code will try to parse the '[' as a constexpr lambda | |||
3409 | // and consume enough tokens that the alignas parsing code will eat the | |||
3410 | // opening '{'. So bail out if the next token isn't one we expect. | |||
3411 | if (!Tok.is(tok::colon) && !Tok.is(tok::l_brace)) { | |||
3412 | if (TagDecl) | |||
3413 | Actions.ActOnTagDefinitionError(getCurScope(), TagDecl); | |||
3414 | return; | |||
3415 | } | |||
3416 | } | |||
3417 | ||||
3418 | if (Tok.is(tok::colon)) { | |||
3419 | ParseScope InheritanceScope(this, getCurScope()->getFlags() | | |||
3420 | Scope::ClassInheritanceScope); | |||
3421 | ||||
3422 | ParseBaseClause(TagDecl); | |||
3423 | if (!Tok.is(tok::l_brace)) { | |||
3424 | bool SuggestFixIt = false; | |||
3425 | SourceLocation BraceLoc = PP.getLocForEndOfToken(PrevTokLocation); | |||
3426 | if (Tok.isAtStartOfLine()) { | |||
3427 | switch (Tok.getKind()) { | |||
3428 | case tok::kw_private: | |||
3429 | case tok::kw_protected: | |||
3430 | case tok::kw_public: | |||
3431 | SuggestFixIt = NextToken().getKind() == tok::colon; | |||
3432 | break; | |||
3433 | case tok::kw_static_assert: | |||
3434 | case tok::r_brace: | |||
3435 | case tok::kw_using: | |||
3436 | // base-clause can have simple-template-id; 'template' can't be there | |||
3437 | case tok::kw_template: | |||
3438 | SuggestFixIt = true; | |||
3439 | break; | |||
3440 | case tok::identifier: | |||
3441 | SuggestFixIt = isConstructorDeclarator(true); | |||
3442 | break; | |||
3443 | default: | |||
3444 | SuggestFixIt = isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false); | |||
3445 | break; | |||
3446 | } | |||
3447 | } | |||
3448 | DiagnosticBuilder LBraceDiag = | |||
3449 | Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers); | |||
3450 | if (SuggestFixIt) { | |||
3451 | LBraceDiag << FixItHint::CreateInsertion(BraceLoc, " {"); | |||
3452 | // Try recovering from missing { after base-clause. | |||
3453 | PP.EnterToken(Tok, /*IsReinject*/true); | |||
3454 | Tok.setKind(tok::l_brace); | |||
3455 | } else { | |||
3456 | if (TagDecl) | |||
3457 | Actions.ActOnTagDefinitionError(getCurScope(), TagDecl); | |||
3458 | return; | |||
3459 | } | |||
3460 | } | |||
3461 | } | |||
3462 | ||||
3463 | assert(Tok.is(tok::l_brace))((void)0); | |||
3464 | BalancedDelimiterTracker T(*this, tok::l_brace); | |||
3465 | T.consumeOpen(); | |||
3466 | ||||
3467 | if (TagDecl) | |||
3468 | Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc, | |||
3469 | IsFinalSpelledSealed, IsAbstract, | |||
3470 | T.getOpenLocation()); | |||
3471 | ||||
3472 | // C++ 11p3: Members of a class defined with the keyword class are private | |||
3473 | // by default. Members of a class defined with the keywords struct or union | |||
3474 | // are public by default. | |||
3475 | AccessSpecifier CurAS; | |||
3476 | if (TagType == DeclSpec::TST_class) | |||
3477 | CurAS = AS_private; | |||
3478 | else | |||
3479 | CurAS = AS_public; | |||
3480 | ParsedAttributesWithRange AccessAttrs(AttrFactory); | |||
3481 | ||||
3482 | if (TagDecl) { | |||
3483 | // While we still have something to read, read the member-declarations. | |||
3484 | while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && | |||
3485 | Tok.isNot(tok::eof)) { | |||
3486 | // Each iteration of this loop reads one member-declaration. | |||
3487 | ParseCXXClassMemberDeclarationWithPragmas( | |||
3488 | CurAS, AccessAttrs, static_cast<DeclSpec::TST>(TagType), TagDecl); | |||
3489 | MaybeDestroyTemplateIds(); | |||
3490 | } | |||
3491 | T.consumeClose(); | |||
3492 | } else { | |||
3493 | SkipUntil(tok::r_brace); | |||
3494 | } | |||
3495 | ||||
3496 | // If attributes exist after class contents, parse them. | |||
3497 | ParsedAttributes attrs(AttrFactory); | |||
3498 | MaybeParseGNUAttributes(attrs); | |||
3499 | ||||
3500 | if (TagDecl) | |||
3501 | Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl, | |||
3502 | T.getOpenLocation(), | |||
3503 | T.getCloseLocation(), attrs); | |||
3504 | ||||
3505 | // C++11 [class.mem]p2: | |||
3506 | // Within the class member-specification, the class is regarded as complete | |||
3507 | // within function bodies, default arguments, exception-specifications, and | |||
3508 | // brace-or-equal-initializers for non-static data members (including such | |||
3509 | // things in nested classes). | |||
3510 | if (TagDecl && NonNestedClass) { | |||
3511 | // We are not inside a nested class. This class and its nested classes | |||
3512 | // are complete and we can parse the delayed portions of method | |||
3513 | // declarations and the lexed inline method definitions, along with any | |||
3514 | // delayed attributes. | |||
3515 | ||||
3516 | SourceLocation SavedPrevTokLocation = PrevTokLocation; | |||
3517 | ParseLexedPragmas(getCurrentClass()); | |||
3518 | ParseLexedAttributes(getCurrentClass()); | |||
3519 | ParseLexedMethodDeclarations(getCurrentClass()); | |||
3520 | ||||
3521 | // We've finished with all pending member declarations. | |||
3522 | Actions.ActOnFinishCXXMemberDecls(); | |||
3523 | ||||
3524 | ParseLexedMemberInitializers(getCurrentClass()); | |||
3525 | ParseLexedMethodDefs(getCurrentClass()); | |||
3526 | PrevTokLocation = SavedPrevTokLocation; | |||
3527 | ||||
3528 | // We've finished parsing everything, including default argument | |||
3529 | // initializers. | |||
3530 | Actions.ActOnFinishCXXNonNestedClass(); | |||
3531 | } | |||
3532 | ||||
3533 | if (TagDecl) | |||
3534 | Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange()); | |||
3535 | ||||
3536 | // Leave the class scope. | |||
3537 | ParsingDef.Pop(); | |||
3538 | ClassScope.Exit(); | |||
3539 | } | |||
3540 | ||||
3541 | void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) { | |||
3542 | assert(Tok.is(tok::kw_namespace))((void)0); | |||
3543 | ||||
3544 | // FIXME: Suggest where the close brace should have gone by looking | |||
3545 | // at indentation changes within the definition body. | |||
3546 | Diag(D->getLocation(), | |||
3547 | diag::err_missing_end_of_definition) << D; | |||
3548 | Diag(Tok.getLocation(), | |||
3549 | diag::note_missing_end_of_definition_before) << D; | |||
3550 | ||||
3551 | // Push '};' onto the token stream to recover. | |||
3552 | PP.EnterToken(Tok, /*IsReinject*/ true); | |||
3553 | ||||
3554 | Tok.startToken(); | |||
3555 | Tok.setLocation(PP.getLocForEndOfToken(PrevTokLocation)); | |||
3556 | Tok.setKind(tok::semi); | |||
3557 | PP.EnterToken(Tok, /*IsReinject*/ true); | |||
3558 | ||||
3559 | Tok.setKind(tok::r_brace); | |||
3560 | } | |||
3561 | ||||
3562 | /// ParseConstructorInitializer - Parse a C++ constructor initializer, | |||
3563 | /// which explicitly initializes the members or base classes of a | |||
3564 | /// class (C++ [class.base.init]). For example, the three initializers | |||
3565 | /// after the ':' in the Derived constructor below: | |||
3566 | /// | |||
3567 | /// @code | |||
3568 | /// class Base { }; | |||
3569 | /// class Derived : Base { | |||
3570 | /// int x; | |||
3571 | /// float f; | |||
3572 | /// public: | |||
3573 | /// Derived(float f) : Base(), x(17), f(f) { } | |||
3574 | /// }; | |||
3575 | /// @endcode | |||
3576 | /// | |||
3577 | /// [C++] ctor-initializer: | |||
3578 | /// ':' mem-initializer-list | |||
3579 | /// | |||
3580 | /// [C++] mem-initializer-list: | |||
3581 | /// mem-initializer ...[opt] | |||
3582 | /// mem-initializer ...[opt] , mem-initializer-list | |||
3583 | void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) { | |||
3584 | assert(Tok.is(tok::colon) &&((void)0) | |||
3585 | "Constructor initializer always starts with ':'")((void)0); | |||
3586 | ||||
3587 | // Poison the SEH identifiers so they are flagged as illegal in constructor | |||
3588 | // initializers. | |||
3589 | PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); | |||
3590 | SourceLocation ColonLoc = ConsumeToken(); | |||
3591 | ||||
3592 | SmallVector<CXXCtorInitializer*, 4> MemInitializers; | |||
3593 | bool AnyErrors = false; | |||
3594 | ||||
3595 | do { | |||
3596 | if (Tok.is(tok::code_completion)) { | |||
3597 | cutOffParsing(); | |||
3598 | Actions.CodeCompleteConstructorInitializer(ConstructorDecl, | |||
3599 | MemInitializers); | |||
3600 | return; | |||
3601 | } | |||
3602 | ||||
3603 | MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); | |||
3604 | if (!MemInit.isInvalid()) | |||
3605 | MemInitializers.push_back(MemInit.get()); | |||
3606 | else | |||
3607 | AnyErrors = true; | |||
3608 | ||||
3609 | if (Tok.is(tok::comma)) | |||
3610 | ConsumeToken(); | |||
3611 | else if (Tok.is(tok::l_brace)) | |||
3612 | break; | |||
3613 | // If the previous initializer was valid and the next token looks like a | |||
3614 | // base or member initializer, assume that we're just missing a comma. | |||
3615 | else if (!MemInit.isInvalid() && | |||
3616 | Tok.isOneOf(tok::identifier, tok::coloncolon)) { | |||
3617 | SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); | |||
3618 | Diag(Loc, diag::err_ctor_init_missing_comma) | |||
3619 | << FixItHint::CreateInsertion(Loc, ", "); | |||
3620 | } else { | |||
3621 | // Skip over garbage, until we get to '{'. Don't eat the '{'. | |||
3622 | if (!MemInit.isInvalid()) | |||
3623 | Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace | |||
3624 | << tok::comma; | |||
3625 | SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch); | |||
3626 | break; | |||
3627 | } | |||
3628 | } while (true); | |||
3629 | ||||
3630 | Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers, | |||
3631 | AnyErrors); | |||
3632 | } | |||
3633 | ||||
3634 | /// ParseMemInitializer - Parse a C++ member initializer, which is | |||
3635 | /// part of a constructor initializer that explicitly initializes one | |||
3636 | /// member or base class (C++ [class.base.init]). See | |||
3637 | /// ParseConstructorInitializer for an example. | |||
3638 | /// | |||
3639 | /// [C++] mem-initializer: | |||
3640 | /// mem-initializer-id '(' expression-list[opt] ')' | |||
3641 | /// [C++0x] mem-initializer-id braced-init-list | |||
3642 | /// | |||
3643 | /// [C++] mem-initializer-id: | |||
3644 | /// '::'[opt] nested-name-specifier[opt] class-name | |||
3645 | /// identifier | |||
3646 | MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { | |||
3647 | // parse '::'[opt] nested-name-specifier[opt] | |||
3648 | CXXScopeSpec SS; | |||
3649 | if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, | |||
3650 | /*ObjectHadErrors=*/false, | |||
3651 | /*EnteringContext=*/false)) | |||
3652 | return true; | |||
3653 | ||||
3654 | // : identifier | |||
3655 | IdentifierInfo *II = nullptr; | |||
3656 | SourceLocation IdLoc = Tok.getLocation(); | |||
3657 | // : declype(...) | |||
3658 | DeclSpec DS(AttrFactory); | |||
3659 | // : template_name<...> | |||
3660 | TypeResult TemplateTypeTy; | |||
3661 | ||||
3662 | if (Tok.is(tok::identifier)) { | |||
3663 | // Get the identifier. This may be a member name or a class name, | |||
3664 | // but we'll let the semantic analysis determine which it is. | |||
3665 | II = Tok.getIdentifierInfo(); | |||
3666 | ConsumeToken(); | |||
3667 | } else if (Tok.is(tok::annot_decltype)) { | |||
3668 | // Get the decltype expression, if there is one. | |||
3669 | // Uses of decltype will already have been converted to annot_decltype by | |||
3670 | // ParseOptionalCXXScopeSpecifier at this point. | |||
3671 | // FIXME: Can we get here with a scope specifier? | |||
3672 | ParseDecltypeSpecifier(DS); | |||
3673 | } else { | |||
3674 | TemplateIdAnnotation *TemplateId = Tok.is(tok::annot_template_id) | |||
3675 | ? takeTemplateIdAnnotation(Tok) | |||
3676 | : nullptr; | |||
3677 | if (TemplateId && TemplateId->mightBeType()) { | |||
3678 | AnnotateTemplateIdTokenAsType(SS, /*IsClassName*/true); | |||
3679 | assert(Tok.is(tok::annot_typename) && "template-id -> type failed")((void)0); | |||
3680 | TemplateTypeTy = getTypeAnnotation(Tok); | |||
3681 | ConsumeAnnotationToken(); | |||
3682 | } else { | |||
3683 | Diag(Tok, diag::err_expected_member_or_base_name); | |||
3684 | return true; | |||
3685 | } | |||
3686 | } | |||
3687 | ||||
3688 | // Parse the '('. | |||
3689 | if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { | |||
3690 | Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); | |||
3691 | ||||
3692 | // FIXME: Add support for signature help inside initializer lists. | |||
3693 | ExprResult InitList = ParseBraceInitializer(); | |||
3694 | if (InitList.isInvalid()) | |||
3695 | return true; | |||
3696 | ||||
3697 | SourceLocation EllipsisLoc; | |||
3698 | TryConsumeToken(tok::ellipsis, EllipsisLoc); | |||
3699 | ||||
3700 | if (TemplateTypeTy.isInvalid()) | |||
3701 | return true; | |||
3702 | return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, | |||
3703 | TemplateTypeTy.get(), DS, IdLoc, | |||
3704 | InitList.get(), EllipsisLoc); | |||
3705 | } else if(Tok.is(tok::l_paren)) { | |||
3706 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
3707 | T.consumeOpen(); | |||
3708 | ||||
3709 | // Parse the optional expression-list. | |||
3710 | ExprVector ArgExprs; | |||
3711 | CommaLocsTy CommaLocs; | |||
3712 | auto RunSignatureHelp = [&] { | |||
3713 | if (TemplateTypeTy.isInvalid()) | |||
3714 | return QualType(); | |||
3715 | QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp( | |||
3716 | getCurScope(), ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II, | |||
3717 | T.getOpenLocation()); | |||
3718 | CalledSignatureHelp = true; | |||
3719 | return PreferredType; | |||
3720 | }; | |||
3721 | if (Tok.isNot(tok::r_paren) && | |||
3722 | ParseExpressionList(ArgExprs, CommaLocs, [&] { | |||
3723 | PreferredType.enterFunctionArgument(Tok.getLocation(), | |||
3724 | RunSignatureHelp); | |||
3725 | })) { | |||
3726 | if (PP.isCodeCompletionReached() && !CalledSignatureHelp) | |||
3727 | RunSignatureHelp(); | |||
3728 | SkipUntil(tok::r_paren, StopAtSemi); | |||
3729 | return true; | |||
3730 | } | |||
3731 | ||||
3732 | T.consumeClose(); | |||
3733 | ||||
3734 | SourceLocation EllipsisLoc; | |||
3735 | TryConsumeToken(tok::ellipsis, EllipsisLoc); | |||
3736 | ||||
3737 | if (TemplateTypeTy.isInvalid()) | |||
3738 | return true; | |||
3739 | return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, | |||
3740 | TemplateTypeTy.get(), DS, IdLoc, | |||
3741 | T.getOpenLocation(), ArgExprs, | |||
3742 | T.getCloseLocation(), EllipsisLoc); | |||
3743 | } | |||
3744 | ||||
3745 | if (TemplateTypeTy.isInvalid()) | |||
3746 | return true; | |||
3747 | ||||
3748 | if (getLangOpts().CPlusPlus11) | |||
3749 | return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace; | |||
3750 | else | |||
3751 | return Diag(Tok, diag::err_expected) << tok::l_paren; | |||
3752 | } | |||
3753 | ||||
3754 | /// Parse a C++ exception-specification if present (C++0x [except.spec]). | |||
3755 | /// | |||
3756 | /// exception-specification: | |||
3757 | /// dynamic-exception-specification | |||
3758 | /// noexcept-specification | |||
3759 | /// | |||
3760 | /// noexcept-specification: | |||
3761 | /// 'noexcept' | |||
3762 | /// 'noexcept' '(' constant-expression ')' | |||
3763 | ExceptionSpecificationType | |||
3764 | Parser::tryParseExceptionSpecification(bool Delayed, | |||
3765 | SourceRange &SpecificationRange, | |||
3766 | SmallVectorImpl<ParsedType> &DynamicExceptions, | |||
3767 | SmallVectorImpl<SourceRange> &DynamicExceptionRanges, | |||
3768 | ExprResult &NoexceptExpr, | |||
3769 | CachedTokens *&ExceptionSpecTokens) { | |||
3770 | ExceptionSpecificationType Result = EST_None; | |||
3771 | ExceptionSpecTokens = nullptr; | |||
3772 | ||||
3773 | // Handle delayed parsing of exception-specifications. | |||
3774 | if (Delayed) { | |||
3775 | if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept)) | |||
3776 | return EST_None; | |||
3777 | ||||
3778 | // Consume and cache the starting token. | |||
3779 | bool IsNoexcept = Tok.is(tok::kw_noexcept); | |||
3780 | Token StartTok = Tok; | |||
3781 | SpecificationRange = SourceRange(ConsumeToken()); | |||
3782 | ||||
3783 | // Check for a '('. | |||
3784 | if (!Tok.is(tok::l_paren)) { | |||
3785 | // If this is a bare 'noexcept', we're done. | |||
3786 | if (IsNoexcept) { | |||
3787 | Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); | |||
3788 | NoexceptExpr = nullptr; | |||
3789 | return EST_BasicNoexcept; | |||
3790 | } | |||
3791 | ||||
3792 | Diag(Tok, diag::err_expected_lparen_after) << "throw"; | |||
3793 | return EST_DynamicNone; | |||
3794 | } | |||
3795 | ||||
3796 | // Cache the tokens for the exception-specification. | |||
3797 | ExceptionSpecTokens = new CachedTokens; | |||
3798 | ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept' | |||
3799 | ExceptionSpecTokens->push_back(Tok); // '(' | |||
3800 | SpecificationRange.setEnd(ConsumeParen()); // '(' | |||
3801 | ||||
3802 | ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens, | |||
3803 | /*StopAtSemi=*/true, | |||
3804 | /*ConsumeFinalToken=*/true); | |||
3805 | SpecificationRange.setEnd(ExceptionSpecTokens->back().getLocation()); | |||
3806 | ||||
3807 | return EST_Unparsed; | |||
3808 | } | |||
3809 | ||||
3810 | // See if there's a dynamic specification. | |||
3811 | if (Tok.is(tok::kw_throw)) { | |||
3812 | Result = ParseDynamicExceptionSpecification(SpecificationRange, | |||
3813 | DynamicExceptions, | |||
3814 | DynamicExceptionRanges); | |||
3815 | assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&((void)0) | |||
3816 | "Produced different number of exception types and ranges.")((void)0); | |||
3817 | } | |||
3818 | ||||
3819 | // If there's no noexcept specification, we're done. | |||
3820 | if (Tok.isNot(tok::kw_noexcept)) | |||
3821 | return Result; | |||
3822 | ||||
3823 | Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); | |||
3824 | ||||
3825 | // If we already had a dynamic specification, parse the noexcept for, | |||
3826 | // recovery, but emit a diagnostic and don't store the results. | |||
3827 | SourceRange NoexceptRange; | |||
3828 | ExceptionSpecificationType NoexceptType = EST_None; | |||
3829 | ||||
3830 | SourceLocation KeywordLoc = ConsumeToken(); | |||
3831 | if (Tok.is(tok::l_paren)) { | |||
3832 | // There is an argument. | |||
3833 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
3834 | T.consumeOpen(); | |||
3835 | NoexceptExpr = ParseConstantExpression(); | |||
3836 | T.consumeClose(); | |||
3837 | if (!NoexceptExpr.isInvalid()) { | |||
3838 | NoexceptExpr = Actions.ActOnNoexceptSpec(KeywordLoc, NoexceptExpr.get(), | |||
3839 | NoexceptType); | |||
3840 | NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation()); | |||
3841 | } else { | |||
3842 | NoexceptType = EST_BasicNoexcept; | |||
3843 | } | |||
3844 | } else { | |||
3845 | // There is no argument. | |||
3846 | NoexceptType = EST_BasicNoexcept; | |||
3847 | NoexceptRange = SourceRange(KeywordLoc, KeywordLoc); | |||
3848 | } | |||
3849 | ||||
3850 | if (Result == EST_None) { | |||
3851 | SpecificationRange = NoexceptRange; | |||
3852 | Result = NoexceptType; | |||
3853 | ||||
3854 | // If there's a dynamic specification after a noexcept specification, | |||
3855 | // parse that and ignore the results. | |||
3856 | if (Tok.is(tok::kw_throw)) { | |||
3857 | Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); | |||
3858 | ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions, | |||
3859 | DynamicExceptionRanges); | |||
3860 | } | |||
3861 | } else { | |||
3862 | Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); | |||
3863 | } | |||
3864 | ||||
3865 | return Result; | |||
3866 | } | |||
3867 | ||||
3868 | static void diagnoseDynamicExceptionSpecification( | |||
3869 | Parser &P, SourceRange Range, bool IsNoexcept) { | |||
3870 | if (P.getLangOpts().CPlusPlus11) { | |||
3871 | const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)"; | |||
3872 | P.Diag(Range.getBegin(), | |||
3873 | P.getLangOpts().CPlusPlus17 && !IsNoexcept | |||
3874 | ? diag::ext_dynamic_exception_spec | |||
3875 | : diag::warn_exception_spec_deprecated) | |||
3876 | << Range; | |||
3877 | P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated) | |||
3878 | << Replacement << FixItHint::CreateReplacement(Range, Replacement); | |||
3879 | } | |||
3880 | } | |||
3881 | ||||
3882 | /// ParseDynamicExceptionSpecification - Parse a C++ | |||
3883 | /// dynamic-exception-specification (C++ [except.spec]). | |||
3884 | /// | |||
3885 | /// dynamic-exception-specification: | |||
3886 | /// 'throw' '(' type-id-list [opt] ')' | |||
3887 | /// [MS] 'throw' '(' '...' ')' | |||
3888 | /// | |||
3889 | /// type-id-list: | |||
3890 | /// type-id ... [opt] | |||
3891 | /// type-id-list ',' type-id ... [opt] | |||
3892 | /// | |||
3893 | ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification( | |||
3894 | SourceRange &SpecificationRange, | |||
3895 | SmallVectorImpl<ParsedType> &Exceptions, | |||
3896 | SmallVectorImpl<SourceRange> &Ranges) { | |||
3897 | assert(Tok.is(tok::kw_throw) && "expected throw")((void)0); | |||
3898 | ||||
3899 | SpecificationRange.setBegin(ConsumeToken()); | |||
3900 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
3901 | if (T.consumeOpen()) { | |||
3902 | Diag(Tok, diag::err_expected_lparen_after) << "throw"; | |||
3903 | SpecificationRange.setEnd(SpecificationRange.getBegin()); | |||
3904 | return EST_DynamicNone; | |||
3905 | } | |||
3906 | ||||
3907 | // Parse throw(...), a Microsoft extension that means "this function | |||
3908 | // can throw anything". | |||
3909 | if (Tok.is(tok::ellipsis)) { | |||
3910 | SourceLocation EllipsisLoc = ConsumeToken(); | |||
3911 | if (!getLangOpts().MicrosoftExt) | |||
3912 | Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); | |||
3913 | T.consumeClose(); | |||
3914 | SpecificationRange.setEnd(T.getCloseLocation()); | |||
3915 | diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false); | |||
3916 | return EST_MSAny; | |||
3917 | } | |||
3918 | ||||
3919 | // Parse the sequence of type-ids. | |||
3920 | SourceRange Range; | |||
3921 | while (Tok.isNot(tok::r_paren)) { | |||
3922 | TypeResult Res(ParseTypeName(&Range)); | |||
3923 | ||||
3924 | if (Tok.is(tok::ellipsis)) { | |||
3925 | // C++0x [temp.variadic]p5: | |||
3926 | // - In a dynamic-exception-specification (15.4); the pattern is a | |||
3927 | // type-id. | |||
3928 | SourceLocation Ellipsis = ConsumeToken(); | |||
3929 | Range.setEnd(Ellipsis); | |||
3930 | if (!Res.isInvalid()) | |||
3931 | Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis); | |||
3932 | } | |||
3933 | ||||
3934 | if (!Res.isInvalid()) { | |||
3935 | Exceptions.push_back(Res.get()); | |||
3936 | Ranges.push_back(Range); | |||
3937 | } | |||
3938 | ||||
3939 | if (!TryConsumeToken(tok::comma)) | |||
3940 | break; | |||
3941 | } | |||
3942 | ||||
3943 | T.consumeClose(); | |||
3944 | SpecificationRange.setEnd(T.getCloseLocation()); | |||
3945 | diagnoseDynamicExceptionSpecification(*this, SpecificationRange, | |||
3946 | Exceptions.empty()); | |||
3947 | return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic; | |||
3948 | } | |||
3949 | ||||
3950 | /// ParseTrailingReturnType - Parse a trailing return type on a new-style | |||
3951 | /// function declaration. | |||
3952 | TypeResult Parser::ParseTrailingReturnType(SourceRange &Range, | |||
3953 | bool MayBeFollowedByDirectInit) { | |||
3954 | assert(Tok.is(tok::arrow) && "expected arrow")((void)0); | |||
3955 | ||||
3956 | ConsumeToken(); | |||
3957 | ||||
3958 | return ParseTypeName(&Range, MayBeFollowedByDirectInit | |||
3959 | ? DeclaratorContext::TrailingReturnVar | |||
3960 | : DeclaratorContext::TrailingReturn); | |||
3961 | } | |||
3962 | ||||
3963 | /// Parse a requires-clause as part of a function declaration. | |||
3964 | void Parser::ParseTrailingRequiresClause(Declarator &D) { | |||
3965 | assert(Tok.is(tok::kw_requires) && "expected requires")((void)0); | |||
3966 | ||||
3967 | SourceLocation RequiresKWLoc = ConsumeToken(); | |||
3968 | ||||
3969 | ExprResult TrailingRequiresClause; | |||
3970 | ParseScope ParamScope(this, | |||
3971 | Scope::DeclScope | | |||
3972 | Scope::FunctionDeclarationScope | | |||
3973 | Scope::FunctionPrototypeScope); | |||
3974 | ||||
3975 | Actions.ActOnStartTrailingRequiresClause(getCurScope(), D); | |||
3976 | ||||
3977 | llvm::Optional<Sema::CXXThisScopeRAII> ThisScope; | |||
3978 | InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope); | |||
3979 | ||||
3980 | TrailingRequiresClause = | |||
3981 | ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true); | |||
3982 | ||||
3983 | TrailingRequiresClause = | |||
3984 | Actions.ActOnFinishTrailingRequiresClause(TrailingRequiresClause); | |||
3985 | ||||
3986 | if (!D.isDeclarationOfFunction()) { | |||
3987 | Diag(RequiresKWLoc, | |||
3988 | diag::err_requires_clause_on_declarator_not_declaring_a_function); | |||
3989 | return; | |||
3990 | } | |||
3991 | ||||
3992 | if (TrailingRequiresClause.isInvalid()) | |||
3993 | SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon}, | |||
3994 | StopAtSemi | StopBeforeMatch); | |||
3995 | else | |||
3996 | D.setTrailingRequiresClause(TrailingRequiresClause.get()); | |||
3997 | ||||
3998 | // Did the user swap the trailing return type and requires clause? | |||
3999 | if (D.isFunctionDeclarator() && Tok.is(tok::arrow) && | |||
4000 | D.getDeclSpec().getTypeSpecType() == TST_auto) { | |||
4001 | SourceLocation ArrowLoc = Tok.getLocation(); | |||
4002 | SourceRange Range; | |||
4003 | TypeResult TrailingReturnType = | |||
4004 | ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit=*/false); | |||
4005 | ||||
4006 | if (!TrailingReturnType.isInvalid()) { | |||
4007 | Diag(ArrowLoc, | |||
4008 | diag::err_requires_clause_must_appear_after_trailing_return) | |||
4009 | << Range; | |||
4010 | auto &FunctionChunk = D.getFunctionTypeInfo(); | |||
4011 | FunctionChunk.HasTrailingReturnType = TrailingReturnType.isUsable(); | |||
4012 | FunctionChunk.TrailingReturnType = TrailingReturnType.get(); | |||
4013 | FunctionChunk.TrailingReturnTypeLoc = Range.getBegin(); | |||
4014 | } else | |||
4015 | SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma}, | |||
4016 | StopAtSemi | StopBeforeMatch); | |||
4017 | } | |||
4018 | } | |||
4019 | ||||
4020 | /// We have just started parsing the definition of a new class, | |||
4021 | /// so push that class onto our stack of classes that is currently | |||
4022 | /// being parsed. | |||
4023 | Sema::ParsingClassState | |||
4024 | Parser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass, | |||
4025 | bool IsInterface) { | |||
4026 | assert((NonNestedClass || !ClassStack.empty()) &&((void)0) | |||
4027 | "Nested class without outer class")((void)0); | |||
4028 | ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface)); | |||
4029 | return Actions.PushParsingClass(); | |||
4030 | } | |||
4031 | ||||
4032 | /// Deallocate the given parsed class and all of its nested | |||
4033 | /// classes. | |||
4034 | void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) { | |||
4035 | for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I) | |||
4036 | delete Class->LateParsedDeclarations[I]; | |||
4037 | delete Class; | |||
4038 | } | |||
4039 | ||||
4040 | /// Pop the top class of the stack of classes that are | |||
4041 | /// currently being parsed. | |||
4042 | /// | |||
4043 | /// This routine should be called when we have finished parsing the | |||
4044 | /// definition of a class, but have not yet popped the Scope | |||
4045 | /// associated with the class's definition. | |||
4046 | void Parser::PopParsingClass(Sema::ParsingClassState state) { | |||
4047 | assert(!ClassStack.empty() && "Mismatched push/pop for class parsing")((void)0); | |||
4048 | ||||
4049 | Actions.PopParsingClass(state); | |||
4050 | ||||
4051 | ParsingClass *Victim = ClassStack.top(); | |||
4052 | ClassStack.pop(); | |||
4053 | if (Victim->TopLevelClass) { | |||
4054 | // Deallocate all of the nested classes of this class, | |||
4055 | // recursively: we don't need to keep any of this information. | |||
4056 | DeallocateParsedClasses(Victim); | |||
4057 | return; | |||
4058 | } | |||
4059 | assert(!ClassStack.empty() && "Missing top-level class?")((void)0); | |||
4060 | ||||
4061 | if (Victim->LateParsedDeclarations.empty()) { | |||
4062 | // The victim is a nested class, but we will not need to perform | |||
4063 | // any processing after the definition of this class since it has | |||
4064 | // no members whose handling was delayed. Therefore, we can just | |||
4065 | // remove this nested class. | |||
4066 | DeallocateParsedClasses(Victim); | |||
4067 | return; | |||
4068 | } | |||
4069 | ||||
4070 | // This nested class has some members that will need to be processed | |||
4071 | // after the top-level class is completely defined. Therefore, add | |||
4072 | // it to the list of nested classes within its parent. | |||
4073 | assert(getCurScope()->isClassScope() && "Nested class outside of class scope?")((void)0); | |||
4074 | ClassStack.top()->LateParsedDeclarations.push_back( | |||
4075 | new LateParsedClass(this, Victim)); | |||
4076 | } | |||
4077 | ||||
4078 | /// Try to parse an 'identifier' which appears within an attribute-token. | |||
4079 | /// | |||
4080 | /// \return the parsed identifier on success, and 0 if the next token is not an | |||
4081 | /// attribute-token. | |||
4082 | /// | |||
4083 | /// C++11 [dcl.attr.grammar]p3: | |||
4084 | /// If a keyword or an alternative token that satisfies the syntactic | |||
4085 | /// requirements of an identifier is contained in an attribute-token, | |||
4086 | /// it is considered an identifier. | |||
4087 | IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) { | |||
4088 | switch (Tok.getKind()) { | |||
4089 | default: | |||
4090 | // Identifiers and keywords have identifier info attached. | |||
4091 | if (!Tok.isAnnotation()) { | |||
4092 | if (IdentifierInfo *II = Tok.getIdentifierInfo()) { | |||
4093 | Loc = ConsumeToken(); | |||
4094 | return II; | |||
4095 | } | |||
4096 | } | |||
4097 | return nullptr; | |||
4098 | ||||
4099 | case tok::numeric_constant: { | |||
4100 | // If we got a numeric constant, check to see if it comes from a macro that | |||
4101 | // corresponds to the predefined __clang__ macro. If it does, warn the user | |||
4102 | // and recover by pretending they said _Clang instead. | |||
4103 | if (Tok.getLocation().isMacroID()) { | |||
4104 | SmallString<8> ExpansionBuf; | |||
4105 | SourceLocation ExpansionLoc = | |||
4106 | PP.getSourceManager().getExpansionLoc(Tok.getLocation()); | |||
4107 | StringRef Spelling = PP.getSpelling(ExpansionLoc, ExpansionBuf); | |||
4108 | if (Spelling == "__clang__") { | |||
4109 | SourceRange TokRange( | |||
4110 | ExpansionLoc, | |||
4111 | PP.getSourceManager().getExpansionLoc(Tok.getEndLoc())); | |||
4112 | Diag(Tok, diag::warn_wrong_clang_attr_namespace) | |||
4113 | << FixItHint::CreateReplacement(TokRange, "_Clang"); | |||
4114 | Loc = ConsumeToken(); | |||
4115 | return &PP.getIdentifierTable().get("_Clang"); | |||
4116 | } | |||
4117 | } | |||
4118 | return nullptr; | |||
4119 | } | |||
4120 | ||||
4121 | case tok::ampamp: // 'and' | |||
4122 | case tok::pipe: // 'bitor' | |||
4123 | case tok::pipepipe: // 'or' | |||
4124 | case tok::caret: // 'xor' | |||
4125 | case tok::tilde: // 'compl' | |||
4126 | case tok::amp: // 'bitand' | |||
4127 | case tok::ampequal: // 'and_eq' | |||
4128 | case tok::pipeequal: // 'or_eq' | |||
4129 | case tok::caretequal: // 'xor_eq' | |||
4130 | case tok::exclaim: // 'not' | |||
4131 | case tok::exclaimequal: // 'not_eq' | |||
4132 | // Alternative tokens do not have identifier info, but their spelling | |||
4133 | // starts with an alphabetical character. | |||
4134 | SmallString<8> SpellingBuf; | |||
4135 | SourceLocation SpellingLoc = | |||
4136 | PP.getSourceManager().getSpellingLoc(Tok.getLocation()); | |||
4137 | StringRef Spelling = PP.getSpelling(SpellingLoc, SpellingBuf); | |||
4138 | if (isLetter(Spelling[0])) { | |||
4139 | Loc = ConsumeToken(); | |||
4140 | return &PP.getIdentifierTable().get(Spelling); | |||
4141 | } | |||
4142 | return nullptr; | |||
4143 | } | |||
4144 | } | |||
4145 | ||||
4146 | void Parser::ParseOpenMPAttributeArgs(IdentifierInfo *AttrName, | |||
4147 | CachedTokens &OpenMPTokens) { | |||
4148 | // Both 'sequence' and 'directive' attributes require arguments, so parse the | |||
4149 | // open paren for the argument list. | |||
4150 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
4151 | if (T.consumeOpen()) { | |||
4152 | Diag(Tok, diag::err_expected) << tok::l_paren; | |||
4153 | return; | |||
4154 | } | |||
4155 | ||||
4156 | if (AttrName->isStr("directive")) { | |||
4157 | // If the attribute is named `directive`, we can consume its argument list | |||
4158 | // and push the tokens from it into the cached token stream for a new OpenMP | |||
4159 | // pragma directive. | |||
4160 | Token OMPBeginTok; | |||
4161 | OMPBeginTok.startToken(); | |||
4162 | OMPBeginTok.setKind(tok::annot_attr_openmp); | |||
4163 | OMPBeginTok.setLocation(Tok.getLocation()); | |||
4164 | OpenMPTokens.push_back(OMPBeginTok); | |||
4165 | ||||
4166 | ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens, /*StopAtSemi=*/false, | |||
4167 | /*ConsumeFinalToken*/ false); | |||
4168 | Token OMPEndTok; | |||
4169 | OMPEndTok.startToken(); | |||
4170 | OMPEndTok.setKind(tok::annot_pragma_openmp_end); | |||
4171 | OMPEndTok.setLocation(Tok.getLocation()); | |||
4172 | OpenMPTokens.push_back(OMPEndTok); | |||
4173 | } else { | |||
4174 | assert(AttrName->isStr("sequence") &&((void)0) | |||
4175 | "Expected either 'directive' or 'sequence'")((void)0); | |||
4176 | // If the attribute is named 'sequence', its argument is a list of one or | |||
4177 | // more OpenMP attributes (either 'omp::directive' or 'omp::sequence', | |||
4178 | // where the 'omp::' is optional). | |||
4179 | do { | |||
4180 | // We expect to see one of the following: | |||
4181 | // * An identifier (omp) for the attribute namespace followed by :: | |||
4182 | // * An identifier (directive) or an identifier (sequence). | |||
4183 | SourceLocation IdentLoc; | |||
4184 | IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc); | |||
4185 | ||||
4186 | // If there is an identifier and it is 'omp', a double colon is required | |||
4187 | // followed by the actual identifier we're after. | |||
4188 | if (Ident && Ident->isStr("omp") && !ExpectAndConsume(tok::coloncolon)) | |||
4189 | Ident = TryParseCXX11AttributeIdentifier(IdentLoc); | |||
4190 | ||||
4191 | // If we failed to find an identifier (scoped or otherwise), or we found | |||
4192 | // an unexpected identifier, diagnose. | |||
4193 | if (!Ident || (!Ident->isStr("directive") && !Ident->isStr("sequence"))) { | |||
4194 | Diag(Tok.getLocation(), diag::err_expected_sequence_or_directive); | |||
4195 | SkipUntil(tok::r_paren, StopBeforeMatch); | |||
4196 | continue; | |||
4197 | } | |||
4198 | // We read an identifier. If the identifier is one of the ones we | |||
4199 | // expected, we can recurse to parse the args. | |||
4200 | ParseOpenMPAttributeArgs(Ident, OpenMPTokens); | |||
4201 | ||||
4202 | // There may be a comma to signal that we expect another directive in the | |||
4203 | // sequence. | |||
4204 | } while (TryConsumeToken(tok::comma)); | |||
4205 | } | |||
4206 | // Parse the closing paren for the argument list. | |||
4207 | T.consumeClose(); | |||
4208 | } | |||
4209 | ||||
4210 | static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, | |||
4211 | IdentifierInfo *ScopeName) { | |||
4212 | switch ( | |||
4213 | ParsedAttr::getParsedKind(AttrName, ScopeName, ParsedAttr::AS_CXX11)) { | |||
4214 | case ParsedAttr::AT_CarriesDependency: | |||
4215 | case ParsedAttr::AT_Deprecated: | |||
4216 | case ParsedAttr::AT_FallThrough: | |||
4217 | case ParsedAttr::AT_CXX11NoReturn: | |||
4218 | case ParsedAttr::AT_NoUniqueAddress: | |||
4219 | case ParsedAttr::AT_Likely: | |||
4220 | case ParsedAttr::AT_Unlikely: | |||
4221 | return true; | |||
4222 | case ParsedAttr::AT_WarnUnusedResult: | |||
4223 | return !ScopeName && AttrName->getName().equals("nodiscard"); | |||
4224 | case ParsedAttr::AT_Unused: | |||
4225 | return !ScopeName && AttrName->getName().equals("maybe_unused"); | |||
4226 | default: | |||
4227 | return false; | |||
4228 | } | |||
4229 | } | |||
4230 | ||||
4231 | /// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause. | |||
4232 | /// | |||
4233 | /// [C++11] attribute-argument-clause: | |||
4234 | /// '(' balanced-token-seq ')' | |||
4235 | /// | |||
4236 | /// [C++11] balanced-token-seq: | |||
4237 | /// balanced-token | |||
4238 | /// balanced-token-seq balanced-token | |||
4239 | /// | |||
4240 | /// [C++11] balanced-token: | |||
4241 | /// '(' balanced-token-seq ')' | |||
4242 | /// '[' balanced-token-seq ']' | |||
4243 | /// '{' balanced-token-seq '}' | |||
4244 | /// any token but '(', ')', '[', ']', '{', or '}' | |||
4245 | bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName, | |||
4246 | SourceLocation AttrNameLoc, | |||
4247 | ParsedAttributes &Attrs, | |||
4248 | SourceLocation *EndLoc, | |||
4249 | IdentifierInfo *ScopeName, | |||
4250 | SourceLocation ScopeLoc, | |||
4251 | CachedTokens &OpenMPTokens) { | |||
4252 | assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list")((void)0); | |||
4253 | SourceLocation LParenLoc = Tok.getLocation(); | |||
4254 | const LangOptions &LO = getLangOpts(); | |||
4255 | ParsedAttr::Syntax Syntax = | |||
4256 | LO.CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x; | |||
4257 | ||||
4258 | // If the attribute isn't known, we will not attempt to parse any | |||
4259 | // arguments. | |||
4260 | if (!hasAttribute(LO.CPlusPlus ? AttrSyntax::CXX : AttrSyntax::C, ScopeName, | |||
4261 | AttrName, getTargetInfo(), getLangOpts())) { | |||
4262 | // Eat the left paren, then skip to the ending right paren. | |||
4263 | ConsumeParen(); | |||
4264 | SkipUntil(tok::r_paren); | |||
4265 | return false; | |||
4266 | } | |||
4267 | ||||
4268 | if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) { | |||
4269 | // GNU-scoped attributes have some special cases to handle GNU-specific | |||
4270 | // behaviors. | |||
4271 | ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, | |||
4272 | ScopeLoc, Syntax, nullptr); | |||
4273 | return true; | |||
4274 | } | |||
4275 | ||||
4276 | if (ScopeName && ScopeName->isStr("omp")) { | |||
4277 | Diag(AttrNameLoc, getLangOpts().OpenMP >= 51 | |||
4278 | ? diag::warn_omp51_compat_attributes | |||
4279 | : diag::ext_omp_attributes); | |||
4280 | ||||
4281 | ParseOpenMPAttributeArgs(AttrName, OpenMPTokens); | |||
4282 | ||||
4283 | // We claim that an attribute was parsed and added so that one is not | |||
4284 | // created for us by the caller. | |||
4285 | return true; | |||
4286 | } | |||
4287 | ||||
4288 | unsigned NumArgs; | |||
4289 | // Some Clang-scoped attributes have some special parsing behavior. | |||
4290 | if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"))) | |||
4291 | NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, | |||
4292 | ScopeName, ScopeLoc, Syntax); | |||
4293 | else | |||
4294 | NumArgs = | |||
4295 | ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, | |||
4296 | ScopeName, ScopeLoc, Syntax); | |||
4297 | ||||
4298 | if (!Attrs.empty() && | |||
4299 | IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) { | |||
4300 | ParsedAttr &Attr = Attrs.back(); | |||
4301 | // If the attribute is a standard or built-in attribute and we are | |||
4302 | // parsing an argument list, we need to determine whether this attribute | |||
4303 | // was allowed to have an argument list (such as [[deprecated]]), and how | |||
4304 | // many arguments were parsed (so we can diagnose on [[deprecated()]]). | |||
4305 | if (Attr.getMaxArgs() && !NumArgs) { | |||
4306 | // The attribute was allowed to have arguments, but none were provided | |||
4307 | // even though the attribute parsed successfully. This is an error. | |||
4308 | Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName; | |||
4309 | Attr.setInvalid(true); | |||
4310 | } else if (!Attr.getMaxArgs()) { | |||
4311 | // The attribute parsed successfully, but was not allowed to have any | |||
4312 | // arguments. It doesn't matter whether any were provided -- the | |||
4313 | // presence of the argument list (even if empty) is diagnosed. | |||
4314 | Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments) | |||
4315 | << AttrName | |||
4316 | << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc)); | |||
4317 | Attr.setInvalid(true); | |||
4318 | } | |||
4319 | } | |||
4320 | return true; | |||
4321 | } | |||
4322 | ||||
4323 | /// ParseCXX11AttributeSpecifier - Parse a C++11 or C2x attribute-specifier. | |||
4324 | /// | |||
4325 | /// [C++11] attribute-specifier: | |||
4326 | /// '[' '[' attribute-list ']' ']' | |||
4327 | /// alignment-specifier | |||
4328 | /// | |||
4329 | /// [C++11] attribute-list: | |||
4330 | /// attribute[opt] | |||
4331 | /// attribute-list ',' attribute[opt] | |||
4332 | /// attribute '...' | |||
4333 | /// attribute-list ',' attribute '...' | |||
4334 | /// | |||
4335 | /// [C++11] attribute: | |||
4336 | /// attribute-token attribute-argument-clause[opt] | |||
4337 | /// | |||
4338 | /// [C++11] attribute-token: | |||
4339 | /// identifier | |||
4340 | /// attribute-scoped-token | |||
4341 | /// | |||
4342 | /// [C++11] attribute-scoped-token: | |||
4343 | /// attribute-namespace '::' identifier | |||
4344 | /// | |||
4345 | /// [C++11] attribute-namespace: | |||
4346 | /// identifier | |||
4347 | void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs, | |||
4348 | CachedTokens &OpenMPTokens, | |||
4349 | SourceLocation *EndLoc) { | |||
4350 | if (Tok.is(tok::kw_alignas)) { | |||
4351 | Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas); | |||
4352 | ParseAlignmentSpecifier(Attrs, EndLoc); | |||
4353 | return; | |||
4354 | } | |||
4355 | ||||
4356 | assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) &&((void)0) | |||
4357 | "Not a double square bracket attribute list")((void)0); | |||
4358 | ||||
4359 | SourceLocation OpenLoc = Tok.getLocation(); | |||
4360 | Diag(OpenLoc, diag::warn_cxx98_compat_attribute); | |||
4361 | ||||
4362 | ConsumeBracket(); | |||
4363 | checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin); | |||
4364 | ConsumeBracket(); | |||
4365 | ||||
4366 | SourceLocation CommonScopeLoc; | |||
4367 | IdentifierInfo *CommonScopeName = nullptr; | |||
4368 | if (Tok.is(tok::kw_using)) { | |||
4369 | Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 | |||
4370 | ? diag::warn_cxx14_compat_using_attribute_ns | |||
4371 | : diag::ext_using_attribute_ns); | |||
4372 | ConsumeToken(); | |||
4373 | ||||
4374 | CommonScopeName = TryParseCXX11AttributeIdentifier(CommonScopeLoc); | |||
4375 | if (!CommonScopeName) { | |||
4376 | Diag(Tok.getLocation(), diag::err_expected) << tok::identifier; | |||
4377 | SkipUntil(tok::r_square, tok::colon, StopBeforeMatch); | |||
4378 | } | |||
4379 | if (!TryConsumeToken(tok::colon) && CommonScopeName) | |||
4380 | Diag(Tok.getLocation(), diag::err_expected) << tok::colon; | |||
4381 | } | |||
4382 | ||||
4383 | llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs; | |||
4384 | ||||
4385 | bool AttrParsed = false; | |||
4386 | while (!Tok.isOneOf(tok::r_square, tok::semi)) { | |||
4387 | if (AttrParsed) { | |||
4388 | // If we parsed an attribute, a comma is required before parsing any | |||
4389 | // additional attributes. | |||
4390 | if (ExpectAndConsume(tok::comma)) { | |||
4391 | SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch); | |||
4392 | continue; | |||
4393 | } | |||
4394 | AttrParsed = false; | |||
4395 | } | |||
4396 | ||||
4397 | // Eat all remaining superfluous commas before parsing the next attribute. | |||
4398 | while (TryConsumeToken(tok::comma)) | |||
4399 | ; | |||
4400 | ||||
4401 | SourceLocation ScopeLoc, AttrLoc; | |||
4402 | IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr; | |||
4403 | ||||
4404 | AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); | |||
4405 | if (!AttrName) | |||
4406 | // Break out to the "expected ']'" diagnostic. | |||
4407 | break; | |||
4408 | ||||
4409 | // scoped attribute | |||
4410 | if (TryConsumeToken(tok::coloncolon)) { | |||
4411 | ScopeName = AttrName; | |||
4412 | ScopeLoc = AttrLoc; | |||
4413 | ||||
4414 | AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); | |||
4415 | if (!AttrName) { | |||
4416 | Diag(Tok.getLocation(), diag::err_expected) << tok::identifier; | |||
4417 | SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch); | |||
4418 | continue; | |||
4419 | } | |||
4420 | } | |||
4421 | ||||
4422 | if (CommonScopeName) { | |||
4423 | if (ScopeName) { | |||
4424 | Diag(ScopeLoc, diag::err_using_attribute_ns_conflict) | |||
4425 | << SourceRange(CommonScopeLoc); | |||
4426 | } else { | |||
4427 | ScopeName = CommonScopeName; | |||
4428 | ScopeLoc = CommonScopeLoc; | |||
4429 | } | |||
4430 | } | |||
4431 | ||||
4432 | // Parse attribute arguments | |||
4433 | if (Tok.is(tok::l_paren)) | |||
4434 | AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc, | |||
4435 | ScopeName, ScopeLoc, OpenMPTokens); | |||
4436 | ||||
4437 | if (!AttrParsed) { | |||
4438 | Attrs.addNew( | |||
4439 | AttrName, | |||
4440 | SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc), | |||
4441 | ScopeName, ScopeLoc, nullptr, 0, | |||
4442 | getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C2x); | |||
4443 | AttrParsed = true; | |||
4444 | } | |||
4445 | ||||
4446 | if (TryConsumeToken(tok::ellipsis)) | |||
4447 | Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) | |||
4448 | << AttrName; | |||
4449 | } | |||
4450 | ||||
4451 | // If we hit an error and recovered by parsing up to a semicolon, eat the | |||
4452 | // semicolon and don't issue further diagnostics about missing brackets. | |||
4453 | if (Tok.is(tok::semi)) { | |||
4454 | ConsumeToken(); | |||
4455 | return; | |||
4456 | } | |||
4457 | ||||
4458 | SourceLocation CloseLoc = Tok.getLocation(); | |||
4459 | if (ExpectAndConsume(tok::r_square)) | |||
4460 | SkipUntil(tok::r_square); | |||
4461 | else if (Tok.is(tok::r_square)) | |||
4462 | checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd); | |||
4463 | if (EndLoc) | |||
4464 | *EndLoc = Tok.getLocation(); | |||
4465 | if (ExpectAndConsume(tok::r_square)) | |||
4466 | SkipUntil(tok::r_square); | |||
4467 | } | |||
4468 | ||||
4469 | /// ParseCXX11Attributes - Parse a C++11 or C2x attribute-specifier-seq. | |||
4470 | /// | |||
4471 | /// attribute-specifier-seq: | |||
4472 | /// attribute-specifier-seq[opt] attribute-specifier | |||
4473 | void Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs, | |||
4474 | SourceLocation *endLoc) { | |||
4475 | assert(standardAttributesAllowed())((void)0); | |||
4476 | ||||
4477 | SourceLocation StartLoc = Tok.getLocation(), Loc; | |||
4478 | if (!endLoc) | |||
4479 | endLoc = &Loc; | |||
4480 | ||||
4481 | do { | |||
4482 | ParseCXX11AttributeSpecifier(attrs, endLoc); | |||
4483 | } while (isCXX11AttributeSpecifier()); | |||
4484 | ||||
4485 | attrs.Range = SourceRange(StartLoc, *endLoc); | |||
4486 | } | |||
4487 | ||||
4488 | void Parser::DiagnoseAndSkipCXX11Attributes() { | |||
4489 | // Start and end location of an attribute or an attribute list. | |||
4490 | SourceLocation StartLoc = Tok.getLocation(); | |||
4491 | SourceLocation EndLoc = SkipCXX11Attributes(); | |||
4492 | ||||
4493 | if (EndLoc.isValid()) { | |||
4494 | SourceRange Range(StartLoc, EndLoc); | |||
4495 | Diag(StartLoc, diag::err_attributes_not_allowed) | |||
4496 | << Range; | |||
4497 | } | |||
4498 | } | |||
4499 | ||||
4500 | SourceLocation Parser::SkipCXX11Attributes() { | |||
4501 | SourceLocation EndLoc; | |||
4502 | ||||
4503 | if (!isCXX11AttributeSpecifier()) | |||
4504 | return EndLoc; | |||
4505 | ||||
4506 | do { | |||
4507 | if (Tok.is(tok::l_square)) { | |||
4508 | BalancedDelimiterTracker T(*this, tok::l_square); | |||
4509 | T.consumeOpen(); | |||
4510 | T.skipToEnd(); | |||
4511 | EndLoc = T.getCloseLocation(); | |||
4512 | } else { | |||
4513 | assert(Tok.is(tok::kw_alignas) && "not an attribute specifier")((void)0); | |||
4514 | ConsumeToken(); | |||
4515 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
4516 | if (!T.consumeOpen()) | |||
4517 | T.skipToEnd(); | |||
4518 | EndLoc = T.getCloseLocation(); | |||
4519 | } | |||
4520 | } while (isCXX11AttributeSpecifier()); | |||
4521 | ||||
4522 | return EndLoc; | |||
4523 | } | |||
4524 | ||||
4525 | /// Parse uuid() attribute when it appears in a [] Microsoft attribute. | |||
4526 | void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) { | |||
4527 | assert(Tok.is(tok::identifier) && "Not a Microsoft attribute list")((void)0); | |||
4528 | IdentifierInfo *UuidIdent = Tok.getIdentifierInfo(); | |||
4529 | assert(UuidIdent->getName() == "uuid" && "Not a Microsoft attribute list")((void)0); | |||
4530 | ||||
4531 | SourceLocation UuidLoc = Tok.getLocation(); | |||
4532 | ConsumeToken(); | |||
4533 | ||||
4534 | // Ignore the left paren location for now. | |||
4535 | BalancedDelimiterTracker T(*this, tok::l_paren); | |||
4536 | if (T.consumeOpen()) { | |||
4537 | Diag(Tok, diag::err_expected) << tok::l_paren; | |||
4538 | return; | |||
4539 | } | |||
4540 | ||||
4541 | ArgsVector ArgExprs; | |||
4542 | if (Tok.is(tok::string_literal)) { | |||
4543 | // Easy case: uuid("...") -- quoted string. | |||
4544 | ExprResult StringResult = ParseStringLiteralExpression(); | |||
4545 | if (StringResult.isInvalid()) | |||
4546 | return; | |||
4547 | ArgExprs.push_back(StringResult.get()); | |||
4548 | } else { | |||
4549 | // something like uuid({000000A0-0000-0000-C000-000000000049}) -- no | |||
4550 | // quotes in the parens. Just append the spelling of all tokens encountered | |||
4551 | // until the closing paren. | |||
4552 | ||||
4553 | SmallString<42> StrBuffer; // 2 "", 36 bytes UUID, 2 optional {}, 1 nul | |||
4554 | StrBuffer += "\""; | |||
4555 | ||||
4556 | // Since none of C++'s keywords match [a-f]+, accepting just tok::l_brace, | |||
4557 | // tok::r_brace, tok::minus, tok::identifier (think C000) and | |||
4558 | // tok::numeric_constant (0000) should be enough. But the spelling of the | |||
4559 | // uuid argument is checked later anyways, so there's no harm in accepting | |||
4560 | // almost anything here. | |||
4561 | // cl is very strict about whitespace in this form and errors out if any | |||
4562 | // is present, so check the space flags on the tokens. | |||
4563 | SourceLocation StartLoc = Tok.getLocation(); | |||
4564 | while (Tok.isNot(tok::r_paren)) { | |||
4565 | if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) { | |||
4566 | Diag(Tok, diag::err_attribute_uuid_malformed_guid); | |||
4567 | SkipUntil(tok::r_paren, StopAtSemi); | |||
4568 | return; | |||
4569 | } | |||
4570 | SmallString<16> SpellingBuffer; | |||
4571 | SpellingBuffer.resize(Tok.getLength() + 1); | |||
4572 | bool Invalid = false; | |||
4573 | StringRef TokSpelling = PP.getSpelling(Tok, SpellingBuffer, &Invalid); | |||
4574 | if (Invalid) { | |||
4575 | SkipUntil(tok::r_paren, StopAtSemi); | |||
4576 | return; | |||
4577 | } | |||
4578 | StrBuffer += TokSpelling; | |||
4579 | ConsumeAnyToken(); | |||
4580 | } | |||
4581 | StrBuffer += "\""; | |||
4582 | ||||
4583 | if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) { | |||
4584 | Diag(Tok, diag::err_attribute_uuid_malformed_guid); | |||
4585 | ConsumeParen(); | |||
4586 | return; | |||
4587 | } | |||
4588 | ||||
4589 | // Pretend the user wrote the appropriate string literal here. | |||
4590 | // ActOnStringLiteral() copies the string data into the literal, so it's | |||
4591 | // ok that the Token points to StrBuffer. | |||
4592 | Token Toks[1]; | |||
4593 | Toks[0].startToken(); | |||
4594 | Toks[0].setKind(tok::string_literal); | |||
4595 | Toks[0].setLocation(StartLoc); | |||
4596 | Toks[0].setLiteralData(StrBuffer.data()); | |||
4597 | Toks[0].setLength(StrBuffer.size()); | |||
4598 | StringLiteral *UuidString = | |||
4599 | cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get()); | |||
4600 | ArgExprs.push_back(UuidString); | |||
4601 | } | |||
4602 | ||||
4603 | if (!T.consumeClose()) { | |||
4604 | Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr, | |||
4605 | SourceLocation(), ArgExprs.data(), ArgExprs.size(), | |||
4606 | ParsedAttr::AS_Microsoft); | |||
4607 | } | |||
4608 | } | |||
4609 | ||||
4610 | /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr] | |||
4611 | /// | |||
4612 | /// [MS] ms-attribute: | |||
4613 | /// '[' token-seq ']' | |||
4614 | /// | |||
4615 | /// [MS] ms-attribute-seq: | |||
4616 | /// ms-attribute[opt] | |||
4617 | /// ms-attribute ms-attribute-seq | |||
4618 | void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs, | |||
4619 | SourceLocation *endLoc) { | |||
4620 | assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list")((void)0); | |||
4621 | ||||
4622 | do { | |||
4623 | // FIXME: If this is actually a C++11 attribute, parse it as one. | |||
4624 | BalancedDelimiterTracker T(*this, tok::l_square); | |||
4625 | T.consumeOpen(); | |||
4626 | ||||
4627 | // Skip most ms attributes except for a specific list. | |||
4628 | while (true) { | |||
4629 | SkipUntil(tok::r_square, tok::identifier, StopAtSemi | StopBeforeMatch); | |||
4630 | if (Tok.isNot(tok::identifier)) // ']', but also eof | |||
4631 | break; | |||
4632 | if (Tok.getIdentifierInfo()->getName() == "uuid") | |||
4633 | ParseMicrosoftUuidAttributeArgs(attrs); | |||
4634 | else | |||
4635 | ConsumeToken(); | |||
4636 | } | |||
4637 | ||||
4638 | T.consumeClose(); | |||
4639 | if (endLoc) | |||
4640 | *endLoc = T.getCloseLocation(); | |||
4641 | } while (Tok.is(tok::l_square)); | |||
4642 | } | |||
4643 | ||||
4644 | void Parser::ParseMicrosoftIfExistsClassDeclaration( | |||
4645 | DeclSpec::TST TagType, ParsedAttributes &AccessAttrs, | |||
4646 | AccessSpecifier &CurAS) { | |||
4647 | IfExistsCondition Result; | |||
4648 | if (ParseMicrosoftIfExistsCondition(Result)) | |||
4649 | return; | |||
4650 | ||||
4651 | BalancedDelimiterTracker Braces(*this, tok::l_brace); | |||
4652 | if (Braces.consumeOpen()) { | |||
4653 | Diag(Tok, diag::err_expected) << tok::l_brace; | |||
4654 | return; | |||
4655 | } | |||
4656 | ||||
4657 | switch (Result.Behavior) { | |||
4658 | case IEB_Parse: | |||
4659 | // Parse the declarations below. | |||
4660 | break; | |||
4661 | ||||
4662 | case IEB_Dependent: | |||
4663 | Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists) | |||
4664 | << Result.IsIfExists; | |||
4665 | // Fall through to skip. | |||
4666 | LLVM_FALLTHROUGH[[gnu::fallthrough]]; | |||
4667 | ||||
4668 | case IEB_Skip: | |||
4669 | Braces.skipToEnd(); | |||
4670 | return; | |||
4671 | } | |||
4672 | ||||
4673 | while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { | |||
4674 | // __if_exists, __if_not_exists can nest. | |||
4675 | if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) { | |||
4676 | ParseMicrosoftIfExistsClassDeclaration(TagType, | |||
4677 | AccessAttrs, CurAS); | |||
4678 | continue; | |||
4679 | } | |||
4680 | ||||
4681 | // Check for extraneous top-level semicolon. | |||
4682 | if (Tok.is(tok::semi)) { | |||
4683 | ConsumeExtraSemi(InsideStruct, TagType); | |||
4684 | continue; | |||
4685 | } | |||
4686 | ||||
4687 | AccessSpecifier AS = getAccessSpecifierIfPresent(); | |||
4688 | if (AS != AS_none) { | |||
4689 | // Current token is a C++ access specifier. | |||
4690 | CurAS = AS; | |||
4691 | SourceLocation ASLoc = Tok.getLocation(); | |||
4692 | ConsumeToken(); | |||
4693 | if (Tok.is(tok::colon)) | |||
4694 | Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation(), | |||
4695 | ParsedAttributesView{}); | |||
4696 | else | |||
4697 | Diag(Tok, diag::err_expected) << tok::colon; | |||
4698 | ConsumeToken(); | |||
4699 | continue; | |||
4700 | } | |||
4701 | ||||
4702 | // Parse all the comma separated declarators. | |||
4703 | ParseCXXClassMemberDeclaration(CurAS, AccessAttrs); | |||
4704 | } | |||
4705 | ||||
4706 | Braces.consumeClose(); | |||
4707 | } |
1 | //===--- Token.h - Token interface ------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the Token interface. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_CLANG_LEX_TOKEN_H |
14 | #define LLVM_CLANG_LEX_TOKEN_H |
15 | |
16 | #include "clang/Basic/SourceLocation.h" |
17 | #include "clang/Basic/TokenKinds.h" |
18 | #include "llvm/ADT/StringRef.h" |
19 | #include <cassert> |
20 | |
21 | namespace clang { |
22 | |
23 | class IdentifierInfo; |
24 | |
25 | /// Token - This structure provides full information about a lexed token. |
26 | /// It is not intended to be space efficient, it is intended to return as much |
27 | /// information as possible about each returned token. This is expected to be |
28 | /// compressed into a smaller form if memory footprint is important. |
29 | /// |
30 | /// The parser can create a special "annotation token" representing a stream of |
31 | /// tokens that were parsed and semantically resolved, e.g.: "foo::MyClass<int>" |
32 | /// can be represented by a single typename annotation token that carries |
33 | /// information about the SourceRange of the tokens and the type object. |
34 | class Token { |
35 | /// The location of the token. This is actually a SourceLocation. |
36 | SourceLocation::UIntTy Loc; |
37 | |
38 | // Conceptually these next two fields could be in a union. However, this |
39 | // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical |
40 | // routine. Keeping as separate members with casts until a more beautiful fix |
41 | // presents itself. |
42 | |
43 | /// UintData - This holds either the length of the token text, when |
44 | /// a normal token, or the end of the SourceRange when an annotation |
45 | /// token. |
46 | SourceLocation::UIntTy UintData; |
47 | |
48 | /// PtrData - This is a union of four different pointer types, which depends |
49 | /// on what type of token this is: |
50 | /// Identifiers, keywords, etc: |
51 | /// This is an IdentifierInfo*, which contains the uniqued identifier |
52 | /// spelling. |
53 | /// Literals: isLiteral() returns true. |
54 | /// This is a pointer to the start of the token in a text buffer, which |
55 | /// may be dirty (have trigraphs / escaped newlines). |
56 | /// Annotations (resolved type names, C++ scopes, etc): isAnnotation(). |
57 | /// This is a pointer to sema-specific data for the annotation token. |
58 | /// Eof: |
59 | // This is a pointer to a Decl. |
60 | /// Other: |
61 | /// This is null. |
62 | void *PtrData; |
63 | |
64 | /// Kind - The actual flavor of token this is. |
65 | tok::TokenKind Kind; |
66 | |
67 | /// Flags - Bits we track about this token, members of the TokenFlags enum. |
68 | unsigned short Flags; |
69 | |
70 | public: |
71 | // Various flags set per token: |
72 | enum TokenFlags { |
73 | StartOfLine = 0x01, // At start of line or only after whitespace |
74 | // (considering the line after macro expansion). |
75 | LeadingSpace = 0x02, // Whitespace exists before this token (considering |
76 | // whitespace after macro expansion). |
77 | DisableExpand = 0x04, // This identifier may never be macro expanded. |
78 | NeedsCleaning = 0x08, // Contained an escaped newline or trigraph. |
79 | LeadingEmptyMacro = 0x10, // Empty macro exists before this token. |
80 | HasUDSuffix = 0x20, // This string or character literal has a ud-suffix. |
81 | HasUCN = 0x40, // This identifier contains a UCN. |
82 | IgnoredComma = 0x80, // This comma is not a macro argument separator (MS). |
83 | StringifiedInMacro = 0x100, // This string or character literal is formed by |
84 | // macro stringizing or charizing operator. |
85 | CommaAfterElided = 0x200, // The comma following this token was elided (MS). |
86 | IsEditorPlaceholder = 0x400, // This identifier is a placeholder. |
87 | IsReinjected = 0x800, // A phase 4 token that was produced before and |
88 | // re-added, e.g. via EnterTokenStream. Annotation |
89 | // tokens are *not* reinjected. |
90 | }; |
91 | |
92 | tok::TokenKind getKind() const { return Kind; } |
93 | void setKind(tok::TokenKind K) { Kind = K; } |
94 | |
95 | /// is/isNot - Predicates to check if this token is a specific kind, as in |
96 | /// "if (Tok.is(tok::l_brace)) {...}". |
97 | bool is(tok::TokenKind K) const { return Kind == K; } |
98 | bool isNot(tok::TokenKind K) const { return Kind != K; } |
99 | bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { |
100 | return is(K1) || is(K2); |
101 | } |
102 | template <typename... Ts> |
103 | bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, Ts... Ks) const { |
104 | return is(K1) || isOneOf(K2, Ks...); |
105 | } |
106 | |
107 | /// Return true if this is a raw identifier (when lexing |
108 | /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode). |
109 | bool isAnyIdentifier() const { |
110 | return tok::isAnyIdentifier(getKind()); |
111 | } |
112 | |
113 | /// Return true if this is a "literal", like a numeric |
114 | /// constant, string, etc. |
115 | bool isLiteral() const { |
116 | return tok::isLiteral(getKind()); |
117 | } |
118 | |
119 | /// Return true if this is any of tok::annot_* kind tokens. |
120 | bool isAnnotation() const { |
121 | return tok::isAnnotation(getKind()); |
122 | } |
123 | |
124 | /// Return a source location identifier for the specified |
125 | /// offset in the current file. |
126 | SourceLocation getLocation() const { |
127 | return SourceLocation::getFromRawEncoding(Loc); |
128 | } |
129 | unsigned getLength() const { |
130 | assert(!isAnnotation() && "Annotation tokens have no length field")((void)0); |
131 | return UintData; |
132 | } |
133 | |
134 | void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); } |
135 | void setLength(unsigned Len) { |
136 | assert(!isAnnotation() && "Annotation tokens have no length field")((void)0); |
137 | UintData = Len; |
138 | } |
139 | |
140 | SourceLocation getAnnotationEndLoc() const { |
141 | assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token")((void)0); |
142 | return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc); |
143 | } |
144 | void setAnnotationEndLoc(SourceLocation L) { |
145 | assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token")((void)0); |
146 | UintData = L.getRawEncoding(); |
147 | } |
148 | |
149 | SourceLocation getLastLoc() const { |
150 | return isAnnotation() ? getAnnotationEndLoc() : getLocation(); |
151 | } |
152 | |
153 | SourceLocation getEndLoc() const { |
154 | return isAnnotation() ? getAnnotationEndLoc() |
155 | : getLocation().getLocWithOffset(getLength()); |
156 | } |
157 | |
158 | /// SourceRange of the group of tokens that this annotation token |
159 | /// represents. |
160 | SourceRange getAnnotationRange() const { |
161 | return SourceRange(getLocation(), getAnnotationEndLoc()); |
162 | } |
163 | void setAnnotationRange(SourceRange R) { |
164 | setLocation(R.getBegin()); |
165 | setAnnotationEndLoc(R.getEnd()); |
166 | } |
167 | |
168 | const char *getName() const { return tok::getTokenName(Kind); } |
169 | |
170 | /// Reset all flags to cleared. |
171 | void startToken() { |
172 | Kind = tok::unknown; |
173 | Flags = 0; |
174 | PtrData = nullptr; |
175 | UintData = 0; |
176 | Loc = SourceLocation().getRawEncoding(); |
177 | } |
178 | |
179 | IdentifierInfo *getIdentifierInfo() const { |
180 | assert(isNot(tok::raw_identifier) &&((void)0) |
181 | "getIdentifierInfo() on a tok::raw_identifier token!")((void)0); |
182 | assert(!isAnnotation() &&((void)0) |
183 | "getIdentifierInfo() on an annotation token!")((void)0); |
184 | if (isLiteral()) return nullptr; |
185 | if (is(tok::eof)) return nullptr; |
186 | return (IdentifierInfo*) PtrData; |
187 | } |
188 | void setIdentifierInfo(IdentifierInfo *II) { |
189 | PtrData = (void*) II; |
190 | } |
191 | |
192 | const void *getEofData() const { |
193 | assert(is(tok::eof))((void)0); |
194 | return reinterpret_cast<const void *>(PtrData); |
195 | } |
196 | void setEofData(const void *D) { |
197 | assert(is(tok::eof))((void)0); |
198 | assert(!PtrData)((void)0); |
199 | PtrData = const_cast<void *>(D); |
200 | } |
201 | |
202 | /// getRawIdentifier - For a raw identifier token (i.e., an identifier |
203 | /// lexed in raw mode), returns a reference to the text substring in the |
204 | /// buffer if known. |
205 | StringRef getRawIdentifier() const { |
206 | assert(is(tok::raw_identifier))((void)0); |
207 | return StringRef(reinterpret_cast<const char *>(PtrData), getLength()); |
208 | } |
209 | void setRawIdentifierData(const char *Ptr) { |
210 | assert(is(tok::raw_identifier))((void)0); |
211 | PtrData = const_cast<char*>(Ptr); |
212 | } |
213 | |
214 | /// getLiteralData - For a literal token (numeric constant, string, etc), this |
215 | /// returns a pointer to the start of it in the text buffer if known, null |
216 | /// otherwise. |
217 | const char *getLiteralData() const { |
218 | assert(isLiteral() && "Cannot get literal data of non-literal")((void)0); |
219 | return reinterpret_cast<const char*>(PtrData); |
220 | } |
221 | void setLiteralData(const char *Ptr) { |
222 | assert(isLiteral() && "Cannot set literal data of non-literal")((void)0); |
223 | PtrData = const_cast<char*>(Ptr); |
224 | } |
225 | |
226 | void *getAnnotationValue() const { |
227 | assert(isAnnotation() && "Used AnnotVal on non-annotation token")((void)0); |
228 | return PtrData; |
229 | } |
230 | void setAnnotationValue(void *val) { |
231 | assert(isAnnotation() && "Used AnnotVal on non-annotation token")((void)0); |
232 | PtrData = val; |
233 | } |
234 | |
235 | /// Set the specified flag. |
236 | void setFlag(TokenFlags Flag) { |
237 | Flags |= Flag; |
238 | } |
239 | |
240 | /// Get the specified flag. |
241 | bool getFlag(TokenFlags Flag) const { |
242 | return (Flags & Flag) != 0; |
243 | } |
244 | |
245 | /// Unset the specified flag. |
246 | void clearFlag(TokenFlags Flag) { |
247 | Flags &= ~Flag; |
248 | } |
249 | |
250 | /// Return the internal represtation of the flags. |
251 | /// |
252 | /// This is only intended for low-level operations such as writing tokens to |
253 | /// disk. |
254 | unsigned getFlags() const { |
255 | return Flags; |
256 | } |
257 | |
258 | /// Set a flag to either true or false. |
259 | void setFlagValue(TokenFlags Flag, bool Val) { |
260 | if (Val) |
261 | setFlag(Flag); |
262 | else |
263 | clearFlag(Flag); |
264 | } |
265 | |
266 | /// isAtStartOfLine - Return true if this token is at the start of a line. |
267 | /// |
268 | bool isAtStartOfLine() const { return getFlag(StartOfLine); } |
269 | |
270 | /// Return true if this token has whitespace before it. |
271 | /// |
272 | bool hasLeadingSpace() const { return getFlag(LeadingSpace); } |
273 | |
274 | /// Return true if this identifier token should never |
275 | /// be expanded in the future, due to C99 6.10.3.4p2. |
276 | bool isExpandDisabled() const { return getFlag(DisableExpand); } |
277 | |
278 | /// Return true if we have an ObjC keyword identifier. |
279 | bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const; |
280 | |
281 | /// Return the ObjC keyword kind. |
282 | tok::ObjCKeywordKind getObjCKeywordID() const; |
283 | |
284 | /// Return true if this token has trigraphs or escaped newlines in it. |
285 | bool needsCleaning() const { return getFlag(NeedsCleaning); } |
286 | |
287 | /// Return true if this token has an empty macro before it. |
288 | /// |
289 | bool hasLeadingEmptyMacro() const { return getFlag(LeadingEmptyMacro); } |
290 | |
291 | /// Return true if this token is a string or character literal which |
292 | /// has a ud-suffix. |
293 | bool hasUDSuffix() const { return getFlag(HasUDSuffix); } |
294 | |
295 | /// Returns true if this token contains a universal character name. |
296 | bool hasUCN() const { return getFlag(HasUCN); } |
297 | |
298 | /// Returns true if this token is formed by macro by stringizing or charizing |
299 | /// operator. |
300 | bool stringifiedInMacro() const { return getFlag(StringifiedInMacro); } |
301 | |
302 | /// Returns true if the comma after this token was elided. |
303 | bool commaAfterElided() const { return getFlag(CommaAfterElided); } |
304 | |
305 | /// Returns true if this token is an editor placeholder. |
306 | /// |
307 | /// Editor placeholders are produced by the code-completion engine and are |
308 | /// represented as characters between '<#' and '#>' in the source code. The |
309 | /// lexer uses identifier tokens to represent placeholders. |
310 | bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); } |
311 | }; |
312 | |
313 | /// Information about the conditional stack (\#if directives) |
314 | /// currently active. |
315 | struct PPConditionalInfo { |
316 | /// Location where the conditional started. |
317 | SourceLocation IfLoc; |
318 | |
319 | /// True if this was contained in a skipping directive, e.g., |
320 | /// in a "\#if 0" block. |
321 | bool WasSkipping; |
322 | |
323 | /// True if we have emitted tokens already, and now we're in |
324 | /// an \#else block or something. Only useful in Skipping blocks. |
325 | bool FoundNonSkip; |
326 | |
327 | /// True if we've seen a \#else in this block. If so, |
328 | /// \#elif/\#else directives are not allowed. |
329 | bool FoundElse; |
330 | }; |
331 | |
332 | } // end namespace clang |
333 | |
334 | #endif // LLVM_CLANG_LEX_TOKEN_H |
1 | //===--- DeclSpec.h - Parsed declaration specifiers -------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// |
9 | /// \file |
10 | /// This file defines the classes used to store parsed information about |
11 | /// declaration-specifiers and declarators. |
12 | /// |
13 | /// \verbatim |
14 | /// static const int volatile x, *y, *(*(*z)[10])(const void *x); |
15 | /// ------------------------- - -- --------------------------- |
16 | /// declaration-specifiers \ | / |
17 | /// declarators |
18 | /// \endverbatim |
19 | /// |
20 | //===----------------------------------------------------------------------===// |
21 | |
22 | #ifndef LLVM_CLANG_SEMA_DECLSPEC_H |
23 | #define LLVM_CLANG_SEMA_DECLSPEC_H |
24 | |
25 | #include "clang/AST/DeclCXX.h" |
26 | #include "clang/AST/DeclObjCCommon.h" |
27 | #include "clang/AST/NestedNameSpecifier.h" |
28 | #include "clang/Basic/ExceptionSpecificationType.h" |
29 | #include "clang/Basic/Lambda.h" |
30 | #include "clang/Basic/OperatorKinds.h" |
31 | #include "clang/Basic/Specifiers.h" |
32 | #include "clang/Lex/Token.h" |
33 | #include "clang/Sema/Ownership.h" |
34 | #include "clang/Sema/ParsedAttr.h" |
35 | #include "llvm/ADT/SmallVector.h" |
36 | #include "llvm/Support/Compiler.h" |
37 | #include "llvm/Support/ErrorHandling.h" |
38 | |
39 | namespace clang { |
40 | class ASTContext; |
41 | class CXXRecordDecl; |
42 | class TypeLoc; |
43 | class LangOptions; |
44 | class IdentifierInfo; |
45 | class NamespaceAliasDecl; |
46 | class NamespaceDecl; |
47 | class ObjCDeclSpec; |
48 | class Sema; |
49 | class Declarator; |
50 | struct TemplateIdAnnotation; |
51 | |
52 | /// Represents a C++ nested-name-specifier or a global scope specifier. |
53 | /// |
54 | /// These can be in 3 states: |
55 | /// 1) Not present, identified by isEmpty() |
56 | /// 2) Present, identified by isNotEmpty() |
57 | /// 2.a) Valid, identified by isValid() |
58 | /// 2.b) Invalid, identified by isInvalid(). |
59 | /// |
60 | /// isSet() is deprecated because it mostly corresponded to "valid" but was |
61 | /// often used as if it meant "present". |
62 | /// |
63 | /// The actual scope is described by getScopeRep(). |
64 | class CXXScopeSpec { |
65 | SourceRange Range; |
66 | NestedNameSpecifierLocBuilder Builder; |
67 | |
68 | public: |
69 | SourceRange getRange() const { return Range; } |
70 | void setRange(SourceRange R) { Range = R; } |
71 | void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } |
72 | void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); } |
73 | SourceLocation getBeginLoc() const { return Range.getBegin(); } |
74 | SourceLocation getEndLoc() const { return Range.getEnd(); } |
75 | |
76 | /// Retrieve the representation of the nested-name-specifier. |
77 | NestedNameSpecifier *getScopeRep() const { |
78 | return Builder.getRepresentation(); |
79 | } |
80 | |
81 | /// Extend the current nested-name-specifier by another |
82 | /// nested-name-specifier component of the form 'type::'. |
83 | /// |
84 | /// \param Context The AST context in which this nested-name-specifier |
85 | /// resides. |
86 | /// |
87 | /// \param TemplateKWLoc The location of the 'template' keyword, if present. |
88 | /// |
89 | /// \param TL The TypeLoc that describes the type preceding the '::'. |
90 | /// |
91 | /// \param ColonColonLoc The location of the trailing '::'. |
92 | void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, |
93 | SourceLocation ColonColonLoc); |
94 | |
95 | /// Extend the current nested-name-specifier by another |
96 | /// nested-name-specifier component of the form 'identifier::'. |
97 | /// |
98 | /// \param Context The AST context in which this nested-name-specifier |
99 | /// resides. |
100 | /// |
101 | /// \param Identifier The identifier. |
102 | /// |
103 | /// \param IdentifierLoc The location of the identifier. |
104 | /// |
105 | /// \param ColonColonLoc The location of the trailing '::'. |
106 | void Extend(ASTContext &Context, IdentifierInfo *Identifier, |
107 | SourceLocation IdentifierLoc, SourceLocation ColonColonLoc); |
108 | |
109 | /// Extend the current nested-name-specifier by another |
110 | /// nested-name-specifier component of the form 'namespace::'. |
111 | /// |
112 | /// \param Context The AST context in which this nested-name-specifier |
113 | /// resides. |
114 | /// |
115 | /// \param Namespace The namespace. |
116 | /// |
117 | /// \param NamespaceLoc The location of the namespace name. |
118 | /// |
119 | /// \param ColonColonLoc The location of the trailing '::'. |
120 | void Extend(ASTContext &Context, NamespaceDecl *Namespace, |
121 | SourceLocation NamespaceLoc, SourceLocation ColonColonLoc); |
122 | |
123 | /// Extend the current nested-name-specifier by another |
124 | /// nested-name-specifier component of the form 'namespace-alias::'. |
125 | /// |
126 | /// \param Context The AST context in which this nested-name-specifier |
127 | /// resides. |
128 | /// |
129 | /// \param Alias The namespace alias. |
130 | /// |
131 | /// \param AliasLoc The location of the namespace alias |
132 | /// name. |
133 | /// |
134 | /// \param ColonColonLoc The location of the trailing '::'. |
135 | void Extend(ASTContext &Context, NamespaceAliasDecl *Alias, |
136 | SourceLocation AliasLoc, SourceLocation ColonColonLoc); |
137 | |
138 | /// Turn this (empty) nested-name-specifier into the global |
139 | /// nested-name-specifier '::'. |
140 | void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); |
141 | |
142 | /// Turns this (empty) nested-name-specifier into '__super' |
143 | /// nested-name-specifier. |
144 | /// |
145 | /// \param Context The AST context in which this nested-name-specifier |
146 | /// resides. |
147 | /// |
148 | /// \param RD The declaration of the class in which nested-name-specifier |
149 | /// appeared. |
150 | /// |
151 | /// \param SuperLoc The location of the '__super' keyword. |
152 | /// name. |
153 | /// |
154 | /// \param ColonColonLoc The location of the trailing '::'. |
155 | void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, |
156 | SourceLocation SuperLoc, SourceLocation ColonColonLoc); |
157 | |
158 | /// Make a new nested-name-specifier from incomplete source-location |
159 | /// information. |
160 | /// |
161 | /// FIXME: This routine should be used very, very rarely, in cases where we |
162 | /// need to synthesize a nested-name-specifier. Most code should instead use |
163 | /// \c Adopt() with a proper \c NestedNameSpecifierLoc. |
164 | void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, |
165 | SourceRange R); |
166 | |
167 | /// Adopt an existing nested-name-specifier (with source-range |
168 | /// information). |
169 | void Adopt(NestedNameSpecifierLoc Other); |
170 | |
171 | /// Retrieve a nested-name-specifier with location information, copied |
172 | /// into the given AST context. |
173 | /// |
174 | /// \param Context The context into which this nested-name-specifier will be |
175 | /// copied. |
176 | NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; |
177 | |
178 | /// Retrieve the location of the name in the last qualifier |
179 | /// in this nested name specifier. |
180 | /// |
181 | /// For example, the location of \c bar |
182 | /// in |
183 | /// \verbatim |
184 | /// \::foo::bar<0>:: |
185 | /// ^~~ |
186 | /// \endverbatim |
187 | SourceLocation getLastQualifierNameLoc() const; |
188 | |
189 | /// No scope specifier. |
190 | bool isEmpty() const { return Range.isInvalid() && getScopeRep() == nullptr; } |
191 | /// A scope specifier is present, but may be valid or invalid. |
192 | bool isNotEmpty() const { return !isEmpty(); } |
193 | |
194 | /// An error occurred during parsing of the scope specifier. |
195 | bool isInvalid() const { return Range.isValid() && getScopeRep() == nullptr; } |
196 | /// A scope specifier is present, and it refers to a real scope. |
197 | bool isValid() const { return getScopeRep() != nullptr; } |
198 | |
199 | /// Indicate that this nested-name-specifier is invalid. |
200 | void SetInvalid(SourceRange R) { |
201 | assert(R.isValid() && "Must have a valid source range")((void)0); |
202 | if (Range.getBegin().isInvalid()) |
203 | Range.setBegin(R.getBegin()); |
204 | Range.setEnd(R.getEnd()); |
205 | Builder.Clear(); |
206 | } |
207 | |
208 | /// Deprecated. Some call sites intend isNotEmpty() while others intend |
209 | /// isValid(). |
210 | bool isSet() const { return getScopeRep() != nullptr; } |
211 | |
212 | void clear() { |
213 | Range = SourceRange(); |
214 | Builder.Clear(); |
215 | } |
216 | |
217 | /// Retrieve the data associated with the source-location information. |
218 | char *location_data() const { return Builder.getBuffer().first; } |
219 | |
220 | /// Retrieve the size of the data associated with source-location |
221 | /// information. |
222 | unsigned location_size() const { return Builder.getBuffer().second; } |
223 | }; |
224 | |
225 | /// Captures information about "declaration specifiers". |
226 | /// |
227 | /// "Declaration specifiers" encompasses storage-class-specifiers, |
228 | /// type-specifiers, type-qualifiers, and function-specifiers. |
229 | class DeclSpec { |
230 | public: |
231 | /// storage-class-specifier |
232 | /// \note The order of these enumerators is important for diagnostics. |
233 | enum SCS { |
234 | SCS_unspecified = 0, |
235 | SCS_typedef, |
236 | SCS_extern, |
237 | SCS_static, |
238 | SCS_auto, |
239 | SCS_register, |
240 | SCS_private_extern, |
241 | SCS_mutable |
242 | }; |
243 | |
244 | // Import thread storage class specifier enumeration and constants. |
245 | // These can be combined with SCS_extern and SCS_static. |
246 | typedef ThreadStorageClassSpecifier TSCS; |
247 | static const TSCS TSCS_unspecified = clang::TSCS_unspecified; |
248 | static const TSCS TSCS___thread = clang::TSCS___thread; |
249 | static const TSCS TSCS_thread_local = clang::TSCS_thread_local; |
250 | static const TSCS TSCS__Thread_local = clang::TSCS__Thread_local; |
251 | |
252 | enum TSC { |
253 | TSC_unspecified, |
254 | TSC_imaginary, |
255 | TSC_complex |
256 | }; |
257 | |
258 | // Import type specifier type enumeration and constants. |
259 | typedef TypeSpecifierType TST; |
260 | static const TST TST_unspecified = clang::TST_unspecified; |
261 | static const TST TST_void = clang::TST_void; |
262 | static const TST TST_char = clang::TST_char; |
263 | static const TST TST_wchar = clang::TST_wchar; |
264 | static const TST TST_char8 = clang::TST_char8; |
265 | static const TST TST_char16 = clang::TST_char16; |
266 | static const TST TST_char32 = clang::TST_char32; |
267 | static const TST TST_int = clang::TST_int; |
268 | static const TST TST_int128 = clang::TST_int128; |
269 | static const TST TST_extint = clang::TST_extint; |
270 | static const TST TST_half = clang::TST_half; |
271 | static const TST TST_BFloat16 = clang::TST_BFloat16; |
272 | static const TST TST_float = clang::TST_float; |
273 | static const TST TST_double = clang::TST_double; |
274 | static const TST TST_float16 = clang::TST_Float16; |
275 | static const TST TST_accum = clang::TST_Accum; |
276 | static const TST TST_fract = clang::TST_Fract; |
277 | static const TST TST_float128 = clang::TST_float128; |
278 | static const TST TST_bool = clang::TST_bool; |
279 | static const TST TST_decimal32 = clang::TST_decimal32; |
280 | static const TST TST_decimal64 = clang::TST_decimal64; |
281 | static const TST TST_decimal128 = clang::TST_decimal128; |
282 | static const TST TST_enum = clang::TST_enum; |
283 | static const TST TST_union = clang::TST_union; |
284 | static const TST TST_struct = clang::TST_struct; |
285 | static const TST TST_interface = clang::TST_interface; |
286 | static const TST TST_class = clang::TST_class; |
287 | static const TST TST_typename = clang::TST_typename; |
288 | static const TST TST_typeofType = clang::TST_typeofType; |
289 | static const TST TST_typeofExpr = clang::TST_typeofExpr; |
290 | static const TST TST_decltype = clang::TST_decltype; |
291 | static const TST TST_decltype_auto = clang::TST_decltype_auto; |
292 | static const TST TST_underlyingType = clang::TST_underlyingType; |
293 | static const TST TST_auto = clang::TST_auto; |
294 | static const TST TST_auto_type = clang::TST_auto_type; |
295 | static const TST TST_unknown_anytype = clang::TST_unknown_anytype; |
296 | static const TST TST_atomic = clang::TST_atomic; |
297 | #define GENERIC_IMAGE_TYPE(ImgType, Id) \ |
298 | static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t; |
299 | #include "clang/Basic/OpenCLImageTypes.def" |
300 | static const TST TST_error = clang::TST_error; |
301 | |
302 | // type-qualifiers |
303 | enum TQ { // NOTE: These flags must be kept in sync with Qualifiers::TQ. |
304 | TQ_unspecified = 0, |
305 | TQ_const = 1, |
306 | TQ_restrict = 2, |
307 | TQ_volatile = 4, |
308 | TQ_unaligned = 8, |
309 | // This has no corresponding Qualifiers::TQ value, because it's not treated |
310 | // as a qualifier in our type system. |
311 | TQ_atomic = 16 |
312 | }; |
313 | |
314 | /// ParsedSpecifiers - Flags to query which specifiers were applied. This is |
315 | /// returned by getParsedSpecifiers. |
316 | enum ParsedSpecifiers { |
317 | PQ_None = 0, |
318 | PQ_StorageClassSpecifier = 1, |
319 | PQ_TypeSpecifier = 2, |
320 | PQ_TypeQualifier = 4, |
321 | PQ_FunctionSpecifier = 8 |
322 | // FIXME: Attributes should be included here. |
323 | }; |
324 | |
325 | private: |
326 | // storage-class-specifier |
327 | /*SCS*/unsigned StorageClassSpec : 3; |
328 | /*TSCS*/unsigned ThreadStorageClassSpec : 2; |
329 | unsigned SCS_extern_in_linkage_spec : 1; |
330 | |
331 | // type-specifier |
332 | /*TypeSpecifierWidth*/ unsigned TypeSpecWidth : 2; |
333 | /*TSC*/unsigned TypeSpecComplex : 2; |
334 | /*TSS*/unsigned TypeSpecSign : 2; |
335 | /*TST*/unsigned TypeSpecType : 6; |
336 | unsigned TypeAltiVecVector : 1; |
337 | unsigned TypeAltiVecPixel : 1; |
338 | unsigned TypeAltiVecBool : 1; |
339 | unsigned TypeSpecOwned : 1; |
340 | unsigned TypeSpecPipe : 1; |
341 | unsigned TypeSpecSat : 1; |
342 | unsigned ConstrainedAuto : 1; |
343 | |
344 | // type-qualifiers |
345 | unsigned TypeQualifiers : 5; // Bitwise OR of TQ. |
346 | |
347 | // function-specifier |
348 | unsigned FS_inline_specified : 1; |
349 | unsigned FS_forceinline_specified: 1; |
350 | unsigned FS_virtual_specified : 1; |
351 | unsigned FS_noreturn_specified : 1; |
352 | |
353 | // friend-specifier |
354 | unsigned Friend_specified : 1; |
355 | |
356 | // constexpr-specifier |
357 | unsigned ConstexprSpecifier : 2; |
358 | |
359 | union { |
360 | UnionParsedType TypeRep; |
361 | Decl *DeclRep; |
362 | Expr *ExprRep; |
363 | TemplateIdAnnotation *TemplateIdRep; |
364 | }; |
365 | |
366 | /// ExplicitSpecifier - Store information about explicit spicifer. |
367 | ExplicitSpecifier FS_explicit_specifier; |
368 | |
369 | // attributes. |
370 | ParsedAttributes Attrs; |
371 | |
372 | // Scope specifier for the type spec, if applicable. |
373 | CXXScopeSpec TypeScope; |
374 | |
375 | // SourceLocation info. These are null if the item wasn't specified or if |
376 | // the setting was synthesized. |
377 | SourceRange Range; |
378 | |
379 | SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc; |
380 | SourceRange TSWRange; |
381 | SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc, TSSatLoc; |
382 | /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, |
383 | /// typename, then this is the location of the named type (if present); |
384 | /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and |
385 | /// TSTNameLoc provides source range info for tag types. |
386 | SourceLocation TSTNameLoc; |
387 | SourceRange TypeofParensRange; |
388 | SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc, |
389 | TQ_unalignedLoc; |
390 | SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; |
391 | SourceLocation FS_explicitCloseParenLoc; |
392 | SourceLocation FS_forceinlineLoc; |
393 | SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; |
394 | SourceLocation TQ_pipeLoc; |
395 | |
396 | WrittenBuiltinSpecs writtenBS; |
397 | void SaveWrittenBuiltinSpecs(); |
398 | |
399 | ObjCDeclSpec *ObjCQualifiers; |
400 | |
401 | static bool isTypeRep(TST T) { |
402 | return (T == TST_typename || T == TST_typeofType || |
403 | T == TST_underlyingType || T == TST_atomic); |
404 | } |
405 | static bool isExprRep(TST T) { |
406 | return (T == TST_typeofExpr || T == TST_decltype || T == TST_extint); |
407 | } |
408 | static bool isTemplateIdRep(TST T) { |
409 | return (T == TST_auto || T == TST_decltype_auto); |
410 | } |
411 | |
412 | DeclSpec(const DeclSpec &) = delete; |
413 | void operator=(const DeclSpec &) = delete; |
414 | public: |
415 | static bool isDeclRep(TST T) { |
416 | return (T == TST_enum || T == TST_struct || |
417 | T == TST_interface || T == TST_union || |
418 | T == TST_class); |
419 | } |
420 | |
421 | DeclSpec(AttributeFactory &attrFactory) |
422 | : StorageClassSpec(SCS_unspecified), |
423 | ThreadStorageClassSpec(TSCS_unspecified), |
424 | SCS_extern_in_linkage_spec(false), |
425 | TypeSpecWidth(static_cast<unsigned>(TypeSpecifierWidth::Unspecified)), |
426 | TypeSpecComplex(TSC_unspecified), |
427 | TypeSpecSign(static_cast<unsigned>(TypeSpecifierSign::Unspecified)), |
428 | TypeSpecType(TST_unspecified), TypeAltiVecVector(false), |
429 | TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false), |
430 | TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false), |
431 | TypeQualifiers(TQ_unspecified), FS_inline_specified(false), |
432 | FS_forceinline_specified(false), FS_virtual_specified(false), |
433 | FS_noreturn_specified(false), Friend_specified(false), |
434 | ConstexprSpecifier( |
435 | static_cast<unsigned>(ConstexprSpecKind::Unspecified)), |
436 | FS_explicit_specifier(), Attrs(attrFactory), writtenBS(), |
437 | ObjCQualifiers(nullptr) {} |
438 | |
439 | // storage-class-specifier |
440 | SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } |
441 | TSCS getThreadStorageClassSpec() const { |
442 | return (TSCS)ThreadStorageClassSpec; |
443 | } |
444 | bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; } |
445 | void setExternInLinkageSpec(bool Value) { |
446 | SCS_extern_in_linkage_spec = Value; |
447 | } |
448 | |
449 | SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; } |
450 | SourceLocation getThreadStorageClassSpecLoc() const { |
451 | return ThreadStorageClassSpecLoc; |
452 | } |
453 | |
454 | void ClearStorageClassSpecs() { |
455 | StorageClassSpec = DeclSpec::SCS_unspecified; |
456 | ThreadStorageClassSpec = DeclSpec::TSCS_unspecified; |
457 | SCS_extern_in_linkage_spec = false; |
458 | StorageClassSpecLoc = SourceLocation(); |
459 | ThreadStorageClassSpecLoc = SourceLocation(); |
460 | } |
461 | |
462 | void ClearTypeSpecType() { |
463 | TypeSpecType = DeclSpec::TST_unspecified; |
464 | TypeSpecOwned = false; |
465 | TSTLoc = SourceLocation(); |
466 | } |
467 | |
468 | // type-specifier |
469 | TypeSpecifierWidth getTypeSpecWidth() const { |
470 | return static_cast<TypeSpecifierWidth>(TypeSpecWidth); |
471 | } |
472 | TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; } |
473 | TypeSpecifierSign getTypeSpecSign() const { |
474 | return static_cast<TypeSpecifierSign>(TypeSpecSign); |
475 | } |
476 | TST getTypeSpecType() const { return (TST)TypeSpecType; } |
477 | bool isTypeAltiVecVector() const { return TypeAltiVecVector; } |
478 | bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; } |
479 | bool isTypeAltiVecBool() const { return TypeAltiVecBool; } |
480 | bool isTypeSpecOwned() const { return TypeSpecOwned; } |
481 | bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); } |
482 | bool isTypeSpecPipe() const { return TypeSpecPipe; } |
483 | bool isTypeSpecSat() const { return TypeSpecSat; } |
484 | bool isConstrainedAuto() const { return ConstrainedAuto; } |
485 | |
486 | ParsedType getRepAsType() const { |
487 | assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type")((void)0); |
488 | return TypeRep; |
489 | } |
490 | Decl *getRepAsDecl() const { |
491 | assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl")((void)0); |
492 | return DeclRep; |
493 | } |
494 | Expr *getRepAsExpr() const { |
495 | assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr")((void)0); |
496 | return ExprRep; |
497 | } |
498 | TemplateIdAnnotation *getRepAsTemplateId() const { |
499 | assert(isTemplateIdRep((TST) TypeSpecType) &&((void)0) |
500 | "DeclSpec does not store a template id")((void)0); |
501 | return TemplateIdRep; |
502 | } |
503 | CXXScopeSpec &getTypeSpecScope() { return TypeScope; } |
504 | const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } |
505 | |
506 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { return Range; } |
507 | SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) { return Range.getBegin(); } |
508 | SourceLocation getEndLoc() const LLVM_READONLY__attribute__((__pure__)) { return Range.getEnd(); } |
509 | |
510 | SourceLocation getTypeSpecWidthLoc() const { return TSWRange.getBegin(); } |
511 | SourceRange getTypeSpecWidthRange() const { return TSWRange; } |
512 | SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; } |
513 | SourceLocation getTypeSpecSignLoc() const { return TSSLoc; } |
514 | SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } |
515 | SourceLocation getAltiVecLoc() const { return AltiVecLoc; } |
516 | SourceLocation getTypeSpecSatLoc() const { return TSSatLoc; } |
517 | |
518 | SourceLocation getTypeSpecTypeNameLoc() const { |
519 | assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename)((void)0); |
520 | return TSTNameLoc; |
521 | } |
522 | |
523 | SourceRange getTypeofParensRange() const { return TypeofParensRange; } |
524 | void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } |
525 | |
526 | bool hasAutoTypeSpec() const { |
527 | return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type || |
528 | TypeSpecType == TST_decltype_auto); |
529 | } |
530 | |
531 | bool hasTagDefinition() const; |
532 | |
533 | /// Turn a type-specifier-type into a string like "_Bool" or "union". |
534 | static const char *getSpecifierName(DeclSpec::TST T, |
535 | const PrintingPolicy &Policy); |
536 | static const char *getSpecifierName(DeclSpec::TQ Q); |
537 | static const char *getSpecifierName(TypeSpecifierSign S); |
538 | static const char *getSpecifierName(DeclSpec::TSC C); |
539 | static const char *getSpecifierName(TypeSpecifierWidth W); |
540 | static const char *getSpecifierName(DeclSpec::SCS S); |
541 | static const char *getSpecifierName(DeclSpec::TSCS S); |
542 | static const char *getSpecifierName(ConstexprSpecKind C); |
543 | |
544 | // type-qualifiers |
545 | |
546 | /// getTypeQualifiers - Return a set of TQs. |
547 | unsigned getTypeQualifiers() const { return TypeQualifiers; } |
548 | SourceLocation getConstSpecLoc() const { return TQ_constLoc; } |
549 | SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } |
550 | SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } |
551 | SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } |
552 | SourceLocation getUnalignedSpecLoc() const { return TQ_unalignedLoc; } |
553 | SourceLocation getPipeLoc() const { return TQ_pipeLoc; } |
554 | |
555 | /// Clear out all of the type qualifiers. |
556 | void ClearTypeQualifiers() { |
557 | TypeQualifiers = 0; |
558 | TQ_constLoc = SourceLocation(); |
559 | TQ_restrictLoc = SourceLocation(); |
560 | TQ_volatileLoc = SourceLocation(); |
561 | TQ_atomicLoc = SourceLocation(); |
562 | TQ_unalignedLoc = SourceLocation(); |
563 | TQ_pipeLoc = SourceLocation(); |
564 | } |
565 | |
566 | // function-specifier |
567 | bool isInlineSpecified() const { |
568 | return FS_inline_specified | FS_forceinline_specified; |
569 | } |
570 | SourceLocation getInlineSpecLoc() const { |
571 | return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc; |
572 | } |
573 | |
574 | ExplicitSpecifier getExplicitSpecifier() const { |
575 | return FS_explicit_specifier; |
576 | } |
577 | |
578 | bool isVirtualSpecified() const { return FS_virtual_specified; } |
579 | SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; } |
580 | |
581 | bool hasExplicitSpecifier() const { |
582 | return FS_explicit_specifier.isSpecified(); |
583 | } |
584 | SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; } |
585 | SourceRange getExplicitSpecRange() const { |
586 | return FS_explicit_specifier.getExpr() |
587 | ? SourceRange(FS_explicitLoc, FS_explicitCloseParenLoc) |
588 | : SourceRange(FS_explicitLoc); |
589 | } |
590 | |
591 | bool isNoreturnSpecified() const { return FS_noreturn_specified; } |
592 | SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; } |
593 | |
594 | void ClearFunctionSpecs() { |
595 | FS_inline_specified = false; |
596 | FS_inlineLoc = SourceLocation(); |
597 | FS_forceinline_specified = false; |
598 | FS_forceinlineLoc = SourceLocation(); |
599 | FS_virtual_specified = false; |
600 | FS_virtualLoc = SourceLocation(); |
601 | FS_explicit_specifier = ExplicitSpecifier(); |
602 | FS_explicitLoc = SourceLocation(); |
603 | FS_explicitCloseParenLoc = SourceLocation(); |
604 | FS_noreturn_specified = false; |
605 | FS_noreturnLoc = SourceLocation(); |
606 | } |
607 | |
608 | /// This method calls the passed in handler on each CVRU qual being |
609 | /// set. |
610 | /// Handle - a handler to be invoked. |
611 | void forEachCVRUQualifier( |
612 | llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle); |
613 | |
614 | /// This method calls the passed in handler on each qual being |
615 | /// set. |
616 | /// Handle - a handler to be invoked. |
617 | void forEachQualifier( |
618 | llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle); |
619 | |
620 | /// Return true if any type-specifier has been found. |
621 | bool hasTypeSpecifier() const { |
622 | return getTypeSpecType() != DeclSpec::TST_unspecified || |
623 | getTypeSpecWidth() != TypeSpecifierWidth::Unspecified || |
624 | getTypeSpecComplex() != DeclSpec::TSC_unspecified || |
625 | getTypeSpecSign() != TypeSpecifierSign::Unspecified; |
626 | } |
627 | |
628 | /// Return a bitmask of which flavors of specifiers this |
629 | /// DeclSpec includes. |
630 | unsigned getParsedSpecifiers() const; |
631 | |
632 | /// isEmpty - Return true if this declaration specifier is completely empty: |
633 | /// no tokens were parsed in the production of it. |
634 | bool isEmpty() const { |
635 | return getParsedSpecifiers() == DeclSpec::PQ_None; |
636 | } |
637 | |
638 | void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); } |
639 | void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); } |
640 | |
641 | /// These methods set the specified attribute of the DeclSpec and |
642 | /// return false if there was no error. If an error occurs (for |
643 | /// example, if we tried to set "auto" on a spec with "extern" |
644 | /// already set), they return true and set PrevSpec and DiagID |
645 | /// such that |
646 | /// Diag(Loc, DiagID) << PrevSpec; |
647 | /// will yield a useful result. |
648 | /// |
649 | /// TODO: use a more general approach that still allows these |
650 | /// diagnostics to be ignored when desired. |
651 | bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, |
652 | const char *&PrevSpec, unsigned &DiagID, |
653 | const PrintingPolicy &Policy); |
654 | bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, |
655 | const char *&PrevSpec, unsigned &DiagID); |
656 | bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, |
657 | const char *&PrevSpec, unsigned &DiagID, |
658 | const PrintingPolicy &Policy); |
659 | bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, |
660 | unsigned &DiagID); |
661 | bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, |
662 | const char *&PrevSpec, unsigned &DiagID); |
663 | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
664 | unsigned &DiagID, const PrintingPolicy &Policy); |
665 | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
666 | unsigned &DiagID, ParsedType Rep, |
667 | const PrintingPolicy &Policy); |
668 | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
669 | unsigned &DiagID, TypeResult Rep, |
670 | const PrintingPolicy &Policy) { |
671 | if (Rep.isInvalid()) |
672 | return SetTypeSpecError(); |
673 | return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Rep.get(), Policy); |
674 | } |
675 | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
676 | unsigned &DiagID, Decl *Rep, bool Owned, |
677 | const PrintingPolicy &Policy); |
678 | bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, |
679 | SourceLocation TagNameLoc, const char *&PrevSpec, |
680 | unsigned &DiagID, ParsedType Rep, |
681 | const PrintingPolicy &Policy); |
682 | bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, |
683 | SourceLocation TagNameLoc, const char *&PrevSpec, |
684 | unsigned &DiagID, Decl *Rep, bool Owned, |
685 | const PrintingPolicy &Policy); |
686 | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
687 | unsigned &DiagID, TemplateIdAnnotation *Rep, |
688 | const PrintingPolicy &Policy); |
689 | |
690 | bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, |
691 | unsigned &DiagID, Expr *Rep, |
692 | const PrintingPolicy &policy); |
693 | bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, |
694 | const char *&PrevSpec, unsigned &DiagID, |
695 | const PrintingPolicy &Policy); |
696 | bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, |
697 | const char *&PrevSpec, unsigned &DiagID, |
698 | const PrintingPolicy &Policy); |
699 | bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, |
700 | const char *&PrevSpec, unsigned &DiagID, |
701 | const PrintingPolicy &Policy); |
702 | bool SetTypePipe(bool isPipe, SourceLocation Loc, |
703 | const char *&PrevSpec, unsigned &DiagID, |
704 | const PrintingPolicy &Policy); |
705 | bool SetExtIntType(SourceLocation KWLoc, Expr *BitWidth, |
706 | const char *&PrevSpec, unsigned &DiagID, |
707 | const PrintingPolicy &Policy); |
708 | bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, |
709 | unsigned &DiagID); |
710 | bool SetTypeSpecError(); |
711 | void UpdateDeclRep(Decl *Rep) { |
712 | assert(isDeclRep((TST) TypeSpecType))((void)0); |
713 | DeclRep = Rep; |
714 | } |
715 | void UpdateTypeRep(ParsedType Rep) { |
716 | assert(isTypeRep((TST) TypeSpecType))((void)0); |
717 | TypeRep = Rep; |
718 | } |
719 | void UpdateExprRep(Expr *Rep) { |
720 | assert(isExprRep((TST) TypeSpecType))((void)0); |
721 | ExprRep = Rep; |
722 | } |
723 | |
724 | bool SetTypeQual(TQ T, SourceLocation Loc); |
725 | |
726 | bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, |
727 | unsigned &DiagID, const LangOptions &Lang); |
728 | |
729 | bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, |
730 | unsigned &DiagID); |
731 | bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, |
732 | unsigned &DiagID); |
733 | bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, |
734 | unsigned &DiagID); |
735 | bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, |
736 | unsigned &DiagID, ExplicitSpecifier ExplicitSpec, |
737 | SourceLocation CloseParenLoc); |
738 | bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, |
739 | unsigned &DiagID); |
740 | |
741 | bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, |
742 | unsigned &DiagID); |
743 | bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, |
744 | unsigned &DiagID); |
745 | bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, |
746 | const char *&PrevSpec, unsigned &DiagID); |
747 | |
748 | bool isFriendSpecified() const { return Friend_specified; } |
749 | SourceLocation getFriendSpecLoc() const { return FriendLoc; } |
750 | |
751 | bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); } |
752 | SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; } |
753 | |
754 | ConstexprSpecKind getConstexprSpecifier() const { |
755 | return ConstexprSpecKind(ConstexprSpecifier); |
756 | } |
757 | |
758 | SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } |
759 | bool hasConstexprSpecifier() const { |
760 | return getConstexprSpecifier() != ConstexprSpecKind::Unspecified; |
761 | } |
762 | |
763 | void ClearConstexprSpec() { |
764 | ConstexprSpecifier = static_cast<unsigned>(ConstexprSpecKind::Unspecified); |
765 | ConstexprLoc = SourceLocation(); |
766 | } |
767 | |
768 | AttributePool &getAttributePool() const { |
769 | return Attrs.getPool(); |
770 | } |
771 | |
772 | /// Concatenates two attribute lists. |
773 | /// |
774 | /// The GCC attribute syntax allows for the following: |
775 | /// |
776 | /// \code |
777 | /// short __attribute__(( unused, deprecated )) |
778 | /// int __attribute__(( may_alias, aligned(16) )) var; |
779 | /// \endcode |
780 | /// |
781 | /// This declares 4 attributes using 2 lists. The following syntax is |
782 | /// also allowed and equivalent to the previous declaration. |
783 | /// |
784 | /// \code |
785 | /// short __attribute__((unused)) __attribute__((deprecated)) |
786 | /// int __attribute__((may_alias)) __attribute__((aligned(16))) var; |
787 | /// \endcode |
788 | /// |
789 | void addAttributes(ParsedAttributesView &AL) { |
790 | Attrs.addAll(AL.begin(), AL.end()); |
791 | } |
792 | |
793 | bool hasAttributes() const { return !Attrs.empty(); } |
794 | |
795 | ParsedAttributes &getAttributes() { return Attrs; } |
796 | const ParsedAttributes &getAttributes() const { return Attrs; } |
797 | |
798 | void takeAttributesFrom(ParsedAttributes &attrs) { |
799 | Attrs.takeAllFrom(attrs); |
800 | } |
801 | |
802 | /// Finish - This does final analysis of the declspec, issuing diagnostics for |
803 | /// things like "_Imaginary" (lacking an FP type). After calling this method, |
804 | /// DeclSpec is guaranteed self-consistent, even if an error occurred. |
805 | void Finish(Sema &S, const PrintingPolicy &Policy); |
806 | |
807 | const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { |
808 | return writtenBS; |
809 | } |
810 | |
811 | ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; } |
812 | void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; } |
813 | |
814 | /// Checks if this DeclSpec can stand alone, without a Declarator. |
815 | /// |
816 | /// Only tag declspecs can stand alone. |
817 | bool isMissingDeclaratorOk(); |
818 | }; |
819 | |
820 | /// Captures information about "declaration specifiers" specific to |
821 | /// Objective-C. |
822 | class ObjCDeclSpec { |
823 | public: |
824 | /// ObjCDeclQualifier - Qualifier used on types in method |
825 | /// declarations. Not all combinations are sensible. Parameters |
826 | /// can be one of { in, out, inout } with one of { bycopy, byref }. |
827 | /// Returns can either be { oneway } or not. |
828 | /// |
829 | /// This should be kept in sync with Decl::ObjCDeclQualifier. |
830 | enum ObjCDeclQualifier { |
831 | DQ_None = 0x0, |
832 | DQ_In = 0x1, |
833 | DQ_Inout = 0x2, |
834 | DQ_Out = 0x4, |
835 | DQ_Bycopy = 0x8, |
836 | DQ_Byref = 0x10, |
837 | DQ_Oneway = 0x20, |
838 | DQ_CSNullability = 0x40 |
839 | }; |
840 | |
841 | ObjCDeclSpec() |
842 | : objcDeclQualifier(DQ_None), |
843 | PropertyAttributes(ObjCPropertyAttribute::kind_noattr), Nullability(0), |
844 | GetterName(nullptr), SetterName(nullptr) {} |
845 | |
846 | ObjCDeclQualifier getObjCDeclQualifier() const { |
847 | return (ObjCDeclQualifier)objcDeclQualifier; |
848 | } |
849 | void setObjCDeclQualifier(ObjCDeclQualifier DQVal) { |
850 | objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); |
851 | } |
852 | void clearObjCDeclQualifier(ObjCDeclQualifier DQVal) { |
853 | objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier & ~DQVal); |
854 | } |
855 | |
856 | ObjCPropertyAttribute::Kind getPropertyAttributes() const { |
857 | return ObjCPropertyAttribute::Kind(PropertyAttributes); |
858 | } |
859 | void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) { |
860 | PropertyAttributes = |
861 | (ObjCPropertyAttribute::Kind)(PropertyAttributes | PRVal); |
862 | } |
863 | |
864 | NullabilityKind getNullability() const { |
865 | assert(((void)0) |
866 | ((getObjCDeclQualifier() & DQ_CSNullability) ||((void)0) |
867 | (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) &&((void)0) |
868 | "Objective-C declspec doesn't have nullability")((void)0); |
869 | return static_cast<NullabilityKind>(Nullability); |
870 | } |
871 | |
872 | SourceLocation getNullabilityLoc() const { |
873 | assert(((void)0) |
874 | ((getObjCDeclQualifier() & DQ_CSNullability) ||((void)0) |
875 | (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) &&((void)0) |
876 | "Objective-C declspec doesn't have nullability")((void)0); |
877 | return NullabilityLoc; |
878 | } |
879 | |
880 | void setNullability(SourceLocation loc, NullabilityKind kind) { |
881 | assert(((void)0) |
882 | ((getObjCDeclQualifier() & DQ_CSNullability) ||((void)0) |
883 | (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) &&((void)0) |
884 | "Set the nullability declspec or property attribute first")((void)0); |
885 | Nullability = static_cast<unsigned>(kind); |
886 | NullabilityLoc = loc; |
887 | } |
888 | |
889 | const IdentifierInfo *getGetterName() const { return GetterName; } |
890 | IdentifierInfo *getGetterName() { return GetterName; } |
891 | SourceLocation getGetterNameLoc() const { return GetterNameLoc; } |
892 | void setGetterName(IdentifierInfo *name, SourceLocation loc) { |
893 | GetterName = name; |
894 | GetterNameLoc = loc; |
895 | } |
896 | |
897 | const IdentifierInfo *getSetterName() const { return SetterName; } |
898 | IdentifierInfo *getSetterName() { return SetterName; } |
899 | SourceLocation getSetterNameLoc() const { return SetterNameLoc; } |
900 | void setSetterName(IdentifierInfo *name, SourceLocation loc) { |
901 | SetterName = name; |
902 | SetterNameLoc = loc; |
903 | } |
904 | |
905 | private: |
906 | // FIXME: These two are unrelated and mutually exclusive. So perhaps |
907 | // we can put them in a union to reflect their mutual exclusivity |
908 | // (space saving is negligible). |
909 | unsigned objcDeclQualifier : 7; |
910 | |
911 | // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttribute::Kind |
912 | unsigned PropertyAttributes : NumObjCPropertyAttrsBits; |
913 | |
914 | unsigned Nullability : 2; |
915 | |
916 | SourceLocation NullabilityLoc; |
917 | |
918 | IdentifierInfo *GetterName; // getter name or NULL if no getter |
919 | IdentifierInfo *SetterName; // setter name or NULL if no setter |
920 | SourceLocation GetterNameLoc; // location of the getter attribute's value |
921 | SourceLocation SetterNameLoc; // location of the setter attribute's value |
922 | |
923 | }; |
924 | |
925 | /// Describes the kind of unqualified-id parsed. |
926 | enum class UnqualifiedIdKind { |
927 | /// An identifier. |
928 | IK_Identifier, |
929 | /// An overloaded operator name, e.g., operator+. |
930 | IK_OperatorFunctionId, |
931 | /// A conversion function name, e.g., operator int. |
932 | IK_ConversionFunctionId, |
933 | /// A user-defined literal name, e.g., operator "" _i. |
934 | IK_LiteralOperatorId, |
935 | /// A constructor name. |
936 | IK_ConstructorName, |
937 | /// A constructor named via a template-id. |
938 | IK_ConstructorTemplateId, |
939 | /// A destructor name. |
940 | IK_DestructorName, |
941 | /// A template-id, e.g., f<int>. |
942 | IK_TemplateId, |
943 | /// An implicit 'self' parameter |
944 | IK_ImplicitSelfParam, |
945 | /// A deduction-guide name (a template-name) |
946 | IK_DeductionGuideName |
947 | }; |
948 | |
949 | /// Represents a C++ unqualified-id that has been parsed. |
950 | class UnqualifiedId { |
951 | private: |
952 | UnqualifiedId(const UnqualifiedId &Other) = delete; |
953 | const UnqualifiedId &operator=(const UnqualifiedId &) = delete; |
954 | |
955 | public: |
956 | /// Describes the kind of unqualified-id parsed. |
957 | UnqualifiedIdKind Kind; |
958 | |
959 | struct OFI { |
960 | /// The kind of overloaded operator. |
961 | OverloadedOperatorKind Operator; |
962 | |
963 | /// The source locations of the individual tokens that name |
964 | /// the operator, e.g., the "new", "[", and "]" tokens in |
965 | /// operator new []. |
966 | /// |
967 | /// Different operators have different numbers of tokens in their name, |
968 | /// up to three. Any remaining source locations in this array will be |
969 | /// set to an invalid value for operators with fewer than three tokens. |
970 | SourceLocation SymbolLocations[3]; |
971 | }; |
972 | |
973 | /// Anonymous union that holds extra data associated with the |
974 | /// parsed unqualified-id. |
975 | union { |
976 | /// When Kind == IK_Identifier, the parsed identifier, or when |
977 | /// Kind == IK_UserLiteralId, the identifier suffix. |
978 | IdentifierInfo *Identifier; |
979 | |
980 | /// When Kind == IK_OperatorFunctionId, the overloaded operator |
981 | /// that we parsed. |
982 | struct OFI OperatorFunctionId; |
983 | |
984 | /// When Kind == IK_ConversionFunctionId, the type that the |
985 | /// conversion function names. |
986 | UnionParsedType ConversionFunctionId; |
987 | |
988 | /// When Kind == IK_ConstructorName, the class-name of the type |
989 | /// whose constructor is being referenced. |
990 | UnionParsedType ConstructorName; |
991 | |
992 | /// When Kind == IK_DestructorName, the type referred to by the |
993 | /// class-name. |
994 | UnionParsedType DestructorName; |
995 | |
996 | /// When Kind == IK_DeductionGuideName, the parsed template-name. |
997 | UnionParsedTemplateTy TemplateName; |
998 | |
999 | /// When Kind == IK_TemplateId or IK_ConstructorTemplateId, |
1000 | /// the template-id annotation that contains the template name and |
1001 | /// template arguments. |
1002 | TemplateIdAnnotation *TemplateId; |
1003 | }; |
1004 | |
1005 | /// The location of the first token that describes this unqualified-id, |
1006 | /// which will be the location of the identifier, "operator" keyword, |
1007 | /// tilde (for a destructor), or the template name of a template-id. |
1008 | SourceLocation StartLocation; |
1009 | |
1010 | /// The location of the last token that describes this unqualified-id. |
1011 | SourceLocation EndLocation; |
1012 | |
1013 | UnqualifiedId() |
1014 | : Kind(UnqualifiedIdKind::IK_Identifier), Identifier(nullptr) {} |
1015 | |
1016 | /// Clear out this unqualified-id, setting it to default (invalid) |
1017 | /// state. |
1018 | void clear() { |
1019 | Kind = UnqualifiedIdKind::IK_Identifier; |
1020 | Identifier = nullptr; |
1021 | StartLocation = SourceLocation(); |
1022 | EndLocation = SourceLocation(); |
1023 | } |
1024 | |
1025 | /// Determine whether this unqualified-id refers to a valid name. |
1026 | bool isValid() const { return StartLocation.isValid(); } |
1027 | |
1028 | /// Determine whether this unqualified-id refers to an invalid name. |
1029 | bool isInvalid() const { return !isValid(); } |
1030 | |
1031 | /// Determine what kind of name we have. |
1032 | UnqualifiedIdKind getKind() const { return Kind; } |
1033 | |
1034 | /// Specify that this unqualified-id was parsed as an identifier. |
1035 | /// |
1036 | /// \param Id the parsed identifier. |
1037 | /// \param IdLoc the location of the parsed identifier. |
1038 | void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) { |
1039 | Kind = UnqualifiedIdKind::IK_Identifier; |
1040 | Identifier = const_cast<IdentifierInfo *>(Id); |
1041 | StartLocation = EndLocation = IdLoc; |
1042 | } |
1043 | |
1044 | /// Specify that this unqualified-id was parsed as an |
1045 | /// operator-function-id. |
1046 | /// |
1047 | /// \param OperatorLoc the location of the 'operator' keyword. |
1048 | /// |
1049 | /// \param Op the overloaded operator. |
1050 | /// |
1051 | /// \param SymbolLocations the locations of the individual operator symbols |
1052 | /// in the operator. |
1053 | void setOperatorFunctionId(SourceLocation OperatorLoc, |
1054 | OverloadedOperatorKind Op, |
1055 | SourceLocation SymbolLocations[3]); |
1056 | |
1057 | /// Specify that this unqualified-id was parsed as a |
1058 | /// conversion-function-id. |
1059 | /// |
1060 | /// \param OperatorLoc the location of the 'operator' keyword. |
1061 | /// |
1062 | /// \param Ty the type to which this conversion function is converting. |
1063 | /// |
1064 | /// \param EndLoc the location of the last token that makes up the type name. |
1065 | void setConversionFunctionId(SourceLocation OperatorLoc, |
1066 | ParsedType Ty, |
1067 | SourceLocation EndLoc) { |
1068 | Kind = UnqualifiedIdKind::IK_ConversionFunctionId; |
1069 | StartLocation = OperatorLoc; |
1070 | EndLocation = EndLoc; |
1071 | ConversionFunctionId = Ty; |
1072 | } |
1073 | |
1074 | /// Specific that this unqualified-id was parsed as a |
1075 | /// literal-operator-id. |
1076 | /// |
1077 | /// \param Id the parsed identifier. |
1078 | /// |
1079 | /// \param OpLoc the location of the 'operator' keyword. |
1080 | /// |
1081 | /// \param IdLoc the location of the identifier. |
1082 | void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc, |
1083 | SourceLocation IdLoc) { |
1084 | Kind = UnqualifiedIdKind::IK_LiteralOperatorId; |
1085 | Identifier = const_cast<IdentifierInfo *>(Id); |
1086 | StartLocation = OpLoc; |
1087 | EndLocation = IdLoc; |
1088 | } |
1089 | |
1090 | /// Specify that this unqualified-id was parsed as a constructor name. |
1091 | /// |
1092 | /// \param ClassType the class type referred to by the constructor name. |
1093 | /// |
1094 | /// \param ClassNameLoc the location of the class name. |
1095 | /// |
1096 | /// \param EndLoc the location of the last token that makes up the type name. |
1097 | void setConstructorName(ParsedType ClassType, |
1098 | SourceLocation ClassNameLoc, |
1099 | SourceLocation EndLoc) { |
1100 | Kind = UnqualifiedIdKind::IK_ConstructorName; |
1101 | StartLocation = ClassNameLoc; |
1102 | EndLocation = EndLoc; |
1103 | ConstructorName = ClassType; |
1104 | } |
1105 | |
1106 | /// Specify that this unqualified-id was parsed as a |
1107 | /// template-id that names a constructor. |
1108 | /// |
1109 | /// \param TemplateId the template-id annotation that describes the parsed |
1110 | /// template-id. This UnqualifiedId instance will take ownership of the |
1111 | /// \p TemplateId and will free it on destruction. |
1112 | void setConstructorTemplateId(TemplateIdAnnotation *TemplateId); |
1113 | |
1114 | /// Specify that this unqualified-id was parsed as a destructor name. |
1115 | /// |
1116 | /// \param TildeLoc the location of the '~' that introduces the destructor |
1117 | /// name. |
1118 | /// |
1119 | /// \param ClassType the name of the class referred to by the destructor name. |
1120 | void setDestructorName(SourceLocation TildeLoc, |
1121 | ParsedType ClassType, |
1122 | SourceLocation EndLoc) { |
1123 | Kind = UnqualifiedIdKind::IK_DestructorName; |
1124 | StartLocation = TildeLoc; |
1125 | EndLocation = EndLoc; |
1126 | DestructorName = ClassType; |
1127 | } |
1128 | |
1129 | /// Specify that this unqualified-id was parsed as a template-id. |
1130 | /// |
1131 | /// \param TemplateId the template-id annotation that describes the parsed |
1132 | /// template-id. This UnqualifiedId instance will take ownership of the |
1133 | /// \p TemplateId and will free it on destruction. |
1134 | void setTemplateId(TemplateIdAnnotation *TemplateId); |
1135 | |
1136 | /// Specify that this unqualified-id was parsed as a template-name for |
1137 | /// a deduction-guide. |
1138 | /// |
1139 | /// \param Template The parsed template-name. |
1140 | /// \param TemplateLoc The location of the parsed template-name. |
1141 | void setDeductionGuideName(ParsedTemplateTy Template, |
1142 | SourceLocation TemplateLoc) { |
1143 | Kind = UnqualifiedIdKind::IK_DeductionGuideName; |
1144 | TemplateName = Template; |
1145 | StartLocation = EndLocation = TemplateLoc; |
1146 | } |
1147 | |
1148 | /// Specify that this unqualified-id is an implicit 'self' |
1149 | /// parameter. |
1150 | /// |
1151 | /// \param Id the identifier. |
1152 | void setImplicitSelfParam(const IdentifierInfo *Id) { |
1153 | Kind = UnqualifiedIdKind::IK_ImplicitSelfParam; |
1154 | Identifier = const_cast<IdentifierInfo *>(Id); |
1155 | StartLocation = EndLocation = SourceLocation(); |
1156 | } |
1157 | |
1158 | /// Return the source range that covers this unqualified-id. |
1159 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { |
1160 | return SourceRange(StartLocation, EndLocation); |
1161 | } |
1162 | SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) { return StartLocation; } |
1163 | SourceLocation getEndLoc() const LLVM_READONLY__attribute__((__pure__)) { return EndLocation; } |
1164 | }; |
1165 | |
1166 | /// A set of tokens that has been cached for later parsing. |
1167 | typedef SmallVector<Token, 4> CachedTokens; |
1168 | |
1169 | /// One instance of this struct is used for each type in a |
1170 | /// declarator that is parsed. |
1171 | /// |
1172 | /// This is intended to be a small value object. |
1173 | struct DeclaratorChunk { |
1174 | DeclaratorChunk() {}; |
1175 | |
1176 | enum { |
1177 | Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren, Pipe |
1178 | } Kind; |
1179 | |
1180 | /// Loc - The place where this type was defined. |
1181 | SourceLocation Loc; |
1182 | /// EndLoc - If valid, the place where this chunck ends. |
1183 | SourceLocation EndLoc; |
1184 | |
1185 | SourceRange getSourceRange() const { |
1186 | if (EndLoc.isInvalid()) |
1187 | return SourceRange(Loc, Loc); |
1188 | return SourceRange(Loc, EndLoc); |
1189 | } |
1190 | |
1191 | ParsedAttributesView AttrList; |
1192 | |
1193 | struct PointerTypeInfo { |
1194 | /// The type qualifiers: const/volatile/restrict/unaligned/atomic. |
1195 | unsigned TypeQuals : 5; |
1196 | |
1197 | /// The location of the const-qualifier, if any. |
1198 | SourceLocation ConstQualLoc; |
1199 | |
1200 | /// The location of the volatile-qualifier, if any. |
1201 | SourceLocation VolatileQualLoc; |
1202 | |
1203 | /// The location of the restrict-qualifier, if any. |
1204 | SourceLocation RestrictQualLoc; |
1205 | |
1206 | /// The location of the _Atomic-qualifier, if any. |
1207 | SourceLocation AtomicQualLoc; |
1208 | |
1209 | /// The location of the __unaligned-qualifier, if any. |
1210 | SourceLocation UnalignedQualLoc; |
1211 | |
1212 | void destroy() { |
1213 | } |
1214 | }; |
1215 | |
1216 | struct ReferenceTypeInfo { |
1217 | /// The type qualifier: restrict. [GNU] C++ extension |
1218 | bool HasRestrict : 1; |
1219 | /// True if this is an lvalue reference, false if it's an rvalue reference. |
1220 | bool LValueRef : 1; |
1221 | void destroy() { |
1222 | } |
1223 | }; |
1224 | |
1225 | struct ArrayTypeInfo { |
1226 | /// The type qualifiers for the array: |
1227 | /// const/volatile/restrict/__unaligned/_Atomic. |
1228 | unsigned TypeQuals : 5; |
1229 | |
1230 | /// True if this dimension included the 'static' keyword. |
1231 | unsigned hasStatic : 1; |
1232 | |
1233 | /// True if this dimension was [*]. In this case, NumElts is null. |
1234 | unsigned isStar : 1; |
1235 | |
1236 | /// This is the size of the array, or null if [] or [*] was specified. |
1237 | /// Since the parser is multi-purpose, and we don't want to impose a root |
1238 | /// expression class on all clients, NumElts is untyped. |
1239 | Expr *NumElts; |
1240 | |
1241 | void destroy() {} |
1242 | }; |
1243 | |
1244 | /// ParamInfo - An array of paraminfo objects is allocated whenever a function |
1245 | /// declarator is parsed. There are two interesting styles of parameters |
1246 | /// here: |
1247 | /// K&R-style identifier lists and parameter type lists. K&R-style identifier |
1248 | /// lists will have information about the identifier, but no type information. |
1249 | /// Parameter type lists will have type info (if the actions module provides |
1250 | /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'. |
1251 | struct ParamInfo { |
1252 | IdentifierInfo *Ident; |
1253 | SourceLocation IdentLoc; |
1254 | Decl *Param; |
1255 | |
1256 | /// DefaultArgTokens - When the parameter's default argument |
1257 | /// cannot be parsed immediately (because it occurs within the |
1258 | /// declaration of a member function), it will be stored here as a |
1259 | /// sequence of tokens to be parsed once the class definition is |
1260 | /// complete. Non-NULL indicates that there is a default argument. |
1261 | std::unique_ptr<CachedTokens> DefaultArgTokens; |
1262 | |
1263 | ParamInfo() = default; |
1264 | ParamInfo(IdentifierInfo *ident, SourceLocation iloc, |
1265 | Decl *param, |
1266 | std::unique_ptr<CachedTokens> DefArgTokens = nullptr) |
1267 | : Ident(ident), IdentLoc(iloc), Param(param), |
1268 | DefaultArgTokens(std::move(DefArgTokens)) {} |
1269 | }; |
1270 | |
1271 | struct TypeAndRange { |
1272 | ParsedType Ty; |
1273 | SourceRange Range; |
1274 | }; |
1275 | |
1276 | struct FunctionTypeInfo { |
1277 | /// hasPrototype - This is true if the function had at least one typed |
1278 | /// parameter. If the function is () or (a,b,c), then it has no prototype, |
1279 | /// and is treated as a K&R-style function. |
1280 | unsigned hasPrototype : 1; |
1281 | |
1282 | /// isVariadic - If this function has a prototype, and if that |
1283 | /// proto ends with ',...)', this is true. When true, EllipsisLoc |
1284 | /// contains the location of the ellipsis. |
1285 | unsigned isVariadic : 1; |
1286 | |
1287 | /// Can this declaration be a constructor-style initializer? |
1288 | unsigned isAmbiguous : 1; |
1289 | |
1290 | /// Whether the ref-qualifier (if any) is an lvalue reference. |
1291 | /// Otherwise, it's an rvalue reference. |
1292 | unsigned RefQualifierIsLValueRef : 1; |
1293 | |
1294 | /// ExceptionSpecType - An ExceptionSpecificationType value. |
1295 | unsigned ExceptionSpecType : 4; |
1296 | |
1297 | /// DeleteParams - If this is true, we need to delete[] Params. |
1298 | unsigned DeleteParams : 1; |
1299 | |
1300 | /// HasTrailingReturnType - If this is true, a trailing return type was |
1301 | /// specified. |
1302 | unsigned HasTrailingReturnType : 1; |
1303 | |
1304 | /// The location of the left parenthesis in the source. |
1305 | SourceLocation LParenLoc; |
1306 | |
1307 | /// When isVariadic is true, the location of the ellipsis in the source. |
1308 | SourceLocation EllipsisLoc; |
1309 | |
1310 | /// The location of the right parenthesis in the source. |
1311 | SourceLocation RParenLoc; |
1312 | |
1313 | /// NumParams - This is the number of formal parameters specified by the |
1314 | /// declarator. |
1315 | unsigned NumParams; |
1316 | |
1317 | /// NumExceptionsOrDecls - This is the number of types in the |
1318 | /// dynamic-exception-decl, if the function has one. In C, this is the |
1319 | /// number of declarations in the function prototype. |
1320 | unsigned NumExceptionsOrDecls; |
1321 | |
1322 | /// The location of the ref-qualifier, if any. |
1323 | /// |
1324 | /// If this is an invalid location, there is no ref-qualifier. |
1325 | SourceLocation RefQualifierLoc; |
1326 | |
1327 | /// The location of the 'mutable' qualifer in a lambda-declarator, if |
1328 | /// any. |
1329 | SourceLocation MutableLoc; |
1330 | |
1331 | /// The beginning location of the exception specification, if any. |
1332 | SourceLocation ExceptionSpecLocBeg; |
1333 | |
1334 | /// The end location of the exception specification, if any. |
1335 | SourceLocation ExceptionSpecLocEnd; |
1336 | |
1337 | /// Params - This is a pointer to a new[]'d array of ParamInfo objects that |
1338 | /// describe the parameters specified by this function declarator. null if |
1339 | /// there are no parameters specified. |
1340 | ParamInfo *Params; |
1341 | |
1342 | /// DeclSpec for the function with the qualifier related info. |
1343 | DeclSpec *MethodQualifiers; |
1344 | |
1345 | /// AtttibuteFactory for the MethodQualifiers. |
1346 | AttributeFactory *QualAttrFactory; |
1347 | |
1348 | union { |
1349 | /// Pointer to a new[]'d array of TypeAndRange objects that |
1350 | /// contain the types in the function's dynamic exception specification |
1351 | /// and their locations, if there is one. |
1352 | TypeAndRange *Exceptions; |
1353 | |
1354 | /// Pointer to the expression in the noexcept-specifier of this |
1355 | /// function, if it has one. |
1356 | Expr *NoexceptExpr; |
1357 | |
1358 | /// Pointer to the cached tokens for an exception-specification |
1359 | /// that has not yet been parsed. |
1360 | CachedTokens *ExceptionSpecTokens; |
1361 | |
1362 | /// Pointer to a new[]'d array of declarations that need to be available |
1363 | /// for lookup inside the function body, if one exists. Does not exist in |
1364 | /// C++. |
1365 | NamedDecl **DeclsInPrototype; |
1366 | }; |
1367 | |
1368 | /// If HasTrailingReturnType is true, this is the trailing return |
1369 | /// type specified. |
1370 | UnionParsedType TrailingReturnType; |
1371 | |
1372 | /// If HasTrailingReturnType is true, this is the location of the trailing |
1373 | /// return type. |
1374 | SourceLocation TrailingReturnTypeLoc; |
1375 | |
1376 | /// Reset the parameter list to having zero parameters. |
1377 | /// |
1378 | /// This is used in various places for error recovery. |
1379 | void freeParams() { |
1380 | for (unsigned I = 0; I < NumParams; ++I) |
1381 | Params[I].DefaultArgTokens.reset(); |
1382 | if (DeleteParams) { |
1383 | delete[] Params; |
1384 | DeleteParams = false; |
1385 | } |
1386 | NumParams = 0; |
1387 | } |
1388 | |
1389 | void destroy() { |
1390 | freeParams(); |
1391 | delete QualAttrFactory; |
1392 | delete MethodQualifiers; |
1393 | switch (getExceptionSpecType()) { |
1394 | default: |
1395 | break; |
1396 | case EST_Dynamic: |
1397 | delete[] Exceptions; |
1398 | break; |
1399 | case EST_Unparsed: |
1400 | delete ExceptionSpecTokens; |
1401 | break; |
1402 | case EST_None: |
1403 | if (NumExceptionsOrDecls != 0) |
1404 | delete[] DeclsInPrototype; |
1405 | break; |
1406 | } |
1407 | } |
1408 | |
1409 | DeclSpec &getOrCreateMethodQualifiers() { |
1410 | if (!MethodQualifiers) { |
1411 | QualAttrFactory = new AttributeFactory(); |
1412 | MethodQualifiers = new DeclSpec(*QualAttrFactory); |
1413 | } |
1414 | return *MethodQualifiers; |
1415 | } |
1416 | |
1417 | /// isKNRPrototype - Return true if this is a K&R style identifier list, |
1418 | /// like "void foo(a,b,c)". In a function definition, this will be followed |
1419 | /// by the parameter type definitions. |
1420 | bool isKNRPrototype() const { return !hasPrototype && NumParams != 0; } |
1421 | |
1422 | SourceLocation getLParenLoc() const { return LParenLoc; } |
1423 | |
1424 | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } |
1425 | |
1426 | SourceLocation getRParenLoc() const { return RParenLoc; } |
1427 | |
1428 | SourceLocation getExceptionSpecLocBeg() const { |
1429 | return ExceptionSpecLocBeg; |
1430 | } |
1431 | |
1432 | SourceLocation getExceptionSpecLocEnd() const { |
1433 | return ExceptionSpecLocEnd; |
1434 | } |
1435 | |
1436 | SourceRange getExceptionSpecRange() const { |
1437 | return SourceRange(getExceptionSpecLocBeg(), getExceptionSpecLocEnd()); |
1438 | } |
1439 | |
1440 | /// Retrieve the location of the ref-qualifier, if any. |
1441 | SourceLocation getRefQualifierLoc() const { return RefQualifierLoc; } |
1442 | |
1443 | /// Retrieve the location of the 'const' qualifier. |
1444 | SourceLocation getConstQualifierLoc() const { |
1445 | assert(MethodQualifiers)((void)0); |
1446 | return MethodQualifiers->getConstSpecLoc(); |
1447 | } |
1448 | |
1449 | /// Retrieve the location of the 'volatile' qualifier. |
1450 | SourceLocation getVolatileQualifierLoc() const { |
1451 | assert(MethodQualifiers)((void)0); |
1452 | return MethodQualifiers->getVolatileSpecLoc(); |
1453 | } |
1454 | |
1455 | /// Retrieve the location of the 'restrict' qualifier. |
1456 | SourceLocation getRestrictQualifierLoc() const { |
1457 | assert(MethodQualifiers)((void)0); |
1458 | return MethodQualifiers->getRestrictSpecLoc(); |
1459 | } |
1460 | |
1461 | /// Retrieve the location of the 'mutable' qualifier, if any. |
1462 | SourceLocation getMutableLoc() const { return MutableLoc; } |
1463 | |
1464 | /// Determine whether this function declaration contains a |
1465 | /// ref-qualifier. |
1466 | bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } |
1467 | |
1468 | /// Determine whether this lambda-declarator contains a 'mutable' |
1469 | /// qualifier. |
1470 | bool hasMutableQualifier() const { return getMutableLoc().isValid(); } |
1471 | |
1472 | /// Determine whether this method has qualifiers. |
1473 | bool hasMethodTypeQualifiers() const { |
1474 | return MethodQualifiers && (MethodQualifiers->getTypeQualifiers() || |
1475 | MethodQualifiers->getAttributes().size()); |
1476 | } |
1477 | |
1478 | /// Get the type of exception specification this function has. |
1479 | ExceptionSpecificationType getExceptionSpecType() const { |
1480 | return static_cast<ExceptionSpecificationType>(ExceptionSpecType); |
1481 | } |
1482 | |
1483 | /// Get the number of dynamic exception specifications. |
1484 | unsigned getNumExceptions() const { |
1485 | assert(ExceptionSpecType != EST_None)((void)0); |
1486 | return NumExceptionsOrDecls; |
1487 | } |
1488 | |
1489 | /// Get the non-parameter decls defined within this function |
1490 | /// prototype. Typically these are tag declarations. |
1491 | ArrayRef<NamedDecl *> getDeclsInPrototype() const { |
1492 | assert(ExceptionSpecType == EST_None)((void)0); |
1493 | return llvm::makeArrayRef(DeclsInPrototype, NumExceptionsOrDecls); |
1494 | } |
1495 | |
1496 | /// Determine whether this function declarator had a |
1497 | /// trailing-return-type. |
1498 | bool hasTrailingReturnType() const { return HasTrailingReturnType; } |
1499 | |
1500 | /// Get the trailing-return-type for this function declarator. |
1501 | ParsedType getTrailingReturnType() const { |
1502 | assert(HasTrailingReturnType)((void)0); |
1503 | return TrailingReturnType; |
1504 | } |
1505 | |
1506 | /// Get the trailing-return-type location for this function declarator. |
1507 | SourceLocation getTrailingReturnTypeLoc() const { |
1508 | assert(HasTrailingReturnType)((void)0); |
1509 | return TrailingReturnTypeLoc; |
1510 | } |
1511 | }; |
1512 | |
1513 | struct BlockPointerTypeInfo { |
1514 | /// For now, sema will catch these as invalid. |
1515 | /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. |
1516 | unsigned TypeQuals : 5; |
1517 | |
1518 | void destroy() { |
1519 | } |
1520 | }; |
1521 | |
1522 | struct MemberPointerTypeInfo { |
1523 | /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. |
1524 | unsigned TypeQuals : 5; |
1525 | /// Location of the '*' token. |
1526 | SourceLocation StarLoc; |
1527 | // CXXScopeSpec has a constructor, so it can't be a direct member. |
1528 | // So we need some pointer-aligned storage and a bit of trickery. |
1529 | alignas(CXXScopeSpec) char ScopeMem[sizeof(CXXScopeSpec)]; |
1530 | CXXScopeSpec &Scope() { |
1531 | return *reinterpret_cast<CXXScopeSpec *>(ScopeMem); |
1532 | } |
1533 | const CXXScopeSpec &Scope() const { |
1534 | return *reinterpret_cast<const CXXScopeSpec *>(ScopeMem); |
1535 | } |
1536 | void destroy() { |
1537 | Scope().~CXXScopeSpec(); |
1538 | } |
1539 | }; |
1540 | |
1541 | struct PipeTypeInfo { |
1542 | /// The access writes. |
1543 | unsigned AccessWrites : 3; |
1544 | |
1545 | void destroy() {} |
1546 | }; |
1547 | |
1548 | union { |
1549 | PointerTypeInfo Ptr; |
1550 | ReferenceTypeInfo Ref; |
1551 | ArrayTypeInfo Arr; |
1552 | FunctionTypeInfo Fun; |
1553 | BlockPointerTypeInfo Cls; |
1554 | MemberPointerTypeInfo Mem; |
1555 | PipeTypeInfo PipeInfo; |
1556 | }; |
1557 | |
1558 | void destroy() { |
1559 | switch (Kind) { |
1560 | case DeclaratorChunk::Function: return Fun.destroy(); |
1561 | case DeclaratorChunk::Pointer: return Ptr.destroy(); |
1562 | case DeclaratorChunk::BlockPointer: return Cls.destroy(); |
1563 | case DeclaratorChunk::Reference: return Ref.destroy(); |
1564 | case DeclaratorChunk::Array: return Arr.destroy(); |
1565 | case DeclaratorChunk::MemberPointer: return Mem.destroy(); |
1566 | case DeclaratorChunk::Paren: return; |
1567 | case DeclaratorChunk::Pipe: return PipeInfo.destroy(); |
1568 | } |
1569 | } |
1570 | |
1571 | /// If there are attributes applied to this declaratorchunk, return |
1572 | /// them. |
1573 | const ParsedAttributesView &getAttrs() const { return AttrList; } |
1574 | ParsedAttributesView &getAttrs() { return AttrList; } |
1575 | |
1576 | /// Return a DeclaratorChunk for a pointer. |
1577 | static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, |
1578 | SourceLocation ConstQualLoc, |
1579 | SourceLocation VolatileQualLoc, |
1580 | SourceLocation RestrictQualLoc, |
1581 | SourceLocation AtomicQualLoc, |
1582 | SourceLocation UnalignedQualLoc) { |
1583 | DeclaratorChunk I; |
1584 | I.Kind = Pointer; |
1585 | I.Loc = Loc; |
1586 | new (&I.Ptr) PointerTypeInfo; |
1587 | I.Ptr.TypeQuals = TypeQuals; |
1588 | I.Ptr.ConstQualLoc = ConstQualLoc; |
1589 | I.Ptr.VolatileQualLoc = VolatileQualLoc; |
1590 | I.Ptr.RestrictQualLoc = RestrictQualLoc; |
1591 | I.Ptr.AtomicQualLoc = AtomicQualLoc; |
1592 | I.Ptr.UnalignedQualLoc = UnalignedQualLoc; |
1593 | return I; |
1594 | } |
1595 | |
1596 | /// Return a DeclaratorChunk for a reference. |
1597 | static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, |
1598 | bool lvalue) { |
1599 | DeclaratorChunk I; |
1600 | I.Kind = Reference; |
1601 | I.Loc = Loc; |
1602 | I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0; |
1603 | I.Ref.LValueRef = lvalue; |
1604 | return I; |
1605 | } |
1606 | |
1607 | /// Return a DeclaratorChunk for an array. |
1608 | static DeclaratorChunk getArray(unsigned TypeQuals, |
1609 | bool isStatic, bool isStar, Expr *NumElts, |
1610 | SourceLocation LBLoc, SourceLocation RBLoc) { |
1611 | DeclaratorChunk I; |
1612 | I.Kind = Array; |
1613 | I.Loc = LBLoc; |
1614 | I.EndLoc = RBLoc; |
1615 | I.Arr.TypeQuals = TypeQuals; |
1616 | I.Arr.hasStatic = isStatic; |
1617 | I.Arr.isStar = isStar; |
1618 | I.Arr.NumElts = NumElts; |
1619 | return I; |
1620 | } |
1621 | |
1622 | /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. |
1623 | /// "TheDeclarator" is the declarator that this will be added to. |
1624 | static DeclaratorChunk getFunction(bool HasProto, |
1625 | bool IsAmbiguous, |
1626 | SourceLocation LParenLoc, |
1627 | ParamInfo *Params, unsigned NumParams, |
1628 | SourceLocation EllipsisLoc, |
1629 | SourceLocation RParenLoc, |
1630 | bool RefQualifierIsLvalueRef, |
1631 | SourceLocation RefQualifierLoc, |
1632 | SourceLocation MutableLoc, |
1633 | ExceptionSpecificationType ESpecType, |
1634 | SourceRange ESpecRange, |
1635 | ParsedType *Exceptions, |
1636 | SourceRange *ExceptionRanges, |
1637 | unsigned NumExceptions, |
1638 | Expr *NoexceptExpr, |
1639 | CachedTokens *ExceptionSpecTokens, |
1640 | ArrayRef<NamedDecl *> DeclsInPrototype, |
1641 | SourceLocation LocalRangeBegin, |
1642 | SourceLocation LocalRangeEnd, |
1643 | Declarator &TheDeclarator, |
1644 | TypeResult TrailingReturnType = |
1645 | TypeResult(), |
1646 | SourceLocation TrailingReturnTypeLoc = |
1647 | SourceLocation(), |
1648 | DeclSpec *MethodQualifiers = nullptr); |
1649 | |
1650 | /// Return a DeclaratorChunk for a block. |
1651 | static DeclaratorChunk getBlockPointer(unsigned TypeQuals, |
1652 | SourceLocation Loc) { |
1653 | DeclaratorChunk I; |
1654 | I.Kind = BlockPointer; |
1655 | I.Loc = Loc; |
1656 | I.Cls.TypeQuals = TypeQuals; |
1657 | return I; |
1658 | } |
1659 | |
1660 | /// Return a DeclaratorChunk for a block. |
1661 | static DeclaratorChunk getPipe(unsigned TypeQuals, |
1662 | SourceLocation Loc) { |
1663 | DeclaratorChunk I; |
1664 | I.Kind = Pipe; |
1665 | I.Loc = Loc; |
1666 | I.Cls.TypeQuals = TypeQuals; |
1667 | return I; |
1668 | } |
1669 | |
1670 | static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, |
1671 | unsigned TypeQuals, |
1672 | SourceLocation StarLoc, |
1673 | SourceLocation EndLoc) { |
1674 | DeclaratorChunk I; |
1675 | I.Kind = MemberPointer; |
1676 | I.Loc = SS.getBeginLoc(); |
1677 | I.EndLoc = EndLoc; |
1678 | new (&I.Mem) MemberPointerTypeInfo; |
1679 | I.Mem.StarLoc = StarLoc; |
1680 | I.Mem.TypeQuals = TypeQuals; |
1681 | new (I.Mem.ScopeMem) CXXScopeSpec(SS); |
1682 | return I; |
1683 | } |
1684 | |
1685 | /// Return a DeclaratorChunk for a paren. |
1686 | static DeclaratorChunk getParen(SourceLocation LParenLoc, |
1687 | SourceLocation RParenLoc) { |
1688 | DeclaratorChunk I; |
1689 | I.Kind = Paren; |
1690 | I.Loc = LParenLoc; |
1691 | I.EndLoc = RParenLoc; |
1692 | return I; |
1693 | } |
1694 | |
1695 | bool isParen() const { |
1696 | return Kind == Paren; |
1697 | } |
1698 | }; |
1699 | |
1700 | /// A parsed C++17 decomposition declarator of the form |
1701 | /// '[' identifier-list ']' |
1702 | class DecompositionDeclarator { |
1703 | public: |
1704 | struct Binding { |
1705 | IdentifierInfo *Name; |
1706 | SourceLocation NameLoc; |
1707 | }; |
1708 | |
1709 | private: |
1710 | /// The locations of the '[' and ']' tokens. |
1711 | SourceLocation LSquareLoc, RSquareLoc; |
1712 | |
1713 | /// The bindings. |
1714 | Binding *Bindings; |
1715 | unsigned NumBindings : 31; |
1716 | unsigned DeleteBindings : 1; |
1717 | |
1718 | friend class Declarator; |
1719 | |
1720 | public: |
1721 | DecompositionDeclarator() |
1722 | : Bindings(nullptr), NumBindings(0), DeleteBindings(false) {} |
1723 | DecompositionDeclarator(const DecompositionDeclarator &G) = delete; |
1724 | DecompositionDeclarator &operator=(const DecompositionDeclarator &G) = delete; |
1725 | ~DecompositionDeclarator() { |
1726 | if (DeleteBindings) |
1727 | delete[] Bindings; |
1728 | } |
1729 | |
1730 | void clear() { |
1731 | LSquareLoc = RSquareLoc = SourceLocation(); |
1732 | if (DeleteBindings) |
1733 | delete[] Bindings; |
1734 | Bindings = nullptr; |
1735 | NumBindings = 0; |
1736 | DeleteBindings = false; |
1737 | } |
1738 | |
1739 | ArrayRef<Binding> bindings() const { |
1740 | return llvm::makeArrayRef(Bindings, NumBindings); |
1741 | } |
1742 | |
1743 | bool isSet() const { return LSquareLoc.isValid(); } |
1744 | |
1745 | SourceLocation getLSquareLoc() const { return LSquareLoc; } |
1746 | SourceLocation getRSquareLoc() const { return RSquareLoc; } |
1747 | SourceRange getSourceRange() const { |
1748 | return SourceRange(LSquareLoc, RSquareLoc); |
1749 | } |
1750 | }; |
1751 | |
1752 | /// Described the kind of function definition (if any) provided for |
1753 | /// a function. |
1754 | enum class FunctionDefinitionKind { |
1755 | Declaration, |
1756 | Definition, |
1757 | Defaulted, |
1758 | Deleted |
1759 | }; |
1760 | |
1761 | enum class DeclaratorContext { |
1762 | File, // File scope declaration. |
1763 | Prototype, // Within a function prototype. |
1764 | ObjCResult, // An ObjC method result type. |
1765 | ObjCParameter, // An ObjC method parameter type. |
1766 | KNRTypeList, // K&R type definition list for formals. |
1767 | TypeName, // Abstract declarator for types. |
1768 | FunctionalCast, // Type in a C++ functional cast expression. |
1769 | Member, // Struct/Union field. |
1770 | Block, // Declaration within a block in a function. |
1771 | ForInit, // Declaration within first part of a for loop. |
1772 | SelectionInit, // Declaration within optional init stmt of if/switch. |
1773 | Condition, // Condition declaration in a C++ if/switch/while/for. |
1774 | TemplateParam, // Within a template parameter list. |
1775 | CXXNew, // C++ new-expression. |
1776 | CXXCatch, // C++ catch exception-declaration |
1777 | ObjCCatch, // Objective-C catch exception-declaration |
1778 | BlockLiteral, // Block literal declarator. |
1779 | LambdaExpr, // Lambda-expression declarator. |
1780 | LambdaExprParameter, // Lambda-expression parameter declarator. |
1781 | ConversionId, // C++ conversion-type-id. |
1782 | TrailingReturn, // C++11 trailing-type-specifier. |
1783 | TrailingReturnVar, // C++11 trailing-type-specifier for variable. |
1784 | TemplateArg, // Any template argument (in template argument list). |
1785 | TemplateTypeArg, // Template type argument (in default argument). |
1786 | AliasDecl, // C++11 alias-declaration. |
1787 | AliasTemplate, // C++11 alias-declaration template. |
1788 | RequiresExpr // C++2a requires-expression. |
1789 | }; |
1790 | |
1791 | /// Information about one declarator, including the parsed type |
1792 | /// information and the identifier. |
1793 | /// |
1794 | /// When the declarator is fully formed, this is turned into the appropriate |
1795 | /// Decl object. |
1796 | /// |
1797 | /// Declarators come in two types: normal declarators and abstract declarators. |
1798 | /// Abstract declarators are used when parsing types, and don't have an |
1799 | /// identifier. Normal declarators do have ID's. |
1800 | /// |
1801 | /// Instances of this class should be a transient object that lives on the |
1802 | /// stack, not objects that are allocated in large quantities on the heap. |
1803 | class Declarator { |
1804 | |
1805 | private: |
1806 | const DeclSpec &DS; |
1807 | CXXScopeSpec SS; |
1808 | UnqualifiedId Name; |
1809 | SourceRange Range; |
1810 | |
1811 | /// Where we are parsing this declarator. |
1812 | DeclaratorContext Context; |
1813 | |
1814 | /// The C++17 structured binding, if any. This is an alternative to a Name. |
1815 | DecompositionDeclarator BindingGroup; |
1816 | |
1817 | /// DeclTypeInfo - This holds each type that the declarator includes as it is |
1818 | /// parsed. This is pushed from the identifier out, which means that element |
1819 | /// #0 will be the most closely bound to the identifier, and |
1820 | /// DeclTypeInfo.back() will be the least closely bound. |
1821 | SmallVector<DeclaratorChunk, 8> DeclTypeInfo; |
1822 | |
1823 | /// InvalidType - Set by Sema::GetTypeForDeclarator(). |
1824 | unsigned InvalidType : 1; |
1825 | |
1826 | /// GroupingParens - Set by Parser::ParseParenDeclarator(). |
1827 | unsigned GroupingParens : 1; |
1828 | |
1829 | /// FunctionDefinition - Is this Declarator for a function or member |
1830 | /// definition and, if so, what kind? |
1831 | /// |
1832 | /// Actually a FunctionDefinitionKind. |
1833 | unsigned FunctionDefinition : 2; |
1834 | |
1835 | /// Is this Declarator a redeclaration? |
1836 | unsigned Redeclaration : 1; |
1837 | |
1838 | /// true if the declaration is preceded by \c __extension__. |
1839 | unsigned Extension : 1; |
1840 | |
1841 | /// Indicates whether this is an Objective-C instance variable. |
1842 | unsigned ObjCIvar : 1; |
1843 | |
1844 | /// Indicates whether this is an Objective-C 'weak' property. |
1845 | unsigned ObjCWeakProperty : 1; |
1846 | |
1847 | /// Indicates whether the InlineParams / InlineBindings storage has been used. |
1848 | unsigned InlineStorageUsed : 1; |
1849 | |
1850 | /// Indicates whether this declarator has an initializer. |
1851 | unsigned HasInitializer : 1; |
1852 | |
1853 | /// Attrs - Attributes. |
1854 | ParsedAttributes Attrs; |
1855 | |
1856 | /// The asm label, if specified. |
1857 | Expr *AsmLabel; |
1858 | |
1859 | /// \brief The constraint-expression specified by the trailing |
1860 | /// requires-clause, or null if no such clause was specified. |
1861 | Expr *TrailingRequiresClause; |
1862 | |
1863 | /// If this declarator declares a template, its template parameter lists. |
1864 | ArrayRef<TemplateParameterList *> TemplateParameterLists; |
1865 | |
1866 | /// If the declarator declares an abbreviated function template, the innermost |
1867 | /// template parameter list containing the invented and explicit template |
1868 | /// parameters (if any). |
1869 | TemplateParameterList *InventedTemplateParameterList; |
1870 | |
1871 | #ifndef _MSC_VER |
1872 | union { |
1873 | #endif |
1874 | /// InlineParams - This is a local array used for the first function decl |
1875 | /// chunk to avoid going to the heap for the common case when we have one |
1876 | /// function chunk in the declarator. |
1877 | DeclaratorChunk::ParamInfo InlineParams[16]; |
1878 | DecompositionDeclarator::Binding InlineBindings[16]; |
1879 | #ifndef _MSC_VER |
1880 | }; |
1881 | #endif |
1882 | |
1883 | /// If this is the second or subsequent declarator in this declaration, |
1884 | /// the location of the comma before this declarator. |
1885 | SourceLocation CommaLoc; |
1886 | |
1887 | /// If provided, the source location of the ellipsis used to describe |
1888 | /// this declarator as a parameter pack. |
1889 | SourceLocation EllipsisLoc; |
1890 | |
1891 | friend struct DeclaratorChunk; |
1892 | |
1893 | public: |
1894 | Declarator(const DeclSpec &ds, DeclaratorContext C) |
1895 | : DS(ds), Range(ds.getSourceRange()), Context(C), |
1896 | InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error), |
1897 | GroupingParens(false), FunctionDefinition(static_cast<unsigned>( |
1898 | FunctionDefinitionKind::Declaration)), |
1899 | Redeclaration(false), Extension(false), ObjCIvar(false), |
1900 | ObjCWeakProperty(false), InlineStorageUsed(false), |
1901 | HasInitializer(false), Attrs(ds.getAttributePool().getFactory()), |
1902 | AsmLabel(nullptr), TrailingRequiresClause(nullptr), |
1903 | InventedTemplateParameterList(nullptr) {} |
1904 | |
1905 | ~Declarator() { |
1906 | clear(); |
1907 | } |
1908 | /// getDeclSpec - Return the declaration-specifier that this declarator was |
1909 | /// declared with. |
1910 | const DeclSpec &getDeclSpec() const { return DS; } |
1911 | |
1912 | /// getMutableDeclSpec - Return a non-const version of the DeclSpec. This |
1913 | /// should be used with extreme care: declspecs can often be shared between |
1914 | /// multiple declarators, so mutating the DeclSpec affects all of the |
1915 | /// Declarators. This should only be done when the declspec is known to not |
1916 | /// be shared or when in error recovery etc. |
1917 | DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); } |
1918 | |
1919 | AttributePool &getAttributePool() const { |
1920 | return Attrs.getPool(); |
1921 | } |
1922 | |
1923 | /// getCXXScopeSpec - Return the C++ scope specifier (global scope or |
1924 | /// nested-name-specifier) that is part of the declarator-id. |
1925 | const CXXScopeSpec &getCXXScopeSpec() const { return SS; } |
1926 | CXXScopeSpec &getCXXScopeSpec() { return SS; } |
1927 | |
1928 | /// Retrieve the name specified by this declarator. |
1929 | UnqualifiedId &getName() { return Name; } |
1930 | |
1931 | const DecompositionDeclarator &getDecompositionDeclarator() const { |
1932 | return BindingGroup; |
1933 | } |
1934 | |
1935 | DeclaratorContext getContext() const { return Context; } |
1936 | |
1937 | bool isPrototypeContext() const { |
1938 | return (Context == DeclaratorContext::Prototype || |
1939 | Context == DeclaratorContext::ObjCParameter || |
1940 | Context == DeclaratorContext::ObjCResult || |
1941 | Context == DeclaratorContext::LambdaExprParameter); |
1942 | } |
1943 | |
1944 | /// Get the source range that spans this declarator. |
1945 | SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) { return Range; } |
1946 | SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) { return Range.getBegin(); } |
1947 | SourceLocation getEndLoc() const LLVM_READONLY__attribute__((__pure__)) { return Range.getEnd(); } |
1948 | |
1949 | void SetSourceRange(SourceRange R) { Range = R; } |
1950 | /// SetRangeBegin - Set the start of the source range to Loc, unless it's |
1951 | /// invalid. |
1952 | void SetRangeBegin(SourceLocation Loc) { |
1953 | if (!Loc.isInvalid()) |
1954 | Range.setBegin(Loc); |
1955 | } |
1956 | /// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid. |
1957 | void SetRangeEnd(SourceLocation Loc) { |
1958 | if (!Loc.isInvalid()) |
1959 | Range.setEnd(Loc); |
1960 | } |
1961 | /// ExtendWithDeclSpec - Extend the declarator source range to include the |
1962 | /// given declspec, unless its location is invalid. Adopts the range start if |
1963 | /// the current range start is invalid. |
1964 | void ExtendWithDeclSpec(const DeclSpec &DS) { |
1965 | SourceRange SR = DS.getSourceRange(); |
1966 | if (Range.getBegin().isInvalid()) |
1967 | Range.setBegin(SR.getBegin()); |
1968 | if (!SR.getEnd().isInvalid()) |
1969 | Range.setEnd(SR.getEnd()); |
1970 | } |
1971 | |
1972 | /// Reset the contents of this Declarator. |
1973 | void clear() { |
1974 | SS.clear(); |
1975 | Name.clear(); |
1976 | Range = DS.getSourceRange(); |
1977 | BindingGroup.clear(); |
1978 | |
1979 | for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) |
1980 | DeclTypeInfo[i].destroy(); |
1981 | DeclTypeInfo.clear(); |
1982 | Attrs.clear(); |
1983 | AsmLabel = nullptr; |
1984 | InlineStorageUsed = false; |
1985 | HasInitializer = false; |
1986 | ObjCIvar = false; |
1987 | ObjCWeakProperty = false; |
1988 | CommaLoc = SourceLocation(); |
1989 | EllipsisLoc = SourceLocation(); |
1990 | } |
1991 | |
1992 | /// mayOmitIdentifier - Return true if the identifier is either optional or |
1993 | /// not allowed. This is true for typenames, prototypes, and template |
1994 | /// parameter lists. |
1995 | bool mayOmitIdentifier() const { |
1996 | switch (Context) { |
1997 | case DeclaratorContext::File: |
1998 | case DeclaratorContext::KNRTypeList: |
1999 | case DeclaratorContext::Member: |
2000 | case DeclaratorContext::Block: |
2001 | case DeclaratorContext::ForInit: |
2002 | case DeclaratorContext::SelectionInit: |
2003 | case DeclaratorContext::Condition: |
2004 | return false; |
2005 | |
2006 | case DeclaratorContext::TypeName: |
2007 | case DeclaratorContext::FunctionalCast: |
2008 | case DeclaratorContext::AliasDecl: |
2009 | case DeclaratorContext::AliasTemplate: |
2010 | case DeclaratorContext::Prototype: |
2011 | case DeclaratorContext::LambdaExprParameter: |
2012 | case DeclaratorContext::ObjCParameter: |
2013 | case DeclaratorContext::ObjCResult: |
2014 | case DeclaratorContext::TemplateParam: |
2015 | case DeclaratorContext::CXXNew: |
2016 | case DeclaratorContext::CXXCatch: |
2017 | case DeclaratorContext::ObjCCatch: |
2018 | case DeclaratorContext::BlockLiteral: |
2019 | case DeclaratorContext::LambdaExpr: |
2020 | case DeclaratorContext::ConversionId: |
2021 | case DeclaratorContext::TemplateArg: |
2022 | case DeclaratorContext::TemplateTypeArg: |
2023 | case DeclaratorContext::TrailingReturn: |
2024 | case DeclaratorContext::TrailingReturnVar: |
2025 | case DeclaratorContext::RequiresExpr: |
2026 | return true; |
2027 | } |
2028 | llvm_unreachable("unknown context kind!")__builtin_unreachable(); |
2029 | } |
2030 | |
2031 | /// mayHaveIdentifier - Return true if the identifier is either optional or |
2032 | /// required. This is true for normal declarators and prototypes, but not |
2033 | /// typenames. |
2034 | bool mayHaveIdentifier() const { |
2035 | switch (Context) { |
2036 | case DeclaratorContext::File: |
2037 | case DeclaratorContext::KNRTypeList: |
2038 | case DeclaratorContext::Member: |
2039 | case DeclaratorContext::Block: |
2040 | case DeclaratorContext::ForInit: |
2041 | case DeclaratorContext::SelectionInit: |
2042 | case DeclaratorContext::Condition: |
2043 | case DeclaratorContext::Prototype: |
2044 | case DeclaratorContext::LambdaExprParameter: |
2045 | case DeclaratorContext::TemplateParam: |
2046 | case DeclaratorContext::CXXCatch: |
2047 | case DeclaratorContext::ObjCCatch: |
2048 | case DeclaratorContext::RequiresExpr: |
2049 | return true; |
2050 | |
2051 | case DeclaratorContext::TypeName: |
2052 | case DeclaratorContext::FunctionalCast: |
2053 | case DeclaratorContext::CXXNew: |
2054 | case DeclaratorContext::AliasDecl: |
2055 | case DeclaratorContext::AliasTemplate: |
2056 | case DeclaratorContext::ObjCParameter: |
2057 | case DeclaratorContext::ObjCResult: |
2058 | case DeclaratorContext::BlockLiteral: |
2059 | case DeclaratorContext::LambdaExpr: |
2060 | case DeclaratorContext::ConversionId: |
2061 | case DeclaratorContext::TemplateArg: |
2062 | case DeclaratorContext::TemplateTypeArg: |
2063 | case DeclaratorContext::TrailingReturn: |
2064 | case DeclaratorContext::TrailingReturnVar: |
2065 | return false; |
2066 | } |
2067 | llvm_unreachable("unknown context kind!")__builtin_unreachable(); |
2068 | } |
2069 | |
2070 | /// Return true if the context permits a C++17 decomposition declarator. |
2071 | bool mayHaveDecompositionDeclarator() const { |
2072 | switch (Context) { |
2073 | case DeclaratorContext::File: |
2074 | // FIXME: It's not clear that the proposal meant to allow file-scope |
2075 | // structured bindings, but it does. |
2076 | case DeclaratorContext::Block: |
2077 | case DeclaratorContext::ForInit: |
2078 | case DeclaratorContext::SelectionInit: |
2079 | case DeclaratorContext::Condition: |
2080 | return true; |
2081 | |
2082 | case DeclaratorContext::Member: |
2083 | case DeclaratorContext::Prototype: |
2084 | case DeclaratorContext::TemplateParam: |
2085 | case DeclaratorContext::RequiresExpr: |
2086 | // Maybe one day... |
2087 | return false; |
2088 | |
2089 | // These contexts don't allow any kind of non-abstract declarator. |
2090 | case DeclaratorContext::KNRTypeList: |
2091 | case DeclaratorContext::TypeName: |
2092 | case DeclaratorContext::FunctionalCast: |
2093 | case DeclaratorContext::AliasDecl: |
2094 | case DeclaratorContext::AliasTemplate: |
2095 | case DeclaratorContext::LambdaExprParameter: |
2096 | case DeclaratorContext::ObjCParameter: |
2097 | case DeclaratorContext::ObjCResult: |
2098 | case DeclaratorContext::CXXNew: |
2099 | case DeclaratorContext::CXXCatch: |
2100 | case DeclaratorContext::ObjCCatch: |
2101 | case DeclaratorContext::BlockLiteral: |
2102 | case DeclaratorContext::LambdaExpr: |
2103 | case DeclaratorContext::ConversionId: |
2104 | case DeclaratorContext::TemplateArg: |
2105 | case DeclaratorContext::TemplateTypeArg: |
2106 | case DeclaratorContext::TrailingReturn: |
2107 | case DeclaratorContext::TrailingReturnVar: |
2108 | return false; |
2109 | } |
2110 | llvm_unreachable("unknown context kind!")__builtin_unreachable(); |
2111 | } |
2112 | |
2113 | /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be |
2114 | /// followed by a C++ direct initializer, e.g. "int x(1);". |
2115 | bool mayBeFollowedByCXXDirectInit() const { |
2116 | if (hasGroupingParens()) return false; |
2117 | |
2118 | if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) |
2119 | return false; |
2120 | |
2121 | if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern && |
2122 | Context != DeclaratorContext::File) |
2123 | return false; |
2124 | |
2125 | // Special names can't have direct initializers. |
2126 | if (Name.getKind() != UnqualifiedIdKind::IK_Identifier) |
2127 | return false; |
2128 | |
2129 | switch (Context) { |
2130 | case DeclaratorContext::File: |
2131 | case DeclaratorContext::Block: |
2132 | case DeclaratorContext::ForInit: |
2133 | case DeclaratorContext::SelectionInit: |
2134 | case DeclaratorContext::TrailingReturnVar: |
2135 | return true; |
2136 | |
2137 | case DeclaratorContext::Condition: |
2138 | // This may not be followed by a direct initializer, but it can't be a |
2139 | // function declaration either, and we'd prefer to perform a tentative |
2140 | // parse in order to produce the right diagnostic. |
2141 | return true; |
2142 | |
2143 | case DeclaratorContext::KNRTypeList: |
2144 | case DeclaratorContext::Member: |
2145 | case DeclaratorContext::Prototype: |
2146 | case DeclaratorContext::LambdaExprParameter: |
2147 | case DeclaratorContext::ObjCParameter: |
2148 | case DeclaratorContext::ObjCResult: |
2149 | case DeclaratorContext::TemplateParam: |
2150 | case DeclaratorContext::CXXCatch: |
2151 | case DeclaratorContext::ObjCCatch: |
2152 | case DeclaratorContext::TypeName: |
2153 | case DeclaratorContext::FunctionalCast: // FIXME |
2154 | case DeclaratorContext::CXXNew: |
2155 | case DeclaratorContext::AliasDecl: |
2156 | case DeclaratorContext::AliasTemplate: |
2157 | case DeclaratorContext::BlockLiteral: |
2158 | case DeclaratorContext::LambdaExpr: |
2159 | case DeclaratorContext::ConversionId: |
2160 | case DeclaratorContext::TemplateArg: |
2161 | case DeclaratorContext::TemplateTypeArg: |
2162 | case DeclaratorContext::TrailingReturn: |
2163 | case DeclaratorContext::RequiresExpr: |
2164 | return false; |
2165 | } |
2166 | llvm_unreachable("unknown context kind!")__builtin_unreachable(); |
2167 | } |
2168 | |
2169 | /// isPastIdentifier - Return true if we have parsed beyond the point where |
2170 | /// the name would appear. (This may happen even if we haven't actually parsed |
2171 | /// a name, perhaps because this context doesn't require one.) |
2172 | bool isPastIdentifier() const { return Name.isValid(); } |
2173 | |
2174 | /// hasName - Whether this declarator has a name, which might be an |
2175 | /// identifier (accessible via getIdentifier()) or some kind of |
2176 | /// special C++ name (constructor, destructor, etc.), or a structured |
2177 | /// binding (which is not exactly a name, but occupies the same position). |
2178 | bool hasName() const { |
2179 | return Name.getKind() != UnqualifiedIdKind::IK_Identifier || |
2180 | Name.Identifier || isDecompositionDeclarator(); |
2181 | } |
2182 | |
2183 | /// Return whether this declarator is a decomposition declarator. |
2184 | bool isDecompositionDeclarator() const { |
2185 | return BindingGroup.isSet(); |
2186 | } |
2187 | |
2188 | IdentifierInfo *getIdentifier() const { |
2189 | if (Name.getKind() == UnqualifiedIdKind::IK_Identifier) |
2190 | return Name.Identifier; |
2191 | |
2192 | return nullptr; |
2193 | } |
2194 | SourceLocation getIdentifierLoc() const { return Name.StartLocation; } |
2195 | |
2196 | /// Set the name of this declarator to be the given identifier. |
2197 | void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) { |
2198 | Name.setIdentifier(Id, IdLoc); |
2199 | } |
2200 | |
2201 | /// Set the decomposition bindings for this declarator. |
2202 | void |
2203 | setDecompositionBindings(SourceLocation LSquareLoc, |
2204 | ArrayRef<DecompositionDeclarator::Binding> Bindings, |
2205 | SourceLocation RSquareLoc); |
2206 | |
2207 | /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to |
2208 | /// EndLoc, which should be the last token of the chunk. |
2209 | /// This function takes attrs by R-Value reference because it takes ownership |
2210 | /// of those attributes from the parameter. |
2211 | void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, |
2212 | SourceLocation EndLoc) { |
2213 | DeclTypeInfo.push_back(TI); |
2214 | DeclTypeInfo.back().getAttrs().addAll(attrs.begin(), attrs.end()); |
2215 | getAttributePool().takeAllFrom(attrs.getPool()); |
2216 | |
2217 | if (!EndLoc.isInvalid()) |
2218 | SetRangeEnd(EndLoc); |
2219 | } |
2220 | |
2221 | /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to |
2222 | /// EndLoc, which should be the last token of the chunk. |
2223 | void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) { |
2224 | DeclTypeInfo.push_back(TI); |
2225 | |
2226 | if (!EndLoc.isInvalid()) |
2227 | SetRangeEnd(EndLoc); |
2228 | } |
2229 | |
2230 | /// Add a new innermost chunk to this declarator. |
2231 | void AddInnermostTypeInfo(const DeclaratorChunk &TI) { |
2232 | DeclTypeInfo.insert(DeclTypeInfo.begin(), TI); |
2233 | } |
2234 | |
2235 | /// Return the number of types applied to this declarator. |
2236 | unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); } |
2237 | |
2238 | /// Return the specified TypeInfo from this declarator. TypeInfo #0 is |
2239 | /// closest to the identifier. |
2240 | const DeclaratorChunk &getTypeObject(unsigned i) const { |
2241 | assert(i < DeclTypeInfo.size() && "Invalid type chunk")((void)0); |
2242 | return DeclTypeInfo[i]; |
2243 | } |
2244 | DeclaratorChunk &getTypeObject(unsigned i) { |
2245 | assert(i < DeclTypeInfo.size() && "Invalid type chunk")((void)0); |
2246 | return DeclTypeInfo[i]; |
2247 | } |
2248 | |
2249 | typedef SmallVectorImpl<DeclaratorChunk>::const_iterator type_object_iterator; |
2250 | typedef llvm::iterator_range<type_object_iterator> type_object_range; |
2251 | |
2252 | /// Returns the range of type objects, from the identifier outwards. |
2253 | type_object_range type_objects() const { |
2254 | return type_object_range(DeclTypeInfo.begin(), DeclTypeInfo.end()); |
2255 | } |
2256 | |
2257 | void DropFirstTypeObject() { |
2258 | assert(!DeclTypeInfo.empty() && "No type chunks to drop.")((void)0); |
2259 | DeclTypeInfo.front().destroy(); |
2260 | DeclTypeInfo.erase(DeclTypeInfo.begin()); |
2261 | } |
2262 | |
2263 | /// Return the innermost (closest to the declarator) chunk of this |
2264 | /// declarator that is not a parens chunk, or null if there are no |
2265 | /// non-parens chunks. |
2266 | const DeclaratorChunk *getInnermostNonParenChunk() const { |
2267 | for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { |
2268 | if (!DeclTypeInfo[i].isParen()) |
2269 | return &DeclTypeInfo[i]; |
2270 | } |
2271 | return nullptr; |
2272 | } |
2273 | |
2274 | /// Return the outermost (furthest from the declarator) chunk of |
2275 | /// this declarator that is not a parens chunk, or null if there are |
2276 | /// no non-parens chunks. |
2277 | const DeclaratorChunk *getOutermostNonParenChunk() const { |
2278 | for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) { |
2279 | if (!DeclTypeInfo[i-1].isParen()) |
2280 | return &DeclTypeInfo[i-1]; |
2281 | } |
2282 | return nullptr; |
2283 | } |
2284 | |
2285 | /// isArrayOfUnknownBound - This method returns true if the declarator |
2286 | /// is a declarator for an array of unknown bound (looking through |
2287 | /// parentheses). |
2288 | bool isArrayOfUnknownBound() const { |
2289 | const DeclaratorChunk *chunk = getInnermostNonParenChunk(); |
2290 | return (chunk && chunk->Kind == DeclaratorChunk::Array && |
2291 | !chunk->Arr.NumElts); |
2292 | } |
2293 | |
2294 | /// isFunctionDeclarator - This method returns true if the declarator |
2295 | /// is a function declarator (looking through parentheses). |
2296 | /// If true is returned, then the reference type parameter idx is |
2297 | /// assigned with the index of the declaration chunk. |
2298 | bool isFunctionDeclarator(unsigned& idx) const { |
2299 | for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { |
2300 | switch (DeclTypeInfo[i].Kind) { |
2301 | case DeclaratorChunk::Function: |
2302 | idx = i; |
2303 | return true; |
2304 | case DeclaratorChunk::Paren: |
2305 | continue; |
2306 | case DeclaratorChunk::Pointer: |
2307 | case DeclaratorChunk::Reference: |
2308 | case DeclaratorChunk::Array: |
2309 | case DeclaratorChunk::BlockPointer: |
2310 | case DeclaratorChunk::MemberPointer: |
2311 | case DeclaratorChunk::Pipe: |
2312 | return false; |
2313 | } |
2314 | llvm_unreachable("Invalid type chunk")__builtin_unreachable(); |
2315 | } |
2316 | return false; |
2317 | } |
2318 | |
2319 | /// isFunctionDeclarator - Once this declarator is fully parsed and formed, |
2320 | /// this method returns true if the identifier is a function declarator |
2321 | /// (looking through parentheses). |
2322 | bool isFunctionDeclarator() const { |
2323 | unsigned index; |
2324 | return isFunctionDeclarator(index); |
2325 | } |
2326 | |
2327 | /// getFunctionTypeInfo - Retrieves the function type info object |
2328 | /// (looking through parentheses). |
2329 | DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() { |
2330 | assert(isFunctionDeclarator() && "Not a function declarator!")((void)0); |
2331 | unsigned index = 0; |
2332 | isFunctionDeclarator(index); |
2333 | return DeclTypeInfo[index].Fun; |
2334 | } |
2335 | |
2336 | /// getFunctionTypeInfo - Retrieves the function type info object |
2337 | /// (looking through parentheses). |
2338 | const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const { |
2339 | return const_cast<Declarator*>(this)->getFunctionTypeInfo(); |
2340 | } |
2341 | |
2342 | /// Determine whether the declaration that will be produced from |
2343 | /// this declaration will be a function. |
2344 | /// |
2345 | /// A declaration can declare a function even if the declarator itself |
2346 | /// isn't a function declarator, if the type specifier refers to a function |
2347 | /// type. This routine checks for both cases. |
2348 | bool isDeclarationOfFunction() const; |
2349 | |
2350 | /// Return true if this declaration appears in a context where a |
2351 | /// function declarator would be a function declaration. |
2352 | bool isFunctionDeclarationContext() const { |
2353 | if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) |
2354 | return false; |
2355 | |
2356 | switch (Context) { |
2357 | case DeclaratorContext::File: |
2358 | case DeclaratorContext::Member: |
2359 | case DeclaratorContext::Block: |
2360 | case DeclaratorContext::ForInit: |
2361 | case DeclaratorContext::SelectionInit: |
2362 | return true; |
2363 | |
2364 | case DeclaratorContext::Condition: |
2365 | case DeclaratorContext::KNRTypeList: |
2366 | case DeclaratorContext::TypeName: |
2367 | case DeclaratorContext::FunctionalCast: |
2368 | case DeclaratorContext::AliasDecl: |
2369 | case DeclaratorContext::AliasTemplate: |
2370 | case DeclaratorContext::Prototype: |
2371 | case DeclaratorContext::LambdaExprParameter: |
2372 | case DeclaratorContext::ObjCParameter: |
2373 | case DeclaratorContext::ObjCResult: |
2374 | case DeclaratorContext::TemplateParam: |
2375 | case DeclaratorContext::CXXNew: |
2376 | case DeclaratorContext::CXXCatch: |
2377 | case DeclaratorContext::ObjCCatch: |
2378 | case DeclaratorContext::BlockLiteral: |
2379 | case DeclaratorContext::LambdaExpr: |
2380 | case DeclaratorContext::ConversionId: |
2381 | case DeclaratorContext::TemplateArg: |
2382 | case DeclaratorContext::TemplateTypeArg: |
2383 | case DeclaratorContext::TrailingReturn: |
2384 | case DeclaratorContext::TrailingReturnVar: |
2385 | case DeclaratorContext::RequiresExpr: |
2386 | return false; |
2387 | } |
2388 | llvm_unreachable("unknown context kind!")__builtin_unreachable(); |
2389 | } |
2390 | |
2391 | /// Determine whether this declaration appears in a context where an |
2392 | /// expression could appear. |
2393 | bool isExpressionContext() const { |
2394 | switch (Context) { |
2395 | case DeclaratorContext::File: |
2396 | case DeclaratorContext::KNRTypeList: |
2397 | case DeclaratorContext::Member: |
2398 | |
2399 | // FIXME: sizeof(...) permits an expression. |
2400 | case DeclaratorContext::TypeName: |
2401 | |
2402 | case DeclaratorContext::FunctionalCast: |
2403 | case DeclaratorContext::AliasDecl: |
2404 | case DeclaratorContext::AliasTemplate: |
2405 | case DeclaratorContext::Prototype: |
2406 | case DeclaratorContext::LambdaExprParameter: |
2407 | case DeclaratorContext::ObjCParameter: |
2408 | case DeclaratorContext::ObjCResult: |
2409 | case DeclaratorContext::TemplateParam: |
2410 | case DeclaratorContext::CXXNew: |
2411 | case DeclaratorContext::CXXCatch: |
2412 | case DeclaratorContext::ObjCCatch: |
2413 | case DeclaratorContext::BlockLiteral: |
2414 | case DeclaratorContext::LambdaExpr: |
2415 | case DeclaratorContext::ConversionId: |
2416 | case DeclaratorContext::TrailingReturn: |
2417 | case DeclaratorContext::TrailingReturnVar: |
2418 | case DeclaratorContext::TemplateTypeArg: |
2419 | case DeclaratorContext::RequiresExpr: |
2420 | return false; |
2421 | |
2422 | case DeclaratorContext::Block: |
2423 | case DeclaratorContext::ForInit: |
2424 | case DeclaratorContext::SelectionInit: |
2425 | case DeclaratorContext::Condition: |
2426 | case DeclaratorContext::TemplateArg: |
2427 | return true; |
2428 | } |
2429 | |
2430 | llvm_unreachable("unknown context kind!")__builtin_unreachable(); |
2431 | } |
2432 | |
2433 | /// Return true if a function declarator at this position would be a |
2434 | /// function declaration. |
2435 | bool isFunctionDeclaratorAFunctionDeclaration() const { |
2436 | if (!isFunctionDeclarationContext()) |
2437 | return false; |
2438 | |
2439 | for (unsigned I = 0, N = getNumTypeObjects(); I != N; ++I) |
2440 | if (getTypeObject(I).Kind != DeclaratorChunk::Paren) |
2441 | return false; |
2442 | |
2443 | return true; |
2444 | } |
2445 | |
2446 | /// Determine whether a trailing return type was written (at any |
2447 | /// level) within this declarator. |
2448 | bool hasTrailingReturnType() const { |
2449 | for (const auto &Chunk : type_objects()) |
2450 | if (Chunk.Kind == DeclaratorChunk::Function && |
2451 | Chunk.Fun.hasTrailingReturnType()) |
2452 | return true; |
2453 | return false; |
2454 | } |
2455 | /// Get the trailing return type appearing (at any level) within this |
2456 | /// declarator. |
2457 | ParsedType getTrailingReturnType() const { |
2458 | for (const auto &Chunk : type_objects()) |
2459 | if (Chunk.Kind == DeclaratorChunk::Function && |
2460 | Chunk.Fun.hasTrailingReturnType()) |
2461 | return Chunk.Fun.getTrailingReturnType(); |
2462 | return ParsedType(); |
2463 | } |
2464 | |
2465 | /// \brief Sets a trailing requires clause for this declarator. |
2466 | void setTrailingRequiresClause(Expr *TRC) { |
2467 | TrailingRequiresClause = TRC; |
2468 | |
2469 | SetRangeEnd(TRC->getEndLoc()); |
2470 | } |
2471 | |
2472 | /// \brief Sets a trailing requires clause for this declarator. |
2473 | Expr *getTrailingRequiresClause() { |
2474 | return TrailingRequiresClause; |
2475 | } |
2476 | |
2477 | /// \brief Determine whether a trailing requires clause was written in this |
2478 | /// declarator. |
2479 | bool hasTrailingRequiresClause() const { |
2480 | return TrailingRequiresClause != nullptr; |
2481 | } |
2482 | |
2483 | /// Sets the template parameter lists that preceded the declarator. |
2484 | void setTemplateParameterLists(ArrayRef<TemplateParameterList *> TPLs) { |
2485 | TemplateParameterLists = TPLs; |
2486 | } |
2487 | |
2488 | /// The template parameter lists that preceded the declarator. |
2489 | ArrayRef<TemplateParameterList *> getTemplateParameterLists() const { |
2490 | return TemplateParameterLists; |
2491 | } |
2492 | |
2493 | /// Sets the template parameter list generated from the explicit template |
2494 | /// parameters along with any invented template parameters from |
2495 | /// placeholder-typed parameters. |
2496 | void setInventedTemplateParameterList(TemplateParameterList *Invented) { |
2497 | InventedTemplateParameterList = Invented; |
2498 | } |
2499 | |
2500 | /// The template parameter list generated from the explicit template |
2501 | /// parameters along with any invented template parameters from |
2502 | /// placeholder-typed parameters, if there were any such parameters. |
2503 | TemplateParameterList * getInventedTemplateParameterList() const { |
2504 | return InventedTemplateParameterList; |
2505 | } |
2506 | |
2507 | /// takeAttributes - Takes attributes from the given parsed-attributes |
2508 | /// set and add them to this declarator. |
2509 | /// |
2510 | /// These examples both add 3 attributes to "var": |
2511 | /// short int var __attribute__((aligned(16),common,deprecated)); |
2512 | /// short int x, __attribute__((aligned(16)) var |
2513 | /// __attribute__((common,deprecated)); |
2514 | /// |
2515 | /// Also extends the range of the declarator. |
2516 | void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) { |
2517 | Attrs.takeAllFrom(attrs); |
2518 | |
2519 | if (!lastLoc.isInvalid()) |
2520 | SetRangeEnd(lastLoc); |
2521 | } |
2522 | |
2523 | const ParsedAttributes &getAttributes() const { return Attrs; } |
2524 | ParsedAttributes &getAttributes() { return Attrs; } |
2525 | |
2526 | /// hasAttributes - do we contain any attributes? |
2527 | bool hasAttributes() const { |
2528 | if (!getAttributes().empty() || getDeclSpec().hasAttributes()) |
2529 | return true; |
2530 | for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i) |
2531 | if (!getTypeObject(i).getAttrs().empty()) |
2532 | return true; |
2533 | return false; |
2534 | } |
2535 | |
2536 | /// Return a source range list of C++11 attributes associated |
2537 | /// with the declarator. |
2538 | void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) { |
2539 | for (const ParsedAttr &AL : Attrs) |
2540 | if (AL.isCXX11Attribute()) |
2541 | Ranges.push_back(AL.getRange()); |
2542 | } |
2543 | |
2544 | void setAsmLabel(Expr *E) { AsmLabel = E; } |
2545 | Expr *getAsmLabel() const { return AsmLabel; } |
2546 | |
2547 | void setExtension(bool Val = true) { Extension = Val; } |
2548 | bool getExtension() const { return Extension; } |
2549 | |
2550 | void setObjCIvar(bool Val = true) { ObjCIvar = Val; } |
2551 | bool isObjCIvar() const { return ObjCIvar; } |
2552 | |
2553 | void setObjCWeakProperty(bool Val = true) { ObjCWeakProperty = Val; } |
2554 | bool isObjCWeakProperty() const { return ObjCWeakProperty; } |
2555 | |
2556 | void setInvalidType(bool Val = true) { InvalidType = Val; } |
2557 | bool isInvalidType() const { |
2558 | return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error; |
2559 | } |
2560 | |
2561 | void setGroupingParens(bool flag) { GroupingParens = flag; } |
2562 | bool hasGroupingParens() const { return GroupingParens; } |
2563 | |
2564 | bool isFirstDeclarator() const { return !CommaLoc.isValid(); } |
2565 | SourceLocation getCommaLoc() const { return CommaLoc; } |
2566 | void setCommaLoc(SourceLocation CL) { CommaLoc = CL; } |
2567 | |
2568 | bool hasEllipsis() const { return EllipsisLoc.isValid(); } |
2569 | SourceLocation getEllipsisLoc() const { return EllipsisLoc; } |
2570 | void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; } |
2571 | |
2572 | void setFunctionDefinitionKind(FunctionDefinitionKind Val) { |
2573 | FunctionDefinition = static_cast<unsigned>(Val); |
2574 | } |
2575 | |
2576 | bool isFunctionDefinition() const { |
2577 | return getFunctionDefinitionKind() != FunctionDefinitionKind::Declaration; |
2578 | } |
2579 | |
2580 | FunctionDefinitionKind getFunctionDefinitionKind() const { |
2581 | return (FunctionDefinitionKind)FunctionDefinition; |
2582 | } |
2583 | |
2584 | void setHasInitializer(bool Val = true) { HasInitializer = Val; } |
2585 | bool hasInitializer() const { return HasInitializer; } |
2586 | |
2587 | /// Returns true if this declares a real member and not a friend. |
2588 | bool isFirstDeclarationOfMember() { |
2589 | return getContext() == DeclaratorContext::Member && |
2590 | !getDeclSpec().isFriendSpecified(); |
2591 | } |
2592 | |
2593 | /// Returns true if this declares a static member. This cannot be called on a |
2594 | /// declarator outside of a MemberContext because we won't know until |
2595 | /// redeclaration time if the decl is static. |
2596 | bool isStaticMember(); |
2597 | |
2598 | /// Returns true if this declares a constructor or a destructor. |
2599 | bool isCtorOrDtor(); |
2600 | |
2601 | void setRedeclaration(bool Val) { Redeclaration = Val; } |
2602 | bool isRedeclaration() const { return Redeclaration; } |
2603 | }; |
2604 | |
2605 | /// This little struct is used to capture information about |
2606 | /// structure field declarators, which is basically just a bitfield size. |
2607 | struct FieldDeclarator { |
2608 | Declarator D; |
2609 | Expr *BitfieldSize; |
2610 | explicit FieldDeclarator(const DeclSpec &DS) |
2611 | : D(DS, DeclaratorContext::Member), BitfieldSize(nullptr) {} |
2612 | }; |
2613 | |
2614 | /// Represents a C++11 virt-specifier-seq. |
2615 | class VirtSpecifiers { |
2616 | public: |
2617 | enum Specifier { |
2618 | VS_None = 0, |
2619 | VS_Override = 1, |
2620 | VS_Final = 2, |
2621 | VS_Sealed = 4, |
2622 | // Represents the __final keyword, which is legal for gcc in pre-C++11 mode. |
2623 | VS_GNU_Final = 8, |
2624 | VS_Abstract = 16 |
2625 | }; |
2626 | |
2627 | VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { } |
2628 | |
2629 | bool SetSpecifier(Specifier VS, SourceLocation Loc, |
2630 | const char *&PrevSpec); |
2631 | |
2632 | bool isUnset() const { return Specifiers == 0; } |
2633 | |
2634 | bool isOverrideSpecified() const { return Specifiers & VS_Override; } |
2635 | SourceLocation getOverrideLoc() const { return VS_overrideLoc; } |
2636 | |
2637 | bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed | VS_GNU_Final); } |
2638 | bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; } |
2639 | SourceLocation getFinalLoc() const { return VS_finalLoc; } |
2640 | SourceLocation getAbstractLoc() const { return VS_abstractLoc; } |
2641 | |
2642 | void clear() { Specifiers = 0; } |
2643 | |
2644 | static const char *getSpecifierName(Specifier VS); |
2645 | |
2646 | SourceLocation getFirstLocation() const { return FirstLocation; } |
2647 | SourceLocation getLastLocation() const { return LastLocation; } |
2648 | Specifier getLastSpecifier() const { return LastSpecifier; } |
2649 | |
2650 | private: |
2651 | unsigned Specifiers; |
2652 | Specifier LastSpecifier; |
2653 | |
2654 | SourceLocation VS_overrideLoc, VS_finalLoc, VS_abstractLoc; |
2655 | SourceLocation FirstLocation; |
2656 | SourceLocation LastLocation; |
2657 | }; |
2658 | |
2659 | enum class LambdaCaptureInitKind { |
2660 | NoInit, //!< [a] |
2661 | CopyInit, //!< [a = b], [a = {b}] |
2662 | DirectInit, //!< [a(b)] |
2663 | ListInit //!< [a{b}] |
2664 | }; |
2665 | |
2666 | /// Represents a complete lambda introducer. |
2667 | struct LambdaIntroducer { |
2668 | /// An individual capture in a lambda introducer. |
2669 | struct LambdaCapture { |
2670 | LambdaCaptureKind Kind; |
2671 | SourceLocation Loc; |
2672 | IdentifierInfo *Id; |
2673 | SourceLocation EllipsisLoc; |
2674 | LambdaCaptureInitKind InitKind; |
2675 | ExprResult Init; |
2676 | ParsedType InitCaptureType; |
2677 | SourceRange ExplicitRange; |
2678 | |
2679 | LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc, |
2680 | IdentifierInfo *Id, SourceLocation EllipsisLoc, |
2681 | LambdaCaptureInitKind InitKind, ExprResult Init, |
2682 | ParsedType InitCaptureType, |
2683 | SourceRange ExplicitRange) |
2684 | : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), |
2685 | InitKind(InitKind), Init(Init), InitCaptureType(InitCaptureType), |
2686 | ExplicitRange(ExplicitRange) {} |
2687 | }; |
2688 | |
2689 | SourceRange Range; |
2690 | SourceLocation DefaultLoc; |
2691 | LambdaCaptureDefault Default; |
2692 | SmallVector<LambdaCapture, 4> Captures; |
2693 | |
2694 | LambdaIntroducer() |
2695 | : Default(LCD_None) {} |
2696 | |
2697 | /// Append a capture in a lambda introducer. |
2698 | void addCapture(LambdaCaptureKind Kind, |
2699 | SourceLocation Loc, |
2700 | IdentifierInfo* Id, |
2701 | SourceLocation EllipsisLoc, |
2702 | LambdaCaptureInitKind InitKind, |
2703 | ExprResult Init, |
2704 | ParsedType InitCaptureType, |
2705 | SourceRange ExplicitRange) { |
2706 | Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init, |
2707 | InitCaptureType, ExplicitRange)); |
2708 | } |
2709 | }; |
2710 | |
2711 | struct InventedTemplateParameterInfo { |
2712 | /// The number of parameters in the template parameter list that were |
2713 | /// explicitly specified by the user, as opposed to being invented by use |
2714 | /// of an auto parameter. |
2715 | unsigned NumExplicitTemplateParams = 0; |
2716 | |
2717 | /// If this is a generic lambda or abbreviated function template, use this |
2718 | /// as the depth of each 'auto' parameter, during initial AST construction. |
2719 | unsigned AutoTemplateParameterDepth = 0; |
2720 | |
2721 | /// Store the list of the template parameters for a generic lambda or an |
2722 | /// abbreviated function template. |
2723 | /// If this is a generic lambda or abbreviated function template, this holds |
2724 | /// the explicit template parameters followed by the auto parameters |
2725 | /// converted into TemplateTypeParmDecls. |
2726 | /// It can be used to construct the generic lambda or abbreviated template's |
2727 | /// template parameter list during initial AST construction. |
2728 | SmallVector<NamedDecl*, 4> TemplateParams; |
2729 | }; |
2730 | |
2731 | } // end namespace clang |
2732 | |
2733 | #endif // LLVM_CLANG_SEMA_DECLSPEC_H |