1//===--- ParseDecl.cpp - 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 Declaration portions of the Parser interfaces.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/AST/PrettyDeclStackTrace.h"
16#include "clang/Basic/AddressSpaces.h"
17#include "clang/Basic/AttributeCommonInfo.h"
18#include "clang/Basic/Attributes.h"
19#include "clang/Basic/CharInfo.h"
20#include "clang/Basic/DiagnosticParse.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/TokenKinds.h"
23#include "clang/Parse/Parser.h"
24#include "clang/Parse/RAIIObjectsForParser.h"
25#include "clang/Sema/EnterExpressionEvaluationContext.h"
26#include "clang/Sema/Lookup.h"
27#include "clang/Sema/ParsedAttr.h"
28#include "clang/Sema/ParsedTemplate.h"
29#include "clang/Sema/Scope.h"
30#include "clang/Sema/SemaCUDA.h"
31#include "clang/Sema/SemaCodeCompletion.h"
32#include "clang/Sema/SemaObjC.h"
33#include "clang/Sema/SemaOpenMP.h"
34#include "llvm/ADT/SmallSet.h"
35#include "llvm/ADT/StringSwitch.h"
36#include <optional>
37
38using namespace clang;
39
40//===----------------------------------------------------------------------===//
41// C99 6.7: Declarations.
42//===----------------------------------------------------------------------===//
43
44TypeResult Parser::ParseTypeName(SourceRange *Range, DeclaratorContext Context,
45 AccessSpecifier AS, Decl **OwnedType,
46 ParsedAttributes *Attrs) {
47 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
48 if (DSC == DeclSpecContext::DSC_normal)
49 DSC = DeclSpecContext::DSC_type_specifier;
50
51 // Parse the common declaration-specifiers piece.
52 DeclSpec DS(AttrFactory);
53 if (Attrs)
54 DS.addAttributes(AL: *Attrs);
55 ParseSpecifierQualifierList(DS, AS, DSC);
56 if (OwnedType)
57 *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr;
58
59 // Move declspec attributes to ParsedAttributes
60 if (Attrs) {
61 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
62 for (ParsedAttr &AL : DS.getAttributes()) {
63 if (AL.isDeclspecAttribute())
64 ToBeMoved.push_back(Elt: &AL);
65 }
66
67 for (ParsedAttr *AL : ToBeMoved)
68 Attrs->takeOneFrom(Other&: DS.getAttributes(), PA: AL);
69 }
70
71 // Parse the abstract-declarator, if present.
72 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), Context);
73 ParseDeclarator(D&: DeclaratorInfo);
74 if (Range)
75 *Range = DeclaratorInfo.getSourceRange();
76
77 if (DeclaratorInfo.isInvalidType())
78 return true;
79
80 return Actions.ActOnTypeName(D&: DeclaratorInfo);
81}
82
83/// Normalizes an attribute name by dropping prefixed and suffixed __.
84static StringRef normalizeAttrName(StringRef Name) {
85 if (Name.size() >= 4 && Name.starts_with(Prefix: "__") && Name.ends_with(Suffix: "__"))
86 return Name.drop_front(N: 2).drop_back(N: 2);
87 return Name;
88}
89
90/// returns true iff attribute is annotated with `LateAttrParseExperimentalExt`
91/// in `Attr.td`.
92static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II) {
93#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
94 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
95#include "clang/Parse/AttrParserStringSwitches.inc"
96 .Default(Value: false);
97#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
98}
99
100/// returns true iff attribute is annotated with `LateAttrParseStandard` in
101/// `Attr.td`.
102static bool IsAttributeLateParsedStandard(const IdentifierInfo &II) {
103#define CLANG_ATTR_LATE_PARSED_LIST
104 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
105#include "clang/Parse/AttrParserStringSwitches.inc"
106 .Default(Value: false);
107#undef CLANG_ATTR_LATE_PARSED_LIST
108}
109
110/// Check if the a start and end source location expand to the same macro.
111static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc,
112 SourceLocation EndLoc) {
113 if (!StartLoc.isMacroID() || !EndLoc.isMacroID())
114 return false;
115
116 SourceManager &SM = PP.getSourceManager();
117 if (SM.getFileID(SpellingLoc: StartLoc) != SM.getFileID(SpellingLoc: EndLoc))
118 return false;
119
120 bool AttrStartIsInMacro =
121 Lexer::isAtStartOfMacroExpansion(loc: StartLoc, SM, LangOpts: PP.getLangOpts());
122 bool AttrEndIsInMacro =
123 Lexer::isAtEndOfMacroExpansion(loc: EndLoc, SM, LangOpts: PP.getLangOpts());
124 return AttrStartIsInMacro && AttrEndIsInMacro;
125}
126
127void Parser::ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
128 LateParsedAttrList *LateAttrs) {
129 bool MoreToParse;
130 do {
131 // Assume there's nothing left to parse, but if any attributes are in fact
132 // parsed, loop to ensure all specified attribute combinations are parsed.
133 MoreToParse = false;
134 if (WhichAttrKinds & PAKM_CXX11)
135 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
136 if (WhichAttrKinds & PAKM_GNU)
137 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
138 if (WhichAttrKinds & PAKM_Declspec)
139 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
140 } while (MoreToParse);
141}
142
143bool Parser::ParseSingleGNUAttribute(ParsedAttributes &Attrs,
144 SourceLocation &EndLoc,
145 LateParsedAttrList *LateAttrs,
146 Declarator *D) {
147 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
148 if (!AttrName)
149 return true;
150
151 SourceLocation AttrNameLoc = ConsumeToken();
152
153 if (Tok.isNot(K: tok::l_paren)) {
154 Attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
155 form: ParsedAttr::Form::GNU());
156 return false;
157 }
158
159 bool LateParse = false;
160 if (!LateAttrs)
161 LateParse = false;
162 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
163 // The caller requested that this attribute **only** be late
164 // parsed for `LateAttrParseExperimentalExt` attributes. This will
165 // only be late parsed if the experimental language option is enabled.
166 LateParse = getLangOpts().ExperimentalLateParseAttributes &&
167 IsAttributeLateParsedExperimentalExt(II: *AttrName);
168 } else {
169 // The caller did not restrict late parsing to only
170 // `LateAttrParseExperimentalExt` attributes so late parse
171 // both `LateAttrParseStandard` and `LateAttrParseExperimentalExt`
172 // attributes.
173 LateParse = IsAttributeLateParsedExperimentalExt(II: *AttrName) ||
174 IsAttributeLateParsedStandard(II: *AttrName);
175 }
176
177 // Handle "parameterized" attributes
178 if (!LateParse) {
179 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc: &EndLoc, ScopeName: nullptr,
180 ScopeLoc: SourceLocation(), Form: ParsedAttr::Form::GNU(), D);
181 return false;
182 }
183
184 // Handle attributes with arguments that require late parsing.
185 LateParsedAttribute *LA =
186 new LateParsedAttribute(this, *AttrName, AttrNameLoc);
187 LateAttrs->push_back(Elt: LA);
188
189 // Attributes in a class are parsed at the end of the class, along
190 // with other late-parsed declarations.
191 if (!ClassStack.empty() && !LateAttrs->parseSoon())
192 getCurrentClass().LateParsedDeclarations.push_back(Elt: LA);
193
194 // Be sure ConsumeAndStoreUntil doesn't see the start l_paren, since it
195 // recursively consumes balanced parens.
196 LA->Toks.push_back(Elt: Tok);
197 ConsumeParen();
198 // Consume everything up to and including the matching right parens.
199 ConsumeAndStoreUntil(T1: tok::r_paren, Toks&: LA->Toks, /*StopAtSemi=*/true);
200
201 Token Eof;
202 Eof.startToken();
203 Eof.setLocation(Tok.getLocation());
204 LA->Toks.push_back(Elt: Eof);
205
206 return false;
207}
208
209void Parser::ParseGNUAttributes(ParsedAttributes &Attrs,
210 LateParsedAttrList *LateAttrs, Declarator *D) {
211 assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
212
213 SourceLocation StartLoc = Tok.getLocation();
214 SourceLocation EndLoc = StartLoc;
215
216 while (Tok.is(K: tok::kw___attribute)) {
217 SourceLocation AttrTokLoc = ConsumeToken();
218 unsigned OldNumAttrs = Attrs.size();
219 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
220
221 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
222 "attribute")) {
223 SkipUntil(T: tok::r_paren, Flags: StopAtSemi); // skip until ) or ;
224 return;
225 }
226 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
227 SkipUntil(T: tok::r_paren, Flags: StopAtSemi); // skip until ) or ;
228 return;
229 }
230 // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
231 do {
232 // Eat preceeding commas to allow __attribute__((,,,foo))
233 while (TryConsumeToken(Expected: tok::comma))
234 ;
235
236 // Expect an identifier or declaration specifier (const, int, etc.)
237 if (Tok.isAnnotation())
238 break;
239 if (Tok.is(K: tok::code_completion)) {
240 cutOffParsing();
241 Actions.CodeCompletion().CodeCompleteAttribute(
242 Syntax: AttributeCommonInfo::Syntax::AS_GNU);
243 break;
244 }
245
246 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
247 break;
248 } while (Tok.is(K: tok::comma));
249
250 if (ExpectAndConsume(ExpectedTok: tok::r_paren))
251 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
252 SourceLocation Loc = Tok.getLocation();
253 if (ExpectAndConsume(ExpectedTok: tok::r_paren))
254 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
255 EndLoc = Loc;
256
257 // If this was declared in a macro, attach the macro IdentifierInfo to the
258 // parsed attribute.
259 auto &SM = PP.getSourceManager();
260 if (!SM.isWrittenInBuiltinFile(Loc: SM.getSpellingLoc(Loc: AttrTokLoc)) &&
261 FindLocsWithCommonFileID(PP, StartLoc: AttrTokLoc, EndLoc: Loc)) {
262 CharSourceRange ExpansionRange = SM.getExpansionRange(Loc: AttrTokLoc);
263 StringRef FoundName =
264 Lexer::getSourceText(Range: ExpansionRange, SM, LangOpts: PP.getLangOpts());
265 IdentifierInfo *MacroII = PP.getIdentifierInfo(Name: FoundName);
266
267 for (unsigned i = OldNumAttrs; i < Attrs.size(); ++i)
268 Attrs[i].setMacroIdentifier(MacroName: MacroII, Loc: ExpansionRange.getBegin());
269
270 if (LateAttrs) {
271 for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
272 (*LateAttrs)[i]->MacroII = MacroII;
273 }
274 }
275 }
276
277 Attrs.Range = SourceRange(StartLoc, EndLoc);
278}
279
280/// Determine whether the given attribute has an identifier argument.
281static bool attributeHasIdentifierArg(const llvm::Triple &T,
282 const IdentifierInfo &II,
283 ParsedAttr::Syntax Syntax,
284 IdentifierInfo *ScopeName) {
285#define CLANG_ATTR_IDENTIFIER_ARG_LIST
286 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
287#include "clang/Parse/AttrParserStringSwitches.inc"
288 .Default(Value: false);
289#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
290}
291
292/// Determine whether the given attribute has string arguments.
293static ParsedAttributeArgumentsProperties
294attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II,
295 ParsedAttr::Syntax Syntax,
296 IdentifierInfo *ScopeName) {
297#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
298 return llvm::StringSwitch<uint32_t>(normalizeAttrName(Name: II.getName()))
299#include "clang/Parse/AttrParserStringSwitches.inc"
300 .Default(Value: 0);
301#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
302}
303
304/// Determine whether the given attribute has a variadic identifier argument.
305static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II,
306 ParsedAttr::Syntax Syntax,
307 IdentifierInfo *ScopeName) {
308#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
309 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
310#include "clang/Parse/AttrParserStringSwitches.inc"
311 .Default(Value: false);
312#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
313}
314
315/// Determine whether the given attribute treats kw_this as an identifier.
316static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II,
317 ParsedAttr::Syntax Syntax,
318 IdentifierInfo *ScopeName) {
319#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
320 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
321#include "clang/Parse/AttrParserStringSwitches.inc"
322 .Default(Value: false);
323#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
324}
325
326/// Determine if an attribute accepts parameter packs.
327static bool attributeAcceptsExprPack(const IdentifierInfo &II,
328 ParsedAttr::Syntax Syntax,
329 IdentifierInfo *ScopeName) {
330#define CLANG_ATTR_ACCEPTS_EXPR_PACK
331 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
332#include "clang/Parse/AttrParserStringSwitches.inc"
333 .Default(Value: false);
334#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
335}
336
337/// Determine whether the given attribute parses a type argument.
338static bool attributeIsTypeArgAttr(const IdentifierInfo &II,
339 ParsedAttr::Syntax Syntax,
340 IdentifierInfo *ScopeName) {
341#define CLANG_ATTR_TYPE_ARG_LIST
342 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
343#include "clang/Parse/AttrParserStringSwitches.inc"
344 .Default(Value: false);
345#undef CLANG_ATTR_TYPE_ARG_LIST
346}
347
348/// Determine whether the given attribute takes a strict identifier argument.
349static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II,
350 ParsedAttr::Syntax Syntax,
351 IdentifierInfo *ScopeName) {
352#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
353 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
354#include "clang/Parse/AttrParserStringSwitches.inc"
355 .Default(Value: false);
356#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
357}
358
359/// Determine whether the given attribute requires parsing its arguments
360/// in an unevaluated context or not.
361static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II,
362 ParsedAttr::Syntax Syntax,
363 IdentifierInfo *ScopeName) {
364#define CLANG_ATTR_ARG_CONTEXT_LIST
365 return llvm::StringSwitch<bool>(normalizeAttrName(Name: II.getName()))
366#include "clang/Parse/AttrParserStringSwitches.inc"
367 .Default(Value: false);
368#undef CLANG_ATTR_ARG_CONTEXT_LIST
369}
370
371IdentifierLoc *Parser::ParseIdentifierLoc() {
372 assert(Tok.is(tok::identifier) && "expected an identifier");
373 IdentifierLoc *IL = new (Actions.Context)
374 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
375 ConsumeToken();
376 return IL;
377}
378
379void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
380 SourceLocation AttrNameLoc,
381 ParsedAttributes &Attrs,
382 IdentifierInfo *ScopeName,
383 SourceLocation ScopeLoc,
384 ParsedAttr::Form Form) {
385 BalancedDelimiterTracker Parens(*this, tok::l_paren);
386 Parens.consumeOpen();
387
388 TypeResult T;
389 if (Tok.isNot(K: tok::r_paren))
390 T = ParseTypeName();
391
392 if (Parens.consumeClose())
393 return;
394
395 if (T.isInvalid())
396 return;
397
398 if (T.isUsable())
399 Attrs.addNewTypeAttr(attrName: &AttrName,
400 attrRange: SourceRange(AttrNameLoc, Parens.getCloseLocation()),
401 scopeName: ScopeName, scopeLoc: ScopeLoc, typeArg: T.get(), formUsed: Form);
402 else
403 Attrs.addNew(attrName: &AttrName, attrRange: SourceRange(AttrNameLoc, Parens.getCloseLocation()),
404 scopeName: ScopeName, scopeLoc: ScopeLoc, args: nullptr, numArgs: 0, form: Form);
405}
406
407ExprResult
408Parser::ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName) {
409 if (Tok.is(K: tok::l_paren)) {
410 BalancedDelimiterTracker Paren(*this, tok::l_paren);
411 Paren.consumeOpen();
412 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
413 Paren.consumeClose();
414 return Res;
415 }
416 if (!isTokenStringLiteral()) {
417 Diag(Tok.getLocation(), diag::err_expected_string_literal)
418 << /*in attribute...*/ 4 << AttrName.getName();
419 return ExprError();
420 }
421 return ParseUnevaluatedStringLiteralExpression();
422}
423
424bool Parser::ParseAttributeArgumentList(
425 const IdentifierInfo &AttrName, SmallVectorImpl<Expr *> &Exprs,
426 ParsedAttributeArgumentsProperties ArgsProperties) {
427 bool SawError = false;
428 unsigned Arg = 0;
429 while (true) {
430 ExprResult Expr;
431 if (ArgsProperties.isStringLiteralArg(I: Arg)) {
432 Expr = ParseUnevaluatedStringInAttribute(AttrName);
433 } else if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::l_brace)) {
434 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
435 Expr = ParseBraceInitializer();
436 } else {
437 Expr = ParseAssignmentExpression();
438 }
439 Expr = Actions.CorrectDelayedTyposInExpr(ER: Expr);
440
441 if (Tok.is(K: tok::ellipsis))
442 Expr = Actions.ActOnPackExpansion(Pattern: Expr.get(), EllipsisLoc: ConsumeToken());
443 else if (Tok.is(K: tok::code_completion)) {
444 // There's nothing to suggest in here as we parsed a full expression.
445 // Instead fail and propagate the error since caller might have something
446 // the suggest, e.g. signature help in function call. Note that this is
447 // performed before pushing the \p Expr, so that signature help can report
448 // current argument correctly.
449 SawError = true;
450 cutOffParsing();
451 break;
452 }
453
454 if (Expr.isInvalid()) {
455 SawError = true;
456 break;
457 }
458
459 if (Actions.DiagnoseUnexpandedParameterPack(E: Expr.get())) {
460 SawError = true;
461 break;
462 }
463
464 Exprs.push_back(Elt: Expr.get());
465
466 if (Tok.isNot(K: tok::comma))
467 break;
468 // Move to the next argument, remember where the comma was.
469 Token Comma = Tok;
470 ConsumeToken();
471 checkPotentialAngleBracketDelimiter(OpToken: Comma);
472 Arg++;
473 }
474
475 if (SawError) {
476 // Ensure typos get diagnosed when errors were encountered while parsing the
477 // expression list.
478 for (auto &E : Exprs) {
479 ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E);
480 if (Expr.isUsable())
481 E = Expr.get();
482 }
483 }
484 return SawError;
485}
486
487unsigned Parser::ParseAttributeArgsCommon(
488 IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
489 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
490 SourceLocation ScopeLoc, ParsedAttr::Form Form) {
491 // Ignore the left paren location for now.
492 ConsumeParen();
493
494 bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier(
495 II: *AttrName, Syntax: Form.getSyntax(), ScopeName);
496 bool AttributeIsTypeArgAttr =
497 attributeIsTypeArgAttr(II: *AttrName, Syntax: Form.getSyntax(), ScopeName);
498 bool AttributeHasVariadicIdentifierArg =
499 attributeHasVariadicIdentifierArg(II: *AttrName, Syntax: Form.getSyntax(), ScopeName);
500
501 // Interpret "kw_this" as an identifier if the attributed requests it.
502 if (ChangeKWThisToIdent && Tok.is(K: tok::kw_this))
503 Tok.setKind(tok::identifier);
504
505 ArgsVector ArgExprs;
506 if (Tok.is(K: tok::identifier)) {
507 // If this attribute wants an 'identifier' argument, make it so.
508 bool IsIdentifierArg =
509 AttributeHasVariadicIdentifierArg ||
510 attributeHasIdentifierArg(T: getTargetInfo().getTriple(), II: *AttrName,
511 Syntax: Form.getSyntax(), ScopeName);
512 ParsedAttr::Kind AttrKind =
513 ParsedAttr::getParsedKind(Name: AttrName, Scope: ScopeName, SyntaxUsed: Form.getSyntax());
514
515 // If we don't know how to parse this attribute, but this is the only
516 // token in this argument, assume it's meant to be an identifier.
517 if (AttrKind == ParsedAttr::UnknownAttribute ||
518 AttrKind == ParsedAttr::IgnoredAttribute) {
519 const Token &Next = NextToken();
520 IsIdentifierArg = Next.isOneOf(K1: tok::r_paren, K2: tok::comma);
521 }
522
523 if (IsIdentifierArg)
524 ArgExprs.push_back(Elt: ParseIdentifierLoc());
525 }
526
527 ParsedType TheParsedType;
528 if (!ArgExprs.empty() ? Tok.is(K: tok::comma) : Tok.isNot(K: tok::r_paren)) {
529 // Eat the comma.
530 if (!ArgExprs.empty())
531 ConsumeToken();
532
533 if (AttributeIsTypeArgAttr) {
534 // FIXME: Multiple type arguments are not implemented.
535 TypeResult T = ParseTypeName();
536 if (T.isInvalid()) {
537 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
538 return 0;
539 }
540 if (T.isUsable())
541 TheParsedType = T.get();
542 } else if (AttributeHasVariadicIdentifierArg ||
543 attributeHasStrictIdentifierArgs(II: *AttrName, Syntax: Form.getSyntax(),
544 ScopeName)) {
545 // Parse variadic identifier arg. This can either consume identifiers or
546 // expressions. Variadic identifier args do not support parameter packs
547 // because those are typically used for attributes with enumeration
548 // arguments, and those enumerations are not something the user could
549 // express via a pack.
550 do {
551 // Interpret "kw_this" as an identifier if the attributed requests it.
552 if (ChangeKWThisToIdent && Tok.is(K: tok::kw_this))
553 Tok.setKind(tok::identifier);
554
555 ExprResult ArgExpr;
556 if (Tok.is(K: tok::identifier)) {
557 ArgExprs.push_back(Elt: ParseIdentifierLoc());
558 } else {
559 bool Uneval = attributeParsedArgsUnevaluated(
560 II: *AttrName, Syntax: Form.getSyntax(), ScopeName);
561 EnterExpressionEvaluationContext Unevaluated(
562 Actions,
563 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
564 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
565 nullptr,
566 Sema::ExpressionEvaluationContextRecord::EK_AttrArgument);
567
568 ExprResult ArgExpr(
569 Actions.CorrectDelayedTyposInExpr(ER: ParseAssignmentExpression()));
570
571 if (ArgExpr.isInvalid()) {
572 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
573 return 0;
574 }
575 ArgExprs.push_back(Elt: ArgExpr.get());
576 }
577 // Eat the comma, move to the next argument
578 } while (TryConsumeToken(Expected: tok::comma));
579 } else {
580 // General case. Parse all available expressions.
581 bool Uneval = attributeParsedArgsUnevaluated(II: *AttrName, Syntax: Form.getSyntax(),
582 ScopeName);
583 EnterExpressionEvaluationContext Unevaluated(
584 Actions,
585 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
586 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
587 nullptr,
588 Sema::ExpressionEvaluationContextRecord::ExpressionKind::
589 EK_AttrArgument);
590
591 ExprVector ParsedExprs;
592 ParsedAttributeArgumentsProperties ArgProperties =
593 attributeStringLiteralListArg(T: getTargetInfo().getTriple(), II: *AttrName,
594 Syntax: Form.getSyntax(), ScopeName);
595 if (ParseAttributeArgumentList(AttrName: *AttrName, Exprs&: ParsedExprs, ArgsProperties: ArgProperties)) {
596 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
597 return 0;
598 }
599
600 // Pack expansion must currently be explicitly supported by an attribute.
601 for (size_t I = 0; I < ParsedExprs.size(); ++I) {
602 if (!isa<PackExpansionExpr>(Val: ParsedExprs[I]))
603 continue;
604
605 if (!attributeAcceptsExprPack(II: *AttrName, Syntax: Form.getSyntax(), ScopeName)) {
606 Diag(Tok.getLocation(),
607 diag::err_attribute_argument_parm_pack_not_supported)
608 << AttrName;
609 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
610 return 0;
611 }
612 }
613
614 llvm::append_range(C&: ArgExprs, R&: ParsedExprs);
615 }
616 }
617
618 SourceLocation RParen = Tok.getLocation();
619 if (!ExpectAndConsume(ExpectedTok: tok::r_paren)) {
620 SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
621
622 if (AttributeIsTypeArgAttr && !TheParsedType.get().isNull()) {
623 Attrs.addNewTypeAttr(attrName: AttrName, attrRange: SourceRange(AttrNameLoc, RParen),
624 scopeName: ScopeName, scopeLoc: ScopeLoc, typeArg: TheParsedType, formUsed: Form);
625 } else {
626 Attrs.addNew(attrName: AttrName, attrRange: SourceRange(AttrLoc, RParen), scopeName: ScopeName, scopeLoc: ScopeLoc,
627 args: ArgExprs.data(), numArgs: ArgExprs.size(), form: Form);
628 }
629 }
630
631 if (EndLoc)
632 *EndLoc = RParen;
633
634 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.get().isNull());
635}
636
637void Parser::ParseGNUAttributeArgs(
638 IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
639 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
640 SourceLocation ScopeLoc, ParsedAttr::Form Form, Declarator *D) {
641
642 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
643
644 ParsedAttr::Kind AttrKind =
645 ParsedAttr::getParsedKind(Name: AttrName, Scope: ScopeName, SyntaxUsed: Form.getSyntax());
646
647 if (AttrKind == ParsedAttr::AT_Availability) {
648 ParseAvailabilityAttribute(Availability&: *AttrName, AvailabilityLoc: AttrNameLoc, attrs&: Attrs, endLoc: EndLoc, ScopeName,
649 ScopeLoc, Form);
650 return;
651 } else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
652 ParseExternalSourceSymbolAttribute(ExternalSourceSymbol&: *AttrName, Loc: AttrNameLoc, Attrs, EndLoc,
653 ScopeName, ScopeLoc, Form);
654 return;
655 } else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
656 ParseObjCBridgeRelatedAttribute(ObjCBridgeRelated&: *AttrName, ObjCBridgeRelatedLoc: AttrNameLoc, Attrs, EndLoc,
657 ScopeName, ScopeLoc, Form);
658 return;
659 } else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
660 ParseSwiftNewTypeAttribute(AttrName&: *AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
661 ScopeLoc, Form);
662 return;
663 } else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
664 ParseTypeTagForDatatypeAttribute(AttrName&: *AttrName, AttrNameLoc, Attrs, EndLoc,
665 ScopeName, ScopeLoc, Form);
666 return;
667 } else if (attributeIsTypeArgAttr(II: *AttrName, Syntax: Form.getSyntax(), ScopeName)) {
668 ParseAttributeWithTypeArg(AttrName&: *AttrName, AttrNameLoc, Attrs, ScopeName,
669 ScopeLoc, Form);
670 return;
671 } else if (AttrKind == ParsedAttr::AT_CountedBy ||
672 AttrKind == ParsedAttr::AT_CountedByOrNull ||
673 AttrKind == ParsedAttr::AT_SizedBy ||
674 AttrKind == ParsedAttr::AT_SizedByOrNull) {
675 ParseBoundsAttribute(AttrName&: *AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
676 Form);
677 return;
678 } else if (AttrKind == ParsedAttr::AT_CXXAssume) {
679 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
680 ScopeLoc, EndLoc, Form);
681 return;
682 }
683
684 // These may refer to the function arguments, but need to be parsed early to
685 // participate in determining whether it's a redeclaration.
686 std::optional<ParseScope> PrototypeScope;
687 if (normalizeAttrName(Name: AttrName->getName()) == "enable_if" &&
688 D && D->isFunctionDeclarator()) {
689 DeclaratorChunk::FunctionTypeInfo FTI = D->getFunctionTypeInfo();
690 PrototypeScope.emplace(args: this, args: Scope::FunctionPrototypeScope |
691 Scope::FunctionDeclarationScope |
692 Scope::DeclScope);
693 for (unsigned i = 0; i != FTI.NumParams; ++i) {
694 ParmVarDecl *Param = cast<ParmVarDecl>(Val: FTI.Params[i].Param);
695 Actions.ActOnReenterCXXMethodParameter(S: getCurScope(), Param);
696 }
697 }
698
699 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
700 ScopeLoc, Form);
701}
702
703unsigned Parser::ParseClangAttributeArgs(
704 IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
705 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
706 SourceLocation ScopeLoc, ParsedAttr::Form Form) {
707 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
708
709 ParsedAttr::Kind AttrKind =
710 ParsedAttr::getParsedKind(Name: AttrName, Scope: ScopeName, SyntaxUsed: Form.getSyntax());
711
712 switch (AttrKind) {
713 default:
714 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
715 ScopeName, ScopeLoc, Form);
716 case ParsedAttr::AT_ExternalSourceSymbol:
717 ParseExternalSourceSymbolAttribute(ExternalSourceSymbol&: *AttrName, Loc: AttrNameLoc, Attrs, EndLoc,
718 ScopeName, ScopeLoc, Form);
719 break;
720 case ParsedAttr::AT_Availability:
721 ParseAvailabilityAttribute(Availability&: *AttrName, AvailabilityLoc: AttrNameLoc, attrs&: Attrs, endLoc: EndLoc, ScopeName,
722 ScopeLoc, Form);
723 break;
724 case ParsedAttr::AT_ObjCBridgeRelated:
725 ParseObjCBridgeRelatedAttribute(ObjCBridgeRelated&: *AttrName, ObjCBridgeRelatedLoc: AttrNameLoc, Attrs, EndLoc,
726 ScopeName, ScopeLoc, Form);
727 break;
728 case ParsedAttr::AT_SwiftNewType:
729 ParseSwiftNewTypeAttribute(AttrName&: *AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
730 ScopeLoc, Form);
731 break;
732 case ParsedAttr::AT_TypeTagForDatatype:
733 ParseTypeTagForDatatypeAttribute(AttrName&: *AttrName, AttrNameLoc, Attrs, EndLoc,
734 ScopeName, ScopeLoc, Form);
735 break;
736
737 case ParsedAttr::AT_CXXAssume:
738 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
739 ScopeLoc, EndLoc, Form);
740 break;
741 }
742 return !Attrs.empty() ? Attrs.begin()->getNumArgs() : 0;
743}
744
745bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
746 SourceLocation AttrNameLoc,
747 ParsedAttributes &Attrs) {
748 unsigned ExistingAttrs = Attrs.size();
749
750 // If the attribute isn't known, we will not attempt to parse any
751 // arguments.
752 if (!hasAttribute(Syntax: AttributeCommonInfo::Syntax::AS_Declspec, Scope: nullptr, Attr: AttrName,
753 Target: getTargetInfo(), LangOpts: getLangOpts())) {
754 // Eat the left paren, then skip to the ending right paren.
755 ConsumeParen();
756 SkipUntil(T: tok::r_paren);
757 return false;
758 }
759
760 SourceLocation OpenParenLoc = Tok.getLocation();
761
762 if (AttrName->getName() == "property") {
763 // The property declspec is more complex in that it can take one or two
764 // assignment expressions as a parameter, but the lhs of the assignment
765 // must be named get or put.
766
767 BalancedDelimiterTracker T(*this, tok::l_paren);
768 T.expectAndConsume(diag::err_expected_lparen_after,
769 AttrName->getNameStart(), tok::r_paren);
770
771 enum AccessorKind {
772 AK_Invalid = -1,
773 AK_Put = 0,
774 AK_Get = 1 // indices into AccessorNames
775 };
776 IdentifierInfo *AccessorNames[] = {nullptr, nullptr};
777 bool HasInvalidAccessor = false;
778
779 // Parse the accessor specifications.
780 while (true) {
781 // Stop if this doesn't look like an accessor spec.
782 if (!Tok.is(K: tok::identifier)) {
783 // If the user wrote a completely empty list, use a special diagnostic.
784 if (Tok.is(K: tok::r_paren) && !HasInvalidAccessor &&
785 AccessorNames[AK_Put] == nullptr &&
786 AccessorNames[AK_Get] == nullptr) {
787 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
788 break;
789 }
790
791 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
792 break;
793 }
794
795 AccessorKind Kind;
796 SourceLocation KindLoc = Tok.getLocation();
797 StringRef KindStr = Tok.getIdentifierInfo()->getName();
798 if (KindStr == "get") {
799 Kind = AK_Get;
800 } else if (KindStr == "put") {
801 Kind = AK_Put;
802
803 // Recover from the common mistake of using 'set' instead of 'put'.
804 } else if (KindStr == "set") {
805 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
806 << FixItHint::CreateReplacement(KindLoc, "put");
807 Kind = AK_Put;
808
809 // Handle the mistake of forgetting the accessor kind by skipping
810 // this accessor.
811 } else if (NextToken().is(K: tok::comma) || NextToken().is(K: tok::r_paren)) {
812 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
813 ConsumeToken();
814 HasInvalidAccessor = true;
815 goto next_property_accessor;
816
817 // Otherwise, complain about the unknown accessor kind.
818 } else {
819 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
820 HasInvalidAccessor = true;
821 Kind = AK_Invalid;
822
823 // Try to keep parsing unless it doesn't look like an accessor spec.
824 if (!NextToken().is(K: tok::equal))
825 break;
826 }
827
828 // Consume the identifier.
829 ConsumeToken();
830
831 // Consume the '='.
832 if (!TryConsumeToken(Expected: tok::equal)) {
833 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
834 << KindStr;
835 break;
836 }
837
838 // Expect the method name.
839 if (!Tok.is(K: tok::identifier)) {
840 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
841 break;
842 }
843
844 if (Kind == AK_Invalid) {
845 // Just drop invalid accessors.
846 } else if (AccessorNames[Kind] != nullptr) {
847 // Complain about the repeated accessor, ignore it, and keep parsing.
848 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
849 } else {
850 AccessorNames[Kind] = Tok.getIdentifierInfo();
851 }
852 ConsumeToken();
853
854 next_property_accessor:
855 // Keep processing accessors until we run out.
856 if (TryConsumeToken(Expected: tok::comma))
857 continue;
858
859 // If we run into the ')', stop without consuming it.
860 if (Tok.is(K: tok::r_paren))
861 break;
862
863 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
864 break;
865 }
866
867 // Only add the property attribute if it was well-formed.
868 if (!HasInvalidAccessor)
869 Attrs.addNewPropertyAttr(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: SourceLocation(),
870 getterId: AccessorNames[AK_Get], setterId: AccessorNames[AK_Put],
871 formUsed: ParsedAttr::Form::Declspec());
872 T.skipToEnd();
873 return !HasInvalidAccessor;
874 }
875
876 unsigned NumArgs =
877 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc: nullptr, ScopeName: nullptr,
878 ScopeLoc: SourceLocation(), Form: ParsedAttr::Form::Declspec());
879
880 // If this attribute's args were parsed, and it was expected to have
881 // arguments but none were provided, emit a diagnostic.
882 if (ExistingAttrs < Attrs.size() && Attrs.back().getMaxArgs() && !NumArgs) {
883 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
884 return false;
885 }
886 return true;
887}
888
889void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {
890 assert(getLangOpts().DeclSpecKeyword && "__declspec keyword is not enabled");
891 assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
892
893 SourceLocation StartLoc = Tok.getLocation();
894 SourceLocation EndLoc = StartLoc;
895
896 while (Tok.is(K: tok::kw___declspec)) {
897 ConsumeToken();
898 BalancedDelimiterTracker T(*this, tok::l_paren);
899 if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",
900 tok::r_paren))
901 return;
902
903 // An empty declspec is perfectly legal and should not warn. Additionally,
904 // you can specify multiple attributes per declspec.
905 while (Tok.isNot(K: tok::r_paren)) {
906 // Attribute not present.
907 if (TryConsumeToken(Expected: tok::comma))
908 continue;
909
910 if (Tok.is(K: tok::code_completion)) {
911 cutOffParsing();
912 Actions.CodeCompletion().CodeCompleteAttribute(
913 Syntax: AttributeCommonInfo::AS_Declspec);
914 return;
915 }
916
917 // We expect either a well-known identifier or a generic string. Anything
918 // else is a malformed declspec.
919 bool IsString = Tok.getKind() == tok::string_literal;
920 if (!IsString && Tok.getKind() != tok::identifier &&
921 Tok.getKind() != tok::kw_restrict) {
922 Diag(Tok, diag::err_ms_declspec_type);
923 T.skipToEnd();
924 return;
925 }
926
927 IdentifierInfo *AttrName;
928 SourceLocation AttrNameLoc;
929 if (IsString) {
930 SmallString<8> StrBuffer;
931 bool Invalid = false;
932 StringRef Str = PP.getSpelling(Tok, Buffer&: StrBuffer, Invalid: &Invalid);
933 if (Invalid) {
934 T.skipToEnd();
935 return;
936 }
937 AttrName = PP.getIdentifierInfo(Name: Str);
938 AttrNameLoc = ConsumeStringToken();
939 } else {
940 AttrName = Tok.getIdentifierInfo();
941 AttrNameLoc = ConsumeToken();
942 }
943
944 bool AttrHandled = false;
945
946 // Parse attribute arguments.
947 if (Tok.is(K: tok::l_paren))
948 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
949 else if (AttrName->getName() == "property")
950 // The property attribute must have an argument list.
951 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
952 << AttrName->getName();
953
954 if (!AttrHandled)
955 Attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
956 form: ParsedAttr::Form::Declspec());
957 }
958 T.consumeClose();
959 EndLoc = T.getCloseLocation();
960 }
961
962 Attrs.Range = SourceRange(StartLoc, EndLoc);
963}
964
965void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
966 // Treat these like attributes
967 while (true) {
968 auto Kind = Tok.getKind();
969 switch (Kind) {
970 case tok::kw___fastcall:
971 case tok::kw___stdcall:
972 case tok::kw___thiscall:
973 case tok::kw___regcall:
974 case tok::kw___cdecl:
975 case tok::kw___vectorcall:
976 case tok::kw___ptr64:
977 case tok::kw___w64:
978 case tok::kw___ptr32:
979 case tok::kw___sptr:
980 case tok::kw___uptr: {
981 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
982 SourceLocation AttrNameLoc = ConsumeToken();
983 attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
984 form: Kind);
985 break;
986 }
987 default:
988 return;
989 }
990 }
991}
992
993void Parser::ParseWebAssemblyFuncrefTypeAttribute(ParsedAttributes &attrs) {
994 assert(Tok.is(tok::kw___funcref));
995 SourceLocation StartLoc = Tok.getLocation();
996 if (!getTargetInfo().getTriple().isWasm()) {
997 ConsumeToken();
998 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
999 return;
1000 }
1001
1002 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1003 SourceLocation AttrNameLoc = ConsumeToken();
1004 attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, /*ScopeName=*/scopeName: nullptr,
1005 /*ScopeLoc=*/scopeLoc: SourceLocation{}, /*Args=*/args: nullptr, /*numArgs=*/0,
1006 form: tok::kw___funcref);
1007}
1008
1009void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1010 SourceLocation StartLoc = Tok.getLocation();
1011 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1012
1013 if (EndLoc.isValid()) {
1014 SourceRange Range(StartLoc, EndLoc);
1015 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) << Range;
1016 }
1017}
1018
1019SourceLocation Parser::SkipExtendedMicrosoftTypeAttributes() {
1020 SourceLocation EndLoc;
1021
1022 while (true) {
1023 switch (Tok.getKind()) {
1024 case tok::kw_const:
1025 case tok::kw_volatile:
1026 case tok::kw___fastcall:
1027 case tok::kw___stdcall:
1028 case tok::kw___thiscall:
1029 case tok::kw___cdecl:
1030 case tok::kw___vectorcall:
1031 case tok::kw___ptr32:
1032 case tok::kw___ptr64:
1033 case tok::kw___w64:
1034 case tok::kw___unaligned:
1035 case tok::kw___sptr:
1036 case tok::kw___uptr:
1037 EndLoc = ConsumeToken();
1038 break;
1039 default:
1040 return EndLoc;
1041 }
1042 }
1043}
1044
1045void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
1046 // Treat these like attributes
1047 while (Tok.is(K: tok::kw___pascal)) {
1048 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1049 SourceLocation AttrNameLoc = ConsumeToken();
1050 attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
1051 form: tok::kw___pascal);
1052 }
1053}
1054
1055void Parser::ParseOpenCLKernelAttributes(ParsedAttributes &attrs) {
1056 // Treat these like attributes
1057 while (Tok.is(K: tok::kw___kernel)) {
1058 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1059 SourceLocation AttrNameLoc = ConsumeToken();
1060 attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
1061 form: tok::kw___kernel);
1062 }
1063}
1064
1065void Parser::ParseCUDAFunctionAttributes(ParsedAttributes &attrs) {
1066 while (Tok.is(K: tok::kw___noinline__)) {
1067 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1068 SourceLocation AttrNameLoc = ConsumeToken();
1069 attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
1070 form: tok::kw___noinline__);
1071 }
1072}
1073
1074void Parser::ParseOpenCLQualifiers(ParsedAttributes &Attrs) {
1075 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1076 SourceLocation AttrNameLoc = Tok.getLocation();
1077 Attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
1078 form: Tok.getKind());
1079}
1080
1081bool Parser::isHLSLQualifier(const Token &Tok) const {
1082 return Tok.is(K: tok::kw_groupshared);
1083}
1084
1085void Parser::ParseHLSLQualifiers(ParsedAttributes &Attrs) {
1086 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1087 auto Kind = Tok.getKind();
1088 SourceLocation AttrNameLoc = ConsumeToken();
1089 Attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0, form: Kind);
1090}
1091
1092void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {
1093 // Treat these like attributes, even though they're type specifiers.
1094 while (true) {
1095 auto Kind = Tok.getKind();
1096 switch (Kind) {
1097 case tok::kw__Nonnull:
1098 case tok::kw__Nullable:
1099 case tok::kw__Nullable_result:
1100 case tok::kw__Null_unspecified: {
1101 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1102 SourceLocation AttrNameLoc = ConsumeToken();
1103 if (!getLangOpts().ObjC)
1104 Diag(AttrNameLoc, diag::ext_nullability)
1105 << AttrName;
1106 attrs.addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc, args: nullptr, numArgs: 0,
1107 form: Kind);
1108 break;
1109 }
1110 default:
1111 return;
1112 }
1113 }
1114}
1115
1116static bool VersionNumberSeparator(const char Separator) {
1117 return (Separator == '.' || Separator == '_');
1118}
1119
1120VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
1121 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1122
1123 if (!Tok.is(K: tok::numeric_constant)) {
1124 Diag(Tok, diag::err_expected_version);
1125 SkipUntil(T1: tok::comma, T2: tok::r_paren,
1126 Flags: StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
1127 return VersionTuple();
1128 }
1129
1130 // Parse the major (and possibly minor and subminor) versions, which
1131 // are stored in the numeric constant. We utilize a quirk of the
1132 // lexer, which is that it handles something like 1.2.3 as a single
1133 // numeric constant, rather than two separate tokens.
1134 SmallString<512> Buffer;
1135 Buffer.resize(N: Tok.getLength()+1);
1136 const char *ThisTokBegin = &Buffer[0];
1137
1138 // Get the spelling of the token, which eliminates trigraphs, etc.
1139 bool Invalid = false;
1140 unsigned ActualLength = PP.getSpelling(Tok, Buffer&: ThisTokBegin, Invalid: &Invalid);
1141 if (Invalid)
1142 return VersionTuple();
1143
1144 // Parse the major version.
1145 unsigned AfterMajor = 0;
1146 unsigned Major = 0;
1147 while (AfterMajor < ActualLength && isDigit(c: ThisTokBegin[AfterMajor])) {
1148 Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';
1149 ++AfterMajor;
1150 }
1151
1152 if (AfterMajor == 0) {
1153 Diag(Tok, diag::err_expected_version);
1154 SkipUntil(T1: tok::comma, T2: tok::r_paren,
1155 Flags: StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
1156 return VersionTuple();
1157 }
1158
1159 if (AfterMajor == ActualLength) {
1160 ConsumeToken();
1161
1162 // We only had a single version component.
1163 if (Major == 0) {
1164 Diag(Tok, diag::err_zero_version);
1165 return VersionTuple();
1166 }
1167
1168 return VersionTuple(Major);
1169 }
1170
1171 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1172 if (!VersionNumberSeparator(Separator: AfterMajorSeparator)
1173 || (AfterMajor + 1 == ActualLength)) {
1174 Diag(Tok, diag::err_expected_version);
1175 SkipUntil(T1: tok::comma, T2: tok::r_paren,
1176 Flags: StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
1177 return VersionTuple();
1178 }
1179
1180 // Parse the minor version.
1181 unsigned AfterMinor = AfterMajor + 1;
1182 unsigned Minor = 0;
1183 while (AfterMinor < ActualLength && isDigit(c: ThisTokBegin[AfterMinor])) {
1184 Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';
1185 ++AfterMinor;
1186 }
1187
1188 if (AfterMinor == ActualLength) {
1189 ConsumeToken();
1190
1191 // We had major.minor.
1192 if (Major == 0 && Minor == 0) {
1193 Diag(Tok, diag::err_zero_version);
1194 return VersionTuple();
1195 }
1196
1197 return VersionTuple(Major, Minor);
1198 }
1199
1200 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1201 // If what follows is not a '.' or '_', we have a problem.
1202 if (!VersionNumberSeparator(Separator: AfterMinorSeparator)) {
1203 Diag(Tok, diag::err_expected_version);
1204 SkipUntil(T1: tok::comma, T2: tok::r_paren,
1205 Flags: StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
1206 return VersionTuple();
1207 }
1208
1209 // Warn if separators, be it '.' or '_', do not match.
1210 if (AfterMajorSeparator != AfterMinorSeparator)
1211 Diag(Tok, diag::warn_expected_consistent_version_separator);
1212
1213 // Parse the subminor version.
1214 unsigned AfterSubminor = AfterMinor + 1;
1215 unsigned Subminor = 0;
1216 while (AfterSubminor < ActualLength && isDigit(c: ThisTokBegin[AfterSubminor])) {
1217 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';
1218 ++AfterSubminor;
1219 }
1220
1221 if (AfterSubminor != ActualLength) {
1222 Diag(Tok, diag::err_expected_version);
1223 SkipUntil(T1: tok::comma, T2: tok::r_paren,
1224 Flags: StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
1225 return VersionTuple();
1226 }
1227 ConsumeToken();
1228 return VersionTuple(Major, Minor, Subminor);
1229}
1230
1231void Parser::ParseAvailabilityAttribute(
1232 IdentifierInfo &Availability, SourceLocation AvailabilityLoc,
1233 ParsedAttributes &attrs, SourceLocation *endLoc, IdentifierInfo *ScopeName,
1234 SourceLocation ScopeLoc, ParsedAttr::Form Form) {
1235 enum { Introduced, Deprecated, Obsoleted, Unknown };
1236 AvailabilityChange Changes[Unknown];
1237 ExprResult MessageExpr, ReplacementExpr;
1238 IdentifierLoc *EnvironmentLoc = nullptr;
1239
1240 // Opening '('.
1241 BalancedDelimiterTracker T(*this, tok::l_paren);
1242 if (T.consumeOpen()) {
1243 Diag(Tok, diag::err_expected) << tok::l_paren;
1244 return;
1245 }
1246
1247 // Parse the platform name.
1248 if (Tok.isNot(K: tok::identifier)) {
1249 Diag(Tok, diag::err_availability_expected_platform);
1250 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1251 return;
1252 }
1253 IdentifierLoc *Platform = ParseIdentifierLoc();
1254 if (const IdentifierInfo *const Ident = Platform->getIdentifierInfo()) {
1255 // Disallow xrOS for availability attributes.
1256 if (Ident->getName().contains(Other: "xrOS") || Ident->getName().contains(Other: "xros"))
1257 Diag(Platform->getLoc(), diag::warn_availability_unknown_platform)
1258 << Ident;
1259 // Canonicalize platform name from "macosx" to "macos".
1260 else if (Ident->getName() == "macosx")
1261 Platform->setIdentifierInfo(PP.getIdentifierInfo(Name: "macos"));
1262 // Canonicalize platform name from "macosx_app_extension" to
1263 // "macos_app_extension".
1264 else if (Ident->getName() == "macosx_app_extension")
1265 Platform->setIdentifierInfo(PP.getIdentifierInfo(Name: "macos_app_extension"));
1266 else
1267 Platform->setIdentifierInfo(PP.getIdentifierInfo(
1268 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1269 }
1270
1271 // Parse the ',' following the platform name.
1272 if (ExpectAndConsume(ExpectedTok: tok::comma)) {
1273 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1274 return;
1275 }
1276
1277 // If we haven't grabbed the pointers for the identifiers
1278 // "introduced", "deprecated", and "obsoleted", do so now.
1279 if (!Ident_introduced) {
1280 Ident_introduced = PP.getIdentifierInfo(Name: "introduced");
1281 Ident_deprecated = PP.getIdentifierInfo(Name: "deprecated");
1282 Ident_obsoleted = PP.getIdentifierInfo(Name: "obsoleted");
1283 Ident_unavailable = PP.getIdentifierInfo(Name: "unavailable");
1284 Ident_message = PP.getIdentifierInfo(Name: "message");
1285 Ident_strict = PP.getIdentifierInfo(Name: "strict");
1286 Ident_replacement = PP.getIdentifierInfo(Name: "replacement");
1287 Ident_environment = PP.getIdentifierInfo(Name: "environment");
1288 }
1289
1290 // Parse the optional "strict", the optional "replacement" and the set of
1291 // introductions/deprecations/removals.
1292 SourceLocation UnavailableLoc, StrictLoc;
1293 do {
1294 if (Tok.isNot(K: tok::identifier)) {
1295 Diag(Tok, diag::err_availability_expected_change);
1296 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1297 return;
1298 }
1299 IdentifierInfo *Keyword = Tok.getIdentifierInfo();
1300 SourceLocation KeywordLoc = ConsumeToken();
1301
1302 if (Keyword == Ident_strict) {
1303 if (StrictLoc.isValid()) {
1304 Diag(KeywordLoc, diag::err_availability_redundant)
1305 << Keyword << SourceRange(StrictLoc);
1306 }
1307 StrictLoc = KeywordLoc;
1308 continue;
1309 }
1310
1311 if (Keyword == Ident_unavailable) {
1312 if (UnavailableLoc.isValid()) {
1313 Diag(KeywordLoc, diag::err_availability_redundant)
1314 << Keyword << SourceRange(UnavailableLoc);
1315 }
1316 UnavailableLoc = KeywordLoc;
1317 continue;
1318 }
1319
1320 if (Keyword == Ident_deprecated && Platform->getIdentifierInfo() &&
1321 Platform->getIdentifierInfo()->isStr(Str: "swift")) {
1322 // For swift, we deprecate for all versions.
1323 if (Changes[Deprecated].KeywordLoc.isValid()) {
1324 Diag(KeywordLoc, diag::err_availability_redundant)
1325 << Keyword
1326 << SourceRange(Changes[Deprecated].KeywordLoc);
1327 }
1328
1329 Changes[Deprecated].KeywordLoc = KeywordLoc;
1330 // Use a fake version here.
1331 Changes[Deprecated].Version = VersionTuple(1);
1332 continue;
1333 }
1334
1335 if (Keyword == Ident_environment) {
1336 if (EnvironmentLoc != nullptr) {
1337 Diag(KeywordLoc, diag::err_availability_redundant)
1338 << Keyword << SourceRange(EnvironmentLoc->getLoc());
1339 }
1340 }
1341
1342 if (Tok.isNot(K: tok::equal)) {
1343 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1344 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1345 return;
1346 }
1347 ConsumeToken();
1348 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1349 if (!isTokenStringLiteral()) {
1350 Diag(Tok, diag::err_expected_string_literal)
1351 << /*Source='availability attribute'*/2;
1352 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1353 return;
1354 }
1355 if (Keyword == Ident_message) {
1356 MessageExpr = ParseUnevaluatedStringLiteralExpression();
1357 break;
1358 } else {
1359 ReplacementExpr = ParseUnevaluatedStringLiteralExpression();
1360 continue;
1361 }
1362 }
1363 if (Keyword == Ident_environment) {
1364 if (Tok.isNot(K: tok::identifier)) {
1365 Diag(Tok, diag::err_availability_expected_environment);
1366 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1367 return;
1368 }
1369 EnvironmentLoc = ParseIdentifierLoc();
1370 continue;
1371 }
1372
1373 // Special handling of 'NA' only when applied to introduced or
1374 // deprecated.
1375 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1376 Tok.is(K: tok::identifier)) {
1377 IdentifierInfo *NA = Tok.getIdentifierInfo();
1378 if (NA->getName() == "NA") {
1379 ConsumeToken();
1380 if (Keyword == Ident_introduced)
1381 UnavailableLoc = KeywordLoc;
1382 continue;
1383 }
1384 }
1385
1386 SourceRange VersionRange;
1387 VersionTuple Version = ParseVersionTuple(Range&: VersionRange);
1388
1389 if (Version.empty()) {
1390 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1391 return;
1392 }
1393
1394 unsigned Index;
1395 if (Keyword == Ident_introduced)
1396 Index = Introduced;
1397 else if (Keyword == Ident_deprecated)
1398 Index = Deprecated;
1399 else if (Keyword == Ident_obsoleted)
1400 Index = Obsoleted;
1401 else
1402 Index = Unknown;
1403
1404 if (Index < Unknown) {
1405 if (!Changes[Index].KeywordLoc.isInvalid()) {
1406 Diag(KeywordLoc, diag::err_availability_redundant)
1407 << Keyword
1408 << SourceRange(Changes[Index].KeywordLoc,
1409 Changes[Index].VersionRange.getEnd());
1410 }
1411
1412 Changes[Index].KeywordLoc = KeywordLoc;
1413 Changes[Index].Version = Version;
1414 Changes[Index].VersionRange = VersionRange;
1415 } else {
1416 Diag(KeywordLoc, diag::err_availability_unknown_change)
1417 << Keyword << VersionRange;
1418 }
1419
1420 } while (TryConsumeToken(Expected: tok::comma));
1421
1422 // Closing ')'.
1423 if (T.consumeClose())
1424 return;
1425
1426 if (endLoc)
1427 *endLoc = T.getCloseLocation();
1428
1429 // The 'unavailable' availability cannot be combined with any other
1430 // availability changes. Make sure that hasn't happened.
1431 if (UnavailableLoc.isValid()) {
1432 bool Complained = false;
1433 for (unsigned Index = Introduced; Index != Unknown; ++Index) {
1434 if (Changes[Index].KeywordLoc.isValid()) {
1435 if (!Complained) {
1436 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1437 << SourceRange(Changes[Index].KeywordLoc,
1438 Changes[Index].VersionRange.getEnd());
1439 Complained = true;
1440 }
1441
1442 // Clear out the availability.
1443 Changes[Index] = AvailabilityChange();
1444 }
1445 }
1446 }
1447
1448 // Record this attribute
1449 attrs.addNew(attrName: &Availability,
1450 attrRange: SourceRange(AvailabilityLoc, T.getCloseLocation()), scopeName: ScopeName,
1451 scopeLoc: ScopeLoc, Param: Platform, introduced: Changes[Introduced], deprecated: Changes[Deprecated],
1452 obsoleted: Changes[Obsoleted], unavailable: UnavailableLoc, MessageExpr: MessageExpr.get(), form: Form,
1453 strict: StrictLoc, ReplacementExpr: ReplacementExpr.get(), EnvironmentLoc);
1454}
1455
1456void Parser::ParseExternalSourceSymbolAttribute(
1457 IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc,
1458 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
1459 SourceLocation ScopeLoc, ParsedAttr::Form Form) {
1460 // Opening '('.
1461 BalancedDelimiterTracker T(*this, tok::l_paren);
1462 if (T.expectAndConsume())
1463 return;
1464
1465 // Initialize the pointers for the keyword identifiers when required.
1466 if (!Ident_language) {
1467 Ident_language = PP.getIdentifierInfo(Name: "language");
1468 Ident_defined_in = PP.getIdentifierInfo(Name: "defined_in");
1469 Ident_generated_declaration = PP.getIdentifierInfo(Name: "generated_declaration");
1470 Ident_USR = PP.getIdentifierInfo(Name: "USR");
1471 }
1472
1473 ExprResult Language;
1474 bool HasLanguage = false;
1475 ExprResult DefinedInExpr;
1476 bool HasDefinedIn = false;
1477 IdentifierLoc *GeneratedDeclaration = nullptr;
1478 ExprResult USR;
1479 bool HasUSR = false;
1480
1481 // Parse the language/defined_in/generated_declaration keywords
1482 do {
1483 if (Tok.isNot(K: tok::identifier)) {
1484 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1485 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1486 return;
1487 }
1488
1489 SourceLocation KeywordLoc = Tok.getLocation();
1490 IdentifierInfo *Keyword = Tok.getIdentifierInfo();
1491 if (Keyword == Ident_generated_declaration) {
1492 if (GeneratedDeclaration) {
1493 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1494 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1495 return;
1496 }
1497 GeneratedDeclaration = ParseIdentifierLoc();
1498 continue;
1499 }
1500
1501 if (Keyword != Ident_language && Keyword != Ident_defined_in &&
1502 Keyword != Ident_USR) {
1503 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1504 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1505 return;
1506 }
1507
1508 ConsumeToken();
1509 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1510 Keyword->getName())) {
1511 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1512 return;
1513 }
1514
1515 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1516 HadUSR = HasUSR;
1517 if (Keyword == Ident_language)
1518 HasLanguage = true;
1519 else if (Keyword == Ident_USR)
1520 HasUSR = true;
1521 else
1522 HasDefinedIn = true;
1523
1524 if (!isTokenStringLiteral()) {
1525 Diag(Tok, diag::err_expected_string_literal)
1526 << /*Source='external_source_symbol attribute'*/ 3
1527 << /*language | source container | USR*/ (
1528 Keyword == Ident_language
1529 ? 0
1530 : (Keyword == Ident_defined_in ? 1 : 2));
1531 SkipUntil(T1: tok::comma, T2: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
1532 continue;
1533 }
1534 if (Keyword == Ident_language) {
1535 if (HadLanguage) {
1536 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1537 << Keyword;
1538 ParseUnevaluatedStringLiteralExpression();
1539 continue;
1540 }
1541 Language = ParseUnevaluatedStringLiteralExpression();
1542 } else if (Keyword == Ident_USR) {
1543 if (HadUSR) {
1544 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1545 << Keyword;
1546 ParseUnevaluatedStringLiteralExpression();
1547 continue;
1548 }
1549 USR = ParseUnevaluatedStringLiteralExpression();
1550 } else {
1551 assert(Keyword == Ident_defined_in && "Invalid clause keyword!");
1552 if (HadDefinedIn) {
1553 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1554 << Keyword;
1555 ParseUnevaluatedStringLiteralExpression();
1556 continue;
1557 }
1558 DefinedInExpr = ParseUnevaluatedStringLiteralExpression();
1559 }
1560 } while (TryConsumeToken(Expected: tok::comma));
1561
1562 // Closing ')'.
1563 if (T.consumeClose())
1564 return;
1565 if (EndLoc)
1566 *EndLoc = T.getCloseLocation();
1567
1568 ArgsUnion Args[] = {Language.get(), DefinedInExpr.get(), GeneratedDeclaration,
1569 USR.get()};
1570 Attrs.addNew(attrName: &ExternalSourceSymbol, attrRange: SourceRange(Loc, T.getCloseLocation()),
1571 scopeName: ScopeName, scopeLoc: ScopeLoc, args: Args, numArgs: std::size(Args), form: Form);
1572}
1573
1574void Parser::ParseObjCBridgeRelatedAttribute(
1575 IdentifierInfo &ObjCBridgeRelated, SourceLocation ObjCBridgeRelatedLoc,
1576 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
1577 SourceLocation ScopeLoc, ParsedAttr::Form Form) {
1578 // Opening '('.
1579 BalancedDelimiterTracker T(*this, tok::l_paren);
1580 if (T.consumeOpen()) {
1581 Diag(Tok, diag::err_expected) << tok::l_paren;
1582 return;
1583 }
1584
1585 // Parse the related class name.
1586 if (Tok.isNot(K: tok::identifier)) {
1587 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1588 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1589 return;
1590 }
1591 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1592 if (ExpectAndConsume(ExpectedTok: tok::comma)) {
1593 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1594 return;
1595 }
1596
1597 // Parse class method name. It's non-optional in the sense that a trailing
1598 // comma is required, but it can be the empty string, and then we record a
1599 // nullptr.
1600 IdentifierLoc *ClassMethod = nullptr;
1601 if (Tok.is(K: tok::identifier)) {
1602 ClassMethod = ParseIdentifierLoc();
1603 if (!TryConsumeToken(Expected: tok::colon)) {
1604 Diag(Tok, diag::err_objcbridge_related_selector_name);
1605 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1606 return;
1607 }
1608 }
1609 if (!TryConsumeToken(Expected: tok::comma)) {
1610 if (Tok.is(tok::colon))
1611 Diag(Tok, diag::err_objcbridge_related_selector_name);
1612 else
1613 Diag(Tok, diag::err_expected) << tok::comma;
1614 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1615 return;
1616 }
1617
1618 // Parse instance method name. Also non-optional but empty string is
1619 // permitted.
1620 IdentifierLoc *InstanceMethod = nullptr;
1621 if (Tok.is(K: tok::identifier))
1622 InstanceMethod = ParseIdentifierLoc();
1623 else if (Tok.isNot(K: tok::r_paren)) {
1624 Diag(Tok, diag::err_expected) << tok::r_paren;
1625 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
1626 return;
1627 }
1628
1629 // Closing ')'.
1630 if (T.consumeClose())
1631 return;
1632
1633 if (EndLoc)
1634 *EndLoc = T.getCloseLocation();
1635
1636 // Record this attribute
1637 Attrs.addNew(attrName: &ObjCBridgeRelated,
1638 attrRange: SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
1639 scopeName: ScopeName, scopeLoc: ScopeLoc, Param1: RelatedClass, Param2: ClassMethod, Param3: InstanceMethod,
1640 form: Form);
1641}
1642
1643void Parser::ParseSwiftNewTypeAttribute(
1644 IdentifierInfo &AttrName, SourceLocation AttrNameLoc,
1645 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
1646 SourceLocation ScopeLoc, ParsedAttr::Form Form) {
1647 BalancedDelimiterTracker T(*this, tok::l_paren);
1648
1649 // Opening '('
1650 if (T.consumeOpen()) {
1651 Diag(Tok, diag::err_expected) << tok::l_paren;
1652 return;
1653 }
1654
1655 if (Tok.is(K: tok::r_paren)) {
1656 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1657 T.consumeClose();
1658 return;
1659 }
1660 if (Tok.isNot(K: tok::kw_struct) && Tok.isNot(K: tok::kw_enum)) {
1661 Diag(Tok, diag::warn_attribute_type_not_supported)
1662 << &AttrName << Tok.getIdentifierInfo();
1663 if (!isTokenSpecial())
1664 ConsumeToken();
1665 T.consumeClose();
1666 return;
1667 }
1668
1669 auto *SwiftType = new (Actions.Context)
1670 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1671 ConsumeToken();
1672
1673 // Closing ')'
1674 if (T.consumeClose())
1675 return;
1676 if (EndLoc)
1677 *EndLoc = T.getCloseLocation();
1678
1679 ArgsUnion Args[] = {SwiftType};
1680 Attrs.addNew(attrName: &AttrName, attrRange: SourceRange(AttrNameLoc, T.getCloseLocation()),
1681 scopeName: ScopeName, scopeLoc: ScopeLoc, args: Args, numArgs: std::size(Args), form: Form);
1682}
1683
1684void Parser::ParseTypeTagForDatatypeAttribute(
1685 IdentifierInfo &AttrName, SourceLocation AttrNameLoc,
1686 ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
1687 SourceLocation ScopeLoc, ParsedAttr::Form Form) {
1688 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
1689
1690 BalancedDelimiterTracker T(*this, tok::l_paren);
1691 T.consumeOpen();
1692
1693 if (Tok.isNot(K: tok::identifier)) {
1694 Diag(Tok, diag::err_expected) << tok::identifier;
1695 T.skipToEnd();
1696 return;
1697 }
1698 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1699
1700 if (ExpectAndConsume(ExpectedTok: tok::comma)) {
1701 T.skipToEnd();
1702 return;
1703 }
1704
1705 SourceRange MatchingCTypeRange;
1706 TypeResult MatchingCType = ParseTypeName(Range: &MatchingCTypeRange);
1707 if (MatchingCType.isInvalid()) {
1708 T.skipToEnd();
1709 return;
1710 }
1711
1712 bool LayoutCompatible = false;
1713 bool MustBeNull = false;
1714 while (TryConsumeToken(Expected: tok::comma)) {
1715 if (Tok.isNot(K: tok::identifier)) {
1716 Diag(Tok, diag::err_expected) << tok::identifier;
1717 T.skipToEnd();
1718 return;
1719 }
1720 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1721 if (Flag->isStr(Str: "layout_compatible"))
1722 LayoutCompatible = true;
1723 else if (Flag->isStr(Str: "must_be_null"))
1724 MustBeNull = true;
1725 else {
1726 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1727 T.skipToEnd();
1728 return;
1729 }
1730 ConsumeToken(); // consume flag
1731 }
1732
1733 if (!T.consumeClose()) {
1734 Attrs.addNewTypeTagForDatatype(attrName: &AttrName, attrRange: AttrNameLoc, scopeName: ScopeName, scopeLoc: ScopeLoc,
1735 argumentKind: ArgumentKind, matchingCType: MatchingCType.get(),
1736 layoutCompatible: LayoutCompatible, mustBeNull: MustBeNull, form: Form);
1737 }
1738
1739 if (EndLoc)
1740 *EndLoc = T.getCloseLocation();
1741}
1742
1743bool Parser::DiagnoseProhibitedCXX11Attribute() {
1744 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
1745
1746 switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {
1747 case CXX11AttributeKind::NotAttributeSpecifier:
1748 // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.
1749 return false;
1750
1751 case CXX11AttributeKind::InvalidAttributeSpecifier:
1752 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1753 return false;
1754
1755 case CXX11AttributeKind::AttributeSpecifier:
1756 // Parse and discard the attributes.
1757 SourceLocation BeginLoc = ConsumeBracket();
1758 ConsumeBracket();
1759 SkipUntil(T: tok::r_square);
1760 assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");
1761 SourceLocation EndLoc = ConsumeBracket();
1762 Diag(BeginLoc, diag::err_attributes_not_allowed)
1763 << SourceRange(BeginLoc, EndLoc);
1764 return true;
1765 }
1766 llvm_unreachable("All cases handled above.");
1767}
1768
1769void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs,
1770 SourceLocation CorrectLocation) {
1771 assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||
1772 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1773
1774 // Consume the attributes.
1775 auto Keyword =
1776 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() : nullptr;
1777 SourceLocation Loc = Tok.getLocation();
1778 ParseCXX11Attributes(attrs&: Attrs);
1779 CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true);
1780 // FIXME: use err_attributes_misplaced
1781 (Keyword ? Diag(Loc, diag::err_keyword_not_allowed) << Keyword
1782 : Diag(Loc, diag::err_attributes_not_allowed))
1783 << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
1784 << FixItHint::CreateRemoval(AttrRange);
1785}
1786
1787void Parser::DiagnoseProhibitedAttributes(
1788 const ParsedAttributesView &Attrs, const SourceLocation CorrectLocation) {
1789 auto *FirstAttr = Attrs.empty() ? nullptr : &Attrs.front();
1790 if (CorrectLocation.isValid()) {
1791 CharSourceRange AttrRange(Attrs.Range, true);
1792 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1793 ? Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1794 : Diag(CorrectLocation, diag::err_attributes_misplaced))
1795 << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)
1796 << FixItHint::CreateRemoval(AttrRange);
1797 } else {
1798 const SourceRange &Range = Attrs.Range;
1799 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1800 ? Diag(Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1801 : Diag(Range.getBegin(), diag::err_attributes_not_allowed))
1802 << Range;
1803 }
1804}
1805
1806void Parser::ProhibitCXX11Attributes(ParsedAttributes &Attrs,
1807 unsigned AttrDiagID,
1808 unsigned KeywordDiagID,
1809 bool DiagnoseEmptyAttrs,
1810 bool WarnOnUnknownAttrs) {
1811
1812 if (DiagnoseEmptyAttrs && Attrs.empty() && Attrs.Range.isValid()) {
1813 // An attribute list has been parsed, but it was empty.
1814 // This is the case for [[]].
1815 const auto &LangOpts = getLangOpts();
1816 auto &SM = PP.getSourceManager();
1817 Token FirstLSquare;
1818 Lexer::getRawToken(Loc: Attrs.Range.getBegin(), Result&: FirstLSquare, SM, LangOpts);
1819
1820 if (FirstLSquare.is(K: tok::l_square)) {
1821 std::optional<Token> SecondLSquare =
1822 Lexer::findNextToken(Loc: FirstLSquare.getLocation(), SM, LangOpts);
1823
1824 if (SecondLSquare && SecondLSquare->is(K: tok::l_square)) {
1825 // The attribute range starts with [[, but is empty. So this must
1826 // be [[]], which we are supposed to diagnose because
1827 // DiagnoseEmptyAttrs is true.
1828 Diag(Loc: Attrs.Range.getBegin(), DiagID: AttrDiagID) << Attrs.Range;
1829 return;
1830 }
1831 }
1832 }
1833
1834 for (const ParsedAttr &AL : Attrs) {
1835 if (AL.isRegularKeywordAttribute()) {
1836 Diag(Loc: AL.getLoc(), DiagID: KeywordDiagID) << AL;
1837 AL.setInvalid();
1838 continue;
1839 }
1840 if (!AL.isStandardAttributeSyntax())
1841 continue;
1842 if (AL.getKind() == ParsedAttr::UnknownAttribute) {
1843 if (WarnOnUnknownAttrs)
1844 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
1845 << AL << AL.getRange();
1846 } else {
1847 Diag(Loc: AL.getLoc(), DiagID: AttrDiagID) << AL;
1848 AL.setInvalid();
1849 }
1850 }
1851}
1852
1853void Parser::DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs) {
1854 for (const ParsedAttr &PA : Attrs) {
1855 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1856 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1857 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1858 }
1859}
1860
1861void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs,
1862 DeclSpec &DS, TagUseKind TUK) {
1863 if (TUK == TagUseKind::Reference)
1864 return;
1865
1866 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1867
1868 for (ParsedAttr &AL : DS.getAttributes()) {
1869 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1870 AL.isDeclspecAttribute()) ||
1871 AL.isMicrosoftAttribute())
1872 ToBeMoved.push_back(Elt: &AL);
1873 }
1874
1875 for (ParsedAttr *AL : ToBeMoved) {
1876 DS.getAttributes().remove(ToBeRemoved: AL);
1877 Attrs.addAtEnd(newAttr: AL);
1878 }
1879}
1880
1881Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
1882 SourceLocation &DeclEnd,
1883 ParsedAttributes &DeclAttrs,
1884 ParsedAttributes &DeclSpecAttrs,
1885 SourceLocation *DeclSpecStart) {
1886 ParenBraceBracketBalancer BalancerRAIIObj(*this);
1887 // Must temporarily exit the objective-c container scope for
1888 // parsing c none objective-c decls.
1889 ObjCDeclContextSwitch ObjCDC(*this);
1890
1891 Decl *SingleDecl = nullptr;
1892 switch (Tok.getKind()) {
1893 case tok::kw_template:
1894 case tok::kw_export:
1895 ProhibitAttributes(Attrs&: DeclAttrs);
1896 ProhibitAttributes(Attrs&: DeclSpecAttrs);
1897 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, AccessAttrs&: DeclAttrs);
1898 case tok::kw_inline:
1899 // Could be the start of an inline namespace. Allowed as an ext in C++03.
1900 if (getLangOpts().CPlusPlus && NextToken().is(K: tok::kw_namespace)) {
1901 ProhibitAttributes(Attrs&: DeclAttrs);
1902 ProhibitAttributes(Attrs&: DeclSpecAttrs);
1903 SourceLocation InlineLoc = ConsumeToken();
1904 return ParseNamespace(Context, DeclEnd, InlineLoc);
1905 }
1906 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1907 RequireSemi: true, FRI: nullptr, DeclSpecStart);
1908
1909 case tok::kw_cbuffer:
1910 case tok::kw_tbuffer:
1911 SingleDecl = ParseHLSLBuffer(DeclEnd);
1912 break;
1913 case tok::kw_namespace:
1914 ProhibitAttributes(Attrs&: DeclAttrs);
1915 ProhibitAttributes(Attrs&: DeclSpecAttrs);
1916 return ParseNamespace(Context, DeclEnd);
1917 case tok::kw_using: {
1918 takeAndConcatenateAttrs(First&: DeclAttrs, Second: std::move(DeclSpecAttrs));
1919 return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo: ParsedTemplateInfo(),
1920 DeclEnd, Attrs&: DeclAttrs);
1921 }
1922 case tok::kw_static_assert:
1923 case tok::kw__Static_assert:
1924 ProhibitAttributes(Attrs&: DeclAttrs);
1925 ProhibitAttributes(Attrs&: DeclSpecAttrs);
1926 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1927 break;
1928 default:
1929 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1930 RequireSemi: true, FRI: nullptr, DeclSpecStart);
1931 }
1932
1933 // This routine returns a DeclGroup, if the thing we parsed only contains a
1934 // single decl, convert it now.
1935 return Actions.ConvertDeclToDeclGroup(Ptr: SingleDecl);
1936}
1937
1938Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(
1939 DeclaratorContext Context, SourceLocation &DeclEnd,
1940 ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,
1941 bool RequireSemi, ForRangeInit *FRI, SourceLocation *DeclSpecStart) {
1942 // Need to retain these for diagnostics before we add them to the DeclSepc.
1943 ParsedAttributesView OriginalDeclSpecAttrs;
1944 OriginalDeclSpecAttrs.addAll(B: DeclSpecAttrs.begin(), E: DeclSpecAttrs.end());
1945 OriginalDeclSpecAttrs.Range = DeclSpecAttrs.Range;
1946
1947 // Parse the common declaration-specifiers piece.
1948 ParsingDeclSpec DS(*this);
1949 DS.takeAttributesFrom(attrs&: DeclSpecAttrs);
1950
1951 ParsedTemplateInfo TemplateInfo;
1952 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1953 ParseDeclarationSpecifiers(DS, TemplateInfo, AS: AS_none, DSC: DSContext);
1954
1955 // If we had a free-standing type definition with a missing semicolon, we
1956 // may get this far before the problem becomes obvious.
1957 if (DS.hasTagDefinition() &&
1958 DiagnoseMissingSemiAfterTagDefinition(DS, AS: AS_none, DSContext))
1959 return nullptr;
1960
1961 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1962 // declaration-specifiers init-declarator-list[opt] ';'
1963 if (Tok.is(K: tok::semi)) {
1964 ProhibitAttributes(Attrs&: DeclAttrs);
1965 DeclEnd = Tok.getLocation();
1966 if (RequireSemi) ConsumeToken();
1967 RecordDecl *AnonRecord = nullptr;
1968 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1969 S: getCurScope(), AS: AS_none, DS, DeclAttrs: ParsedAttributesView::none(), AnonRecord);
1970 Actions.ActOnDefinedDeclarationSpecifier(D: TheDecl);
1971 DS.complete(D: TheDecl);
1972 if (AnonRecord) {
1973 Decl* decls[] = {AnonRecord, TheDecl};
1974 return Actions.BuildDeclaratorGroup(decls);
1975 }
1976 return Actions.ConvertDeclToDeclGroup(Ptr: TheDecl);
1977 }
1978
1979 if (DS.hasTagDefinition())
1980 Actions.ActOnDefinedDeclarationSpecifier(D: DS.getRepAsDecl());
1981
1982 if (DeclSpecStart)
1983 DS.SetRangeStart(*DeclSpecStart);
1984
1985 return ParseDeclGroup(DS, Context, Attrs&: DeclAttrs, TemplateInfo, DeclEnd: &DeclEnd, FRI);
1986}
1987
1988bool Parser::MightBeDeclarator(DeclaratorContext Context) {
1989 switch (Tok.getKind()) {
1990 case tok::annot_cxxscope:
1991 case tok::annot_template_id:
1992 case tok::caret:
1993 case tok::code_completion:
1994 case tok::coloncolon:
1995 case tok::ellipsis:
1996 case tok::kw___attribute:
1997 case tok::kw_operator:
1998 case tok::l_paren:
1999 case tok::star:
2000 return true;
2001
2002 case tok::amp:
2003 case tok::ampamp:
2004 return getLangOpts().CPlusPlus;
2005
2006 case tok::l_square: // Might be an attribute on an unnamed bit-field.
2007 return Context == DeclaratorContext::Member && getLangOpts().CPlusPlus11 &&
2008 NextToken().is(K: tok::l_square);
2009
2010 case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
2011 return Context == DeclaratorContext::Member || getLangOpts().CPlusPlus;
2012
2013 case tok::identifier:
2014 switch (NextToken().getKind()) {
2015 case tok::code_completion:
2016 case tok::coloncolon:
2017 case tok::comma:
2018 case tok::equal:
2019 case tok::equalequal: // Might be a typo for '='.
2020 case tok::kw_alignas:
2021 case tok::kw_asm:
2022 case tok::kw___attribute:
2023 case tok::l_brace:
2024 case tok::l_paren:
2025 case tok::l_square:
2026 case tok::less:
2027 case tok::r_brace:
2028 case tok::r_paren:
2029 case tok::r_square:
2030 case tok::semi:
2031 return true;
2032
2033 case tok::colon:
2034 // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
2035 // and in block scope it's probably a label. Inside a class definition,
2036 // this is a bit-field.
2037 return Context == DeclaratorContext::Member ||
2038 (getLangOpts().CPlusPlus && Context == DeclaratorContext::File);
2039
2040 case tok::identifier: // Possible virt-specifier.
2041 return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(Tok: NextToken());
2042
2043 default:
2044 return Tok.isRegularKeywordAttribute();
2045 }
2046
2047 default:
2048 return Tok.isRegularKeywordAttribute();
2049 }
2050}
2051
2052void Parser::SkipMalformedDecl() {
2053 while (true) {
2054 switch (Tok.getKind()) {
2055 case tok::l_brace:
2056 // Skip until matching }, then stop. We've probably skipped over
2057 // a malformed class or function definition or similar.
2058 ConsumeBrace();
2059 SkipUntil(T: tok::r_brace);
2060 if (Tok.isOneOf(K1: tok::comma, Ks: tok::l_brace, Ks: tok::kw_try)) {
2061 // This declaration isn't over yet. Keep skipping.
2062 continue;
2063 }
2064 TryConsumeToken(Expected: tok::semi);
2065 return;
2066
2067 case tok::l_square:
2068 ConsumeBracket();
2069 SkipUntil(T: tok::r_square);
2070 continue;
2071
2072 case tok::l_paren:
2073 ConsumeParen();
2074 SkipUntil(T: tok::r_paren);
2075 continue;
2076
2077 case tok::r_brace:
2078 return;
2079
2080 case tok::semi:
2081 ConsumeToken();
2082 return;
2083
2084 case tok::kw_inline:
2085 // 'inline namespace' at the start of a line is almost certainly
2086 // a good place to pick back up parsing, except in an Objective-C
2087 // @interface context.
2088 if (Tok.isAtStartOfLine() && NextToken().is(K: tok::kw_namespace) &&
2089 (!ParsingInObjCContainer || CurParsedObjCImpl))
2090 return;
2091 break;
2092
2093 case tok::kw_namespace:
2094 // 'namespace' at the start of a line is almost certainly a good
2095 // place to pick back up parsing, except in an Objective-C
2096 // @interface context.
2097 if (Tok.isAtStartOfLine() &&
2098 (!ParsingInObjCContainer || CurParsedObjCImpl))
2099 return;
2100 break;
2101
2102 case tok::at:
2103 // @end is very much like } in Objective-C contexts.
2104 if (NextToken().isObjCAtKeyword(objcKey: tok::objc_end) &&
2105 ParsingInObjCContainer)
2106 return;
2107 break;
2108
2109 case tok::minus:
2110 case tok::plus:
2111 // - and + probably start new method declarations in Objective-C contexts.
2112 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2113 return;
2114 break;
2115
2116 case tok::eof:
2117 case tok::annot_module_begin:
2118 case tok::annot_module_end:
2119 case tok::annot_module_include:
2120 case tok::annot_repl_input_end:
2121 return;
2122
2123 default:
2124 break;
2125 }
2126
2127 ConsumeAnyToken();
2128 }
2129}
2130
2131Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
2132 DeclaratorContext Context,
2133 ParsedAttributes &Attrs,
2134 ParsedTemplateInfo &TemplateInfo,
2135 SourceLocation *DeclEnd,
2136 ForRangeInit *FRI) {
2137 // Parse the first declarator.
2138 // Consume all of the attributes from `Attrs` by moving them to our own local
2139 // list. This ensures that we will not attempt to interpret them as statement
2140 // attributes higher up the callchain.
2141 ParsedAttributes LocalAttrs(AttrFactory);
2142 LocalAttrs.takeAllFrom(Other&: Attrs);
2143 ParsingDeclarator D(*this, DS, LocalAttrs, Context);
2144 if (TemplateInfo.TemplateParams)
2145 D.setTemplateParameterLists(*TemplateInfo.TemplateParams);
2146
2147 bool IsTemplateSpecOrInst =
2148 (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation ||
2149 TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization);
2150 SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);
2151
2152 ParseDeclarator(D);
2153
2154 if (IsTemplateSpecOrInst)
2155 SAC.done();
2156
2157 // Bail out if the first declarator didn't seem well-formed.
2158 if (!D.hasName() && !D.mayOmitIdentifier()) {
2159 SkipMalformedDecl();
2160 return nullptr;
2161 }
2162
2163 if (getLangOpts().HLSL)
2164 while (MaybeParseHLSLAnnotations(D))
2165 ;
2166
2167 if (Tok.is(K: tok::kw_requires))
2168 ParseTrailingRequiresClause(D);
2169
2170 // Save late-parsed attributes for now; they need to be parsed in the
2171 // appropriate function scope after the function Decl has been constructed.
2172 // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList.
2173 LateParsedAttrList LateParsedAttrs(true);
2174 if (D.isFunctionDeclarator()) {
2175 MaybeParseGNUAttributes(D, LateAttrs: &LateParsedAttrs);
2176
2177 // The _Noreturn keyword can't appear here, unlike the GNU noreturn
2178 // attribute. If we find the keyword here, tell the user to put it
2179 // at the start instead.
2180 if (Tok.is(K: tok::kw__Noreturn)) {
2181 SourceLocation Loc = ConsumeToken();
2182 const char *PrevSpec;
2183 unsigned DiagID;
2184
2185 // We can offer a fixit if it's valid to mark this function as _Noreturn
2186 // and we don't have any other declarators in this declaration.
2187 bool Fixit = !DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);
2188 MaybeParseGNUAttributes(D, LateAttrs: &LateParsedAttrs);
2189 Fixit &= Tok.isOneOf(K1: tok::semi, Ks: tok::l_brace, Ks: tok::kw_try);
2190
2191 Diag(Loc, diag::err_c11_noreturn_misplaced)
2192 << (Fixit ? FixItHint::CreateRemoval(Loc) : FixItHint())
2193 << (Fixit ? FixItHint::CreateInsertion(D.getBeginLoc(), "_Noreturn ")
2194 : FixItHint());
2195 }
2196
2197 // Check to see if we have a function *definition* which must have a body.
2198 if (Tok.is(K: tok::equal) && NextToken().is(K: tok::code_completion)) {
2199 cutOffParsing();
2200 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2201 return nullptr;
2202 }
2203 // We're at the point where the parsing of function declarator is finished.
2204 //
2205 // A common error is that users accidently add a virtual specifier
2206 // (e.g. override) in an out-line method definition.
2207 // We attempt to recover by stripping all these specifiers coming after
2208 // the declarator.
2209 while (auto Specifier = isCXX11VirtSpecifier()) {
2210 Diag(Tok, diag::err_virt_specifier_outside_class)
2211 << VirtSpecifiers::getSpecifierName(Specifier)
2212 << FixItHint::CreateRemoval(Tok.getLocation());
2213 ConsumeToken();
2214 }
2215 // Look at the next token to make sure that this isn't a function
2216 // declaration. We have to check this because __attribute__ might be the
2217 // start of a function definition in GCC-extended K&R C.
2218 if (!isDeclarationAfterDeclarator()) {
2219
2220 // Function definitions are only allowed at file scope and in C++ classes.
2221 // The C++ inline method definition case is handled elsewhere, so we only
2222 // need to handle the file scope definition case.
2223 if (Context == DeclaratorContext::File) {
2224 if (isStartOfFunctionDefinition(Declarator: D)) {
2225 // C++23 [dcl.typedef] p1:
2226 // The typedef specifier shall not be [...], and it shall not be
2227 // used in the decl-specifier-seq of a parameter-declaration nor in
2228 // the decl-specifier-seq of a function-definition.
2229 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
2230 // If the user intended to write 'typename', we should have already
2231 // suggested adding it elsewhere. In any case, recover by ignoring
2232 // 'typedef' and suggest removing it.
2233 Diag(DS.getStorageClassSpecLoc(),
2234 diag::err_function_declared_typedef)
2235 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
2236 DS.ClearStorageClassSpecs();
2237 }
2238 Decl *TheDecl = nullptr;
2239
2240 if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation) {
2241 if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
2242 // If the declarator-id is not a template-id, issue a diagnostic
2243 // and recover by ignoring the 'template' keyword.
2244 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2245 TheDecl = ParseFunctionDefinition(D, TemplateInfo: ParsedTemplateInfo(),
2246 LateParsedAttrs: &LateParsedAttrs);
2247 } else {
2248 SourceLocation LAngleLoc =
2249 PP.getLocForEndOfToken(Loc: TemplateInfo.TemplateLoc);
2250 Diag(D.getIdentifierLoc(),
2251 diag::err_explicit_instantiation_with_definition)
2252 << SourceRange(TemplateInfo.TemplateLoc)
2253 << FixItHint::CreateInsertion(LAngleLoc, "<>");
2254
2255 // Recover as if it were an explicit specialization.
2256 TemplateParameterLists FakedParamLists;
2257 FakedParamLists.push_back(Elt: Actions.ActOnTemplateParameterList(
2258 Depth: 0, ExportLoc: SourceLocation(), TemplateLoc: TemplateInfo.TemplateLoc, LAngleLoc, Params: {},
2259 RAngleLoc: LAngleLoc, RequiresClause: nullptr));
2260
2261 TheDecl = ParseFunctionDefinition(
2262 D,
2263 TemplateInfo: ParsedTemplateInfo(&FakedParamLists,
2264 /*isSpecialization=*/true,
2265 /*lastParameterListWasEmpty=*/true),
2266 LateParsedAttrs: &LateParsedAttrs);
2267 }
2268 } else {
2269 TheDecl =
2270 ParseFunctionDefinition(D, TemplateInfo, LateParsedAttrs: &LateParsedAttrs);
2271 }
2272
2273 return Actions.ConvertDeclToDeclGroup(Ptr: TheDecl);
2274 }
2275
2276 if (isDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No) ||
2277 Tok.is(K: tok::kw_namespace)) {
2278 // If there is an invalid declaration specifier or a namespace
2279 // definition right after the function prototype, then we must be in a
2280 // missing semicolon case where this isn't actually a body. Just fall
2281 // through into the code that handles it as a prototype, and let the
2282 // top-level code handle the erroneous declspec where it would
2283 // otherwise expect a comma or semicolon. Note that
2284 // isDeclarationSpecifier already covers 'inline namespace', since
2285 // 'inline' can be a declaration specifier.
2286 } else {
2287 Diag(Tok, diag::err_expected_fn_body);
2288 SkipUntil(T: tok::semi);
2289 return nullptr;
2290 }
2291 } else {
2292 if (Tok.is(K: tok::l_brace)) {
2293 Diag(Tok, diag::err_function_definition_not_allowed);
2294 SkipMalformedDecl();
2295 return nullptr;
2296 }
2297 }
2298 }
2299 }
2300
2301 if (ParseAsmAttributesAfterDeclarator(D))
2302 return nullptr;
2303
2304 // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
2305 // must parse and analyze the for-range-initializer before the declaration is
2306 // analyzed.
2307 //
2308 // Handle the Objective-C for-in loop variable similarly, although we
2309 // don't need to parse the container in advance.
2310 if (FRI && (Tok.is(K: tok::colon) || isTokIdentifier_in())) {
2311 bool IsForRangeLoop = false;
2312 if (TryConsumeToken(Expected: tok::colon, Loc&: FRI->ColonLoc)) {
2313 IsForRangeLoop = true;
2314 EnterExpressionEvaluationContext ForRangeInitContext(
2315 Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
2316 /*LambdaContextDecl=*/nullptr,
2317 Sema::ExpressionEvaluationContextRecord::EK_Other,
2318 getLangOpts().CPlusPlus23);
2319
2320 // P2718R0 - Lifetime extension in range-based for loops.
2321 if (getLangOpts().CPlusPlus23) {
2322 auto &LastRecord = Actions.currentEvaluationContext();
2323 LastRecord.InLifetimeExtendingContext = true;
2324 LastRecord.RebuildDefaultArgOrDefaultInit = true;
2325 }
2326
2327 if (getLangOpts().OpenMP)
2328 Actions.OpenMP().startOpenMPCXXRangeFor();
2329 if (Tok.is(K: tok::l_brace))
2330 FRI->RangeExpr = ParseBraceInitializer();
2331 else
2332 FRI->RangeExpr = ParseExpression();
2333
2334 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
2335 assert(
2336 getLangOpts().CPlusPlus23 ||
2337 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2338
2339 // Move the collected materialized temporaries into ForRangeInit before
2340 // ForRangeInitContext exit.
2341 FRI->LifetimeExtendTemps = std::move(
2342 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2343 }
2344
2345 Decl *ThisDecl = Actions.ActOnDeclarator(S: getCurScope(), D);
2346 if (IsForRangeLoop) {
2347 Actions.ActOnCXXForRangeDecl(D: ThisDecl);
2348 } else {
2349 // Obj-C for loop
2350 if (auto *VD = dyn_cast_or_null<VarDecl>(Val: ThisDecl))
2351 VD->setObjCForDecl(true);
2352 }
2353 Actions.FinalizeDeclaration(D: ThisDecl);
2354 D.complete(D: ThisDecl);
2355 return Actions.FinalizeDeclaratorGroup(S: getCurScope(), DS, Group: ThisDecl);
2356 }
2357
2358 SmallVector<Decl *, 8> DeclsInGroup;
2359 Decl *FirstDecl =
2360 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2361 if (LateParsedAttrs.size() > 0)
2362 ParseLexedAttributeList(LAs&: LateParsedAttrs, D: FirstDecl, EnterScope: true, OnDefinition: false);
2363 D.complete(D: FirstDecl);
2364 if (FirstDecl)
2365 DeclsInGroup.push_back(Elt: FirstDecl);
2366
2367 bool ExpectSemi = Context != DeclaratorContext::ForInit;
2368
2369 // If we don't have a comma, it is either the end of the list (a ';') or an
2370 // error, bail out.
2371 SourceLocation CommaLoc;
2372 while (TryConsumeToken(Expected: tok::comma, Loc&: CommaLoc)) {
2373 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2374 // This comma was followed by a line-break and something which can't be
2375 // the start of a declarator. The comma was probably a typo for a
2376 // semicolon.
2377 Diag(CommaLoc, diag::err_expected_semi_declaration)
2378 << FixItHint::CreateReplacement(CommaLoc, ";");
2379 ExpectSemi = false;
2380 break;
2381 }
2382
2383 // C++23 [temp.pre]p5:
2384 // In a template-declaration, explicit specialization, or explicit
2385 // instantiation the init-declarator-list in the declaration shall
2386 // contain at most one declarator.
2387 if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&
2388 D.isFirstDeclarator()) {
2389 Diag(CommaLoc, diag::err_multiple_template_declarators)
2390 << TemplateInfo.Kind;
2391 }
2392
2393 // Parse the next declarator.
2394 D.clear();
2395 D.setCommaLoc(CommaLoc);
2396
2397 // Accept attributes in an init-declarator. In the first declarator in a
2398 // declaration, these would be part of the declspec. In subsequent
2399 // declarators, they become part of the declarator itself, so that they
2400 // don't apply to declarators after *this* one. Examples:
2401 // short __attribute__((common)) var; -> declspec
2402 // short var __attribute__((common)); -> declarator
2403 // short x, __attribute__((common)) var; -> declarator
2404 MaybeParseGNUAttributes(D);
2405
2406 // MSVC parses but ignores qualifiers after the comma as an extension.
2407 if (getLangOpts().MicrosoftExt)
2408 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2409
2410 ParseDeclarator(D);
2411
2412 if (getLangOpts().HLSL)
2413 MaybeParseHLSLAnnotations(D);
2414
2415 if (!D.isInvalidType()) {
2416 // C++2a [dcl.decl]p1
2417 // init-declarator:
2418 // declarator initializer[opt]
2419 // declarator requires-clause
2420 if (Tok.is(K: tok::kw_requires))
2421 ParseTrailingRequiresClause(D);
2422 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2423 D.complete(D: ThisDecl);
2424 if (ThisDecl)
2425 DeclsInGroup.push_back(Elt: ThisDecl);
2426 }
2427 }
2428
2429 if (DeclEnd)
2430 *DeclEnd = Tok.getLocation();
2431
2432 if (ExpectSemi && ExpectAndConsumeSemi(
2433 Context == DeclaratorContext::File
2434 ? diag::err_invalid_token_after_toplevel_declarator
2435 : diag::err_expected_semi_declaration)) {
2436 // Okay, there was no semicolon and one was expected. If we see a
2437 // declaration specifier, just assume it was missing and continue parsing.
2438 // Otherwise things are very confused and we skip to recover.
2439 if (!isDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No))
2440 SkipMalformedDecl();
2441 }
2442
2443 return Actions.FinalizeDeclaratorGroup(S: getCurScope(), DS, Group: DeclsInGroup);
2444}
2445
2446bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
2447 // If a simple-asm-expr is present, parse it.
2448 if (Tok.is(K: tok::kw_asm)) {
2449 SourceLocation Loc;
2450 ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, EndLoc: &Loc));
2451 if (AsmLabel.isInvalid()) {
2452 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
2453 return true;
2454 }
2455
2456 D.setAsmLabel(AsmLabel.get());
2457 D.SetRangeEnd(Loc);
2458 }
2459
2460 MaybeParseGNUAttributes(D);
2461 return false;
2462}
2463
2464Decl *Parser::ParseDeclarationAfterDeclarator(
2465 Declarator &D, const ParsedTemplateInfo &TemplateInfo) {
2466 if (ParseAsmAttributesAfterDeclarator(D))
2467 return nullptr;
2468
2469 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2470}
2471
2472Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2473 Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2474 // RAII type used to track whether we're inside an initializer.
2475 struct InitializerScopeRAII {
2476 Parser &P;
2477 Declarator &D;
2478 Decl *ThisDecl;
2479 bool Entered;
2480
2481 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2482 : P(P), D(D), ThisDecl(ThisDecl), Entered(false) {
2483 if (ThisDecl && P.getLangOpts().CPlusPlus) {
2484 Scope *S = nullptr;
2485 if (D.getCXXScopeSpec().isSet()) {
2486 P.EnterScope(ScopeFlags: 0);
2487 S = P.getCurScope();
2488 }
2489 if (ThisDecl && !ThisDecl->isInvalidDecl()) {
2490 P.Actions.ActOnCXXEnterDeclInitializer(S, Dcl: ThisDecl);
2491 Entered = true;
2492 }
2493 }
2494 }
2495 ~InitializerScopeRAII() {
2496 if (ThisDecl && P.getLangOpts().CPlusPlus) {
2497 Scope *S = nullptr;
2498 if (D.getCXXScopeSpec().isSet())
2499 S = P.getCurScope();
2500
2501 if (Entered)
2502 P.Actions.ActOnCXXExitDeclInitializer(S, Dcl: ThisDecl);
2503 if (S)
2504 P.ExitScope();
2505 }
2506 ThisDecl = nullptr;
2507 }
2508 };
2509
2510 enum class InitKind { Uninitialized, Equal, CXXDirect, CXXBraced };
2511 InitKind TheInitKind;
2512 // If a '==' or '+=' is found, suggest a fixit to '='.
2513 if (isTokenEqualOrEqualTypo())
2514 TheInitKind = InitKind::Equal;
2515 else if (Tok.is(K: tok::l_paren))
2516 TheInitKind = InitKind::CXXDirect;
2517 else if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::l_brace) &&
2518 (!CurParsedObjCImpl || !D.isFunctionDeclarator()))
2519 TheInitKind = InitKind::CXXBraced;
2520 else
2521 TheInitKind = InitKind::Uninitialized;
2522 if (TheInitKind != InitKind::Uninitialized)
2523 D.setHasInitializer();
2524
2525 // Inform Sema that we just parsed this declarator.
2526 Decl *ThisDecl = nullptr;
2527 Decl *OuterDecl = nullptr;
2528 switch (TemplateInfo.Kind) {
2529 case ParsedTemplateKind::NonTemplate:
2530 ThisDecl = Actions.ActOnDeclarator(S: getCurScope(), D);
2531 break;
2532
2533 case ParsedTemplateKind::Template:
2534 case ParsedTemplateKind::ExplicitSpecialization: {
2535 ThisDecl = Actions.ActOnTemplateDeclarator(S: getCurScope(),
2536 TemplateParameterLists: *TemplateInfo.TemplateParams,
2537 D);
2538 if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(Val: ThisDecl)) {
2539 // Re-direct this decl to refer to the templated decl so that we can
2540 // initialize it.
2541 ThisDecl = VT->getTemplatedDecl();
2542 OuterDecl = VT;
2543 }
2544 break;
2545 }
2546 case ParsedTemplateKind::ExplicitInstantiation: {
2547 if (Tok.is(K: tok::semi)) {
2548 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2549 S: getCurScope(), ExternLoc: TemplateInfo.ExternLoc, TemplateLoc: TemplateInfo.TemplateLoc, D);
2550 if (ThisRes.isInvalid()) {
2551 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
2552 return nullptr;
2553 }
2554 ThisDecl = ThisRes.get();
2555 } else {
2556 // FIXME: This check should be for a variable template instantiation only.
2557
2558 // Check that this is a valid instantiation
2559 if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {
2560 // If the declarator-id is not a template-id, issue a diagnostic and
2561 // recover by ignoring the 'template' keyword.
2562 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2563 << 2 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
2564 ThisDecl = Actions.ActOnDeclarator(S: getCurScope(), D);
2565 } else {
2566 SourceLocation LAngleLoc =
2567 PP.getLocForEndOfToken(Loc: TemplateInfo.TemplateLoc);
2568 Diag(D.getIdentifierLoc(),
2569 diag::err_explicit_instantiation_with_definition)
2570 << SourceRange(TemplateInfo.TemplateLoc)
2571 << FixItHint::CreateInsertion(LAngleLoc, "<>");
2572
2573 // Recover as if it were an explicit specialization.
2574 TemplateParameterLists FakedParamLists;
2575 FakedParamLists.push_back(Elt: Actions.ActOnTemplateParameterList(
2576 Depth: 0, ExportLoc: SourceLocation(), TemplateLoc: TemplateInfo.TemplateLoc, LAngleLoc, Params: {},
2577 RAngleLoc: LAngleLoc, RequiresClause: nullptr));
2578
2579 ThisDecl =
2580 Actions.ActOnTemplateDeclarator(S: getCurScope(), TemplateParameterLists: FakedParamLists, D);
2581 }
2582 }
2583 break;
2584 }
2585 }
2586
2587 SemaCUDA::CUDATargetContextRAII X(Actions.CUDA(),
2588 SemaCUDA::CTCK_InitGlobalVar, ThisDecl);
2589 switch (TheInitKind) {
2590 // Parse declarator '=' initializer.
2591 case InitKind::Equal: {
2592 SourceLocation EqualLoc = ConsumeToken();
2593
2594 if (Tok.is(K: tok::kw_delete)) {
2595 if (D.isFunctionDeclarator())
2596 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2597 << 1 /* delete */;
2598 else
2599 Diag(ConsumeToken(), diag::err_deleted_non_function);
2600 SkipDeletedFunctionBody();
2601 } else if (Tok.is(K: tok::kw_default)) {
2602 if (D.isFunctionDeclarator())
2603 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2604 << 0 /* default */;
2605 else
2606 Diag(ConsumeToken(), diag::err_default_special_members)
2607 << getLangOpts().CPlusPlus20;
2608 } else {
2609 InitializerScopeRAII InitScope(*this, D, ThisDecl);
2610
2611 if (Tok.is(K: tok::code_completion)) {
2612 cutOffParsing();
2613 Actions.CodeCompletion().CodeCompleteInitializer(S: getCurScope(),
2614 D: ThisDecl);
2615 Actions.FinalizeDeclaration(D: ThisDecl);
2616 return nullptr;
2617 }
2618
2619 PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);
2620 ExprResult Init = ParseInitializer();
2621
2622 // If this is the only decl in (possibly) range based for statement,
2623 // our best guess is that the user meant ':' instead of '='.
2624 if (Tok.is(K: tok::r_paren) && FRI && D.isFirstDeclarator()) {
2625 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2626 << FixItHint::CreateReplacement(EqualLoc, ":");
2627 // We are trying to stop parser from looking for ';' in this for
2628 // statement, therefore preventing spurious errors to be issued.
2629 FRI->ColonLoc = EqualLoc;
2630 Init = ExprError();
2631 FRI->RangeExpr = Init;
2632 }
2633
2634 if (Init.isInvalid()) {
2635 SmallVector<tok::TokenKind, 2> StopTokens;
2636 StopTokens.push_back(Elt: tok::comma);
2637 if (D.getContext() == DeclaratorContext::ForInit ||
2638 D.getContext() == DeclaratorContext::SelectionInit)
2639 StopTokens.push_back(Elt: tok::r_paren);
2640 SkipUntil(Toks: StopTokens, Flags: StopAtSemi | StopBeforeMatch);
2641 Actions.ActOnInitializerError(Dcl: ThisDecl);
2642 } else
2643 Actions.AddInitializerToDecl(dcl: ThisDecl, init: Init.get(),
2644 /*DirectInit=*/false);
2645 }
2646 break;
2647 }
2648 case InitKind::CXXDirect: {
2649 // Parse C++ direct initializer: '(' expression-list ')'
2650 BalancedDelimiterTracker T(*this, tok::l_paren);
2651 T.consumeOpen();
2652
2653 ExprVector Exprs;
2654
2655 InitializerScopeRAII InitScope(*this, D, ThisDecl);
2656
2657 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(Val: ThisDecl);
2658 auto RunSignatureHelp = [&]() {
2659 QualType PreferredType =
2660 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2661 Type: ThisVarDecl->getType()->getCanonicalTypeInternal(),
2662 Loc: ThisDecl->getLocation(), Args: Exprs, OpenParLoc: T.getOpenLocation(),
2663 /*Braced=*/false);
2664 CalledSignatureHelp = true;
2665 return PreferredType;
2666 };
2667 auto SetPreferredType = [&] {
2668 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
2669 };
2670
2671 llvm::function_ref<void()> ExpressionStarts;
2672 if (ThisVarDecl) {
2673 // ParseExpressionList can sometimes succeed even when ThisDecl is not
2674 // VarDecl. This is an error and it is reported in a call to
2675 // Actions.ActOnInitializerError(). However, we call
2676 // ProduceConstructorSignatureHelp only on VarDecls.
2677 ExpressionStarts = SetPreferredType;
2678 }
2679
2680 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2681
2682 if (SawError) {
2683 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2684 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2685 Type: ThisVarDecl->getType()->getCanonicalTypeInternal(),
2686 Loc: ThisDecl->getLocation(), Args: Exprs, OpenParLoc: T.getOpenLocation(),
2687 /*Braced=*/false);
2688 CalledSignatureHelp = true;
2689 }
2690 Actions.ActOnInitializerError(Dcl: ThisDecl);
2691 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
2692 } else {
2693 // Match the ')'.
2694 T.consumeClose();
2695
2696 ExprResult Initializer = Actions.ActOnParenListExpr(L: T.getOpenLocation(),
2697 R: T.getCloseLocation(),
2698 Val: Exprs);
2699 Actions.AddInitializerToDecl(dcl: ThisDecl, init: Initializer.get(),
2700 /*DirectInit=*/true);
2701 }
2702 break;
2703 }
2704 case InitKind::CXXBraced: {
2705 // Parse C++0x braced-init-list.
2706 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2707
2708 InitializerScopeRAII InitScope(*this, D, ThisDecl);
2709
2710 PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);
2711 ExprResult Init(ParseBraceInitializer());
2712
2713 if (Init.isInvalid()) {
2714 Actions.ActOnInitializerError(Dcl: ThisDecl);
2715 } else
2716 Actions.AddInitializerToDecl(dcl: ThisDecl, init: Init.get(), /*DirectInit=*/true);
2717 break;
2718 }
2719 case InitKind::Uninitialized: {
2720 Actions.ActOnUninitializedDecl(dcl: ThisDecl);
2721 break;
2722 }
2723 }
2724
2725 Actions.FinalizeDeclaration(D: ThisDecl);
2726 return OuterDecl ? OuterDecl : ThisDecl;
2727}
2728
2729void Parser::ParseSpecifierQualifierList(
2730 DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,
2731 AccessSpecifier AS, DeclSpecContext DSC) {
2732 ParsedTemplateInfo TemplateInfo;
2733 /// specifier-qualifier-list is a subset of declaration-specifiers. Just
2734 /// parse declaration-specifiers and complain about extra stuff.
2735 /// TODO: diagnose attribute-specifiers and alignment-specifiers.
2736 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC, LateAttrs: nullptr,
2737 AllowImplicitTypename);
2738
2739 // Validate declspec for type-name.
2740 unsigned Specs = DS.getParsedSpecifiers();
2741 if (isTypeSpecifier(DSC) && !DS.hasTypeSpecifier()) {
2742 Diag(Tok, diag::err_expected_type);
2743 DS.SetTypeSpecError();
2744 } else if (Specs == DeclSpec::PQ_None && !DS.hasAttributes()) {
2745 Diag(Tok, diag::err_typename_requires_specqual);
2746 if (!DS.hasTypeSpecifier())
2747 DS.SetTypeSpecError();
2748 }
2749
2750 // Issue diagnostic and remove storage class if present.
2751 if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
2752 if (DS.getStorageClassSpecLoc().isValid())
2753 Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);
2754 else
2755 Diag(DS.getThreadStorageClassSpecLoc(),
2756 diag::err_typename_invalid_storageclass);
2757 DS.ClearStorageClassSpecs();
2758 }
2759
2760 // Issue diagnostic and remove function specifier if present.
2761 if (Specs & DeclSpec::PQ_FunctionSpecifier) {
2762 if (DS.isInlineSpecified())
2763 Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);
2764 if (DS.isVirtualSpecified())
2765 Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);
2766 if (DS.hasExplicitSpecifier())
2767 Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
2768 if (DS.isNoreturnSpecified())
2769 Diag(DS.getNoreturnSpecLoc(), diag::err_typename_invalid_functionspec);
2770 DS.ClearFunctionSpecs();
2771 }
2772
2773 // Issue diagnostic and remove constexpr specifier if present.
2774 if (DS.hasConstexprSpecifier() && DSC != DeclSpecContext::DSC_condition) {
2775 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr)
2776 << static_cast<int>(DS.getConstexprSpecifier());
2777 DS.ClearConstexprSpec();
2778 }
2779}
2780
2781/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
2782/// specified token is valid after the identifier in a declarator which
2783/// immediately follows the declspec. For example, these things are valid:
2784///
2785/// int x [ 4]; // direct-declarator
2786/// int x ( int y); // direct-declarator
2787/// int(int x ) // direct-declarator
2788/// int x ; // simple-declaration
2789/// int x = 17; // init-declarator-list
2790/// int x , y; // init-declarator-list
2791/// int x __asm__ ("foo"); // init-declarator-list
2792/// int x : 4; // struct-declarator
2793/// int x { 5}; // C++'0x unified initializers
2794///
2795/// This is not, because 'x' does not immediately follow the declspec (though
2796/// ')' happens to be valid anyway).
2797/// int (x)
2798///
2799static bool isValidAfterIdentifierInDeclarator(const Token &T) {
2800 return T.isOneOf(K1: tok::l_square, Ks: tok::l_paren, Ks: tok::r_paren, Ks: tok::semi,
2801 Ks: tok::comma, Ks: tok::equal, Ks: tok::kw_asm, Ks: tok::l_brace,
2802 Ks: tok::colon);
2803}
2804
2805bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
2806 ParsedTemplateInfo &TemplateInfo,
2807 AccessSpecifier AS, DeclSpecContext DSC,
2808 ParsedAttributes &Attrs) {
2809 assert(Tok.is(tok::identifier) && "should have identifier");
2810
2811 SourceLocation Loc = Tok.getLocation();
2812 // If we see an identifier that is not a type name, we normally would
2813 // parse it as the identifier being declared. However, when a typename
2814 // is typo'd or the definition is not included, this will incorrectly
2815 // parse the typename as the identifier name and fall over misparsing
2816 // later parts of the diagnostic.
2817 //
2818 // As such, we try to do some look-ahead in cases where this would
2819 // otherwise be an "implicit-int" case to see if this is invalid. For
2820 // example: "static foo_t x = 4;" In this case, if we parsed foo_t as
2821 // an identifier with implicit int, we'd get a parse error because the
2822 // next token is obviously invalid for a type. Parse these as a case
2823 // with an invalid type specifier.
2824 assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
2825
2826 // Since we know that this either implicit int (which is rare) or an
2827 // error, do lookahead to try to do better recovery. This never applies
2828 // within a type specifier. Outside of C++, we allow this even if the
2829 // language doesn't "officially" support implicit int -- we support
2830 // implicit int as an extension in some language modes.
2831 if (!isTypeSpecifier(DSC) && getLangOpts().isImplicitIntAllowed() &&
2832 isValidAfterIdentifierInDeclarator(T: NextToken())) {
2833 // If this token is valid for implicit int, e.g. "static x = 4", then
2834 // we just avoid eating the identifier, so it will be parsed as the
2835 // identifier in the declarator.
2836 return false;
2837 }
2838
2839 // Early exit as Sema has a dedicated missing_actual_pipe_type diagnostic
2840 // for incomplete declarations such as `pipe p`.
2841 if (getLangOpts().OpenCLCPlusPlus && DS.isTypeSpecPipe())
2842 return false;
2843
2844 if (getLangOpts().CPlusPlus &&
2845 DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
2846 // Don't require a type specifier if we have the 'auto' storage class
2847 // specifier in C++98 -- we'll promote it to a type specifier.
2848 if (SS)
2849 AnnotateScopeToken(SS&: *SS, /*IsNewAnnotation*/false);
2850 return false;
2851 }
2852
2853 if (getLangOpts().CPlusPlus && (!SS || SS->isEmpty()) &&
2854 getLangOpts().MSVCCompat) {
2855 // Lookup of an unqualified type name has failed in MSVC compatibility mode.
2856 // Give Sema a chance to recover if we are in a template with dependent base
2857 // classes.
2858 if (ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2859 II: *Tok.getIdentifierInfo(), NameLoc: Tok.getLocation(),
2860 IsTemplateTypeArg: DSC == DeclSpecContext::DSC_template_type_arg)) {
2861 const char *PrevSpec;
2862 unsigned DiagID;
2863 DS.SetTypeSpecType(T: DeclSpec::TST_typename, Loc, PrevSpec, DiagID, Rep: T,
2864 Policy: Actions.getASTContext().getPrintingPolicy());
2865 DS.SetRangeEnd(Tok.getLocation());
2866 ConsumeToken();
2867 return false;
2868 }
2869 }
2870
2871 // Otherwise, if we don't consume this token, we are going to emit an
2872 // error anyway. Try to recover from various common problems. Check
2873 // to see if this was a reference to a tag name without a tag specified.
2874 // This is a common problem in C (saying 'foo' instead of 'struct foo').
2875 //
2876 // C++ doesn't need this, and isTagName doesn't take SS.
2877 if (SS == nullptr) {
2878 const char *TagName = nullptr, *FixitTagName = nullptr;
2879 tok::TokenKind TagKind = tok::unknown;
2880
2881 switch (Actions.isTagName(II&: *Tok.getIdentifierInfo(), S: getCurScope())) {
2882 default: break;
2883 case DeclSpec::TST_enum:
2884 TagName="enum" ; FixitTagName = "enum " ; TagKind=tok::kw_enum ;break;
2885 case DeclSpec::TST_union:
2886 TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;
2887 case DeclSpec::TST_struct:
2888 TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;
2889 case DeclSpec::TST_interface:
2890 TagName="__interface"; FixitTagName = "__interface ";
2891 TagKind=tok::kw___interface;break;
2892 case DeclSpec::TST_class:
2893 TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;
2894 }
2895
2896 if (TagName) {
2897 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2898 LookupResult R(Actions, TokenName, SourceLocation(),
2899 Sema::LookupOrdinaryName);
2900
2901 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2902 << TokenName << TagName << getLangOpts().CPlusPlus
2903 << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);
2904
2905 if (Actions.LookupName(R, S: getCurScope())) {
2906 for (LookupResult::iterator I = R.begin(), IEnd = R.end();
2907 I != IEnd; ++I)
2908 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2909 << TokenName << TagName;
2910 }
2911
2912 // Parse this as a tag as if the missing tag were present.
2913 if (TagKind == tok::kw_enum)
2914 ParseEnumSpecifier(TagLoc: Loc, DS, TemplateInfo, AS,
2915 DSC: DeclSpecContext::DSC_normal);
2916 else
2917 ParseClassSpecifier(TagTokKind: TagKind, TagLoc: Loc, DS, TemplateInfo, AS,
2918 /*EnteringContext*/ false,
2919 DSC: DeclSpecContext::DSC_normal, Attributes&: Attrs);
2920 return true;
2921 }
2922 }
2923
2924 // Determine whether this identifier could plausibly be the name of something
2925 // being declared (with a missing type).
2926 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2927 DSC == DeclSpecContext::DSC_class)) {
2928 // Look ahead to the next token to try to figure out what this declaration
2929 // was supposed to be.
2930 switch (NextToken().getKind()) {
2931 case tok::l_paren: {
2932 // static x(4); // 'x' is not a type
2933 // x(int n); // 'x' is not a type
2934 // x (*p)[]; // 'x' is a type
2935 //
2936 // Since we're in an error case, we can afford to perform a tentative
2937 // parse to determine which case we're in.
2938 TentativeParsingAction PA(*this);
2939 ConsumeToken();
2940 TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
2941 PA.Revert();
2942
2943 if (TPR != TPResult::False) {
2944 // The identifier is followed by a parenthesized declarator.
2945 // It's supposed to be a type.
2946 break;
2947 }
2948
2949 // If we're in a context where we could be declaring a constructor,
2950 // check whether this is a constructor declaration with a bogus name.
2951 if (DSC == DeclSpecContext::DSC_class ||
2952 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2953 IdentifierInfo *II = Tok.getIdentifierInfo();
2954 if (Actions.isCurrentClassNameTypo(II, SS)) {
2955 Diag(Loc, diag::err_constructor_bad_name)
2956 << Tok.getIdentifierInfo() << II
2957 << FixItHint::CreateReplacement(Tok.getLocation(), II->getName());
2958 Tok.setIdentifierInfo(II);
2959 }
2960 }
2961 // Fall through.
2962 [[fallthrough]];
2963 }
2964 case tok::comma:
2965 case tok::equal:
2966 case tok::kw_asm:
2967 case tok::l_brace:
2968 case tok::l_square:
2969 case tok::semi:
2970 // This looks like a variable or function declaration. The type is
2971 // probably missing. We're done parsing decl-specifiers.
2972 // But only if we are not in a function prototype scope.
2973 if (getCurScope()->isFunctionPrototypeScope())
2974 break;
2975 if (SS)
2976 AnnotateScopeToken(SS&: *SS, /*IsNewAnnotation*/false);
2977 return false;
2978
2979 default:
2980 // This is probably supposed to be a type. This includes cases like:
2981 // int f(itn);
2982 // struct S { unsigned : 4; };
2983 break;
2984 }
2985 }
2986
2987 // This is almost certainly an invalid type name. Let Sema emit a diagnostic
2988 // and attempt to recover.
2989 ParsedType T;
2990 IdentifierInfo *II = Tok.getIdentifierInfo();
2991 bool IsTemplateName = getLangOpts().CPlusPlus && NextToken().is(K: tok::less);
2992 Actions.DiagnoseUnknownTypeName(II, IILoc: Loc, S: getCurScope(), SS, SuggestedType&: T,
2993 IsTemplateName);
2994 if (T) {
2995 // The action has suggested that the type T could be used. Set that as
2996 // the type in the declaration specifiers, consume the would-be type
2997 // name token, and we're done.
2998 const char *PrevSpec;
2999 unsigned DiagID;
3000 DS.SetTypeSpecType(T: DeclSpec::TST_typename, Loc, PrevSpec, DiagID, Rep: T,
3001 Policy: Actions.getASTContext().getPrintingPolicy());
3002 DS.SetRangeEnd(Tok.getLocation());
3003 ConsumeToken();
3004 // There may be other declaration specifiers after this.
3005 return true;
3006 } else if (II != Tok.getIdentifierInfo()) {
3007 // If no type was suggested, the correction is to a keyword
3008 Tok.setKind(II->getTokenID());
3009 // There may be other declaration specifiers after this.
3010 return true;
3011 }
3012
3013 // Otherwise, the action had no suggestion for us. Mark this as an error.
3014 DS.SetTypeSpecError();
3015 DS.SetRangeEnd(Tok.getLocation());
3016 ConsumeToken();
3017
3018 // Eat any following template arguments.
3019 if (IsTemplateName) {
3020 SourceLocation LAngle, RAngle;
3021 TemplateArgList Args;
3022 ParseTemplateIdAfterTemplateName(ConsumeLastToken: true, LAngleLoc&: LAngle, TemplateArgs&: Args, RAngleLoc&: RAngle);
3023 }
3024
3025 // TODO: Could inject an invalid typedef decl in an enclosing scope to
3026 // avoid rippling error messages on subsequent uses of the same type,
3027 // could be useful if #include was forgotten.
3028 return true;
3029}
3030
3031Parser::DeclSpecContext
3032Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {
3033 switch (Context) {
3034 case DeclaratorContext::Member:
3035 return DeclSpecContext::DSC_class;
3036 case DeclaratorContext::File:
3037 return DeclSpecContext::DSC_top_level;
3038 case DeclaratorContext::TemplateParam:
3039 return DeclSpecContext::DSC_template_param;
3040 case DeclaratorContext::TemplateArg:
3041 return DeclSpecContext::DSC_template_arg;
3042 case DeclaratorContext::TemplateTypeArg:
3043 return DeclSpecContext::DSC_template_type_arg;
3044 case DeclaratorContext::TrailingReturn:
3045 case DeclaratorContext::TrailingReturnVar:
3046 return DeclSpecContext::DSC_trailing;
3047 case DeclaratorContext::AliasDecl:
3048 case DeclaratorContext::AliasTemplate:
3049 return DeclSpecContext::DSC_alias_declaration;
3050 case DeclaratorContext::Association:
3051 return DeclSpecContext::DSC_association;
3052 case DeclaratorContext::TypeName:
3053 return DeclSpecContext::DSC_type_specifier;
3054 case DeclaratorContext::Condition:
3055 return DeclSpecContext::DSC_condition;
3056 case DeclaratorContext::ConversionId:
3057 return DeclSpecContext::DSC_conv_operator;
3058 case DeclaratorContext::CXXNew:
3059 return DeclSpecContext::DSC_new;
3060 case DeclaratorContext::Prototype:
3061 case DeclaratorContext::ObjCResult:
3062 case DeclaratorContext::ObjCParameter:
3063 case DeclaratorContext::KNRTypeList:
3064 case DeclaratorContext::FunctionalCast:
3065 case DeclaratorContext::Block:
3066 case DeclaratorContext::ForInit:
3067 case DeclaratorContext::SelectionInit:
3068 case DeclaratorContext::CXXCatch:
3069 case DeclaratorContext::ObjCCatch:
3070 case DeclaratorContext::BlockLiteral:
3071 case DeclaratorContext::LambdaExpr:
3072 case DeclaratorContext::LambdaExprParameter:
3073 case DeclaratorContext::RequiresExpr:
3074 return DeclSpecContext::DSC_normal;
3075 }
3076
3077 llvm_unreachable("Missing DeclaratorContext case");
3078}
3079
3080ExprResult Parser::ParseAlignArgument(StringRef KWName, SourceLocation Start,
3081 SourceLocation &EllipsisLoc, bool &IsType,
3082 ParsedType &TypeResult) {
3083 ExprResult ER;
3084 if (isTypeIdInParens()) {
3085 SourceLocation TypeLoc = Tok.getLocation();
3086 ParsedType Ty = ParseTypeName().get();
3087 SourceRange TypeRange(Start, Tok.getLocation());
3088 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, OpLoc: TypeLoc, R: TypeRange))
3089 return ExprError();
3090 TypeResult = Ty;
3091 IsType = true;
3092 } else {
3093 ER = ParseConstantExpression();
3094 IsType = false;
3095 }
3096
3097 if (getLangOpts().CPlusPlus11)
3098 TryConsumeToken(Expected: tok::ellipsis, Loc&: EllipsisLoc);
3099
3100 return ER;
3101}
3102
3103void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
3104 SourceLocation *EndLoc) {
3105 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3106 "Not an alignment-specifier!");
3107 Token KWTok = Tok;
3108 IdentifierInfo *KWName = KWTok.getIdentifierInfo();
3109 auto Kind = KWTok.getKind();
3110 SourceLocation KWLoc = ConsumeToken();
3111
3112 BalancedDelimiterTracker T(*this, tok::l_paren);
3113 if (T.expectAndConsume())
3114 return;
3115
3116 bool IsType;
3117 ParsedType TypeResult;
3118 SourceLocation EllipsisLoc;
3119 ExprResult ArgExpr =
3120 ParseAlignArgument(KWName: PP.getSpelling(Tok: KWTok), Start: T.getOpenLocation(),
3121 EllipsisLoc, IsType, TypeResult);
3122 if (ArgExpr.isInvalid()) {
3123 T.skipToEnd();
3124 return;
3125 }
3126
3127 T.consumeClose();
3128 if (EndLoc)
3129 *EndLoc = T.getCloseLocation();
3130
3131 if (IsType) {
3132 Attrs.addNewTypeAttr(attrName: KWName, attrRange: KWLoc, scopeName: nullptr, scopeLoc: KWLoc, typeArg: TypeResult, formUsed: Kind,
3133 ellipsisLoc: EllipsisLoc);
3134 } else {
3135 ArgsVector ArgExprs;
3136 ArgExprs.push_back(Elt: ArgExpr.get());
3137 Attrs.addNew(attrName: KWName, attrRange: KWLoc, scopeName: nullptr, scopeLoc: KWLoc, args: ArgExprs.data(), numArgs: 1, form: Kind,
3138 ellipsisLoc: EllipsisLoc);
3139 }
3140}
3141
3142void Parser::DistributeCLateParsedAttrs(Decl *Dcl,
3143 LateParsedAttrList *LateAttrs) {
3144 if (!LateAttrs)
3145 return;
3146
3147 if (Dcl) {
3148 for (auto *LateAttr : *LateAttrs) {
3149 if (LateAttr->Decls.empty())
3150 LateAttr->addDecl(D: Dcl);
3151 }
3152 }
3153}
3154
3155void Parser::ParsePtrauthQualifier(ParsedAttributes &Attrs) {
3156 assert(Tok.is(tok::kw___ptrauth));
3157
3158 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3159 SourceLocation KwLoc = ConsumeToken();
3160
3161 BalancedDelimiterTracker T(*this, tok::l_paren);
3162 if (T.expectAndConsume())
3163 return;
3164
3165 ArgsVector ArgExprs;
3166 do {
3167 ExprResult ER = ParseAssignmentExpression();
3168 if (ER.isInvalid()) {
3169 T.skipToEnd();
3170 return;
3171 }
3172 ArgExprs.push_back(Elt: ER.get());
3173 } while (TryConsumeToken(Expected: tok::comma));
3174
3175 T.consumeClose();
3176 SourceLocation EndLoc = T.getCloseLocation();
3177
3178 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3179 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3180 return;
3181 }
3182
3183 Attrs.addNew(attrName: KwName, attrRange: SourceRange(KwLoc, EndLoc),
3184 /*scope*/ scopeName: nullptr, scopeLoc: SourceLocation(), args: ArgExprs.data(),
3185 numArgs: ArgExprs.size(),
3186 form: ParsedAttr::Form::Keyword(/*IsAlignAs=*/IsAlignas: false,
3187 /*IsRegularKeywordAttribute=*/false));
3188}
3189
3190void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName,
3191 SourceLocation AttrNameLoc,
3192 ParsedAttributes &Attrs,
3193 IdentifierInfo *ScopeName,
3194 SourceLocation ScopeLoc,
3195 ParsedAttr::Form Form) {
3196 assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
3197
3198 BalancedDelimiterTracker Parens(*this, tok::l_paren);
3199 Parens.consumeOpen();
3200
3201 if (Tok.is(K: tok::r_paren)) {
3202 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3203 Parens.consumeClose();
3204 return;
3205 }
3206
3207 ArgsVector ArgExprs;
3208 // Don't evaluate argument when the attribute is ignored.
3209 using ExpressionKind =
3210 Sema::ExpressionEvaluationContextRecord::ExpressionKind;
3211 EnterExpressionEvaluationContext EC(
3212 Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, nullptr,
3213 ExpressionKind::EK_AttrArgument);
3214
3215 ExprResult ArgExpr(
3216 Actions.CorrectDelayedTyposInExpr(ER: ParseAssignmentExpression()));
3217
3218 if (ArgExpr.isInvalid()) {
3219 Parens.skipToEnd();
3220 return;
3221 }
3222
3223 ArgExprs.push_back(Elt: ArgExpr.get());
3224 Parens.consumeClose();
3225
3226 ASTContext &Ctx = Actions.getASTContext();
3227
3228 ArgExprs.push_back(IntegerLiteral::Create(
3229 C: Ctx, V: llvm::APInt(Ctx.getTypeSize(T: Ctx.getSizeType()), 0),
3230 type: Ctx.getSizeType(), l: SourceLocation()));
3231
3232 Attrs.addNew(attrName: &AttrName, attrRange: SourceRange(AttrNameLoc, Parens.getCloseLocation()),
3233 scopeName: ScopeName, scopeLoc: ScopeLoc, args: ArgExprs.data(), numArgs: ArgExprs.size(), form: Form);
3234}
3235
3236ExprResult Parser::ParseExtIntegerArgument() {
3237 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3238 "Not an extended int type");
3239 ConsumeToken();
3240
3241 BalancedDelimiterTracker T(*this, tok::l_paren);
3242 if (T.expectAndConsume())
3243 return ExprError();
3244
3245 ExprResult ER = ParseConstantExpression();
3246 if (ER.isInvalid()) {
3247 T.skipToEnd();
3248 return ExprError();
3249 }
3250
3251 if(T.consumeClose())
3252 return ExprError();
3253 return ER;
3254}
3255
3256bool
3257Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
3258 DeclSpecContext DSContext,
3259 LateParsedAttrList *LateAttrs) {
3260 assert(DS.hasTagDefinition() && "shouldn't call this");
3261
3262 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3263 DSContext == DeclSpecContext::DSC_top_level);
3264
3265 if (getLangOpts().CPlusPlus &&
3266 Tok.isOneOf(K1: tok::identifier, Ks: tok::coloncolon, Ks: tok::kw_decltype,
3267 Ks: tok::annot_template_id) &&
3268 TryAnnotateCXXScopeToken(EnteringContext)) {
3269 SkipMalformedDecl();
3270 return true;
3271 }
3272
3273 bool HasScope = Tok.is(K: tok::annot_cxxscope);
3274 // Make a copy in case GetLookAheadToken invalidates the result of NextToken.
3275 Token AfterScope = HasScope ? NextToken() : Tok;
3276
3277 // Determine whether the following tokens could possibly be a
3278 // declarator.
3279 bool MightBeDeclarator = true;
3280 if (Tok.isOneOf(K1: tok::kw_typename, K2: tok::annot_typename)) {
3281 // A declarator-id can't start with 'typename'.
3282 MightBeDeclarator = false;
3283 } else if (AfterScope.is(K: tok::annot_template_id)) {
3284 // If we have a type expressed as a template-id, this cannot be a
3285 // declarator-id (such a type cannot be redeclared in a simple-declaration).
3286 TemplateIdAnnotation *Annot =
3287 static_cast<TemplateIdAnnotation *>(AfterScope.getAnnotationValue());
3288 if (Annot->Kind == TNK_Type_template)
3289 MightBeDeclarator = false;
3290 } else if (AfterScope.is(K: tok::identifier)) {
3291 const Token &Next = HasScope ? GetLookAheadToken(N: 2) : NextToken();
3292
3293 // These tokens cannot come after the declarator-id in a
3294 // simple-declaration, and are likely to come after a type-specifier.
3295 if (Next.isOneOf(K1: tok::star, Ks: tok::amp, Ks: tok::ampamp, Ks: tok::identifier,
3296 Ks: tok::annot_cxxscope, Ks: tok::coloncolon)) {
3297 // Missing a semicolon.
3298 MightBeDeclarator = false;
3299 } else if (HasScope) {
3300 // If the declarator-id has a scope specifier, it must redeclare a
3301 // previously-declared entity. If that's a type (and this is not a
3302 // typedef), that's an error.
3303 CXXScopeSpec SS;
3304 Actions.RestoreNestedNameSpecifierAnnotation(
3305 Annotation: Tok.getAnnotationValue(), AnnotationRange: Tok.getAnnotationRange(), SS);
3306 IdentifierInfo *Name = AfterScope.getIdentifierInfo();
3307 Sema::NameClassification Classification = Actions.ClassifyName(
3308 S: getCurScope(), SS, Name, NameLoc: AfterScope.getLocation(), NextToken: Next,
3309 /*CCC=*/nullptr);
3310 switch (Classification.getKind()) {
3311 case NameClassificationKind::Error:
3312 SkipMalformedDecl();
3313 return true;
3314
3315 case NameClassificationKind::Keyword:
3316 llvm_unreachable("typo correction is not possible here");
3317
3318 case NameClassificationKind::Type:
3319 case NameClassificationKind::TypeTemplate:
3320 case NameClassificationKind::UndeclaredNonType:
3321 case NameClassificationKind::UndeclaredTemplate:
3322 // Not a previously-declared non-type entity.
3323 MightBeDeclarator = false;
3324 break;
3325
3326 case NameClassificationKind::Unknown:
3327 case NameClassificationKind::NonType:
3328 case NameClassificationKind::DependentNonType:
3329 case NameClassificationKind::OverloadSet:
3330 case NameClassificationKind::VarTemplate:
3331 case NameClassificationKind::FunctionTemplate:
3332 case NameClassificationKind::Concept:
3333 // Might be a redeclaration of a prior entity.
3334 break;
3335 }
3336 }
3337 }
3338
3339 if (MightBeDeclarator)
3340 return false;
3341
3342 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3343 Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getEndLoc()),
3344 diag::err_expected_after)
3345 << DeclSpec::getSpecifierName(DS.getTypeSpecType(), PPol) << tok::semi;
3346
3347 // Try to recover from the typo, by dropping the tag definition and parsing
3348 // the problematic tokens as a type.
3349 //
3350 // FIXME: Split the DeclSpec into pieces for the standalone
3351 // declaration and pieces for the following declaration, instead
3352 // of assuming that all the other pieces attach to new declaration,
3353 // and call ParsedFreeStandingDeclSpec as appropriate.
3354 DS.ClearTypeSpecType();
3355 ParsedTemplateInfo NotATemplate;
3356 ParseDeclarationSpecifiers(DS, TemplateInfo&: NotATemplate, AS, DSC: DSContext, LateAttrs);
3357 return false;
3358}
3359
3360void Parser::ParseDeclarationSpecifiers(
3361 DeclSpec &DS, ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,
3362 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3363 ImplicitTypenameContext AllowImplicitTypename) {
3364 if (DS.getSourceRange().isInvalid()) {
3365 // Start the range at the current token but make the end of the range
3366 // invalid. This will make the entire range invalid unless we successfully
3367 // consume a token.
3368 DS.SetRangeStart(Tok.getLocation());
3369 DS.SetRangeEnd(SourceLocation());
3370 }
3371
3372 // If we are in a operator context, convert it back into a type specifier
3373 // context for better error handling later on.
3374 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3375 // No implicit typename here.
3376 AllowImplicitTypename = ImplicitTypenameContext::No;
3377 DSContext = DeclSpecContext::DSC_type_specifier;
3378 }
3379
3380 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3381 DSContext == DeclSpecContext::DSC_top_level);
3382 bool AttrsLastTime = false;
3383 ParsedAttributes attrs(AttrFactory);
3384 // We use Sema's policy to get bool macros right.
3385 PrintingPolicy Policy = Actions.getPrintingPolicy();
3386 while (true) {
3387 bool isInvalid = false;
3388 bool isStorageClass = false;
3389 const char *PrevSpec = nullptr;
3390 unsigned DiagID = 0;
3391
3392 // This value needs to be set to the location of the last token if the last
3393 // token of the specifier is already consumed.
3394 SourceLocation ConsumedEnd;
3395
3396 // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL
3397 // implementation for VS2013 uses _Atomic as an identifier for one of the
3398 // classes in <atomic>.
3399 //
3400 // A typedef declaration containing _Atomic<...> is among the places where
3401 // the class is used. If we are currently parsing such a declaration, treat
3402 // the token as an identifier.
3403 if (getLangOpts().MSVCCompat && Tok.is(K: tok::kw__Atomic) &&
3404 DS.getStorageClassSpec() == clang::DeclSpec::SCS_typedef &&
3405 !DS.hasTypeSpecifier() && GetLookAheadToken(N: 1).is(K: tok::less))
3406 Tok.setKind(tok::identifier);
3407
3408 SourceLocation Loc = Tok.getLocation();
3409
3410 // Helper for image types in OpenCL.
3411 auto handleOpenCLImageKW = [&] (StringRef Ext, TypeSpecifierType ImageTypeSpec) {
3412 // Check if the image type is supported and otherwise turn the keyword into an identifier
3413 // because image types from extensions are not reserved identifiers.
3414 if (!StringRef(Ext).empty() && !getActions().getOpenCLOptions().isSupported(Ext, LO: getLangOpts())) {
3415 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3416 Tok.setKind(tok::identifier);
3417 return false;
3418 }
3419 isInvalid = DS.SetTypeSpecType(T: ImageTypeSpec, Loc, PrevSpec, DiagID, Policy);
3420 return true;
3421 };
3422
3423 // Turn off usual access checking for template specializations and
3424 // instantiations.
3425 bool IsTemplateSpecOrInst =
3426 (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation ||
3427 TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization);
3428
3429 switch (Tok.getKind()) {
3430 default:
3431 if (Tok.isRegularKeywordAttribute())
3432 goto Attribute;
3433
3434 DoneWithDeclSpec:
3435 if (!AttrsLastTime)
3436 ProhibitAttributes(Attrs&: attrs);
3437 else {
3438 // Reject C++11 / C23 attributes that aren't type attributes.
3439 for (const ParsedAttr &PA : attrs) {
3440 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3441 !PA.isRegularKeywordAttribute())
3442 continue;
3443 if (PA.getKind() == ParsedAttr::UnknownAttribute)
3444 // We will warn about the unknown attribute elsewhere (in
3445 // SemaDeclAttr.cpp)
3446 continue;
3447 // GCC ignores this attribute when placed on the DeclSpec in [[]]
3448 // syntax, so we do the same.
3449 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3450 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3451 PA.setInvalid();
3452 continue;
3453 }
3454 // We reject AT_LifetimeBound and AT_AnyX86NoCfCheck, even though they
3455 // are type attributes, because we historically haven't allowed these
3456 // to be used as type attributes in C++11 / C23 syntax.
3457 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3458 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3459 continue;
3460
3461 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3462 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3463 << PA << PA.isRegularKeywordAttribute()
3464 << ExpectedParameterOrImplicitObjectParameter;
3465 else
3466 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3467 << PA << PA.isRegularKeywordAttribute();
3468 PA.setInvalid();
3469 }
3470
3471 DS.takeAttributesFrom(attrs);
3472 }
3473
3474 // If this is not a declaration specifier token, we're done reading decl
3475 // specifiers. First verify that DeclSpec's are consistent.
3476 DS.Finish(S&: Actions, Policy);
3477 return;
3478
3479 // alignment-specifier
3480 case tok::kw__Alignas:
3481 diagnoseUseOfC11Keyword(Tok);
3482 [[fallthrough]];
3483 case tok::kw_alignas:
3484 // _Alignas and alignas (C23, not C++) should parse the same way. The C++
3485 // parsing for alignas happens through the usual attribute parsing. This
3486 // ensures that an alignas specifier can appear in a type position in C
3487 // despite that not being valid in C++.
3488 if (getLangOpts().C23 || Tok.getKind() == tok::kw__Alignas) {
3489 if (Tok.getKind() == tok::kw_alignas)
3490 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3491 ParseAlignmentSpecifier(Attrs&: DS.getAttributes());
3492 continue;
3493 }
3494 [[fallthrough]];
3495 case tok::l_square:
3496 if (!isAllowedCXX11AttributeSpecifier())
3497 goto DoneWithDeclSpec;
3498
3499 Attribute:
3500 ProhibitAttributes(Attrs&: attrs);
3501 // FIXME: It would be good to recover by accepting the attributes,
3502 // but attempting to do that now would cause serious
3503 // madness in terms of diagnostics.
3504 attrs.clear();
3505 attrs.Range = SourceRange();
3506
3507 ParseCXX11Attributes(attrs);
3508 AttrsLastTime = true;
3509 continue;
3510
3511 case tok::code_completion: {
3512 SemaCodeCompletion::ParserCompletionContext CCC =
3513 SemaCodeCompletion::PCC_Namespace;
3514 if (DS.hasTypeSpecifier()) {
3515 bool AllowNonIdentifiers
3516 = (getCurScope()->getFlags() & (Scope::ControlScope |
3517 Scope::BlockScope |
3518 Scope::TemplateParamScope |
3519 Scope::FunctionPrototypeScope |
3520 Scope::AtCatchScope)) == 0;
3521 bool AllowNestedNameSpecifiers
3522 = DSContext == DeclSpecContext::DSC_top_level ||
3523 (DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified());
3524
3525 cutOffParsing();
3526 Actions.CodeCompletion().CodeCompleteDeclSpec(
3527 S: getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3528 return;
3529 }
3530
3531 // Class context can appear inside a function/block, so prioritise that.
3532 if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate)
3533 CCC = DSContext == DeclSpecContext::DSC_class
3534 ? SemaCodeCompletion::PCC_MemberTemplate
3535 : SemaCodeCompletion::PCC_Template;
3536 else if (DSContext == DeclSpecContext::DSC_class)
3537 CCC = SemaCodeCompletion::PCC_Class;
3538 else if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())
3539 CCC = SemaCodeCompletion::PCC_LocalDeclarationSpecifiers;
3540 else if (CurParsedObjCImpl)
3541 CCC = SemaCodeCompletion::PCC_ObjCImplementation;
3542
3543 cutOffParsing();
3544 Actions.CodeCompletion().CodeCompleteOrdinaryName(S: getCurScope(), CompletionContext: CCC);
3545 return;
3546 }
3547
3548 case tok::coloncolon: // ::foo::bar
3549 // C++ scope specifier. Annotate and loop, or bail out on error.
3550 if (getLangOpts().CPlusPlus &&
3551 TryAnnotateCXXScopeToken(EnteringContext)) {
3552 if (!DS.hasTypeSpecifier())
3553 DS.SetTypeSpecError();
3554 goto DoneWithDeclSpec;
3555 }
3556 if (Tok.is(K: tok::coloncolon)) // ::new or ::delete
3557 goto DoneWithDeclSpec;
3558 continue;
3559
3560 case tok::annot_cxxscope: {
3561 if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())
3562 goto DoneWithDeclSpec;
3563
3564 CXXScopeSpec SS;
3565 if (TemplateInfo.TemplateParams)
3566 SS.setTemplateParamLists(*TemplateInfo.TemplateParams);
3567 Actions.RestoreNestedNameSpecifierAnnotation(Annotation: Tok.getAnnotationValue(),
3568 AnnotationRange: Tok.getAnnotationRange(),
3569 SS);
3570
3571 // We are looking for a qualified typename.
3572 Token Next = NextToken();
3573
3574 TemplateIdAnnotation *TemplateId = Next.is(K: tok::annot_template_id)
3575 ? takeTemplateIdAnnotation(tok: Next)
3576 : nullptr;
3577 if (TemplateId && TemplateId->hasInvalidName()) {
3578 // We found something like 'T::U<Args> x', but U is not a template.
3579 // Assume it was supposed to be a type.
3580 DS.SetTypeSpecError();
3581 ConsumeAnnotationToken();
3582 break;
3583 }
3584
3585 if (TemplateId && TemplateId->Kind == TNK_Type_template) {
3586 // We have a qualified template-id, e.g., N::A<int>
3587
3588 // If this would be a valid constructor declaration with template
3589 // arguments, we will reject the attempt to form an invalid type-id
3590 // referring to the injected-class-name when we annotate the token,
3591 // per C++ [class.qual]p2.
3592 //
3593 // To improve diagnostics for this case, parse the declaration as a
3594 // constructor (and reject the extra template arguments later).
3595 if ((DSContext == DeclSpecContext::DSC_top_level ||
3596 DSContext == DeclSpecContext::DSC_class) &&
3597 TemplateId->Name &&
3598 Actions.isCurrentClassName(II: *TemplateId->Name, S: getCurScope(), SS: &SS) &&
3599 isConstructorDeclarator(/*Unqualified=*/false,
3600 /*DeductionGuide=*/false,
3601 IsFriend: DS.isFriendSpecified())) {
3602 // The user meant this to be an out-of-line constructor
3603 // definition, but template arguments are not allowed
3604 // there. Just allow this as a constructor; we'll
3605 // complain about it later.
3606 goto DoneWithDeclSpec;
3607 }
3608
3609 DS.getTypeSpecScope() = SS;
3610 ConsumeAnnotationToken(); // The C++ scope.
3611 assert(Tok.is(tok::annot_template_id) &&
3612 "ParseOptionalCXXScopeSpecifier not working");
3613 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3614 continue;
3615 }
3616
3617 if (TemplateId && TemplateId->Kind == TNK_Concept_template) {
3618 DS.getTypeSpecScope() = SS;
3619 // This is probably a qualified placeholder-specifier, e.g., ::C<int>
3620 // auto ... Consume the scope annotation and continue to consume the
3621 // template-id as a placeholder-specifier. Let the next iteration
3622 // diagnose a missing auto.
3623 ConsumeAnnotationToken();
3624 continue;
3625 }
3626
3627 if (Next.is(K: tok::annot_typename)) {
3628 DS.getTypeSpecScope() = SS;
3629 ConsumeAnnotationToken(); // The C++ scope.
3630 TypeResult T = getTypeAnnotation(Tok);
3631 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_typename,
3632 Loc: Tok.getAnnotationEndLoc(),
3633 PrevSpec, DiagID, Rep: T, Policy);
3634 if (isInvalid)
3635 break;
3636 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
3637 ConsumeAnnotationToken(); // The typename
3638 }
3639
3640 if (AllowImplicitTypename == ImplicitTypenameContext::Yes &&
3641 Next.is(K: tok::annot_template_id) &&
3642 static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())
3643 ->Kind == TNK_Dependent_template_name) {
3644 DS.getTypeSpecScope() = SS;
3645 ConsumeAnnotationToken(); // The C++ scope.
3646 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3647 continue;
3648 }
3649
3650 if (Next.isNot(K: tok::identifier))
3651 goto DoneWithDeclSpec;
3652
3653 // Check whether this is a constructor declaration. If we're in a
3654 // context where the identifier could be a class name, and it has the
3655 // shape of a constructor declaration, process it as one.
3656 if ((DSContext == DeclSpecContext::DSC_top_level ||
3657 DSContext == DeclSpecContext::DSC_class) &&
3658 Actions.isCurrentClassName(II: *Next.getIdentifierInfo(), S: getCurScope(),
3659 SS: &SS) &&
3660 isConstructorDeclarator(/*Unqualified=*/false,
3661 /*DeductionGuide=*/false,
3662 IsFriend: DS.isFriendSpecified(),
3663 TemplateInfo: &TemplateInfo))
3664 goto DoneWithDeclSpec;
3665
3666 // C++20 [temp.spec] 13.9/6.
3667 // This disables the access checking rules for function template explicit
3668 // instantiation and explicit specialization:
3669 // - `return type`.
3670 SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);
3671
3672 ParsedType TypeRep = Actions.getTypeName(
3673 II: *Next.getIdentifierInfo(), NameLoc: Next.getLocation(), S: getCurScope(), SS: &SS,
3674 isClassName: false, HasTrailingDot: false, ObjectType: nullptr,
3675 /*IsCtorOrDtorName=*/false,
3676 /*WantNontrivialTypeSourceInfo=*/true,
3677 IsClassTemplateDeductionContext: isClassTemplateDeductionContext(DSC: DSContext), AllowImplicitTypename);
3678
3679 if (IsTemplateSpecOrInst)
3680 SAC.done();
3681
3682 // If the referenced identifier is not a type, then this declspec is
3683 // erroneous: We already checked about that it has no type specifier, and
3684 // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the
3685 // typename.
3686 if (!TypeRep) {
3687 if (TryAnnotateTypeConstraint())
3688 goto DoneWithDeclSpec;
3689 if (Tok.isNot(K: tok::annot_cxxscope) ||
3690 NextToken().isNot(K: tok::identifier))
3691 continue;
3692 // Eat the scope spec so the identifier is current.
3693 ConsumeAnnotationToken();
3694 ParsedAttributes Attrs(AttrFactory);
3695 if (ParseImplicitInt(DS, SS: &SS, TemplateInfo, AS, DSC: DSContext, Attrs)) {
3696 if (!Attrs.empty()) {
3697 AttrsLastTime = true;
3698 attrs.takeAllFrom(Other&: Attrs);
3699 }
3700 continue;
3701 }
3702 goto DoneWithDeclSpec;
3703 }
3704
3705 DS.getTypeSpecScope() = SS;
3706 ConsumeAnnotationToken(); // The C++ scope.
3707
3708 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_typename, Loc, PrevSpec,
3709 DiagID, Rep: TypeRep, Policy);
3710 if (isInvalid)
3711 break;
3712
3713 DS.SetRangeEnd(Tok.getLocation());
3714 ConsumeToken(); // The typename.
3715
3716 continue;
3717 }
3718
3719 case tok::annot_typename: {
3720 // If we've previously seen a tag definition, we were almost surely
3721 // missing a semicolon after it.
3722 if (DS.hasTypeSpecifier() && DS.hasTagDefinition())
3723 goto DoneWithDeclSpec;
3724
3725 TypeResult T = getTypeAnnotation(Tok);
3726 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_typename, Loc, PrevSpec,
3727 DiagID, Rep: T, Policy);
3728 if (isInvalid)
3729 break;
3730
3731 DS.SetRangeEnd(Tok.getAnnotationEndLoc());
3732 ConsumeAnnotationToken(); // The typename
3733
3734 continue;
3735 }
3736
3737 case tok::kw___is_signed:
3738 // HACK: before 2022-12, libstdc++ uses __is_signed as an identifier,
3739 // but Clang typically treats it as a trait.
3740 // If we see __is_signed as it appears in libstdc++, e.g.,
3741 //
3742 // static const bool __is_signed;
3743 //
3744 // then treat __is_signed as an identifier rather than as a keyword.
3745 // This was fixed by libstdc++ in December 2022.
3746 if (DS.getTypeSpecType() == TST_bool &&
3747 DS.getTypeQualifiers() == DeclSpec::TQ_const &&
3748 DS.getStorageClassSpec() == DeclSpec::SCS_static)
3749 TryKeywordIdentFallback(DisableKeyword: true);
3750
3751 // We're done with the declaration-specifiers.
3752 goto DoneWithDeclSpec;
3753
3754 // typedef-name
3755 case tok::kw___super:
3756 case tok::kw_decltype:
3757 case tok::identifier:
3758 ParseIdentifier: {
3759 // This identifier can only be a typedef name if we haven't already seen
3760 // a type-specifier. Without this check we misparse:
3761 // typedef int X; struct Y { short X; }; as 'short int'.
3762 if (DS.hasTypeSpecifier())
3763 goto DoneWithDeclSpec;
3764
3765 // If the token is an identifier named "__declspec" and Microsoft
3766 // extensions are not enabled, it is likely that there will be cascading
3767 // parse errors if this really is a __declspec attribute. Attempt to
3768 // recognize that scenario and recover gracefully.
3769 if (!getLangOpts().DeclSpecKeyword && Tok.is(K: tok::identifier) &&
3770 Tok.getIdentifierInfo()->getName() == "__declspec") {
3771 Diag(Loc, diag::err_ms_attributes_not_enabled);
3772
3773 // The next token should be an open paren. If it is, eat the entire
3774 // attribute declaration and continue.
3775 if (NextToken().is(K: tok::l_paren)) {
3776 // Consume the __declspec identifier.
3777 ConsumeToken();
3778
3779 // Eat the parens and everything between them.
3780 BalancedDelimiterTracker T(*this, tok::l_paren);
3781 if (T.consumeOpen()) {
3782 assert(false && "Not a left paren?");
3783 return;
3784 }
3785 T.skipToEnd();
3786 continue;
3787 }
3788 }
3789
3790 // In C++, check to see if this is a scope specifier like foo::bar::, if
3791 // so handle it as such. This is important for ctor parsing.
3792 if (getLangOpts().CPlusPlus) {
3793 // C++20 [temp.spec] 13.9/6.
3794 // This disables the access checking rules for function template
3795 // explicit instantiation and explicit specialization:
3796 // - `return type`.
3797 SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);
3798
3799 const bool Success = TryAnnotateCXXScopeToken(EnteringContext);
3800
3801 if (IsTemplateSpecOrInst)
3802 SAC.done();
3803
3804 if (Success) {
3805 if (IsTemplateSpecOrInst)
3806 SAC.redelay();
3807 DS.SetTypeSpecError();
3808 goto DoneWithDeclSpec;
3809 }
3810
3811 if (!Tok.is(K: tok::identifier))
3812 continue;
3813 }
3814
3815 // Check for need to substitute AltiVec keyword tokens.
3816 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
3817 break;
3818
3819 // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not
3820 // allow the use of a typedef name as a type specifier.
3821 if (DS.isTypeAltiVecVector())
3822 goto DoneWithDeclSpec;
3823
3824 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3825 isObjCInstancetype()) {
3826 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3827 assert(TypeRep);
3828 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_typename, Loc, PrevSpec,
3829 DiagID, Rep: TypeRep, Policy);
3830 if (isInvalid)
3831 break;
3832
3833 DS.SetRangeEnd(Loc);
3834 ConsumeToken();
3835 continue;
3836 }
3837
3838 // If we're in a context where the identifier could be a class name,
3839 // check whether this is a constructor declaration.
3840 if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&
3841 Actions.isCurrentClassName(II: *Tok.getIdentifierInfo(), S: getCurScope()) &&
3842 isConstructorDeclarator(/*Unqualified=*/true,
3843 /*DeductionGuide=*/false,
3844 IsFriend: DS.isFriendSpecified()))
3845 goto DoneWithDeclSpec;
3846
3847 ParsedType TypeRep = Actions.getTypeName(
3848 II: *Tok.getIdentifierInfo(), NameLoc: Tok.getLocation(), S: getCurScope(), SS: nullptr,
3849 isClassName: false, HasTrailingDot: false, ObjectType: nullptr, IsCtorOrDtorName: false, WantNontrivialTypeSourceInfo: false,
3850 IsClassTemplateDeductionContext: isClassTemplateDeductionContext(DSC: DSContext));
3851
3852 // If this is not a typedef name, don't parse it as part of the declspec,
3853 // it must be an implicit int or an error.
3854 if (!TypeRep) {
3855 if (TryAnnotateTypeConstraint())
3856 goto DoneWithDeclSpec;
3857 if (Tok.isNot(K: tok::identifier))
3858 continue;
3859 ParsedAttributes Attrs(AttrFactory);
3860 if (ParseImplicitInt(DS, SS: nullptr, TemplateInfo, AS, DSC: DSContext, Attrs)) {
3861 if (!Attrs.empty()) {
3862 AttrsLastTime = true;
3863 attrs.takeAllFrom(Other&: Attrs);
3864 }
3865 continue;
3866 }
3867 goto DoneWithDeclSpec;
3868 }
3869
3870 // Likewise, if this is a context where the identifier could be a template
3871 // name, check whether this is a deduction guide declaration.
3872 CXXScopeSpec SS;
3873 if (getLangOpts().CPlusPlus17 &&
3874 (DSContext == DeclSpecContext::DSC_class ||
3875 DSContext == DeclSpecContext::DSC_top_level) &&
3876 Actions.isDeductionGuideName(S: getCurScope(), Name: *Tok.getIdentifierInfo(),
3877 NameLoc: Tok.getLocation(), SS) &&
3878 isConstructorDeclarator(/*Unqualified*/ true,
3879 /*DeductionGuide*/ true))
3880 goto DoneWithDeclSpec;
3881
3882 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_typename, Loc, PrevSpec,
3883 DiagID, Rep: TypeRep, Policy);
3884 if (isInvalid)
3885 break;
3886
3887 DS.SetRangeEnd(Tok.getLocation());
3888 ConsumeToken(); // The identifier
3889
3890 // Objective-C supports type arguments and protocol references
3891 // following an Objective-C object or object pointer
3892 // type. Handle either one of them.
3893 if (Tok.is(K: tok::less) && getLangOpts().ObjC) {
3894 SourceLocation NewEndLoc;
3895 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3896 loc: Loc, type: TypeRep, /*consumeLastToken=*/true,
3897 endLoc&: NewEndLoc);
3898 if (NewTypeRep.isUsable()) {
3899 DS.UpdateTypeRep(Rep: NewTypeRep.get());
3900 DS.SetRangeEnd(NewEndLoc);
3901 }
3902 }
3903
3904 // Need to support trailing type qualifiers (e.g. "id<p> const").
3905 // If a type specifier follows, it will be diagnosed elsewhere.
3906 continue;
3907 }
3908
3909 // type-name or placeholder-specifier
3910 case tok::annot_template_id: {
3911 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(tok: Tok);
3912
3913 if (TemplateId->hasInvalidName()) {
3914 DS.SetTypeSpecError();
3915 break;
3916 }
3917
3918 if (TemplateId->Kind == TNK_Concept_template) {
3919 // If we've already diagnosed that this type-constraint has invalid
3920 // arguments, drop it and just form 'auto' or 'decltype(auto)'.
3921 if (TemplateId->hasInvalidArgs())
3922 TemplateId = nullptr;
3923
3924 // Any of the following tokens are likely the start of the user
3925 // forgetting 'auto' or 'decltype(auto)', so diagnose.
3926 // Note: if updating this list, please make sure we update
3927 // isCXXDeclarationSpecifier's check for IsPlaceholderSpecifier to have
3928 // a matching list.
3929 if (NextToken().isOneOf(K1: tok::identifier, Ks: tok::kw_const,
3930 Ks: tok::kw_volatile, Ks: tok::kw_restrict, Ks: tok::amp,
3931 Ks: tok::ampamp)) {
3932 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3933 << FixItHint::CreateInsertion(NextToken().getLocation(), "auto");
3934 // Attempt to continue as if 'auto' was placed here.
3935 isInvalid = DS.SetTypeSpecType(T: TST_auto, Loc, PrevSpec, DiagID,
3936 Rep: TemplateId, Policy);
3937 break;
3938 }
3939 if (!NextToken().isOneOf(K1: tok::kw_auto, K2: tok::kw_decltype))
3940 goto DoneWithDeclSpec;
3941
3942 if (TemplateId && !isInvalid && Actions.CheckTypeConstraint(TypeConstraint: TemplateId))
3943 TemplateId = nullptr;
3944
3945 ConsumeAnnotationToken();
3946 SourceLocation AutoLoc = Tok.getLocation();
3947 if (TryConsumeToken(Expected: tok::kw_decltype)) {
3948 BalancedDelimiterTracker Tracker(*this, tok::l_paren);
3949 if (Tracker.consumeOpen()) {
3950 // Something like `void foo(Iterator decltype i)`
3951 Diag(Tok, diag::err_expected) << tok::l_paren;
3952 } else {
3953 if (!TryConsumeToken(Expected: tok::kw_auto)) {
3954 // Something like `void foo(Iterator decltype(int) i)`
3955 Tracker.skipToEnd();
3956 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3957 << FixItHint::CreateReplacement(SourceRange(AutoLoc,
3958 Tok.getLocation()),
3959 "auto");
3960 } else {
3961 Tracker.consumeClose();
3962 }
3963 }
3964 ConsumedEnd = Tok.getLocation();
3965 DS.setTypeArgumentRange(Tracker.getRange());
3966 // Even if something went wrong above, continue as if we've seen
3967 // `decltype(auto)`.
3968 isInvalid = DS.SetTypeSpecType(T: TST_decltype_auto, Loc, PrevSpec,
3969 DiagID, Rep: TemplateId, Policy);
3970 } else {
3971 isInvalid = DS.SetTypeSpecType(T: TST_auto, Loc: AutoLoc, PrevSpec, DiagID,
3972 Rep: TemplateId, Policy);
3973 }
3974 break;
3975 }
3976
3977 if (TemplateId->Kind != TNK_Type_template &&
3978 TemplateId->Kind != TNK_Undeclared_template) {
3979 // This template-id does not refer to a type name, so we're
3980 // done with the type-specifiers.
3981 goto DoneWithDeclSpec;
3982 }
3983
3984 // If we're in a context where the template-id could be a
3985 // constructor name or specialization, check whether this is a
3986 // constructor declaration.
3987 if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&
3988 Actions.isCurrentClassName(II: *TemplateId->Name, S: getCurScope()) &&
3989 isConstructorDeclarator(/*Unqualified=*/true,
3990 /*DeductionGuide=*/false,
3991 IsFriend: DS.isFriendSpecified()))
3992 goto DoneWithDeclSpec;
3993
3994 // Turn the template-id annotation token into a type annotation
3995 // token, then try again to parse it as a type-specifier.
3996 CXXScopeSpec SS;
3997 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3998 continue;
3999 }
4000
4001 // Attributes support.
4002 case tok::kw___attribute:
4003 case tok::kw___declspec:
4004 ParseAttributes(WhichAttrKinds: PAKM_GNU | PAKM_Declspec, Attrs&: DS.getAttributes(), LateAttrs);
4005 continue;
4006
4007 // Microsoft single token adornments.
4008 case tok::kw___forceinline: {
4009 isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID);
4010 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
4011 SourceLocation AttrNameLoc = Tok.getLocation();
4012 DS.getAttributes().addNew(attrName: AttrName, attrRange: AttrNameLoc, scopeName: nullptr, scopeLoc: AttrNameLoc,
4013 args: nullptr, numArgs: 0, form: tok::kw___forceinline);
4014 break;
4015 }
4016
4017 case tok::kw___unaligned:
4018 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID,
4019 Lang: getLangOpts());
4020 break;
4021
4022 // __ptrauth qualifier.
4023 case tok::kw___ptrauth:
4024 ParsePtrauthQualifier(Attrs&: DS.getAttributes());
4025 continue;
4026
4027 case tok::kw___sptr:
4028 case tok::kw___uptr:
4029 case tok::kw___ptr64:
4030 case tok::kw___ptr32:
4031 case tok::kw___w64:
4032 case tok::kw___cdecl:
4033 case tok::kw___stdcall:
4034 case tok::kw___fastcall:
4035 case tok::kw___thiscall:
4036 case tok::kw___regcall:
4037 case tok::kw___vectorcall:
4038 ParseMicrosoftTypeAttributes(attrs&: DS.getAttributes());
4039 continue;
4040
4041 case tok::kw___funcref:
4042 ParseWebAssemblyFuncrefTypeAttribute(attrs&: DS.getAttributes());
4043 continue;
4044
4045 // Borland single token adornments.
4046 case tok::kw___pascal:
4047 ParseBorlandTypeAttributes(attrs&: DS.getAttributes());
4048 continue;
4049
4050 // OpenCL single token adornments.
4051 case tok::kw___kernel:
4052 ParseOpenCLKernelAttributes(attrs&: DS.getAttributes());
4053 continue;
4054
4055 // CUDA/HIP single token adornments.
4056 case tok::kw___noinline__:
4057 ParseCUDAFunctionAttributes(attrs&: DS.getAttributes());
4058 continue;
4059
4060 // Nullability type specifiers.
4061 case tok::kw__Nonnull:
4062 case tok::kw__Nullable:
4063 case tok::kw__Nullable_result:
4064 case tok::kw__Null_unspecified:
4065 ParseNullabilityTypeSpecifiers(attrs&: DS.getAttributes());
4066 continue;
4067
4068 // Objective-C 'kindof' types.
4069 case tok::kw___kindof:
4070 DS.getAttributes().addNew(attrName: Tok.getIdentifierInfo(), attrRange: Loc, scopeName: nullptr, scopeLoc: Loc,
4071 args: nullptr, numArgs: 0, form: tok::kw___kindof);
4072 (void)ConsumeToken();
4073 continue;
4074
4075 // storage-class-specifier
4076 case tok::kw_typedef:
4077 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_typedef, Loc,
4078 PrevSpec, DiagID, Policy);
4079 isStorageClass = true;
4080 break;
4081 case tok::kw_extern:
4082 if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
4083 Diag(Tok, diag::ext_thread_before) << "extern";
4084 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_extern, Loc,
4085 PrevSpec, DiagID, Policy);
4086 isStorageClass = true;
4087 break;
4088 case tok::kw___private_extern__:
4089 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_private_extern,
4090 Loc, PrevSpec, DiagID, Policy);
4091 isStorageClass = true;
4092 break;
4093 case tok::kw_static:
4094 if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
4095 Diag(Tok, diag::ext_thread_before) << "static";
4096 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_static, Loc,
4097 PrevSpec, DiagID, Policy);
4098 isStorageClass = true;
4099 break;
4100 case tok::kw_auto:
4101 if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {
4102 if (isKnownToBeTypeSpecifier(Tok: GetLookAheadToken(N: 1))) {
4103 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_auto, Loc,
4104 PrevSpec, DiagID, Policy);
4105 if (!isInvalid && !getLangOpts().C23)
4106 Diag(Tok, diag::ext_auto_storage_class)
4107 << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
4108 } else
4109 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_auto, Loc, PrevSpec,
4110 DiagID, Policy);
4111 } else
4112 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_auto, Loc,
4113 PrevSpec, DiagID, Policy);
4114 isStorageClass = true;
4115 break;
4116 case tok::kw___auto_type:
4117 Diag(Tok, diag::ext_auto_type);
4118 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_auto_type, Loc, PrevSpec,
4119 DiagID, Policy);
4120 break;
4121 case tok::kw_register:
4122 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_register, Loc,
4123 PrevSpec, DiagID, Policy);
4124 isStorageClass = true;
4125 break;
4126 case tok::kw_mutable:
4127 isInvalid = DS.SetStorageClassSpec(S&: Actions, SC: DeclSpec::SCS_mutable, Loc,
4128 PrevSpec, DiagID, Policy);
4129 isStorageClass = true;
4130 break;
4131 case tok::kw___thread:
4132 isInvalid = DS.SetStorageClassSpecThread(TSC: DeclSpec::TSCS___thread, Loc,
4133 PrevSpec, DiagID);
4134 isStorageClass = true;
4135 break;
4136 case tok::kw_thread_local:
4137 if (getLangOpts().C23)
4138 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4139 // We map thread_local to _Thread_local in C23 mode so it retains the C
4140 // semantics rather than getting the C++ semantics.
4141 // FIXME: diagnostics will show _Thread_local when the user wrote
4142 // thread_local in source in C23 mode; we need some general way to
4143 // identify which way the user spelled the keyword in source.
4144 isInvalid = DS.SetStorageClassSpecThread(
4145 TSC: getLangOpts().C23 ? DeclSpec::TSCS__Thread_local
4146 : DeclSpec::TSCS_thread_local,
4147 Loc, PrevSpec, DiagID);
4148 isStorageClass = true;
4149 break;
4150 case tok::kw__Thread_local:
4151 diagnoseUseOfC11Keyword(Tok);
4152 isInvalid = DS.SetStorageClassSpecThread(TSC: DeclSpec::TSCS__Thread_local,
4153 Loc, PrevSpec, DiagID);
4154 isStorageClass = true;
4155 break;
4156
4157 // function-specifier
4158 case tok::kw_inline:
4159 isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);
4160 break;
4161 case tok::kw_virtual:
4162 // C++ for OpenCL does not allow virtual function qualifier, to avoid
4163 // function pointers restricted in OpenCL v2.0 s6.9.a.
4164 if (getLangOpts().OpenCLCPlusPlus &&
4165 !getActions().getOpenCLOptions().isAvailableOption(
4166 Ext: "__cl_clang_function_pointers", LO: getLangOpts())) {
4167 DiagID = diag::err_openclcxx_virtual_function;
4168 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4169 isInvalid = true;
4170 } else if (getLangOpts().HLSL) {
4171 DiagID = diag::err_hlsl_virtual_function;
4172 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4173 isInvalid = true;
4174 } else {
4175 isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
4176 }
4177 break;
4178 case tok::kw_explicit: {
4179 SourceLocation ExplicitLoc = Loc;
4180 SourceLocation CloseParenLoc;
4181 ExplicitSpecifier ExplicitSpec(nullptr, ExplicitSpecKind::ResolvedTrue);
4182 ConsumedEnd = ExplicitLoc;
4183 ConsumeToken(); // kw_explicit
4184 if (Tok.is(K: tok::l_paren)) {
4185 if (getLangOpts().CPlusPlus20 || isExplicitBool() == TPResult::True) {
4186 Diag(Tok.getLocation(), getLangOpts().CPlusPlus20
4187 ? diag::warn_cxx17_compat_explicit_bool
4188 : diag::ext_explicit_bool);
4189
4190 ExprResult ExplicitExpr(static_cast<Expr *>(nullptr));
4191 BalancedDelimiterTracker Tracker(*this, tok::l_paren);
4192 Tracker.consumeOpen();
4193
4194 EnterExpressionEvaluationContext ConstantEvaluated(
4195 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
4196
4197 ExplicitExpr = ParseConstantExpressionInExprEvalContext();
4198 ConsumedEnd = Tok.getLocation();
4199 if (ExplicitExpr.isUsable()) {
4200 CloseParenLoc = Tok.getLocation();
4201 Tracker.consumeClose();
4202 ExplicitSpec =
4203 Actions.ActOnExplicitBoolSpecifier(E: ExplicitExpr.get());
4204 } else
4205 Tracker.skipToEnd();
4206 } else {
4207 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4208 }
4209 }
4210 isInvalid = DS.setFunctionSpecExplicit(Loc: ExplicitLoc, PrevSpec, DiagID,
4211 ExplicitSpec, CloseParenLoc);
4212 break;
4213 }
4214 case tok::kw__Noreturn:
4215 diagnoseUseOfC11Keyword(Tok);
4216 isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);
4217 break;
4218
4219 // friend
4220 case tok::kw_friend:
4221 if (DSContext == DeclSpecContext::DSC_class) {
4222 isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);
4223 Scope *CurS = getCurScope();
4224 if (!isInvalid && CurS)
4225 CurS->setFlags(CurS->getFlags() | Scope::FriendScope);
4226 } else {
4227 PrevSpec = ""; // not actually used by the diagnostic
4228 DiagID = diag::err_friend_invalid_in_context;
4229 isInvalid = true;
4230 }
4231 break;
4232
4233 // Modules
4234 case tok::kw___module_private__:
4235 isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);
4236 break;
4237
4238 // constexpr, consteval, constinit specifiers
4239 case tok::kw_constexpr:
4240 if (getLangOpts().C23)
4241 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4242 isInvalid = DS.SetConstexprSpec(ConstexprKind: ConstexprSpecKind::Constexpr, Loc,
4243 PrevSpec, DiagID);
4244 break;
4245 case tok::kw_consteval:
4246 isInvalid = DS.SetConstexprSpec(ConstexprKind: ConstexprSpecKind::Consteval, Loc,
4247 PrevSpec, DiagID);
4248 break;
4249 case tok::kw_constinit:
4250 isInvalid = DS.SetConstexprSpec(ConstexprKind: ConstexprSpecKind::Constinit, Loc,
4251 PrevSpec, DiagID);
4252 break;
4253
4254 // type-specifier
4255 case tok::kw_short:
4256 isInvalid = DS.SetTypeSpecWidth(W: TypeSpecifierWidth::Short, Loc, PrevSpec,
4257 DiagID, Policy);
4258 break;
4259 case tok::kw_long:
4260 if (DS.getTypeSpecWidth() != TypeSpecifierWidth::Long)
4261 isInvalid = DS.SetTypeSpecWidth(W: TypeSpecifierWidth::Long, Loc, PrevSpec,
4262 DiagID, Policy);
4263 else
4264 isInvalid = DS.SetTypeSpecWidth(W: TypeSpecifierWidth::LongLong, Loc,
4265 PrevSpec, DiagID, Policy);
4266 break;
4267 case tok::kw___int64:
4268 isInvalid = DS.SetTypeSpecWidth(W: TypeSpecifierWidth::LongLong, Loc,
4269 PrevSpec, DiagID, Policy);
4270 break;
4271 case tok::kw_signed:
4272 isInvalid =
4273 DS.SetTypeSpecSign(S: TypeSpecifierSign::Signed, Loc, PrevSpec, DiagID);
4274 break;
4275 case tok::kw_unsigned:
4276 isInvalid = DS.SetTypeSpecSign(S: TypeSpecifierSign::Unsigned, Loc, PrevSpec,
4277 DiagID);
4278 break;
4279 case tok::kw__Complex:
4280 if (!getLangOpts().C99)
4281 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4282 isInvalid = DS.SetTypeSpecComplex(C: DeclSpec::TSC_complex, Loc, PrevSpec,
4283 DiagID);
4284 break;
4285 case tok::kw__Imaginary:
4286 if (!getLangOpts().C99)
4287 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4288 isInvalid = DS.SetTypeSpecComplex(C: DeclSpec::TSC_imaginary, Loc, PrevSpec,
4289 DiagID);
4290 break;
4291 case tok::kw_void:
4292 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_void, Loc, PrevSpec,
4293 DiagID, Policy);
4294 break;
4295 case tok::kw_char:
4296 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_char, Loc, PrevSpec,
4297 DiagID, Policy);
4298 break;
4299 case tok::kw_int:
4300 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_int, Loc, PrevSpec,
4301 DiagID, Policy);
4302 break;
4303 case tok::kw__ExtInt:
4304 case tok::kw__BitInt: {
4305 DiagnoseBitIntUse(Tok);
4306 ExprResult ER = ParseExtIntegerArgument();
4307 if (ER.isInvalid())
4308 continue;
4309 isInvalid = DS.SetBitIntType(KWLoc: Loc, BitWidth: ER.get(), PrevSpec, DiagID, Policy);
4310 ConsumedEnd = PrevTokLocation;
4311 break;
4312 }
4313 case tok::kw___int128:
4314 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_int128, Loc, PrevSpec,
4315 DiagID, Policy);
4316 break;
4317 case tok::kw_half:
4318 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_half, Loc, PrevSpec,
4319 DiagID, Policy);
4320 break;
4321 case tok::kw___bf16:
4322 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_BFloat16, Loc, PrevSpec,
4323 DiagID, Policy);
4324 break;
4325 case tok::kw_float:
4326 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_float, Loc, PrevSpec,
4327 DiagID, Policy);
4328 break;
4329 case tok::kw_double:
4330 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_double, Loc, PrevSpec,
4331 DiagID, Policy);
4332 break;
4333 case tok::kw__Float16:
4334 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_float16, Loc, PrevSpec,
4335 DiagID, Policy);
4336 break;
4337 case tok::kw__Accum:
4338 assert(getLangOpts().FixedPoint &&
4339 "This keyword is only used when fixed point types are enabled "
4340 "with `-ffixed-point`");
4341 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_accum, Loc, PrevSpec, DiagID,
4342 Policy);
4343 break;
4344 case tok::kw__Fract:
4345 assert(getLangOpts().FixedPoint &&
4346 "This keyword is only used when fixed point types are enabled "
4347 "with `-ffixed-point`");
4348 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_fract, Loc, PrevSpec, DiagID,
4349 Policy);
4350 break;
4351 case tok::kw__Sat:
4352 assert(getLangOpts().FixedPoint &&
4353 "This keyword is only used when fixed point types are enabled "
4354 "with `-ffixed-point`");
4355 isInvalid = DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);
4356 break;
4357 case tok::kw___float128:
4358 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_float128, Loc, PrevSpec,
4359 DiagID, Policy);
4360 break;
4361 case tok::kw___ibm128:
4362 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_ibm128, Loc, PrevSpec,
4363 DiagID, Policy);
4364 break;
4365 case tok::kw_wchar_t:
4366 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_wchar, Loc, PrevSpec,
4367 DiagID, Policy);
4368 break;
4369 case tok::kw_char8_t:
4370 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_char8, Loc, PrevSpec,
4371 DiagID, Policy);
4372 break;
4373 case tok::kw_char16_t:
4374 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_char16, Loc, PrevSpec,
4375 DiagID, Policy);
4376 break;
4377 case tok::kw_char32_t:
4378 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_char32, Loc, PrevSpec,
4379 DiagID, Policy);
4380 break;
4381 case tok::kw_bool:
4382 if (getLangOpts().C23)
4383 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4384 [[fallthrough]];
4385 case tok::kw__Bool:
4386 if (Tok.is(tok::kw__Bool) && !getLangOpts().C99)
4387 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4388
4389 if (Tok.is(K: tok::kw_bool) &&
4390 DS.getTypeSpecType() != DeclSpec::TST_unspecified &&
4391 DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
4392 PrevSpec = ""; // Not used by the diagnostic.
4393 DiagID = diag::err_bool_redeclaration;
4394 // For better error recovery.
4395 Tok.setKind(tok::identifier);
4396 isInvalid = true;
4397 } else {
4398 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_bool, Loc, PrevSpec,
4399 DiagID, Policy);
4400 }
4401 break;
4402 case tok::kw__Decimal32:
4403 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_decimal32, Loc, PrevSpec,
4404 DiagID, Policy);
4405 break;
4406 case tok::kw__Decimal64:
4407 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_decimal64, Loc, PrevSpec,
4408 DiagID, Policy);
4409 break;
4410 case tok::kw__Decimal128:
4411 isInvalid = DS.SetTypeSpecType(T: DeclSpec::TST_decimal128, Loc, PrevSpec,
4412 DiagID, Policy);
4413 break;
4414 case tok::kw___vector:
4415 isInvalid = DS.SetTypeAltiVecVector(isAltiVecVector: true, Loc, PrevSpec, DiagID, Policy);
4416 break;
4417 case tok::kw___pixel:
4418 isInvalid = DS.SetTypeAltiVecPixel(isAltiVecPixel: true, Loc, PrevSpec, DiagID, Policy);
4419 break;
4420 case tok::kw___bool:
4421 isInvalid = DS.SetTypeAltiVecBool(isAltiVecBool: true, Loc, PrevSpec, DiagID, Policy);
4422 break;
4423 case tok::kw_pipe:
4424 if (!getLangOpts().OpenCL ||
4425 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4426 // OpenCL 2.0 and later define this keyword. OpenCL 1.2 and earlier
4427 // should support the "pipe" word as identifier.
4428 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4429 Tok.setKind(tok::identifier);
4430 goto DoneWithDeclSpec;
4431 } else if (!getLangOpts().OpenCLPipes) {
4432 DiagID = diag::err_opencl_unknown_type_specifier;
4433 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4434 isInvalid = true;
4435 } else
4436 isInvalid = DS.SetTypePipe(isPipe: true, Loc, PrevSpec, DiagID, Policy);
4437 break;
4438// We only need to enumerate each image type once.
4439#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4440#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4441#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4442 case tok::kw_##ImgType##_t: \
4443 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4444 goto DoneWithDeclSpec; \
4445 break;
4446#include "clang/Basic/OpenCLImageTypes.def"
4447 case tok::kw___unknown_anytype:
4448 isInvalid = DS.SetTypeSpecType(T: TST_unknown_anytype, Loc,
4449 PrevSpec, DiagID, Policy);
4450 break;
4451
4452 // class-specifier:
4453 case tok::kw_class:
4454 case tok::kw_struct:
4455 case tok::kw___interface:
4456 case tok::kw_union: {
4457 tok::TokenKind Kind = Tok.getKind();
4458 ConsumeToken();
4459
4460 // These are attributes following class specifiers.
4461 // To produce better diagnostic, we parse them when
4462 // parsing class specifier.
4463 ParsedAttributes Attributes(AttrFactory);
4464 ParseClassSpecifier(TagTokKind: Kind, TagLoc: Loc, DS, TemplateInfo, AS,
4465 EnteringContext, DSC: DSContext, Attributes);
4466
4467 // If there are attributes following class specifier,
4468 // take them over and handle them here.
4469 if (!Attributes.empty()) {
4470 AttrsLastTime = true;
4471 attrs.takeAllFrom(Other&: Attributes);
4472 }
4473 continue;
4474 }
4475
4476 // enum-specifier:
4477 case tok::kw_enum:
4478 ConsumeToken();
4479 ParseEnumSpecifier(TagLoc: Loc, DS, TemplateInfo, AS, DSC: DSContext);
4480 continue;
4481
4482 // cv-qualifier:
4483 case tok::kw_const:
4484 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
4485 Lang: getLangOpts());
4486 break;
4487 case tok::kw_volatile:
4488 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
4489 Lang: getLangOpts());
4490 break;
4491 case tok::kw_restrict:
4492 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
4493 Lang: getLangOpts());
4494 break;
4495
4496 // C++ typename-specifier:
4497 case tok::kw_typename:
4498 if (TryAnnotateTypeOrScopeToken()) {
4499 DS.SetTypeSpecError();
4500 goto DoneWithDeclSpec;
4501 }
4502 if (!Tok.is(K: tok::kw_typename))
4503 continue;
4504 break;
4505
4506 // C23/GNU typeof support.
4507 case tok::kw_typeof:
4508 case tok::kw_typeof_unqual:
4509 ParseTypeofSpecifier(DS);
4510 continue;
4511
4512 case tok::annot_decltype:
4513 ParseDecltypeSpecifier(DS);
4514 continue;
4515
4516 case tok::annot_pack_indexing_type:
4517 ParsePackIndexingType(DS);
4518 continue;
4519
4520 case tok::annot_pragma_pack:
4521 HandlePragmaPack();
4522 continue;
4523
4524 case tok::annot_pragma_ms_pragma:
4525 HandlePragmaMSPragma();
4526 continue;
4527
4528 case tok::annot_pragma_ms_vtordisp:
4529 HandlePragmaMSVtorDisp();
4530 continue;
4531
4532 case tok::annot_pragma_ms_pointers_to_members:
4533 HandlePragmaMSPointersToMembers();
4534 continue;
4535
4536#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4537#include "clang/Basic/TransformTypeTraits.def"
4538 // HACK: libstdc++ already uses '__remove_cv' as an alias template so we
4539 // work around this by expecting all transform type traits to be suffixed
4540 // with '('. They're an identifier otherwise.
4541 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4542 goto ParseIdentifier;
4543 continue;
4544
4545 case tok::kw__Atomic:
4546 // C11 6.7.2.4/4:
4547 // If the _Atomic keyword is immediately followed by a left parenthesis,
4548 // it is interpreted as a type specifier (with a type name), not as a
4549 // type qualifier.
4550 diagnoseUseOfC11Keyword(Tok);
4551 if (NextToken().is(K: tok::l_paren)) {
4552 ParseAtomicSpecifier(DS);
4553 continue;
4554 }
4555 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
4556 Lang: getLangOpts());
4557 break;
4558
4559 // OpenCL address space qualifiers:
4560 case tok::kw___generic:
4561 // generic address space is introduced only in OpenCL v2.0
4562 // see OpenCL C Spec v2.0 s6.5.5
4563 // OpenCL v3.0 introduces __opencl_c_generic_address_space
4564 // feature macro to indicate if generic address space is supported
4565 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4566 DiagID = diag::err_opencl_unknown_type_specifier;
4567 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4568 isInvalid = true;
4569 break;
4570 }
4571 [[fallthrough]];
4572 case tok::kw_private:
4573 // It's fine (but redundant) to check this for __generic on the
4574 // fallthrough path; we only form the __generic token in OpenCL mode.
4575 if (!getLangOpts().OpenCL)
4576 goto DoneWithDeclSpec;
4577 [[fallthrough]];
4578 case tok::kw___private:
4579 case tok::kw___global:
4580 case tok::kw___local:
4581 case tok::kw___constant:
4582 // OpenCL access qualifiers:
4583 case tok::kw___read_only:
4584 case tok::kw___write_only:
4585 case tok::kw___read_write:
4586 ParseOpenCLQualifiers(Attrs&: DS.getAttributes());
4587 break;
4588
4589 case tok::kw_groupshared:
4590 case tok::kw_in:
4591 case tok::kw_inout:
4592 case tok::kw_out:
4593 // NOTE: ParseHLSLQualifiers will consume the qualifier token.
4594 ParseHLSLQualifiers(Attrs&: DS.getAttributes());
4595 continue;
4596
4597#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4598 case tok::kw_##Name: \
4599 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4600 DiagID, Policy); \
4601 break;
4602#include "clang/Basic/HLSLIntangibleTypes.def"
4603
4604 case tok::less:
4605 // GCC ObjC supports types like "<SomeProtocol>" as a synonym for
4606 // "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
4607 // but we support it.
4608 if (DS.hasTypeSpecifier() || !getLangOpts().ObjC)
4609 goto DoneWithDeclSpec;
4610
4611 SourceLocation StartLoc = Tok.getLocation();
4612 SourceLocation EndLoc;
4613 TypeResult Type = parseObjCProtocolQualifierType(rAngleLoc&: EndLoc);
4614 if (Type.isUsable()) {
4615 if (DS.SetTypeSpecType(T: DeclSpec::TST_typename, TagKwLoc: StartLoc, TagNameLoc: StartLoc,
4616 PrevSpec, DiagID, Rep: Type.get(),
4617 Policy: Actions.getASTContext().getPrintingPolicy()))
4618 Diag(Loc: StartLoc, DiagID) << PrevSpec;
4619
4620 DS.SetRangeEnd(EndLoc);
4621 } else {
4622 DS.SetTypeSpecError();
4623 }
4624
4625 // Need to support trailing type qualifiers (e.g. "id<p> const").
4626 // If a type specifier follows, it will be diagnosed elsewhere.
4627 continue;
4628 }
4629
4630 DS.SetRangeEnd(ConsumedEnd.isValid() ? ConsumedEnd : Tok.getLocation());
4631
4632 // If the specifier wasn't legal, issue a diagnostic.
4633 if (isInvalid) {
4634 assert(PrevSpec && "Method did not return previous specifier!");
4635 assert(DiagID);
4636
4637 if (DiagID == diag::ext_duplicate_declspec ||
4638 DiagID == diag::ext_warn_duplicate_declspec ||
4639 DiagID == diag::err_duplicate_declspec)
4640 Diag(Loc, DiagID) << PrevSpec
4641 << FixItHint::CreateRemoval(
4642 RemoveRange: SourceRange(Loc, DS.getEndLoc()));
4643 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4644 Diag(Loc, DiagID) << getLangOpts().getOpenCLVersionString() << PrevSpec
4645 << isStorageClass;
4646 } else
4647 Diag(Loc, DiagID) << PrevSpec;
4648 }
4649
4650 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.isInvalid())
4651 // After an error the next token can be an annotation token.
4652 ConsumeAnyToken();
4653
4654 AttrsLastTime = false;
4655 }
4656}
4657
4658static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS,
4659 Parser &P) {
4660
4661 if (DS.getTypeSpecType() != DeclSpec::TST_struct)
4662 return;
4663
4664 auto *RD = dyn_cast<RecordDecl>(Val: DS.getRepAsDecl());
4665 // We're only interested in unnamed, non-anonymous struct
4666 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4667 return;
4668
4669 for (auto *I : RD->decls()) {
4670 auto *VD = dyn_cast<ValueDecl>(I);
4671 if (!VD)
4672 continue;
4673
4674 auto *CAT = VD->getType()->getAs<CountAttributedType>();
4675 if (!CAT)
4676 continue;
4677
4678 for (const auto &DD : CAT->dependent_decls()) {
4679 if (!RD->containsDecl(DD.getDecl())) {
4680 P.Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4681 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4682 P.Diag(DD.getDecl()->getBeginLoc(),
4683 diag::note_flexible_array_counted_by_attr_field)
4684 << DD.getDecl();
4685 }
4686 }
4687 }
4688}
4689
4690void Parser::ParseStructDeclaration(
4691 ParsingDeclSpec &DS,
4692 llvm::function_ref<Decl *(ParsingFieldDeclarator &)> FieldsCallback,
4693 LateParsedAttrList *LateFieldAttrs) {
4694
4695 if (Tok.is(K: tok::kw___extension__)) {
4696 // __extension__ silences extension warnings in the subexpression.
4697 ExtensionRAIIObject O(Diags); // Use RAII to do this.
4698 ConsumeToken();
4699 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4700 }
4701
4702 // Parse leading attributes.
4703 ParsedAttributes Attrs(AttrFactory);
4704 MaybeParseCXX11Attributes(Attrs);
4705
4706 // Parse the common specifier-qualifiers-list piece.
4707 ParseSpecifierQualifierList(DS);
4708
4709 // If there are no declarators, this is a free-standing declaration
4710 // specifier. Let the actions module cope with it.
4711 if (Tok.is(K: tok::semi)) {
4712 // C23 6.7.2.1p9 : "The optional attribute specifier sequence in a
4713 // member declaration appertains to each of the members declared by the
4714 // member declarator list; it shall not appear if the optional member
4715 // declarator list is omitted."
4716 ProhibitAttributes(Attrs);
4717 RecordDecl *AnonRecord = nullptr;
4718 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4719 S: getCurScope(), AS: AS_none, DS, DeclAttrs: ParsedAttributesView::none(), AnonRecord);
4720 assert(!AnonRecord && "Did not expect anonymous struct or union here");
4721 DS.complete(D: TheDecl);
4722 return;
4723 }
4724
4725 // Read struct-declarators until we find the semicolon.
4726 bool FirstDeclarator = true;
4727 SourceLocation CommaLoc;
4728 while (true) {
4729 ParsingFieldDeclarator DeclaratorInfo(*this, DS, Attrs);
4730 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4731
4732 // Attributes are only allowed here on successive declarators.
4733 if (!FirstDeclarator) {
4734 // However, this does not apply for [[]] attributes (which could show up
4735 // before or after the __attribute__ attributes).
4736 DiagnoseAndSkipCXX11Attributes();
4737 MaybeParseGNUAttributes(D&: DeclaratorInfo.D);
4738 DiagnoseAndSkipCXX11Attributes();
4739 }
4740
4741 /// struct-declarator: declarator
4742 /// struct-declarator: declarator[opt] ':' constant-expression
4743 if (Tok.isNot(K: tok::colon)) {
4744 // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
4745 ColonProtectionRAIIObject X(*this);
4746 ParseDeclarator(D&: DeclaratorInfo.D);
4747 } else
4748 DeclaratorInfo.D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
4749
4750 // Here, we now know that the unnamed struct is not an anonymous struct.
4751 // Report an error if a counted_by attribute refers to a field in a
4752 // different named struct.
4753 DiagnoseCountAttributedTypeInUnnamedAnon(DS, P&: *this);
4754
4755 if (TryConsumeToken(Expected: tok::colon)) {
4756 ExprResult Res(ParseConstantExpression());
4757 if (Res.isInvalid())
4758 SkipUntil(T: tok::semi, Flags: StopBeforeMatch);
4759 else
4760 DeclaratorInfo.BitfieldSize = Res.get();
4761 }
4762
4763 // If attributes exist after the declarator, parse them.
4764 MaybeParseGNUAttributes(D&: DeclaratorInfo.D, LateAttrs: LateFieldAttrs);
4765
4766 // We're done with this declarator; invoke the callback.
4767 Decl *Field = FieldsCallback(DeclaratorInfo);
4768 if (Field)
4769 DistributeCLateParsedAttrs(Dcl: Field, LateAttrs: LateFieldAttrs);
4770
4771 // If we don't have a comma, it is either the end of the list (a ';')
4772 // or an error, bail out.
4773 if (!TryConsumeToken(Expected: tok::comma, Loc&: CommaLoc))
4774 return;
4775
4776 FirstDeclarator = false;
4777 }
4778}
4779
4780// TODO: All callers of this function should be moved to
4781// `Parser::ParseLexedAttributeList`.
4782void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs, bool EnterScope,
4783 ParsedAttributes *OutAttrs) {
4784 assert(LAs.parseSoon() &&
4785 "Attribute list should be marked for immediate parsing.");
4786 for (auto *LA : LAs) {
4787 ParseLexedCAttribute(LA&: *LA, EnterScope, OutAttrs);
4788 delete LA;
4789 }
4790 LAs.clear();
4791}
4792
4793void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
4794 ParsedAttributes *OutAttrs) {
4795 // Create a fake EOF so that attribute parsing won't go off the end of the
4796 // attribute.
4797 Token AttrEnd;
4798 AttrEnd.startToken();
4799 AttrEnd.setKind(tok::eof);
4800 AttrEnd.setLocation(Tok.getLocation());
4801 AttrEnd.setEofData(LA.Toks.data());
4802 LA.Toks.push_back(Elt: AttrEnd);
4803
4804 // Append the current token at the end of the new token stream so that it
4805 // doesn't get lost.
4806 LA.Toks.push_back(Elt: Tok);
4807 PP.EnterTokenStream(Toks: LA.Toks, /*DisableMacroExpansion=*/true,
4808 /*IsReinject=*/true);
4809 // Drop the current token and bring the first cached one. It's the same token
4810 // as when we entered this function.
4811 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
4812
4813 // TODO: Use `EnterScope`
4814 (void)EnterScope;
4815
4816 ParsedAttributes Attrs(AttrFactory);
4817
4818 assert(LA.Decls.size() <= 1 &&
4819 "late field attribute expects to have at most one declaration.");
4820
4821 // Dispatch based on the attribute and parse it
4822 ParseGNUAttributeArgs(AttrName: &LA.AttrName, AttrNameLoc: LA.AttrNameLoc, Attrs, EndLoc: nullptr, ScopeName: nullptr,
4823 ScopeLoc: SourceLocation(), Form: ParsedAttr::Form::GNU(), D: nullptr);
4824
4825 for (auto *D : LA.Decls)
4826 Actions.ActOnFinishDelayedAttribute(S: getCurScope(), D, Attrs);
4827
4828 // Due to a parsing error, we either went over the cached tokens or
4829 // there are still cached tokens left, so we skip the leftover tokens.
4830 while (Tok.isNot(K: tok::eof))
4831 ConsumeAnyToken();
4832
4833 // Consume the fake EOF token if it's there
4834 if (Tok.is(K: tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4835 ConsumeAnyToken();
4836
4837 if (OutAttrs) {
4838 OutAttrs->takeAllFrom(Other&: Attrs);
4839 }
4840}
4841
4842void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
4843 DeclSpec::TST TagType, RecordDecl *TagDecl) {
4844 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
4845 "parsing struct/union body");
4846 assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");
4847
4848 BalancedDelimiterTracker T(*this, tok::l_brace);
4849 if (T.consumeOpen())
4850 return;
4851
4852 ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
4853 Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
4854
4855 // `LateAttrParseExperimentalExtOnly=true` requests that only attributes
4856 // marked with `LateAttrParseExperimentalExt` are late parsed.
4857 LateParsedAttrList LateFieldAttrs(/*PSoon=*/true,
4858 /*LateAttrParseExperimentalExtOnly=*/true);
4859
4860 // While we still have something to read, read the declarations in the struct.
4861 while (!tryParseMisplacedModuleImport() && Tok.isNot(K: tok::r_brace) &&
4862 Tok.isNot(K: tok::eof)) {
4863 // Each iteration of this loop reads one struct-declaration.
4864
4865 // Check for extraneous top-level semicolon.
4866 if (Tok.is(K: tok::semi)) {
4867 ConsumeExtraSemi(Kind: ExtraSemiKind::InsideStruct, T: TagType);
4868 continue;
4869 }
4870
4871 // Parse _Static_assert declaration.
4872 if (Tok.isOneOf(K1: tok::kw__Static_assert, K2: tok::kw_static_assert)) {
4873 SourceLocation DeclEnd;
4874 ParseStaticAssertDeclaration(DeclEnd);
4875 continue;
4876 }
4877
4878 if (Tok.is(K: tok::annot_pragma_pack)) {
4879 HandlePragmaPack();
4880 continue;
4881 }
4882
4883 if (Tok.is(K: tok::annot_pragma_align)) {
4884 HandlePragmaAlign();
4885 continue;
4886 }
4887
4888 if (Tok.isOneOf(K1: tok::annot_pragma_openmp, K2: tok::annot_attr_openmp)) {
4889 // Result can be ignored, because it must be always empty.
4890 AccessSpecifier AS = AS_none;
4891 ParsedAttributes Attrs(AttrFactory);
4892 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4893 continue;
4894 }
4895
4896 if (Tok.is(K: tok::annot_pragma_openacc)) {
4897 AccessSpecifier AS = AS_none;
4898 ParsedAttributes Attrs(AttrFactory);
4899 ParseOpenACCDirectiveDecl(AS, Attrs, TagType, TagDecl);
4900 continue;
4901 }
4902
4903 if (tok::isPragmaAnnotation(K: Tok.getKind())) {
4904 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4905 << DeclSpec::getSpecifierName(
4906 TagType, Actions.getASTContext().getPrintingPolicy());
4907 ConsumeAnnotationToken();
4908 continue;
4909 }
4910
4911 if (!Tok.is(K: tok::at)) {
4912 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4913 // Install the declarator into the current TagDecl.
4914 Decl *Field =
4915 Actions.ActOnField(getCurScope(), TagDecl,
4916 FD.D.getDeclSpec().getSourceRange().getBegin(),
4917 FD.D, FD.BitfieldSize);
4918 FD.complete(D: Field);
4919 return Field;
4920 };
4921
4922 // Parse all the comma separated declarators.
4923 ParsingDeclSpec DS(*this);
4924 ParseStructDeclaration(DS, FieldsCallback: CFieldCallback, LateFieldAttrs: &LateFieldAttrs);
4925 } else { // Handle @defs
4926 ConsumeToken();
4927 if (!Tok.isObjCAtKeyword(objcKey: tok::objc_defs)) {
4928 Diag(Tok, diag::err_unexpected_at);
4929 SkipUntil(T: tok::semi);
4930 continue;
4931 }
4932 ConsumeToken();
4933 ExpectAndConsume(ExpectedTok: tok::l_paren);
4934 if (!Tok.is(K: tok::identifier)) {
4935 Diag(Tok, diag::err_expected) << tok::identifier;
4936 SkipUntil(T: tok::semi);
4937 continue;
4938 }
4939 SmallVector<Decl *, 16> Fields;
4940 Actions.ObjC().ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
4941 Tok.getIdentifierInfo(), Fields);
4942 ConsumeToken();
4943 ExpectAndConsume(ExpectedTok: tok::r_paren);
4944 }
4945
4946 if (TryConsumeToken(Expected: tok::semi))
4947 continue;
4948
4949 if (Tok.is(K: tok::r_brace)) {
4950 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4951 break;
4952 }
4953
4954 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4955 // Skip to end of block or statement to avoid ext-warning on extra ';'.
4956 SkipUntil(T: tok::r_brace, Flags: StopAtSemi | StopBeforeMatch);
4957 // If we stopped at a ';', eat it.
4958 TryConsumeToken(Expected: tok::semi);
4959 }
4960
4961 T.consumeClose();
4962
4963 ParsedAttributes attrs(AttrFactory);
4964 // If attributes exist after struct contents, parse them.
4965 MaybeParseGNUAttributes(Attrs&: attrs, LateAttrs: &LateFieldAttrs);
4966
4967 // Late parse field attributes if necessary.
4968 ParseLexedCAttributeList(LAs&: LateFieldAttrs, /*EnterScope=*/false);
4969
4970 SmallVector<Decl *, 32> FieldDecls(TagDecl->fields());
4971
4972 Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls,
4973 T.getOpenLocation(), T.getCloseLocation(), attrs);
4974 StructScope.Exit();
4975 Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());
4976}
4977
4978void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
4979 const ParsedTemplateInfo &TemplateInfo,
4980 AccessSpecifier AS, DeclSpecContext DSC) {
4981 // Parse the tag portion of this.
4982 if (Tok.is(K: tok::code_completion)) {
4983 // Code completion for an enum name.
4984 cutOffParsing();
4985 Actions.CodeCompletion().CodeCompleteTag(S: getCurScope(), TagSpec: DeclSpec::TST_enum);
4986 DS.SetTypeSpecError(); // Needed by ActOnUsingDeclaration.
4987 return;
4988 }
4989
4990 // If attributes exist after tag, parse them.
4991 ParsedAttributes attrs(AttrFactory);
4992 MaybeParseAttributes(WhichAttrKinds: PAKM_GNU | PAKM_Declspec | PAKM_CXX11, Attrs&: attrs);
4993
4994 SourceLocation ScopedEnumKWLoc;
4995 bool IsScopedUsingClassTag = false;
4996
4997 // In C++11, recognize 'enum class' and 'enum struct'.
4998 if (Tok.isOneOf(K1: tok::kw_class, K2: tok::kw_struct) && getLangOpts().CPlusPlus) {
4999 Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum
5000 : diag::ext_scoped_enum);
5001 IsScopedUsingClassTag = Tok.is(K: tok::kw_class);
5002 ScopedEnumKWLoc = ConsumeToken();
5003
5004 // Attributes are not allowed between these keywords. Diagnose,
5005 // but then just treat them like they appeared in the right place.
5006 ProhibitAttributes(Attrs&: attrs);
5007
5008 // They are allowed afterwards, though.
5009 MaybeParseAttributes(WhichAttrKinds: PAKM_GNU | PAKM_Declspec | PAKM_CXX11, Attrs&: attrs);
5010 }
5011
5012 // C++11 [temp.explicit]p12:
5013 // The usual access controls do not apply to names used to specify
5014 // explicit instantiations.
5015 // We extend this to also cover explicit specializations. Note that
5016 // we don't suppress if this turns out to be an elaborated type
5017 // specifier.
5018 bool shouldDelayDiagsInTag =
5019 (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation ||
5020 TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization);
5021 SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
5022
5023 // Determine whether this declaration is permitted to have an enum-base.
5024 AllowDefiningTypeSpec AllowEnumSpecifier =
5025 isDefiningTypeSpecifierContext(DSC, IsCPlusPlus: getLangOpts().CPlusPlus);
5026 bool CanBeOpaqueEnumDeclaration =
5027 DS.isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5028 bool CanHaveEnumBase = (getLangOpts().CPlusPlus11 || getLangOpts().ObjC ||
5029 getLangOpts().MicrosoftExt) &&
5030 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5031 CanBeOpaqueEnumDeclaration);
5032
5033 CXXScopeSpec &SS = DS.getTypeSpecScope();
5034 if (getLangOpts().CPlusPlus) {
5035 // "enum foo : bar;" is not a potential typo for "enum foo::bar;".
5036 ColonProtectionRAIIObject X(*this);
5037
5038 CXXScopeSpec Spec;
5039 if (ParseOptionalCXXScopeSpecifier(SS&: Spec, /*ObjectType=*/nullptr,
5040 /*ObjectHasErrors=*/false,
5041 /*EnteringContext=*/true))
5042 return;
5043
5044 if (Spec.isSet() && Tok.isNot(K: tok::identifier)) {
5045 Diag(Tok, diag::err_expected) << tok::identifier;
5046 DS.SetTypeSpecError();
5047 if (Tok.isNot(K: tok::l_brace)) {
5048 // Has no name and is not a definition.
5049 // Skip the rest of this declarator, up until the comma or semicolon.
5050 SkipUntil(T: tok::comma, Flags: StopAtSemi);
5051 return;
5052 }
5053 }
5054
5055 SS = Spec;
5056 }
5057
5058 // Must have either 'enum name' or 'enum {...}' or (rarely) 'enum : T { ... }'.
5059 if (Tok.isNot(K: tok::identifier) && Tok.isNot(K: tok::l_brace) &&
5060 Tok.isNot(K: tok::colon)) {
5061 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5062
5063 DS.SetTypeSpecError();
5064 // Skip the rest of this declarator, up until the comma or semicolon.
5065 SkipUntil(T: tok::comma, Flags: StopAtSemi);
5066 return;
5067 }
5068
5069 // If an identifier is present, consume and remember it.
5070 IdentifierInfo *Name = nullptr;
5071 SourceLocation NameLoc;
5072 if (Tok.is(K: tok::identifier)) {
5073 Name = Tok.getIdentifierInfo();
5074 NameLoc = ConsumeToken();
5075 }
5076
5077 if (!Name && ScopedEnumKWLoc.isValid()) {
5078 // C++0x 7.2p2: The optional identifier shall not be omitted in the
5079 // declaration of a scoped enumeration.
5080 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5081 ScopedEnumKWLoc = SourceLocation();
5082 IsScopedUsingClassTag = false;
5083 }
5084
5085 // Okay, end the suppression area. We'll decide whether to emit the
5086 // diagnostics in a second.
5087 if (shouldDelayDiagsInTag)
5088 diagsFromTag.done();
5089
5090 TypeResult BaseType;
5091 SourceRange BaseRange;
5092
5093 bool CanBeBitfield =
5094 getCurScope()->isClassScope() && ScopedEnumKWLoc.isInvalid() && Name;
5095
5096 // Parse the fixed underlying type.
5097 if (Tok.is(K: tok::colon)) {
5098 // This might be an enum-base or part of some unrelated enclosing context.
5099 //
5100 // 'enum E : base' is permitted in two circumstances:
5101 //
5102 // 1) As a defining-type-specifier, when followed by '{'.
5103 // 2) As the sole constituent of a complete declaration -- when DS is empty
5104 // and the next token is ';'.
5105 //
5106 // The restriction to defining-type-specifiers is important to allow parsing
5107 // a ? new enum E : int{}
5108 // _Generic(a, enum E : int{})
5109 // properly.
5110 //
5111 // One additional consideration applies:
5112 //
5113 // C++ [dcl.enum]p1:
5114 // A ':' following "enum nested-name-specifier[opt] identifier" within
5115 // the decl-specifier-seq of a member-declaration is parsed as part of
5116 // an enum-base.
5117 //
5118 // Other language modes supporting enumerations with fixed underlying types
5119 // do not have clear rules on this, so we disambiguate to determine whether
5120 // the tokens form a bit-field width or an enum-base.
5121
5122 if (CanBeBitfield && !isEnumBase(AllowSemi: CanBeOpaqueEnumDeclaration)) {
5123 // Outside C++11, do not interpret the tokens as an enum-base if they do
5124 // not make sense as one. In C++11, it's an error if this happens.
5125 if (getLangOpts().CPlusPlus11)
5126 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5127 } else if (CanHaveEnumBase || !ColonIsSacred) {
5128 SourceLocation ColonLoc = ConsumeToken();
5129
5130 // Parse a type-specifier-seq as a type. We can't just ParseTypeName here,
5131 // because under -fms-extensions,
5132 // enum E : int *p;
5133 // declares 'enum E : int; E *p;' not 'enum E : int*; E p;'.
5134 DeclSpec DS(AttrFactory);
5135 // enum-base is not assumed to be a type and therefore requires the
5136 // typename keyword [p0634r3].
5137 ParseSpecifierQualifierList(DS, AllowImplicitTypename: ImplicitTypenameContext::No, AS,
5138 DSC: DeclSpecContext::DSC_type_specifier);
5139 Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
5140 DeclaratorContext::TypeName);
5141 BaseType = Actions.ActOnTypeName(D&: DeclaratorInfo);
5142
5143 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5144
5145 if (!getLangOpts().ObjC) {
5146 if (getLangOpts().CPlusPlus)
5147 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5148 << BaseRange;
5149 else if (getLangOpts().MicrosoftExt && !getLangOpts().C23)
5150 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5151 << BaseRange;
5152 else
5153 Diag(ColonLoc, getLangOpts().C23
5154 ? diag::warn_c17_compat_enum_fixed_underlying_type
5155 : diag::ext_c23_enum_fixed_underlying_type)
5156 << BaseRange;
5157 }
5158 }
5159 }
5160
5161 // There are four options here. If we have 'friend enum foo;' then this is a
5162 // friend declaration, and cannot have an accompanying definition. If we have
5163 // 'enum foo;', then this is a forward declaration. If we have
5164 // 'enum foo {...' then this is a definition. Otherwise we have something
5165 // like 'enum foo xyz', a reference.
5166 //
5167 // This is needed to handle stuff like this right (C99 6.7.2.3p11):
5168 // enum foo {..}; void bar() { enum foo; } <- new foo in bar.
5169 // enum foo {..}; void bar() { enum foo x; } <- use of old foo.
5170 //
5171 TagUseKind TUK;
5172 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5173 TUK = TagUseKind::Reference;
5174 else if (Tok.is(K: tok::l_brace)) {
5175 if (DS.isFriendSpecified()) {
5176 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5177 << SourceRange(DS.getFriendSpecLoc());
5178 ConsumeBrace();
5179 SkipUntil(T: tok::r_brace, Flags: StopAtSemi);
5180 // Discard any other definition-only pieces.
5181 attrs.clear();
5182 ScopedEnumKWLoc = SourceLocation();
5183 IsScopedUsingClassTag = false;
5184 BaseType = TypeResult();
5185 TUK = TagUseKind::Friend;
5186 } else {
5187 TUK = TagUseKind::Definition;
5188 }
5189 } else if (!isTypeSpecifier(DSC) &&
5190 (Tok.is(K: tok::semi) ||
5191 (Tok.isAtStartOfLine() &&
5192 !isValidAfterTypeSpecifier(CouldBeBitfield: CanBeBitfield)))) {
5193 // An opaque-enum-declaration is required to be standalone (no preceding or
5194 // following tokens in the declaration). Sema enforces this separately by
5195 // diagnosing anything else in the DeclSpec.
5196 TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration;
5197 if (Tok.isNot(K: tok::semi)) {
5198 // A semicolon was missing after this declaration. Diagnose and recover.
5199 ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
5200 PP.EnterToken(Tok, /*IsReinject=*/true);
5201 Tok.setKind(tok::semi);
5202 }
5203 } else {
5204 TUK = TagUseKind::Reference;
5205 }
5206
5207 bool IsElaboratedTypeSpecifier =
5208 TUK == TagUseKind::Reference || TUK == TagUseKind::Friend;
5209
5210 // If this is an elaborated type specifier nested in a larger declaration,
5211 // and we delayed diagnostics before, just merge them into the current pool.
5212 if (TUK == TagUseKind::Reference && shouldDelayDiagsInTag) {
5213 diagsFromTag.redelay();
5214 }
5215
5216 MultiTemplateParamsArg TParams;
5217 if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&
5218 TUK != TagUseKind::Reference) {
5219 if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {
5220 // Skip the rest of this declarator, up until the comma or semicolon.
5221 Diag(Tok, diag::err_enum_template);
5222 SkipUntil(T: tok::comma, Flags: StopAtSemi);
5223 return;
5224 }
5225
5226 if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation) {
5227 // Enumerations can't be explicitly instantiated.
5228 DS.SetTypeSpecError();
5229 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5230 return;
5231 }
5232
5233 assert(TemplateInfo.TemplateParams && "no template parameters");
5234 TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),
5235 TemplateInfo.TemplateParams->size());
5236 SS.setTemplateParamLists(TParams);
5237 }
5238
5239 if (!Name && TUK != TagUseKind::Definition) {
5240 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5241
5242 DS.SetTypeSpecError();
5243 // Skip the rest of this declarator, up until the comma or semicolon.
5244 SkipUntil(T: tok::comma, Flags: StopAtSemi);
5245 return;
5246 }
5247
5248 // An elaborated-type-specifier has a much more constrained grammar:
5249 //
5250 // 'enum' nested-name-specifier[opt] identifier
5251 //
5252 // If we parsed any other bits, reject them now.
5253 //
5254 // MSVC and (for now at least) Objective-C permit a full enum-specifier
5255 // or opaque-enum-declaration anywhere.
5256 if (IsElaboratedTypeSpecifier && !getLangOpts().MicrosoftExt &&
5257 !getLangOpts().ObjC) {
5258 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5259 diag::err_keyword_not_allowed,
5260 /*DiagnoseEmptyAttrs=*/true);
5261 if (BaseType.isUsable())
5262 Diag(BaseRange.getBegin(), diag::ext_enum_base_in_type_specifier)
5263 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5264 else if (ScopedEnumKWLoc.isValid())
5265 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5266 << FixItHint::CreateRemoval(ScopedEnumKWLoc) << IsScopedUsingClassTag;
5267 }
5268
5269 stripTypeAttributesOffDeclSpec(Attrs&: attrs, DS, TUK);
5270
5271 SkipBodyInfo SkipBody;
5272 if (!Name && TUK == TagUseKind::Definition && Tok.is(K: tok::l_brace) &&
5273 NextToken().is(K: tok::identifier))
5274 SkipBody = Actions.shouldSkipAnonEnumBody(S: getCurScope(),
5275 II: NextToken().getIdentifierInfo(),
5276 IILoc: NextToken().getLocation());
5277
5278 bool Owned = false;
5279 bool IsDependent = false;
5280 const char *PrevSpec = nullptr;
5281 unsigned DiagID;
5282 Decl *TagDecl =
5283 Actions.ActOnTag(S: getCurScope(), TagSpec: DeclSpec::TST_enum, TUK, KWLoc: StartLoc, SS,
5284 Name, NameLoc, Attr: attrs, AS, ModulePrivateLoc: DS.getModulePrivateSpecLoc(),
5285 TemplateParameterLists: TParams, OwnedDecl&: Owned, IsDependent, ScopedEnumKWLoc,
5286 ScopedEnumUsesClassTag: IsScopedUsingClassTag,
5287 UnderlyingType: BaseType, IsTypeSpecifier: DSC == DeclSpecContext::DSC_type_specifier,
5288 IsTemplateParamOrArg: DSC == DeclSpecContext::DSC_template_param ||
5289 DSC == DeclSpecContext::DSC_template_type_arg,
5290 OOK: OffsetOfState, SkipBody: &SkipBody).get();
5291
5292 if (SkipBody.ShouldSkip) {
5293 assert(TUK == TagUseKind::Definition && "can only skip a definition");
5294
5295 BalancedDelimiterTracker T(*this, tok::l_brace);
5296 T.consumeOpen();
5297 T.skipToEnd();
5298
5299 if (DS.SetTypeSpecType(T: DeclSpec::TST_enum, TagKwLoc: StartLoc,
5300 TagNameLoc: NameLoc.isValid() ? NameLoc : StartLoc,
5301 PrevSpec, DiagID, Rep: TagDecl, Owned,
5302 Policy: Actions.getASTContext().getPrintingPolicy()))
5303 Diag(Loc: StartLoc, DiagID) << PrevSpec;
5304 return;
5305 }
5306
5307 if (IsDependent) {
5308 // This enum has a dependent nested-name-specifier. Handle it as a
5309 // dependent tag.
5310 if (!Name) {
5311 DS.SetTypeSpecError();
5312 Diag(Tok, diag::err_expected_type_name_after_typename);
5313 return;
5314 }
5315
5316 TypeResult Type = Actions.ActOnDependentTag(
5317 S: getCurScope(), TagSpec: DeclSpec::TST_enum, TUK, SS, Name, TagLoc: StartLoc, NameLoc);
5318 if (Type.isInvalid()) {
5319 DS.SetTypeSpecError();
5320 return;
5321 }
5322
5323 if (DS.SetTypeSpecType(T: DeclSpec::TST_typename, TagKwLoc: StartLoc,
5324 TagNameLoc: NameLoc.isValid() ? NameLoc : StartLoc,
5325 PrevSpec, DiagID, Rep: Type.get(),
5326 Policy: Actions.getASTContext().getPrintingPolicy()))
5327 Diag(Loc: StartLoc, DiagID) << PrevSpec;
5328
5329 return;
5330 }
5331
5332 if (!TagDecl) {
5333 // The action failed to produce an enumeration tag. If this is a
5334 // definition, consume the entire definition.
5335 if (Tok.is(K: tok::l_brace) && TUK != TagUseKind::Reference) {
5336 ConsumeBrace();
5337 SkipUntil(T: tok::r_brace, Flags: StopAtSemi);
5338 }
5339
5340 DS.SetTypeSpecError();
5341 return;
5342 }
5343
5344 if (Tok.is(K: tok::l_brace) && TUK == TagUseKind::Definition) {
5345 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
5346 ParseEnumBody(StartLoc, TagDecl: D, SkipBody: &SkipBody);
5347 if (SkipBody.CheckSameAsPrevious &&
5348 !Actions.ActOnDuplicateDefinition(S: getCurScope(), Prev: TagDecl, SkipBody)) {
5349 DS.SetTypeSpecError();
5350 return;
5351 }
5352 }
5353
5354 if (DS.SetTypeSpecType(T: DeclSpec::TST_enum, TagKwLoc: StartLoc,
5355 TagNameLoc: NameLoc.isValid() ? NameLoc : StartLoc,
5356 PrevSpec, DiagID, Rep: TagDecl, Owned,
5357 Policy: Actions.getASTContext().getPrintingPolicy()))
5358 Diag(Loc: StartLoc, DiagID) << PrevSpec;
5359}
5360
5361void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl,
5362 SkipBodyInfo *SkipBody) {
5363 // Enter the scope of the enum body and start the definition.
5364 ParseScope EnumScope(this, Scope::DeclScope | Scope::EnumScope);
5365 Actions.ActOnTagStartDefinition(S: getCurScope(), TagDecl: EnumDecl);
5366
5367 BalancedDelimiterTracker T(*this, tok::l_brace);
5368 T.consumeOpen();
5369
5370 // C does not allow an empty enumerator-list, C++ does [dcl.enum].
5371 if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
5372 Diag(Tok, diag::err_empty_enum);
5373
5374 SmallVector<Decl *, 32> EnumConstantDecls;
5375 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5376
5377 Decl *LastEnumConstDecl = nullptr;
5378
5379 // Parse the enumerator-list.
5380 while (Tok.isNot(K: tok::r_brace)) {
5381 // Parse enumerator. If failed, try skipping till the start of the next
5382 // enumerator definition.
5383 if (Tok.isNot(K: tok::identifier)) {
5384 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5385 if (SkipUntil(T1: tok::comma, T2: tok::r_brace, Flags: StopBeforeMatch) &&
5386 TryConsumeToken(Expected: tok::comma))
5387 continue;
5388 break;
5389 }
5390 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5391 SourceLocation IdentLoc = ConsumeToken();
5392
5393 // If attributes exist after the enumerator, parse them.
5394 ParsedAttributes attrs(AttrFactory);
5395 MaybeParseGNUAttributes(Attrs&: attrs);
5396 if (isAllowedCXX11AttributeSpecifier()) {
5397 if (getLangOpts().CPlusPlus)
5398 Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
5399 ? diag::warn_cxx14_compat_ns_enum_attribute
5400 : diag::ext_ns_enum_attribute)
5401 << 1 /*enumerator*/;
5402 ParseCXX11Attributes(attrs);
5403 }
5404
5405 SourceLocation EqualLoc;
5406 ExprResult AssignedVal;
5407 EnumAvailabilityDiags.emplace_back(Args&: *this);
5408
5409 EnterExpressionEvaluationContext ConstantEvaluated(
5410 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5411 if (TryConsumeToken(Expected: tok::equal, Loc&: EqualLoc)) {
5412 AssignedVal = ParseConstantExpressionInExprEvalContext();
5413 if (AssignedVal.isInvalid())
5414 SkipUntil(T1: tok::comma, T2: tok::r_brace, Flags: StopBeforeMatch);
5415 }
5416
5417 // Install the enumerator constant into EnumDecl.
5418 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5419 S: getCurScope(), EnumDecl, LastEnumConstant: LastEnumConstDecl, IdLoc: IdentLoc, Id: Ident, Attrs: attrs,
5420 EqualLoc, Val: AssignedVal.get(), SkipBody);
5421 EnumAvailabilityDiags.back().done();
5422
5423 EnumConstantDecls.push_back(Elt: EnumConstDecl);
5424 LastEnumConstDecl = EnumConstDecl;
5425
5426 if (Tok.is(K: tok::identifier)) {
5427 // We're missing a comma between enumerators.
5428 SourceLocation Loc = getEndOfPreviousToken();
5429 Diag(Loc, diag::err_enumerator_list_missing_comma)
5430 << FixItHint::CreateInsertion(Loc, ", ");
5431 continue;
5432 }
5433
5434 // Emumerator definition must be finished, only comma or r_brace are
5435 // allowed here.
5436 SourceLocation CommaLoc;
5437 if (Tok.isNot(K: tok::r_brace) && !TryConsumeToken(Expected: tok::comma, Loc&: CommaLoc)) {
5438 if (EqualLoc.isValid())
5439 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5440 << tok::comma;
5441 else
5442 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5443 if (SkipUntil(T1: tok::comma, T2: tok::r_brace, Flags: StopBeforeMatch)) {
5444 if (TryConsumeToken(Expected: tok::comma, Loc&: CommaLoc))
5445 continue;
5446 } else {
5447 break;
5448 }
5449 }
5450
5451 // If comma is followed by r_brace, emit appropriate warning.
5452 if (Tok.is(K: tok::r_brace) && CommaLoc.isValid()) {
5453 if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)
5454 Diag(CommaLoc, getLangOpts().CPlusPlus ?
5455 diag::ext_enumerator_list_comma_cxx :
5456 diag::ext_enumerator_list_comma_c)
5457 << FixItHint::CreateRemoval(CommaLoc);
5458 else if (getLangOpts().CPlusPlus11)
5459 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5460 << FixItHint::CreateRemoval(CommaLoc);
5461 break;
5462 }
5463 }
5464
5465 // Eat the }.
5466 T.consumeClose();
5467
5468 // If attributes exist after the identifier list, parse them.
5469 ParsedAttributes attrs(AttrFactory);
5470 MaybeParseGNUAttributes(Attrs&: attrs);
5471
5472 Actions.ActOnEnumBody(EnumLoc: StartLoc, BraceRange: T.getRange(), EnumDecl, Elements: EnumConstantDecls,
5473 S: getCurScope(), Attr: attrs);
5474
5475 // Now handle enum constant availability diagnostics.
5476 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5477 for (size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5478 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
5479 EnumAvailabilityDiags[i].redelay();
5480 PD.complete(D: EnumConstantDecls[i]);
5481 }
5482
5483 EnumScope.Exit();
5484 Actions.ActOnTagFinishDefinition(S: getCurScope(), TagDecl: EnumDecl, BraceRange: T.getRange());
5485
5486 // The next token must be valid after an enum definition. If not, a ';'
5487 // was probably forgotten.
5488 bool CanBeBitfield = getCurScope()->isClassScope();
5489 if (!isValidAfterTypeSpecifier(CouldBeBitfield: CanBeBitfield)) {
5490 ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
5491 // Push this token back into the preprocessor and change our current token
5492 // to ';' so that the rest of the code recovers as though there were an
5493 // ';' after the definition.
5494 PP.EnterToken(Tok, /*IsReinject=*/true);
5495 Tok.setKind(tok::semi);
5496 }
5497}
5498
5499bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
5500 switch (Tok.getKind()) {
5501 default: return false;
5502 // type-specifiers
5503 case tok::kw_short:
5504 case tok::kw_long:
5505 case tok::kw___int64:
5506 case tok::kw___int128:
5507 case tok::kw_signed:
5508 case tok::kw_unsigned:
5509 case tok::kw__Complex:
5510 case tok::kw__Imaginary:
5511 case tok::kw_void:
5512 case tok::kw_char:
5513 case tok::kw_wchar_t:
5514 case tok::kw_char8_t:
5515 case tok::kw_char16_t:
5516 case tok::kw_char32_t:
5517 case tok::kw_int:
5518 case tok::kw__ExtInt:
5519 case tok::kw__BitInt:
5520 case tok::kw___bf16:
5521 case tok::kw_half:
5522 case tok::kw_float:
5523 case tok::kw_double:
5524 case tok::kw__Accum:
5525 case tok::kw__Fract:
5526 case tok::kw__Float16:
5527 case tok::kw___float128:
5528 case tok::kw___ibm128:
5529 case tok::kw_bool:
5530 case tok::kw__Bool:
5531 case tok::kw__Decimal32:
5532 case tok::kw__Decimal64:
5533 case tok::kw__Decimal128:
5534 case tok::kw___vector:
5535#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5536#include "clang/Basic/OpenCLImageTypes.def"
5537#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5538#include "clang/Basic/HLSLIntangibleTypes.def"
5539
5540 // struct-or-union-specifier (C99) or class-specifier (C++)
5541 case tok::kw_class:
5542 case tok::kw_struct:
5543 case tok::kw___interface:
5544 case tok::kw_union:
5545 // enum-specifier
5546 case tok::kw_enum:
5547
5548 // typedef-name
5549 case tok::annot_typename:
5550 return true;
5551 }
5552}
5553
5554bool Parser::isTypeSpecifierQualifier() {
5555 switch (Tok.getKind()) {
5556 default: return false;
5557
5558 case tok::identifier: // foo::bar
5559 if (TryAltiVecVectorToken())
5560 return true;
5561 [[fallthrough]];
5562 case tok::kw_typename: // typename T::type
5563 // Annotate typenames and C++ scope specifiers. If we get one, just
5564 // recurse to handle whatever we get.
5565 if (TryAnnotateTypeOrScopeToken())
5566 return true;
5567 if (Tok.is(K: tok::identifier))
5568 return false;
5569 return isTypeSpecifierQualifier();
5570
5571 case tok::coloncolon: // ::foo::bar
5572 if (NextToken().is(K: tok::kw_new) || // ::new
5573 NextToken().is(K: tok::kw_delete)) // ::delete
5574 return false;
5575
5576 if (TryAnnotateTypeOrScopeToken())
5577 return true;
5578 return isTypeSpecifierQualifier();
5579
5580 // GNU attributes support.
5581 case tok::kw___attribute:
5582 // C23/GNU typeof support.
5583 case tok::kw_typeof:
5584 case tok::kw_typeof_unqual:
5585
5586 // type-specifiers
5587 case tok::kw_short:
5588 case tok::kw_long:
5589 case tok::kw___int64:
5590 case tok::kw___int128:
5591 case tok::kw_signed:
5592 case tok::kw_unsigned:
5593 case tok::kw__Complex:
5594 case tok::kw__Imaginary:
5595 case tok::kw_void:
5596 case tok::kw_char:
5597 case tok::kw_wchar_t:
5598 case tok::kw_char8_t:
5599 case tok::kw_char16_t:
5600 case tok::kw_char32_t:
5601 case tok::kw_int:
5602 case tok::kw__ExtInt:
5603 case tok::kw__BitInt:
5604 case tok::kw_half:
5605 case tok::kw___bf16:
5606 case tok::kw_float:
5607 case tok::kw_double:
5608 case tok::kw__Accum:
5609 case tok::kw__Fract:
5610 case tok::kw__Float16:
5611 case tok::kw___float128:
5612 case tok::kw___ibm128:
5613 case tok::kw_bool:
5614 case tok::kw__Bool:
5615 case tok::kw__Decimal32:
5616 case tok::kw__Decimal64:
5617 case tok::kw__Decimal128:
5618 case tok::kw___vector:
5619#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5620#include "clang/Basic/OpenCLImageTypes.def"
5621#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5622#include "clang/Basic/HLSLIntangibleTypes.def"
5623
5624 // struct-or-union-specifier (C99) or class-specifier (C++)
5625 case tok::kw_class:
5626 case tok::kw_struct:
5627 case tok::kw___interface:
5628 case tok::kw_union:
5629 // enum-specifier
5630 case tok::kw_enum:
5631
5632 // type-qualifier
5633 case tok::kw_const:
5634 case tok::kw_volatile:
5635 case tok::kw_restrict:
5636 case tok::kw__Sat:
5637
5638 // Debugger support.
5639 case tok::kw___unknown_anytype:
5640
5641 // typedef-name
5642 case tok::annot_typename:
5643 return true;
5644
5645 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
5646 case tok::less:
5647 return getLangOpts().ObjC;
5648
5649 case tok::kw___cdecl:
5650 case tok::kw___stdcall:
5651 case tok::kw___fastcall:
5652 case tok::kw___thiscall:
5653 case tok::kw___regcall:
5654 case tok::kw___vectorcall:
5655 case tok::kw___w64:
5656 case tok::kw___ptr64:
5657 case tok::kw___ptr32:
5658 case tok::kw___pascal:
5659 case tok::kw___unaligned:
5660 case tok::kw___ptrauth:
5661
5662 case tok::kw__Nonnull:
5663 case tok::kw__Nullable:
5664 case tok::kw__Nullable_result:
5665 case tok::kw__Null_unspecified:
5666
5667 case tok::kw___kindof:
5668
5669 case tok::kw___private:
5670 case tok::kw___local:
5671 case tok::kw___global:
5672 case tok::kw___constant:
5673 case tok::kw___generic:
5674 case tok::kw___read_only:
5675 case tok::kw___read_write:
5676 case tok::kw___write_only:
5677 case tok::kw___funcref:
5678 return true;
5679
5680 case tok::kw_private:
5681 return getLangOpts().OpenCL;
5682
5683 // C11 _Atomic
5684 case tok::kw__Atomic:
5685 return true;
5686
5687 // HLSL type qualifiers
5688 case tok::kw_groupshared:
5689 case tok::kw_in:
5690 case tok::kw_inout:
5691 case tok::kw_out:
5692 return getLangOpts().HLSL;
5693 }
5694}
5695
5696Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() {
5697 assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode");
5698
5699 // Parse a top-level-stmt.
5700 Parser::StmtVector Stmts;
5701 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5702 ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |
5703 Scope::CompoundStmtScope);
5704 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(S: getCurScope());
5705 StmtResult R = ParseStatementOrDeclaration(Stmts, StmtCtx: SubStmtCtx);
5706 if (!R.isUsable())
5707 R = Actions.ActOnNullStmt(SemiLoc: Tok.getLocation());
5708
5709 Actions.ActOnFinishTopLevelStmtDecl(D: TLSD, Statement: R.get());
5710
5711 if (Tok.is(K: tok::annot_repl_input_end) &&
5712 Tok.getAnnotationValue() != nullptr) {
5713 ConsumeAnnotationToken();
5714 TLSD->setSemiMissing();
5715 }
5716
5717 SmallVector<Decl *, 2> DeclsInGroup;
5718 DeclsInGroup.push_back(TLSD);
5719
5720 // Currently happens for things like -fms-extensions and use `__if_exists`.
5721 for (Stmt *S : Stmts) {
5722 // Here we should be safe as `__if_exists` and friends are not introducing
5723 // new variables which need to live outside file scope.
5724 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(S: getCurScope());
5725 Actions.ActOnFinishTopLevelStmtDecl(D, Statement: S);
5726 DeclsInGroup.push_back(D);
5727 }
5728
5729 return Actions.BuildDeclaratorGroup(Group: DeclsInGroup);
5730}
5731
5732bool Parser::isDeclarationSpecifier(
5733 ImplicitTypenameContext AllowImplicitTypename,
5734 bool DisambiguatingWithExpression) {
5735 switch (Tok.getKind()) {
5736 default: return false;
5737
5738 // OpenCL 2.0 and later define this keyword.
5739 case tok::kw_pipe:
5740 return getLangOpts().OpenCL &&
5741 getLangOpts().getOpenCLCompatibleVersion() >= 200;
5742
5743 case tok::identifier: // foo::bar
5744 // Unfortunate hack to support "Class.factoryMethod" notation.
5745 if (getLangOpts().ObjC && NextToken().is(K: tok::period))
5746 return false;
5747 if (TryAltiVecVectorToken())
5748 return true;
5749 [[fallthrough]];
5750 case tok::kw_decltype: // decltype(T())::type
5751 case tok::kw_typename: // typename T::type
5752 // Annotate typenames and C++ scope specifiers. If we get one, just
5753 // recurse to handle whatever we get.
5754 if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))
5755 return true;
5756 if (TryAnnotateTypeConstraint())
5757 return true;
5758 if (Tok.is(K: tok::identifier))
5759 return false;
5760
5761 // If we're in Objective-C and we have an Objective-C class type followed
5762 // by an identifier and then either ':' or ']', in a place where an
5763 // expression is permitted, then this is probably a class message send
5764 // missing the initial '['. In this case, we won't consider this to be
5765 // the start of a declaration.
5766 if (DisambiguatingWithExpression &&
5767 isStartOfObjCClassMessageMissingOpenBracket())
5768 return false;
5769
5770 return isDeclarationSpecifier(AllowImplicitTypename);
5771
5772 case tok::coloncolon: // ::foo::bar
5773 if (!getLangOpts().CPlusPlus)
5774 return false;
5775 if (NextToken().is(K: tok::kw_new) || // ::new
5776 NextToken().is(K: tok::kw_delete)) // ::delete
5777 return false;
5778
5779 // Annotate typenames and C++ scope specifiers. If we get one, just
5780 // recurse to handle whatever we get.
5781 if (TryAnnotateTypeOrScopeToken())
5782 return true;
5783 return isDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No);
5784
5785 // storage-class-specifier
5786 case tok::kw_typedef:
5787 case tok::kw_extern:
5788 case tok::kw___private_extern__:
5789 case tok::kw_static:
5790 case tok::kw_auto:
5791 case tok::kw___auto_type:
5792 case tok::kw_register:
5793 case tok::kw___thread:
5794 case tok::kw_thread_local:
5795 case tok::kw__Thread_local:
5796
5797 // Modules
5798 case tok::kw___module_private__:
5799
5800 // Debugger support
5801 case tok::kw___unknown_anytype:
5802
5803 // type-specifiers
5804 case tok::kw_short:
5805 case tok::kw_long:
5806 case tok::kw___int64:
5807 case tok::kw___int128:
5808 case tok::kw_signed:
5809 case tok::kw_unsigned:
5810 case tok::kw__Complex:
5811 case tok::kw__Imaginary:
5812 case tok::kw_void:
5813 case tok::kw_char:
5814 case tok::kw_wchar_t:
5815 case tok::kw_char8_t:
5816 case tok::kw_char16_t:
5817 case tok::kw_char32_t:
5818
5819 case tok::kw_int:
5820 case tok::kw__ExtInt:
5821 case tok::kw__BitInt:
5822 case tok::kw_half:
5823 case tok::kw___bf16:
5824 case tok::kw_float:
5825 case tok::kw_double:
5826 case tok::kw__Accum:
5827 case tok::kw__Fract:
5828 case tok::kw__Float16:
5829 case tok::kw___float128:
5830 case tok::kw___ibm128:
5831 case tok::kw_bool:
5832 case tok::kw__Bool:
5833 case tok::kw__Decimal32:
5834 case tok::kw__Decimal64:
5835 case tok::kw__Decimal128:
5836 case tok::kw___vector:
5837
5838 // struct-or-union-specifier (C99) or class-specifier (C++)
5839 case tok::kw_class:
5840 case tok::kw_struct:
5841 case tok::kw_union:
5842 case tok::kw___interface:
5843 // enum-specifier
5844 case tok::kw_enum:
5845
5846 // type-qualifier
5847 case tok::kw_const:
5848 case tok::kw_volatile:
5849 case tok::kw_restrict:
5850 case tok::kw__Sat:
5851
5852 // function-specifier
5853 case tok::kw_inline:
5854 case tok::kw_virtual:
5855 case tok::kw_explicit:
5856 case tok::kw__Noreturn:
5857
5858 // alignment-specifier
5859 case tok::kw__Alignas:
5860
5861 // friend keyword.
5862 case tok::kw_friend:
5863
5864 // static_assert-declaration
5865 case tok::kw_static_assert:
5866 case tok::kw__Static_assert:
5867
5868 // C23/GNU typeof support.
5869 case tok::kw_typeof:
5870 case tok::kw_typeof_unqual:
5871
5872 // GNU attributes.
5873 case tok::kw___attribute:
5874
5875 // C++11 decltype and constexpr.
5876 case tok::annot_decltype:
5877 case tok::annot_pack_indexing_type:
5878 case tok::kw_constexpr:
5879
5880 // C++20 consteval and constinit.
5881 case tok::kw_consteval:
5882 case tok::kw_constinit:
5883
5884 // C11 _Atomic
5885 case tok::kw__Atomic:
5886 return true;
5887
5888 case tok::kw_alignas:
5889 // alignas is a type-specifier-qualifier in C23, which is a kind of
5890 // declaration-specifier. Outside of C23 mode (including in C++), it is not.
5891 return getLangOpts().C23;
5892
5893 // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
5894 case tok::less:
5895 return getLangOpts().ObjC;
5896
5897 // typedef-name
5898 case tok::annot_typename:
5899 return !DisambiguatingWithExpression ||
5900 !isStartOfObjCClassMessageMissingOpenBracket();
5901
5902 // placeholder-type-specifier
5903 case tok::annot_template_id: {
5904 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(tok: Tok);
5905 if (TemplateId->hasInvalidName())
5906 return true;
5907 // FIXME: What about type templates that have only been annotated as
5908 // annot_template_id, not as annot_typename?
5909 return isTypeConstraintAnnotation() &&
5910 (NextToken().is(K: tok::kw_auto) || NextToken().is(K: tok::kw_decltype));
5911 }
5912
5913 case tok::annot_cxxscope: {
5914 TemplateIdAnnotation *TemplateId =
5915 NextToken().is(K: tok::annot_template_id)
5916 ? takeTemplateIdAnnotation(tok: NextToken())
5917 : nullptr;
5918 if (TemplateId && TemplateId->hasInvalidName())
5919 return true;
5920 // FIXME: What about type templates that have only been annotated as
5921 // annot_template_id, not as annot_typename?
5922 if (NextToken().is(K: tok::identifier) && TryAnnotateTypeConstraint())
5923 return true;
5924 return isTypeConstraintAnnotation() &&
5925 GetLookAheadToken(N: 2).isOneOf(K1: tok::kw_auto, K2: tok::kw_decltype);
5926 }
5927
5928 case tok::kw___declspec:
5929 case tok::kw___cdecl:
5930 case tok::kw___stdcall:
5931 case tok::kw___fastcall:
5932 case tok::kw___thiscall:
5933 case tok::kw___regcall:
5934 case tok::kw___vectorcall:
5935 case tok::kw___w64:
5936 case tok::kw___sptr:
5937 case tok::kw___uptr:
5938 case tok::kw___ptr64:
5939 case tok::kw___ptr32:
5940 case tok::kw___forceinline:
5941 case tok::kw___pascal:
5942 case tok::kw___unaligned:
5943 case tok::kw___ptrauth:
5944
5945 case tok::kw__Nonnull:
5946 case tok::kw__Nullable:
5947 case tok::kw__Nullable_result:
5948 case tok::kw__Null_unspecified:
5949
5950 case tok::kw___kindof:
5951
5952 case tok::kw___private:
5953 case tok::kw___local:
5954 case tok::kw___global:
5955 case tok::kw___constant:
5956 case tok::kw___generic:
5957 case tok::kw___read_only:
5958 case tok::kw___read_write:
5959 case tok::kw___write_only:
5960#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5961#include "clang/Basic/OpenCLImageTypes.def"
5962#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5963#include "clang/Basic/HLSLIntangibleTypes.def"
5964
5965 case tok::kw___funcref:
5966 case tok::kw_groupshared:
5967 return true;
5968
5969 case tok::kw_private:
5970 return getLangOpts().OpenCL;
5971 }
5972}
5973
5974bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
5975 DeclSpec::FriendSpecified IsFriend,
5976 const ParsedTemplateInfo *TemplateInfo) {
5977 RevertingTentativeParsingAction TPA(*this);
5978 // Parse the C++ scope specifier.
5979 CXXScopeSpec SS;
5980 if (TemplateInfo && TemplateInfo->TemplateParams)
5981 SS.setTemplateParamLists(*TemplateInfo->TemplateParams);
5982
5983 if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
5984 /*ObjectHasErrors=*/false,
5985 /*EnteringContext=*/true)) {
5986 return false;
5987 }
5988
5989 // Parse the constructor name.
5990 if (Tok.is(K: tok::identifier)) {
5991 // We already know that we have a constructor name; just consume
5992 // the token.
5993 ConsumeToken();
5994 } else if (Tok.is(K: tok::annot_template_id)) {
5995 ConsumeAnnotationToken();
5996 } else {
5997 return false;
5998 }
5999
6000 // There may be attributes here, appertaining to the constructor name or type
6001 // we just stepped past.
6002 SkipCXX11Attributes();
6003
6004 // Current class name must be followed by a left parenthesis.
6005 if (Tok.isNot(K: tok::l_paren)) {
6006 return false;
6007 }
6008 ConsumeParen();
6009
6010 // A right parenthesis, or ellipsis followed by a right parenthesis signals
6011 // that we have a constructor.
6012 if (Tok.is(K: tok::r_paren) ||
6013 (Tok.is(K: tok::ellipsis) && NextToken().is(K: tok::r_paren))) {
6014 return true;
6015 }
6016
6017 // A C++11 attribute here signals that we have a constructor, and is an
6018 // attribute on the first constructor parameter.
6019 if (getLangOpts().CPlusPlus11 &&
6020 isCXX11AttributeSpecifier(/*Disambiguate*/ false,
6021 /*OuterMightBeMessageSend*/ true) !=
6022 CXX11AttributeKind::NotAttributeSpecifier) {
6023 return true;
6024 }
6025
6026 // If we need to, enter the specified scope.
6027 DeclaratorScopeObj DeclScopeObj(*this, SS);
6028 if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(S: getCurScope(), SS))
6029 DeclScopeObj.EnterDeclaratorScope();
6030
6031 // Optionally skip Microsoft attributes.
6032 ParsedAttributes Attrs(AttrFactory);
6033 MaybeParseMicrosoftAttributes(Attrs);
6034
6035 // Check whether the next token(s) are part of a declaration
6036 // specifier, in which case we have the start of a parameter and,
6037 // therefore, we know that this is a constructor.
6038 // Due to an ambiguity with implicit typename, the above is not enough.
6039 // Additionally, check to see if we are a friend.
6040 // If we parsed a scope specifier as well as friend,
6041 // we might be parsing a friend constructor.
6042 bool IsConstructor = false;
6043 ImplicitTypenameContext ITC = IsFriend && !SS.isSet()
6044 ? ImplicitTypenameContext::No
6045 : ImplicitTypenameContext::Yes;
6046 // Constructors cannot have this parameters, but we support that scenario here
6047 // to improve diagnostic.
6048 if (Tok.is(K: tok::kw_this)) {
6049 ConsumeToken();
6050 return isDeclarationSpecifier(AllowImplicitTypename: ITC);
6051 }
6052
6053 if (isDeclarationSpecifier(AllowImplicitTypename: ITC))
6054 IsConstructor = true;
6055 else if (Tok.is(K: tok::identifier) ||
6056 (Tok.is(K: tok::annot_cxxscope) && NextToken().is(K: tok::identifier))) {
6057 // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
6058 // This might be a parenthesized member name, but is more likely to
6059 // be a constructor declaration with an invalid argument type. Keep
6060 // looking.
6061 if (Tok.is(K: tok::annot_cxxscope))
6062 ConsumeAnnotationToken();
6063 ConsumeToken();
6064
6065 // If this is not a constructor, we must be parsing a declarator,
6066 // which must have one of the following syntactic forms (see the
6067 // grammar extract at the start of ParseDirectDeclarator):
6068 switch (Tok.getKind()) {
6069 case tok::l_paren:
6070 // C(X ( int));
6071 case tok::l_square:
6072 // C(X [ 5]);
6073 // C(X [ [attribute]]);
6074 case tok::coloncolon:
6075 // C(X :: Y);
6076 // C(X :: *p);
6077 // Assume this isn't a constructor, rather than assuming it's a
6078 // constructor with an unnamed parameter of an ill-formed type.
6079 break;
6080
6081 case tok::r_paren:
6082 // C(X )
6083
6084 // Skip past the right-paren and any following attributes to get to
6085 // the function body or trailing-return-type.
6086 ConsumeParen();
6087 SkipCXX11Attributes();
6088
6089 if (DeductionGuide) {
6090 // C(X) -> ... is a deduction guide.
6091 IsConstructor = Tok.is(K: tok::arrow);
6092 break;
6093 }
6094 if (Tok.is(K: tok::colon) || Tok.is(K: tok::kw_try)) {
6095 // Assume these were meant to be constructors:
6096 // C(X) : (the name of a bit-field cannot be parenthesized).
6097 // C(X) try (this is otherwise ill-formed).
6098 IsConstructor = true;
6099 }
6100 if (Tok.is(K: tok::semi) || Tok.is(K: tok::l_brace)) {
6101 // If we have a constructor name within the class definition,
6102 // assume these were meant to be constructors:
6103 // C(X) {
6104 // C(X) ;
6105 // ... because otherwise we would be declaring a non-static data
6106 // member that is ill-formed because it's of the same type as its
6107 // surrounding class.
6108 //
6109 // FIXME: We can actually do this whether or not the name is qualified,
6110 // because if it is qualified in this context it must be being used as
6111 // a constructor name.
6112 // currently, so we're somewhat conservative here.
6113 IsConstructor = IsUnqualified;
6114 }
6115 break;
6116
6117 default:
6118 IsConstructor = true;
6119 break;
6120 }
6121 }
6122 return IsConstructor;
6123}
6124
6125void Parser::ParseTypeQualifierListOpt(
6126 DeclSpec &DS, unsigned AttrReqs, bool AtomicOrPtrauthAllowed,
6127 bool IdentifierRequired, llvm::function_ref<void()> CodeCompletionHandler) {
6128 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6129 isAllowedCXX11AttributeSpecifier()) {
6130 ParsedAttributes Attrs(AttrFactory);
6131 ParseCXX11Attributes(attrs&: Attrs);
6132 DS.takeAttributesFrom(attrs&: Attrs);
6133 }
6134
6135 SourceLocation EndLoc;
6136
6137 while (true) {
6138 bool isInvalid = false;
6139 const char *PrevSpec = nullptr;
6140 unsigned DiagID = 0;
6141 SourceLocation Loc = Tok.getLocation();
6142
6143 switch (Tok.getKind()) {
6144 case tok::code_completion:
6145 cutOffParsing();
6146 if (CodeCompletionHandler)
6147 CodeCompletionHandler();
6148 else
6149 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6150 return;
6151
6152 case tok::kw_const:
6153 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
6154 Lang: getLangOpts());
6155 break;
6156 case tok::kw_volatile:
6157 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
6158 Lang: getLangOpts());
6159 break;
6160 case tok::kw_restrict:
6161 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
6162 Lang: getLangOpts());
6163 break;
6164 case tok::kw__Atomic:
6165 if (!AtomicOrPtrauthAllowed)
6166 goto DoneWithTypeQuals;
6167 diagnoseUseOfC11Keyword(Tok);
6168 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
6169 Lang: getLangOpts());
6170 break;
6171
6172 // OpenCL qualifiers:
6173 case tok::kw_private:
6174 if (!getLangOpts().OpenCL)
6175 goto DoneWithTypeQuals;
6176 [[fallthrough]];
6177 case tok::kw___private:
6178 case tok::kw___global:
6179 case tok::kw___local:
6180 case tok::kw___constant:
6181 case tok::kw___generic:
6182 case tok::kw___read_only:
6183 case tok::kw___write_only:
6184 case tok::kw___read_write:
6185 ParseOpenCLQualifiers(Attrs&: DS.getAttributes());
6186 break;
6187
6188 case tok::kw_groupshared:
6189 case tok::kw_in:
6190 case tok::kw_inout:
6191 case tok::kw_out:
6192 // NOTE: ParseHLSLQualifiers will consume the qualifier token.
6193 ParseHLSLQualifiers(Attrs&: DS.getAttributes());
6194 continue;
6195
6196 // __ptrauth qualifier.
6197 case tok::kw___ptrauth:
6198 if (!AtomicOrPtrauthAllowed)
6199 goto DoneWithTypeQuals;
6200 ParsePtrauthQualifier(Attrs&: DS.getAttributes());
6201 EndLoc = PrevTokLocation;
6202 continue;
6203
6204 case tok::kw___unaligned:
6205 isInvalid = DS.SetTypeQual(T: DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID,
6206 Lang: getLangOpts());
6207 break;
6208 case tok::kw___uptr:
6209 // GNU libc headers in C mode use '__uptr' as an identifier which conflicts
6210 // with the MS modifier keyword.
6211 if ((AttrReqs & AR_DeclspecAttributesParsed) && !getLangOpts().CPlusPlus &&
6212 IdentifierRequired && DS.isEmpty() && NextToken().is(K: tok::semi)) {
6213 if (TryKeywordIdentFallback(DisableKeyword: false))
6214 continue;
6215 }
6216 [[fallthrough]];
6217 case tok::kw___sptr:
6218 case tok::kw___w64:
6219 case tok::kw___ptr64:
6220 case tok::kw___ptr32:
6221 case tok::kw___cdecl:
6222 case tok::kw___stdcall:
6223 case tok::kw___fastcall:
6224 case tok::kw___thiscall:
6225 case tok::kw___regcall:
6226 case tok::kw___vectorcall:
6227 if (AttrReqs & AR_DeclspecAttributesParsed) {
6228 ParseMicrosoftTypeAttributes(attrs&: DS.getAttributes());
6229 continue;
6230 }
6231 goto DoneWithTypeQuals;
6232
6233 case tok::kw___funcref:
6234 ParseWebAssemblyFuncrefTypeAttribute(attrs&: DS.getAttributes());
6235 continue;
6236 goto DoneWithTypeQuals;
6237
6238 case tok::kw___pascal:
6239 if (AttrReqs & AR_VendorAttributesParsed) {
6240 ParseBorlandTypeAttributes(attrs&: DS.getAttributes());
6241 continue;
6242 }
6243 goto DoneWithTypeQuals;
6244
6245 // Nullability type specifiers.
6246 case tok::kw__Nonnull:
6247 case tok::kw__Nullable:
6248 case tok::kw__Nullable_result:
6249 case tok::kw__Null_unspecified:
6250 ParseNullabilityTypeSpecifiers(attrs&: DS.getAttributes());
6251 continue;
6252
6253 // Objective-C 'kindof' types.
6254 case tok::kw___kindof:
6255 DS.getAttributes().addNew(attrName: Tok.getIdentifierInfo(), attrRange: Loc, scopeName: nullptr, scopeLoc: Loc,
6256 args: nullptr, numArgs: 0, form: tok::kw___kindof);
6257 (void)ConsumeToken();
6258 continue;
6259
6260 case tok::kw___attribute:
6261 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6262 // When GNU attributes are expressly forbidden, diagnose their usage.
6263 Diag(Tok, diag::err_attributes_not_allowed);
6264
6265 // Parse the attributes even if they are rejected to ensure that error
6266 // recovery is graceful.
6267 if (AttrReqs & AR_GNUAttributesParsed ||
6268 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6269 ParseGNUAttributes(Attrs&: DS.getAttributes());
6270 continue; // do *not* consume the next token!
6271 }
6272 // otherwise, FALL THROUGH!
6273 [[fallthrough]];
6274 default:
6275 DoneWithTypeQuals:
6276 // If this is not a type-qualifier token, we're done reading type
6277 // qualifiers. First verify that DeclSpec's are consistent.
6278 DS.Finish(S&: Actions, Policy: Actions.getASTContext().getPrintingPolicy());
6279 if (EndLoc.isValid())
6280 DS.SetRangeEnd(EndLoc);
6281 return;
6282 }
6283
6284 // If the specifier combination wasn't legal, issue a diagnostic.
6285 if (isInvalid) {
6286 assert(PrevSpec && "Method did not return previous specifier!");
6287 Diag(Tok, DiagID) << PrevSpec;
6288 }
6289 EndLoc = ConsumeToken();
6290 }
6291}
6292
6293void Parser::ParseDeclarator(Declarator &D) {
6294 /// This implements the 'declarator' production in the C grammar, then checks
6295 /// for well-formedness and issues diagnostics.
6296 Actions.runWithSufficientStackSpace(Loc: D.getBeginLoc(), Fn: [&] {
6297 ParseDeclaratorInternal(D, DirectDeclParser: &Parser::ParseDirectDeclarator);
6298 });
6299}
6300
6301static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang,
6302 DeclaratorContext TheContext) {
6303 if (Kind == tok::star || Kind == tok::caret)
6304 return true;
6305
6306 // OpenCL 2.0 and later define this keyword.
6307 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6308 Lang.getOpenCLCompatibleVersion() >= 200)
6309 return true;
6310
6311 if (!Lang.CPlusPlus)
6312 return false;
6313
6314 if (Kind == tok::amp)
6315 return true;
6316
6317 // We parse rvalue refs in C++03, because otherwise the errors are scary.
6318 // But we must not parse them in conversion-type-ids and new-type-ids, since
6319 // those can be legitimately followed by a && operator.
6320 // (The same thing can in theory happen after a trailing-return-type, but
6321 // since those are a C++11 feature, there is no rejects-valid issue there.)
6322 if (Kind == tok::ampamp)
6323 return Lang.CPlusPlus11 || (TheContext != DeclaratorContext::ConversionId &&
6324 TheContext != DeclaratorContext::CXXNew);
6325
6326 return false;
6327}
6328
6329// Indicates whether the given declarator is a pipe declarator.
6330static bool isPipeDeclarator(const Declarator &D) {
6331 const unsigned NumTypes = D.getNumTypeObjects();
6332
6333 for (unsigned Idx = 0; Idx != NumTypes; ++Idx)
6334 if (DeclaratorChunk::Pipe == D.getTypeObject(i: Idx).Kind)
6335 return true;
6336
6337 return false;
6338}
6339
6340void Parser::ParseDeclaratorInternal(Declarator &D,
6341 DirectDeclParseFunction DirectDeclParser) {
6342 if (Diags.hasAllExtensionsSilenced())
6343 D.setExtension();
6344
6345 // C++ member pointers start with a '::' or a nested-name.
6346 // Member pointers get special handling, since there's no place for the
6347 // scope spec in the generic path below.
6348 if (getLangOpts().CPlusPlus &&
6349 (Tok.is(K: tok::coloncolon) || Tok.is(K: tok::kw_decltype) ||
6350 (Tok.is(K: tok::identifier) &&
6351 (NextToken().is(K: tok::coloncolon) || NextToken().is(K: tok::less))) ||
6352 Tok.is(K: tok::annot_cxxscope))) {
6353 TentativeParsingAction TPA(*this, /*Unannotated=*/true);
6354 bool EnteringContext = D.getContext() == DeclaratorContext::File ||
6355 D.getContext() == DeclaratorContext::Member;
6356 CXXScopeSpec SS;
6357 SS.setTemplateParamLists(D.getTemplateParameterLists());
6358
6359 if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
6360 /*ObjectHasErrors=*/false,
6361 /*EnteringContext=*/false,
6362 /*MayBePseudoDestructor=*/nullptr,
6363 /*IsTypename=*/false, /*LastII=*/nullptr,
6364 /*OnlyNamespace=*/false,
6365 /*InUsingDeclaration=*/false,
6366 /*Disambiguation=*/EnteringContext) ||
6367
6368 SS.isEmpty() || SS.isInvalid() || !EnteringContext ||
6369 Tok.is(K: tok::star)) {
6370 TPA.Commit();
6371 if (SS.isNotEmpty() && Tok.is(K: tok::star)) {
6372 if (SS.isValid()) {
6373 checkCompoundToken(FirstTokLoc: SS.getEndLoc(), FirstTokKind: tok::coloncolon,
6374 Op: CompoundToken::MemberPtr);
6375 }
6376
6377 SourceLocation StarLoc = ConsumeToken();
6378 D.SetRangeEnd(StarLoc);
6379 DeclSpec DS(AttrFactory);
6380 ParseTypeQualifierListOpt(DS);
6381 D.ExtendWithDeclSpec(DS);
6382
6383 // Recurse to parse whatever is left.
6384 Actions.runWithSufficientStackSpace(Loc: D.getBeginLoc(), Fn: [&] {
6385 ParseDeclaratorInternal(D, DirectDeclParser);
6386 });
6387
6388 // Sema will have to catch (syntactically invalid) pointers into global
6389 // scope. It has to catch pointers into namespace scope anyway.
6390 D.AddTypeInfo(TI: DeclaratorChunk::getMemberPointer(
6391 SS, TypeQuals: DS.getTypeQualifiers(), StarLoc, EndLoc: DS.getEndLoc()),
6392 attrs: std::move(DS.getAttributes()),
6393 /*EndLoc=*/SourceLocation());
6394 return;
6395 }
6396 } else {
6397 TPA.Revert();
6398 SS.clear();
6399 ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
6400 /*ObjectHasErrors=*/false,
6401 /*EnteringContext=*/true);
6402 }
6403
6404 if (SS.isNotEmpty()) {
6405 // The scope spec really belongs to the direct-declarator.
6406 if (D.mayHaveIdentifier())
6407 D.getCXXScopeSpec() = SS;
6408 else
6409 AnnotateScopeToken(SS, IsNewAnnotation: true);
6410
6411 if (DirectDeclParser)
6412 (this->*DirectDeclParser)(D);
6413 return;
6414 }
6415 }
6416
6417 tok::TokenKind Kind = Tok.getKind();
6418
6419 if (D.getDeclSpec().isTypeSpecPipe() && !isPipeDeclarator(D)) {
6420 DeclSpec DS(AttrFactory);
6421 ParseTypeQualifierListOpt(DS);
6422
6423 D.AddTypeInfo(
6424 TI: DeclaratorChunk::getPipe(TypeQuals: DS.getTypeQualifiers(), Loc: DS.getPipeLoc()),
6425 attrs: std::move(DS.getAttributes()), EndLoc: SourceLocation());
6426 }
6427
6428 // Not a pointer, C++ reference, or block.
6429 if (!isPtrOperatorToken(Kind, Lang: getLangOpts(), TheContext: D.getContext())) {
6430 if (DirectDeclParser)
6431 (this->*DirectDeclParser)(D);
6432 return;
6433 }
6434
6435 // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
6436 // '&&' -> rvalue reference
6437 SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&.
6438 D.SetRangeEnd(Loc);
6439
6440 if (Kind == tok::star || Kind == tok::caret) {
6441 // Is a pointer.
6442 DeclSpec DS(AttrFactory);
6443
6444 // GNU attributes are not allowed here in a new-type-id, but Declspec and
6445 // C++11 attributes are allowed.
6446 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6447 ((D.getContext() != DeclaratorContext::CXXNew)
6448 ? AR_GNUAttributesParsed
6449 : AR_GNUAttributesParsedAndRejected);
6450 ParseTypeQualifierListOpt(DS, AttrReqs: Reqs, /*AtomicOrPtrauthAllowed=*/true,
6451 IdentifierRequired: !D.mayOmitIdentifier());
6452 D.ExtendWithDeclSpec(DS);
6453
6454 // Recursively parse the declarator.
6455 Actions.runWithSufficientStackSpace(
6456 Loc: D.getBeginLoc(), Fn: [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6457 if (Kind == tok::star)
6458 // Remember that we parsed a pointer type, and remember the type-quals.
6459 D.AddTypeInfo(TI: DeclaratorChunk::getPointer(
6460 TypeQuals: DS.getTypeQualifiers(), Loc, ConstQualLoc: DS.getConstSpecLoc(),
6461 VolatileQualLoc: DS.getVolatileSpecLoc(), RestrictQualLoc: DS.getRestrictSpecLoc(),
6462 AtomicQualLoc: DS.getAtomicSpecLoc(), UnalignedQualLoc: DS.getUnalignedSpecLoc()),
6463 attrs: std::move(DS.getAttributes()), EndLoc: SourceLocation());
6464 else
6465 // Remember that we parsed a Block type, and remember the type-quals.
6466 D.AddTypeInfo(
6467 TI: DeclaratorChunk::getBlockPointer(TypeQuals: DS.getTypeQualifiers(), Loc),
6468 attrs: std::move(DS.getAttributes()), EndLoc: SourceLocation());
6469 } else {
6470 // Is a reference
6471 DeclSpec DS(AttrFactory);
6472
6473 // Complain about rvalue references in C++03, but then go on and build
6474 // the declarator.
6475 if (Kind == tok::ampamp)
6476 Diag(Loc, getLangOpts().CPlusPlus11 ?
6477 diag::warn_cxx98_compat_rvalue_reference :
6478 diag::ext_rvalue_reference);
6479
6480 // GNU-style and C++11 attributes are allowed here, as is restrict.
6481 ParseTypeQualifierListOpt(DS);
6482 D.ExtendWithDeclSpec(DS);
6483
6484 // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
6485 // cv-qualifiers are introduced through the use of a typedef or of a
6486 // template type argument, in which case the cv-qualifiers are ignored.
6487 if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
6488 if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
6489 Diag(DS.getConstSpecLoc(),
6490 diag::err_invalid_reference_qualifier_application) << "const";
6491 if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
6492 Diag(DS.getVolatileSpecLoc(),
6493 diag::err_invalid_reference_qualifier_application) << "volatile";
6494 // 'restrict' is permitted as an extension.
6495 if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
6496 Diag(DS.getAtomicSpecLoc(),
6497 diag::err_invalid_reference_qualifier_application) << "_Atomic";
6498 }
6499
6500 // Recursively parse the declarator.
6501 Actions.runWithSufficientStackSpace(
6502 Loc: D.getBeginLoc(), Fn: [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6503
6504 if (D.getNumTypeObjects() > 0) {
6505 // C++ [dcl.ref]p4: There shall be no references to references.
6506 DeclaratorChunk& InnerChunk = D.getTypeObject(i: D.getNumTypeObjects() - 1);
6507 if (InnerChunk.Kind == DeclaratorChunk::Reference) {
6508 if (const IdentifierInfo *II = D.getIdentifier())
6509 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
6510 << II;
6511 else
6512 Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)
6513 << "type name";
6514
6515 // Once we've complained about the reference-to-reference, we
6516 // can go ahead and build the (technically ill-formed)
6517 // declarator: reference collapsing will take care of it.
6518 }
6519 }
6520
6521 // Remember that we parsed a reference type.
6522 D.AddTypeInfo(TI: DeclaratorChunk::getReference(TypeQuals: DS.getTypeQualifiers(), Loc,
6523 lvalue: Kind == tok::amp),
6524 attrs: std::move(DS.getAttributes()), EndLoc: SourceLocation());
6525 }
6526}
6527
6528// When correcting from misplaced brackets before the identifier, the location
6529// is saved inside the declarator so that other diagnostic messages can use
6530// them. This extracts and returns that location, or returns the provided
6531// location if a stored location does not exist.
6532static SourceLocation getMissingDeclaratorIdLoc(Declarator &D,
6533 SourceLocation Loc) {
6534 if (D.getName().StartLocation.isInvalid() &&
6535 D.getName().EndLocation.isValid())
6536 return D.getName().EndLocation;
6537
6538 return Loc;
6539}
6540
6541void Parser::ParseDirectDeclarator(Declarator &D) {
6542 DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
6543
6544 if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
6545 // This might be a C++17 structured binding.
6546 if (Tok.is(K: tok::l_square) && !D.mayOmitIdentifier() &&
6547 D.getCXXScopeSpec().isEmpty())
6548 return ParseDecompositionDeclarator(D);
6549
6550 // Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a class, in
6551 // this context it is a bitfield. Also in range-based for statement colon
6552 // may delimit for-range-declaration.
6553 ColonProtectionRAIIObject X(
6554 *this, D.getContext() == DeclaratorContext::Member ||
6555 (D.getContext() == DeclaratorContext::ForInit &&
6556 getLangOpts().CPlusPlus11));
6557
6558 // ParseDeclaratorInternal might already have parsed the scope.
6559 if (D.getCXXScopeSpec().isEmpty()) {
6560 bool EnteringContext = D.getContext() == DeclaratorContext::File ||
6561 D.getContext() == DeclaratorContext::Member;
6562 ParseOptionalCXXScopeSpecifier(
6563 SS&: D.getCXXScopeSpec(), /*ObjectType=*/nullptr,
6564 /*ObjectHasErrors=*/false, EnteringContext);
6565 }
6566
6567 // C++23 [basic.scope.namespace]p1:
6568 // For each non-friend redeclaration or specialization whose target scope
6569 // is or is contained by the scope, the portion after the declarator-id,
6570 // class-head-name, or enum-head-name is also included in the scope.
6571 // C++23 [basic.scope.class]p1:
6572 // For each non-friend redeclaration or specialization whose target scope
6573 // is or is contained by the scope, the portion after the declarator-id,
6574 // class-head-name, or enum-head-name is also included in the scope.
6575 //
6576 // FIXME: We should not be doing this for friend declarations; they have
6577 // their own special lookup semantics specified by [basic.lookup.unqual]p6.
6578 if (D.getCXXScopeSpec().isValid()) {
6579 if (Actions.ShouldEnterDeclaratorScope(S: getCurScope(),
6580 SS: D.getCXXScopeSpec()))
6581 // Change the declaration context for name lookup, until this function
6582 // is exited (and the declarator has been parsed).
6583 DeclScopeObj.EnterDeclaratorScope();
6584 else if (getObjCDeclContext()) {
6585 // Ensure that we don't interpret the next token as an identifier when
6586 // dealing with declarations in an Objective-C container.
6587 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
6588 D.setInvalidType(true);
6589 ConsumeToken();
6590 goto PastIdentifier;
6591 }
6592 }
6593
6594 // C++0x [dcl.fct]p14:
6595 // There is a syntactic ambiguity when an ellipsis occurs at the end of a
6596 // parameter-declaration-clause without a preceding comma. In this case,
6597 // the ellipsis is parsed as part of the abstract-declarator if the type
6598 // of the parameter either names a template parameter pack that has not
6599 // been expanded or contains auto; otherwise, it is parsed as part of the
6600 // parameter-declaration-clause.
6601 if (Tok.is(K: tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&
6602 !((D.getContext() == DeclaratorContext::Prototype ||
6603 D.getContext() == DeclaratorContext::LambdaExprParameter ||
6604 D.getContext() == DeclaratorContext::BlockLiteral) &&
6605 NextToken().is(K: tok::r_paren) && !D.hasGroupingParens() &&
6606 !Actions.containsUnexpandedParameterPacks(D) &&
6607 D.getDeclSpec().getTypeSpecType() != TST_auto)) {
6608 SourceLocation EllipsisLoc = ConsumeToken();
6609 if (isPtrOperatorToken(Kind: Tok.getKind(), Lang: getLangOpts(), TheContext: D.getContext())) {
6610 // The ellipsis was put in the wrong place. Recover, and explain to
6611 // the user what they should have done.
6612 ParseDeclarator(D);
6613 if (EllipsisLoc.isValid())
6614 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6615 return;
6616 } else
6617 D.setEllipsisLoc(EllipsisLoc);
6618
6619 // The ellipsis can't be followed by a parenthesized declarator. We
6620 // check for that in ParseParenDeclarator, after we have disambiguated
6621 // the l_paren token.
6622 }
6623
6624 if (Tok.isOneOf(K1: tok::identifier, Ks: tok::kw_operator, Ks: tok::annot_template_id,
6625 Ks: tok::tilde)) {
6626 // We found something that indicates the start of an unqualified-id.
6627 // Parse that unqualified-id.
6628 bool AllowConstructorName;
6629 bool AllowDeductionGuide;
6630 if (D.getDeclSpec().hasTypeSpecifier()) {
6631 AllowConstructorName = false;
6632 AllowDeductionGuide = false;
6633 } else if (D.getCXXScopeSpec().isSet()) {
6634 AllowConstructorName = (D.getContext() == DeclaratorContext::File ||
6635 D.getContext() == DeclaratorContext::Member);
6636 AllowDeductionGuide = false;
6637 } else {
6638 AllowConstructorName = (D.getContext() == DeclaratorContext::Member);
6639 AllowDeductionGuide = (D.getContext() == DeclaratorContext::File ||
6640 D.getContext() == DeclaratorContext::Member);
6641 }
6642
6643 bool HadScope = D.getCXXScopeSpec().isValid();
6644 SourceLocation TemplateKWLoc;
6645 if (ParseUnqualifiedId(SS&: D.getCXXScopeSpec(),
6646 /*ObjectType=*/nullptr,
6647 /*ObjectHadErrors=*/false,
6648 /*EnteringContext=*/true,
6649 /*AllowDestructorName=*/true, AllowConstructorName,
6650 AllowDeductionGuide, TemplateKWLoc: &TemplateKWLoc,
6651 Result&: D.getName()) ||
6652 // Once we're past the identifier, if the scope was bad, mark the
6653 // whole declarator bad.
6654 D.getCXXScopeSpec().isInvalid()) {
6655 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
6656 D.setInvalidType(true);
6657 } else {
6658 // ParseUnqualifiedId might have parsed a scope specifier during error
6659 // recovery. If it did so, enter that scope.
6660 if (!HadScope && D.getCXXScopeSpec().isValid() &&
6661 Actions.ShouldEnterDeclaratorScope(S: getCurScope(),
6662 SS: D.getCXXScopeSpec()))
6663 DeclScopeObj.EnterDeclaratorScope();
6664
6665 // Parsed the unqualified-id; update range information and move along.
6666 if (D.getSourceRange().getBegin().isInvalid())
6667 D.SetRangeBegin(D.getName().getSourceRange().getBegin());
6668 D.SetRangeEnd(D.getName().getSourceRange().getEnd());
6669 }
6670 goto PastIdentifier;
6671 }
6672
6673 if (D.getCXXScopeSpec().isNotEmpty()) {
6674 // We have a scope specifier but no following unqualified-id.
6675 Diag(PP.getLocForEndOfToken(D.getCXXScopeSpec().getEndLoc()),
6676 diag::err_expected_unqualified_id)
6677 << /*C++*/1;
6678 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
6679 goto PastIdentifier;
6680 }
6681 } else if (Tok.is(K: tok::identifier) && D.mayHaveIdentifier()) {
6682 assert(!getLangOpts().CPlusPlus &&
6683 "There's a C++-specific check for tok::identifier above");
6684 assert(Tok.getIdentifierInfo() && "Not an identifier?");
6685 D.SetIdentifier(Id: Tok.getIdentifierInfo(), IdLoc: Tok.getLocation());
6686 D.SetRangeEnd(Tok.getLocation());
6687 ConsumeToken();
6688 goto PastIdentifier;
6689 } else if (Tok.is(K: tok::identifier) && !D.mayHaveIdentifier()) {
6690 // We're not allowed an identifier here, but we got one. Try to figure out
6691 // if the user was trying to attach a name to the type, or whether the name
6692 // is some unrelated trailing syntax.
6693 bool DiagnoseIdentifier = false;
6694 if (D.hasGroupingParens())
6695 // An identifier within parens is unlikely to be intended to be anything
6696 // other than a name being "declared".
6697 DiagnoseIdentifier = true;
6698 else if (D.getContext() == DeclaratorContext::TemplateArg)
6699 // T<int N> is an accidental identifier; T<int N indicates a missing '>'.
6700 DiagnoseIdentifier =
6701 NextToken().isOneOf(K1: tok::comma, Ks: tok::greater, Ks: tok::greatergreater);
6702 else if (D.getContext() == DeclaratorContext::AliasDecl ||
6703 D.getContext() == DeclaratorContext::AliasTemplate)
6704 // The most likely error is that the ';' was forgotten.
6705 DiagnoseIdentifier = NextToken().isOneOf(K1: tok::comma, K2: tok::semi);
6706 else if ((D.getContext() == DeclaratorContext::TrailingReturn ||
6707 D.getContext() == DeclaratorContext::TrailingReturnVar) &&
6708 !isCXX11VirtSpecifier(Tok))
6709 DiagnoseIdentifier = NextToken().isOneOf(
6710 K1: tok::comma, Ks: tok::semi, Ks: tok::equal, Ks: tok::l_brace, Ks: tok::kw_try);
6711 if (DiagnoseIdentifier) {
6712 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6713 << FixItHint::CreateRemoval(Tok.getLocation());
6714 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
6715 ConsumeToken();
6716 goto PastIdentifier;
6717 }
6718 }
6719
6720 if (Tok.is(K: tok::l_paren)) {
6721 // If this might be an abstract-declarator followed by a direct-initializer,
6722 // check whether this is a valid declarator chunk. If it can't be, assume
6723 // that it's an initializer instead.
6724 if (D.mayOmitIdentifier() && D.mayBeFollowedByCXXDirectInit()) {
6725 RevertingTentativeParsingAction PA(*this);
6726 if (TryParseDeclarator(mayBeAbstract: true, mayHaveIdentifier: D.mayHaveIdentifier(), mayHaveDirectInit: true,
6727 mayHaveTrailingReturnType: D.getDeclSpec().getTypeSpecType() == TST_auto) ==
6728 TPResult::False) {
6729 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
6730 goto PastIdentifier;
6731 }
6732 }
6733
6734 // direct-declarator: '(' declarator ')'
6735 // direct-declarator: '(' attributes declarator ')'
6736 // Example: 'char (*X)' or 'int (*XX)(void)'
6737 ParseParenDeclarator(D);
6738
6739 // If the declarator was parenthesized, we entered the declarator
6740 // scope when parsing the parenthesized declarator, then exited
6741 // the scope already. Re-enter the scope, if we need to.
6742 if (D.getCXXScopeSpec().isSet()) {
6743 // If there was an error parsing parenthesized declarator, declarator
6744 // scope may have been entered before. Don't do it again.
6745 if (!D.isInvalidType() &&
6746 Actions.ShouldEnterDeclaratorScope(S: getCurScope(),
6747 SS: D.getCXXScopeSpec()))
6748 // Change the declaration context for name lookup, until this function
6749 // is exited (and the declarator has been parsed).
6750 DeclScopeObj.EnterDeclaratorScope();
6751 }
6752 } else if (D.mayOmitIdentifier()) {
6753 // This could be something simple like "int" (in which case the declarator
6754 // portion is empty), if an abstract-declarator is allowed.
6755 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
6756
6757 // The grammar for abstract-pack-declarator does not allow grouping parens.
6758 // FIXME: Revisit this once core issue 1488 is resolved.
6759 if (D.hasEllipsis() && D.hasGroupingParens())
6760 Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()),
6761 diag::ext_abstract_pack_declarator_parens);
6762 } else {
6763 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6764 LLVM_BUILTIN_TRAP;
6765 if (Tok.is(K: tok::l_square))
6766 return ParseMisplacedBracketDeclarator(D);
6767 if (D.getContext() == DeclaratorContext::Member) {
6768 // Objective-C++: Detect C++ keywords and try to prevent further errors by
6769 // treating these keyword as valid member names.
6770 if (getLangOpts().ObjC && getLangOpts().CPlusPlus &&
6771 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6772 Tok.getIdentifierInfo()->isCPlusPlusKeyword(LangOpts: getLangOpts())) {
6773 Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
6774 diag::err_expected_member_name_or_semi_objcxx_keyword)
6775 << Tok.getIdentifierInfo()
6776 << (D.getDeclSpec().isEmpty() ? SourceRange()
6777 : D.getDeclSpec().getSourceRange());
6778 D.SetIdentifier(Id: Tok.getIdentifierInfo(), IdLoc: Tok.getLocation());
6779 D.SetRangeEnd(Tok.getLocation());
6780 ConsumeToken();
6781 goto PastIdentifier;
6782 }
6783 Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
6784 diag::err_expected_member_name_or_semi)
6785 << (D.getDeclSpec().isEmpty() ? SourceRange()
6786 : D.getDeclSpec().getSourceRange());
6787 } else {
6788 if (Tok.getKind() == tok::TokenKind::kw_while) {
6789 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6790 } else if (getLangOpts().CPlusPlus) {
6791 if (Tok.isOneOf(K1: tok::period, K2: tok::arrow))
6792 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6793 else {
6794 SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();
6795 if (Tok.isAtStartOfLine() && Loc.isValid())
6796 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6797 << getLangOpts().CPlusPlus;
6798 else
6799 Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
6800 diag::err_expected_unqualified_id)
6801 << getLangOpts().CPlusPlus;
6802 }
6803 } else {
6804 Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
6805 diag::err_expected_either)
6806 << tok::identifier << tok::l_paren;
6807 }
6808 }
6809 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
6810 D.setInvalidType(true);
6811 }
6812
6813 PastIdentifier:
6814 assert(D.isPastIdentifier() &&
6815 "Haven't past the location of the identifier yet?");
6816
6817 // Don't parse attributes unless we have parsed an unparenthesized name.
6818 if (D.hasName() && !D.getNumTypeObjects())
6819 MaybeParseCXX11Attributes(D);
6820
6821 while (true) {
6822 if (Tok.is(K: tok::l_paren)) {
6823 bool IsFunctionDeclaration = D.isFunctionDeclaratorAFunctionDeclaration();
6824 // Enter function-declaration scope, limiting any declarators to the
6825 // function prototype scope, including parameter declarators.
6826 ParseScope PrototypeScope(this,
6827 Scope::FunctionPrototypeScope|Scope::DeclScope|
6828 (IsFunctionDeclaration
6829 ? Scope::FunctionDeclarationScope : 0));
6830
6831 // The paren may be part of a C++ direct initializer, eg. "int x(1);".
6832 // In such a case, check if we actually have a function declarator; if it
6833 // is not, the declarator has been fully parsed.
6834 bool IsAmbiguous = false;
6835 if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
6836 // C++2a [temp.res]p5
6837 // A qualified-id is assumed to name a type if
6838 // - [...]
6839 // - it is a decl-specifier of the decl-specifier-seq of a
6840 // - [...]
6841 // - parameter-declaration in a member-declaration [...]
6842 // - parameter-declaration in a declarator of a function or function
6843 // template declaration whose declarator-id is qualified [...]
6844 auto AllowImplicitTypename = ImplicitTypenameContext::No;
6845 if (D.getCXXScopeSpec().isSet())
6846 AllowImplicitTypename =
6847 (ImplicitTypenameContext)Actions.isDeclaratorFunctionLike(D);
6848 else if (D.getContext() == DeclaratorContext::Member) {
6849 AllowImplicitTypename = ImplicitTypenameContext::Yes;
6850 }
6851
6852 // The name of the declarator, if any, is tentatively declared within
6853 // a possible direct initializer.
6854 TentativelyDeclaredIdentifiers.push_back(Elt: D.getIdentifier());
6855 bool IsFunctionDecl =
6856 isCXXFunctionDeclarator(IsAmbiguous: &IsAmbiguous, AllowImplicitTypename);
6857 TentativelyDeclaredIdentifiers.pop_back();
6858 if (!IsFunctionDecl)
6859 break;
6860 }
6861 ParsedAttributes attrs(AttrFactory);
6862 BalancedDelimiterTracker T(*this, tok::l_paren);
6863 T.consumeOpen();
6864 if (IsFunctionDeclaration)
6865 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6866 TemplateParameterDepth);
6867 ParseFunctionDeclarator(D, FirstArgAttrs&: attrs, Tracker&: T, IsAmbiguous);
6868 if (IsFunctionDeclaration)
6869 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6870 PrototypeScope.Exit();
6871 } else if (Tok.is(K: tok::l_square)) {
6872 ParseBracketDeclarator(D);
6873 } else if (Tok.isRegularKeywordAttribute()) {
6874 // For consistency with attribute parsing.
6875 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6876 bool TakesArgs = doesKeywordAttributeTakeArgs(Kind: Tok.getKind());
6877 ConsumeToken();
6878 if (TakesArgs) {
6879 BalancedDelimiterTracker T(*this, tok::l_paren);
6880 if (!T.consumeOpen())
6881 T.skipToEnd();
6882 }
6883 } else if (Tok.is(K: tok::kw_requires) && D.hasGroupingParens()) {
6884 // This declarator is declaring a function, but the requires clause is
6885 // in the wrong place:
6886 // void (f() requires true);
6887 // instead of
6888 // void f() requires true;
6889 // or
6890 // void (f()) requires true;
6891 Diag(Tok, diag::err_requires_clause_inside_parens);
6892 ConsumeToken();
6893 ExprResult TrailingRequiresClause = Actions.CorrectDelayedTyposInExpr(
6894 ER: ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true));
6895 if (TrailingRequiresClause.isUsable() && D.isFunctionDeclarator() &&
6896 !D.hasTrailingRequiresClause())
6897 // We're already ill-formed if we got here but we'll accept it anyway.
6898 D.setTrailingRequiresClause(TrailingRequiresClause.get());
6899 } else {
6900 break;
6901 }
6902 }
6903}
6904
6905void Parser::ParseDecompositionDeclarator(Declarator &D) {
6906 assert(Tok.is(tok::l_square));
6907
6908 TentativeParsingAction PA(*this);
6909 BalancedDelimiterTracker T(*this, tok::l_square);
6910 T.consumeOpen();
6911
6912 if (isCXX11AttributeSpecifier() != CXX11AttributeKind::NotAttributeSpecifier)
6913 DiagnoseAndSkipCXX11Attributes();
6914
6915 // If this doesn't look like a structured binding, maybe it's a misplaced
6916 // array declarator.
6917 if (!(Tok.isOneOf(K1: tok::identifier, K2: tok::ellipsis) &&
6918 NextToken().isOneOf(K1: tok::comma, Ks: tok::r_square, Ks: tok::kw_alignas,
6919 Ks: tok::identifier, Ks: tok::l_square, Ks: tok::ellipsis)) &&
6920 !(Tok.is(K: tok::r_square) &&
6921 NextToken().isOneOf(K1: tok::equal, K2: tok::l_brace))) {
6922 PA.Revert();
6923 return ParseMisplacedBracketDeclarator(D);
6924 }
6925
6926 SourceLocation PrevEllipsisLoc;
6927 SmallVector<DecompositionDeclarator::Binding, 32> Bindings;
6928 while (Tok.isNot(K: tok::r_square)) {
6929 if (!Bindings.empty()) {
6930 if (Tok.is(K: tok::comma))
6931 ConsumeToken();
6932 else {
6933 if (Tok.is(K: tok::identifier)) {
6934 SourceLocation EndLoc = getEndOfPreviousToken();
6935 Diag(EndLoc, diag::err_expected)
6936 << tok::comma << FixItHint::CreateInsertion(EndLoc, ",");
6937 } else {
6938 Diag(Tok, diag::err_expected_comma_or_rsquare);
6939 }
6940
6941 SkipUntil(Toks: {tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6942 Flags: StopAtSemi | StopBeforeMatch);
6943 if (Tok.is(K: tok::comma))
6944 ConsumeToken();
6945 else if (Tok.is(K: tok::r_square))
6946 break;
6947 }
6948 }
6949
6950 if (isCXX11AttributeSpecifier() !=
6951 CXX11AttributeKind::NotAttributeSpecifier)
6952 DiagnoseAndSkipCXX11Attributes();
6953
6954 SourceLocation EllipsisLoc;
6955
6956 if (Tok.is(K: tok::ellipsis)) {
6957 Diag(Tok, getLangOpts().CPlusPlus26 ? diag::warn_cxx23_compat_binding_pack
6958 : diag::ext_cxx_binding_pack);
6959 if (PrevEllipsisLoc.isValid()) {
6960 Diag(Tok, diag::err_binding_multiple_ellipses);
6961 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
6962 break;
6963 }
6964 EllipsisLoc = Tok.getLocation();
6965 PrevEllipsisLoc = EllipsisLoc;
6966 ConsumeToken();
6967 }
6968
6969 if (Tok.isNot(K: tok::identifier)) {
6970 Diag(Tok, diag::err_expected) << tok::identifier;
6971 break;
6972 }
6973
6974 IdentifierInfo *II = Tok.getIdentifierInfo();
6975 SourceLocation Loc = Tok.getLocation();
6976 ConsumeToken();
6977
6978 if (Tok.is(K: tok::ellipsis) && !PrevEllipsisLoc.isValid()) {
6979 DiagnoseMisplacedEllipsis(EllipsisLoc: Tok.getLocation(), CorrectLoc: Loc, AlreadyHasEllipsis: EllipsisLoc.isValid(),
6980 IdentifierHasName: true);
6981 EllipsisLoc = Tok.getLocation();
6982 ConsumeToken();
6983 }
6984
6985 ParsedAttributes Attrs(AttrFactory);
6986 if (isCXX11AttributeSpecifier() !=
6987 CXX11AttributeKind::NotAttributeSpecifier) {
6988 Diag(Tok, getLangOpts().CPlusPlus26
6989 ? diag::warn_cxx23_compat_decl_attrs_on_binding
6990 : diag::ext_decl_attrs_on_binding);
6991 MaybeParseCXX11Attributes(Attrs);
6992 }
6993
6994 Bindings.push_back(Elt: {.Name: II, .NameLoc: Loc, .Attrs: std::move(Attrs), .EllipsisLoc: EllipsisLoc});
6995 }
6996
6997 if (Tok.isNot(K: tok::r_square))
6998 // We've already diagnosed a problem here.
6999 T.skipToEnd();
7000 else {
7001 // C++17 does not allow the identifier-list in a structured binding
7002 // to be empty.
7003 if (Bindings.empty())
7004 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7005
7006 T.consumeClose();
7007 }
7008
7009 PA.Commit();
7010
7011 return D.setDecompositionBindings(LSquareLoc: T.getOpenLocation(), Bindings,
7012 RSquareLoc: T.getCloseLocation());
7013}
7014
7015void Parser::ParseParenDeclarator(Declarator &D) {
7016 BalancedDelimiterTracker T(*this, tok::l_paren);
7017 T.consumeOpen();
7018
7019 assert(!D.isPastIdentifier() && "Should be called before passing identifier");
7020
7021 // Eat any attributes before we look at whether this is a grouping or function
7022 // declarator paren. If this is a grouping paren, the attribute applies to
7023 // the type being built up, for example:
7024 // int (__attribute__(()) *x)(long y)
7025 // If this ends up not being a grouping paren, the attribute applies to the
7026 // first argument, for example:
7027 // int (__attribute__(()) int x)
7028 // In either case, we need to eat any attributes to be able to determine what
7029 // sort of paren this is.
7030 //
7031 ParsedAttributes attrs(AttrFactory);
7032 bool RequiresArg = false;
7033 if (Tok.is(K: tok::kw___attribute)) {
7034 ParseGNUAttributes(Attrs&: attrs);
7035
7036 // We require that the argument list (if this is a non-grouping paren) be
7037 // present even if the attribute list was empty.
7038 RequiresArg = true;
7039 }
7040
7041 // Eat any Microsoft extensions.
7042 ParseMicrosoftTypeAttributes(attrs);
7043
7044 // Eat any Borland extensions.
7045 if (Tok.is(K: tok::kw___pascal))
7046 ParseBorlandTypeAttributes(attrs);
7047
7048 // If we haven't past the identifier yet (or where the identifier would be
7049 // stored, if this is an abstract declarator), then this is probably just
7050 // grouping parens. However, if this could be an abstract-declarator, then
7051 // this could also be the start of function arguments (consider 'void()').
7052 bool isGrouping;
7053
7054 if (!D.mayOmitIdentifier()) {
7055 // If this can't be an abstract-declarator, this *must* be a grouping
7056 // paren, because we haven't seen the identifier yet.
7057 isGrouping = true;
7058 } else if (Tok.is(K: tok::r_paren) || // 'int()' is a function.
7059 (getLangOpts().CPlusPlus && Tok.is(K: tok::ellipsis) &&
7060 NextToken().is(K: tok::r_paren)) || // C++ int(...)
7061 isDeclarationSpecifier(
7062 AllowImplicitTypename: ImplicitTypenameContext::No) || // 'int(int)' is a function.
7063 isCXX11AttributeSpecifier() !=
7064 CXX11AttributeKind::NotAttributeSpecifier) { // 'int([[]]int)'
7065 // is a function.
7066 // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
7067 // considered to be a type, not a K&R identifier-list.
7068 isGrouping = false;
7069 } else {
7070 // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.
7071 isGrouping = true;
7072 }
7073
7074 // If this is a grouping paren, handle:
7075 // direct-declarator: '(' declarator ')'
7076 // direct-declarator: '(' attributes declarator ')'
7077 if (isGrouping) {
7078 SourceLocation EllipsisLoc = D.getEllipsisLoc();
7079 D.setEllipsisLoc(SourceLocation());
7080
7081 bool hadGroupingParens = D.hasGroupingParens();
7082 D.setGroupingParens(true);
7083 ParseDeclaratorInternal(D, DirectDeclParser: &Parser::ParseDirectDeclarator);
7084 // Match the ')'.
7085 T.consumeClose();
7086 D.AddTypeInfo(
7087 TI: DeclaratorChunk::getParen(LParenLoc: T.getOpenLocation(), RParenLoc: T.getCloseLocation()),
7088 attrs: std::move(attrs), EndLoc: T.getCloseLocation());
7089
7090 D.setGroupingParens(hadGroupingParens);
7091
7092 // An ellipsis cannot be placed outside parentheses.
7093 if (EllipsisLoc.isValid())
7094 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7095
7096 return;
7097 }
7098
7099 // Okay, if this wasn't a grouping paren, it must be the start of a function
7100 // argument list. Recognize that this declarator will never have an
7101 // identifier (and remember where it would have been), then call into
7102 // ParseFunctionDeclarator to handle of argument list.
7103 D.SetIdentifier(Id: nullptr, IdLoc: Tok.getLocation());
7104
7105 // Enter function-declaration scope, limiting any declarators to the
7106 // function prototype scope, including parameter declarators.
7107 ParseScope PrototypeScope(this,
7108 Scope::FunctionPrototypeScope | Scope::DeclScope |
7109 (D.isFunctionDeclaratorAFunctionDeclaration()
7110 ? Scope::FunctionDeclarationScope : 0));
7111 ParseFunctionDeclarator(D, FirstArgAttrs&: attrs, Tracker&: T, IsAmbiguous: false, RequiresArg);
7112 PrototypeScope.Exit();
7113}
7114
7115void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7116 const Declarator &D, const DeclSpec &DS,
7117 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7118 // C++11 [expr.prim.general]p3:
7119 // If a declaration declares a member function or member function
7120 // template of a class X, the expression this is a prvalue of type
7121 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
7122 // and the end of the function-definition, member-declarator, or
7123 // declarator.
7124 // FIXME: currently, "static" case isn't handled correctly.
7125 bool IsCXX11MemberFunction =
7126 getLangOpts().CPlusPlus11 &&
7127 D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
7128 (D.getContext() == DeclaratorContext::Member
7129 ? !D.getDeclSpec().isFriendSpecified()
7130 : D.getContext() == DeclaratorContext::File &&
7131 D.getCXXScopeSpec().isValid() &&
7132 Actions.CurContext->isRecord());
7133 if (!IsCXX11MemberFunction)
7134 return;
7135
7136 Qualifiers Q = Qualifiers::fromCVRUMask(CVRU: DS.getTypeQualifiers());
7137 if (D.getDeclSpec().hasConstexprSpecifier() && !getLangOpts().CPlusPlus14)
7138 Q.addConst();
7139 // FIXME: Collect C++ address spaces.
7140 // If there are multiple different address spaces, the source is invalid.
7141 // Carry on using the first addr space for the qualifiers of 'this'.
7142 // The diagnostic will be given later while creating the function
7143 // prototype for the method.
7144 if (getLangOpts().OpenCLCPlusPlus) {
7145 for (ParsedAttr &attr : DS.getAttributes()) {
7146 LangAS ASIdx = attr.asOpenCLLangAS();
7147 if (ASIdx != LangAS::Default) {
7148 Q.addAddressSpace(space: ASIdx);
7149 break;
7150 }
7151 }
7152 }
7153 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Val: Actions.CurContext), Q,
7154 IsCXX11MemberFunction);
7155}
7156
7157void Parser::ParseFunctionDeclarator(Declarator &D,
7158 ParsedAttributes &FirstArgAttrs,
7159 BalancedDelimiterTracker &Tracker,
7160 bool IsAmbiguous,
7161 bool RequiresArg) {
7162 assert(getCurScope()->isFunctionPrototypeScope() &&
7163 "Should call from a Function scope");
7164 // lparen is already consumed!
7165 assert(D.isPastIdentifier() && "Should not call before identifier!");
7166
7167 // This should be true when the function has typed arguments.
7168 // Otherwise, it is treated as a K&R-style function.
7169 bool HasProto = false;
7170 // Build up an array of information about the parsed arguments.
7171 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7172 // Remember where we see an ellipsis, if any.
7173 SourceLocation EllipsisLoc;
7174
7175 DeclSpec DS(AttrFactory);
7176 bool RefQualifierIsLValueRef = true;
7177 SourceLocation RefQualifierLoc;
7178 ExceptionSpecificationType ESpecType = EST_None;
7179 SourceRange ESpecRange;
7180 SmallVector<ParsedType, 2> DynamicExceptions;
7181 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7182 ExprResult NoexceptExpr;
7183 CachedTokens *ExceptionSpecTokens = nullptr;
7184 ParsedAttributes FnAttrs(AttrFactory);
7185 TypeResult TrailingReturnType;
7186 SourceLocation TrailingReturnTypeLoc;
7187
7188 /* LocalEndLoc is the end location for the local FunctionTypeLoc.
7189 EndLoc is the end location for the function declarator.
7190 They differ for trailing return types. */
7191 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7192 SourceLocation LParenLoc, RParenLoc;
7193 LParenLoc = Tracker.getOpenLocation();
7194 StartLoc = LParenLoc;
7195
7196 if (isFunctionDeclaratorIdentifierList()) {
7197 if (RequiresArg)
7198 Diag(Tok, diag::err_argument_required_after_attribute);
7199
7200 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7201
7202 Tracker.consumeClose();
7203 RParenLoc = Tracker.getCloseLocation();
7204 LocalEndLoc = RParenLoc;
7205 EndLoc = RParenLoc;
7206
7207 // If there are attributes following the identifier list, parse them and
7208 // prohibit them.
7209 MaybeParseCXX11Attributes(Attrs&: FnAttrs);
7210 ProhibitAttributes(Attrs&: FnAttrs);
7211 } else {
7212 if (Tok.isNot(K: tok::r_paren))
7213 ParseParameterDeclarationClause(D, attrs&: FirstArgAttrs, ParamInfo, EllipsisLoc);
7214 else if (RequiresArg)
7215 Diag(Tok, diag::err_argument_required_after_attribute);
7216
7217 // OpenCL disallows functions without a prototype, but it doesn't enforce
7218 // strict prototypes as in C23 because it allows a function definition to
7219 // have an identifier list. See OpenCL 3.0 6.11/g for more details.
7220 HasProto = ParamInfo.size() || getLangOpts().requiresStrictPrototypes() ||
7221 getLangOpts().OpenCL;
7222
7223 // If we have the closing ')', eat it.
7224 Tracker.consumeClose();
7225 RParenLoc = Tracker.getCloseLocation();
7226 LocalEndLoc = RParenLoc;
7227 EndLoc = RParenLoc;
7228
7229 if (getLangOpts().CPlusPlus) {
7230 // FIXME: Accept these components in any order, and produce fixits to
7231 // correct the order if the user gets it wrong. Ideally we should deal
7232 // with the pure-specifier in the same way.
7233
7234 // Parse cv-qualifier-seq[opt].
7235 ParseTypeQualifierListOpt(
7236 DS, AttrReqs: AR_NoAttributesParsed,
7237 /*AtomicOrPtrauthAllowed=*/false,
7238 /*IdentifierRequired=*/false, CodeCompletionHandler: [&]() {
7239 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7240 });
7241 if (!DS.getSourceRange().getEnd().isInvalid()) {
7242 EndLoc = DS.getSourceRange().getEnd();
7243 }
7244
7245 // Parse ref-qualifier[opt].
7246 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7247 EndLoc = RefQualifierLoc;
7248
7249 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7250 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7251
7252 // C++ [class.mem.general]p8:
7253 // A complete-class context of a class (template) is a
7254 // - function body,
7255 // - default argument,
7256 // - default template argument,
7257 // - noexcept-specifier, or
7258 // - default member initializer
7259 // within the member-specification of the class or class template.
7260 //
7261 // Parse exception-specification[opt]. If we are in the
7262 // member-specification of a class or class template, this is a
7263 // complete-class context and parsing of the noexcept-specifier should be
7264 // delayed (even if this is a friend declaration).
7265 bool Delayed = D.getContext() == DeclaratorContext::Member &&
7266 D.isFunctionDeclaratorAFunctionDeclaration();
7267 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7268 GetLookAheadToken(N: 0).is(K: tok::kw_noexcept) &&
7269 GetLookAheadToken(N: 1).is(K: tok::l_paren) &&
7270 GetLookAheadToken(N: 2).is(K: tok::kw_noexcept) &&
7271 GetLookAheadToken(N: 3).is(K: tok::l_paren) &&
7272 GetLookAheadToken(N: 4).is(K: tok::identifier) &&
7273 GetLookAheadToken(N: 4).getIdentifierInfo()->isStr(Str: "swap")) {
7274 // HACK: We've got an exception-specification
7275 // noexcept(noexcept(swap(...)))
7276 // or
7277 // noexcept(noexcept(swap(...)) && noexcept(swap(...)))
7278 // on a 'swap' member function. This is a libstdc++ bug; the lookup
7279 // for 'swap' will only find the function we're currently declaring,
7280 // whereas it expects to find a non-member swap through ADL. Turn off
7281 // delayed parsing to give it a chance to find what it expects.
7282 Delayed = false;
7283 }
7284 ESpecType = tryParseExceptionSpecification(Delayed,
7285 SpecificationRange&: ESpecRange,
7286 DynamicExceptions,
7287 DynamicExceptionRanges,
7288 NoexceptExpr,
7289 ExceptionSpecTokens);
7290 if (ESpecType != EST_None)
7291 EndLoc = ESpecRange.getEnd();
7292
7293 // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes
7294 // after the exception-specification.
7295 MaybeParseCXX11Attributes(Attrs&: FnAttrs);
7296
7297 // Parse trailing-return-type[opt].
7298 LocalEndLoc = EndLoc;
7299 if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::arrow)) {
7300 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7301 if (D.getDeclSpec().getTypeSpecType() == TST_auto)
7302 StartLoc = D.getDeclSpec().getTypeSpecTypeLoc();
7303 LocalEndLoc = Tok.getLocation();
7304 SourceRange Range;
7305 TrailingReturnType =
7306 ParseTrailingReturnType(Range, MayBeFollowedByDirectInit: D.mayBeFollowedByCXXDirectInit());
7307 TrailingReturnTypeLoc = Range.getBegin();
7308 EndLoc = Range.getEnd();
7309 }
7310 } else {
7311 MaybeParseCXX11Attributes(Attrs&: FnAttrs);
7312 }
7313 }
7314
7315 // Collect non-parameter declarations from the prototype if this is a function
7316 // declaration. They will be moved into the scope of the function. Only do
7317 // this in C and not C++, where the decls will continue to live in the
7318 // surrounding context.
7319 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7320 if (getCurScope()->isFunctionDeclarationScope() && !getLangOpts().CPlusPlus) {
7321 for (Decl *D : getCurScope()->decls()) {
7322 NamedDecl *ND = dyn_cast<NamedDecl>(Val: D);
7323 if (!ND || isa<ParmVarDecl>(Val: ND))
7324 continue;
7325 DeclsInPrototype.push_back(Elt: ND);
7326 }
7327 // Sort DeclsInPrototype based on raw encoding of the source location.
7328 // Scope::decls() is iterating over a SmallPtrSet so sort the Decls before
7329 // moving to DeclContext. This provides a stable ordering for traversing
7330 // Decls in DeclContext, which is important for tasks like ASTWriter for
7331 // deterministic output.
7332 llvm::sort(C&: DeclsInPrototype, Comp: [](Decl *D1, Decl *D2) {
7333 return D1->getLocation().getRawEncoding() <
7334 D2->getLocation().getRawEncoding();
7335 });
7336 }
7337
7338 // Remember that we parsed a function type, and remember the attributes.
7339 D.AddTypeInfo(TI: DeclaratorChunk::getFunction(
7340 HasProto, IsAmbiguous, LParenLoc, Params: ParamInfo.data(),
7341 NumParams: ParamInfo.size(), EllipsisLoc, RParenLoc,
7342 RefQualifierIsLvalueRef: RefQualifierIsLValueRef, RefQualifierLoc,
7343 /*MutableLoc=*/SourceLocation(),
7344 ESpecType, ESpecRange, Exceptions: DynamicExceptions.data(),
7345 ExceptionRanges: DynamicExceptionRanges.data(), NumExceptions: DynamicExceptions.size(),
7346 NoexceptExpr: NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
7347 ExceptionSpecTokens, DeclsInPrototype, LocalRangeBegin: StartLoc,
7348 LocalRangeEnd: LocalEndLoc, TheDeclarator&: D, TrailingReturnType, TrailingReturnTypeLoc,
7349 MethodQualifiers: &DS),
7350 attrs: std::move(FnAttrs), EndLoc);
7351}
7352
7353bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,
7354 SourceLocation &RefQualifierLoc) {
7355 if (Tok.isOneOf(K1: tok::amp, K2: tok::ampamp)) {
7356 Diag(Tok, getLangOpts().CPlusPlus11 ?
7357 diag::warn_cxx98_compat_ref_qualifier :
7358 diag::ext_ref_qualifier);
7359
7360 RefQualifierIsLValueRef = Tok.is(K: tok::amp);
7361 RefQualifierLoc = ConsumeToken();
7362 return true;
7363 }
7364 return false;
7365}
7366
7367bool Parser::isFunctionDeclaratorIdentifierList() {
7368 return !getLangOpts().requiresStrictPrototypes()
7369 && Tok.is(K: tok::identifier)
7370 && !TryAltiVecVectorToken()
7371 // K&R identifier lists can't have typedefs as identifiers, per C99
7372 // 6.7.5.3p11.
7373 && (TryAnnotateTypeOrScopeToken() || !Tok.is(K: tok::annot_typename))
7374 // Identifier lists follow a really simple grammar: the identifiers can
7375 // be followed *only* by a ", identifier" or ")". However, K&R
7376 // identifier lists are really rare in the brave new modern world, and
7377 // it is very common for someone to typo a type in a non-K&R style
7378 // list. If we are presented with something like: "void foo(intptr x,
7379 // float y)", we don't want to start parsing the function declarator as
7380 // though it is a K&R style declarator just because intptr is an
7381 // invalid type.
7382 //
7383 // To handle this, we check to see if the token after the first
7384 // identifier is a "," or ")". Only then do we parse it as an
7385 // identifier list.
7386 && (!Tok.is(K: tok::eof) &&
7387 (NextToken().is(K: tok::comma) || NextToken().is(K: tok::r_paren)));
7388}
7389
7390void Parser::ParseFunctionDeclaratorIdentifierList(
7391 Declarator &D,
7392 SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {
7393 // We should never reach this point in C23 or C++.
7394 assert(!getLangOpts().requiresStrictPrototypes() &&
7395 "Cannot parse an identifier list in C23 or C++");
7396
7397 // If there was no identifier specified for the declarator, either we are in
7398 // an abstract-declarator, or we are in a parameter declarator which was found
7399 // to be abstract. In abstract-declarators, identifier lists are not valid:
7400 // diagnose this.
7401 if (!D.getIdentifier())
7402 Diag(Tok, diag::ext_ident_list_in_param);
7403
7404 // Maintain an efficient lookup of params we have seen so far.
7405 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
7406
7407 do {
7408 // If this isn't an identifier, report the error and skip until ')'.
7409 if (Tok.isNot(K: tok::identifier)) {
7410 Diag(Tok, diag::err_expected) << tok::identifier;
7411 SkipUntil(T: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
7412 // Forget we parsed anything.
7413 ParamInfo.clear();
7414 return;
7415 }
7416
7417 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7418
7419 // Reject 'typedef int y; int test(x, y)', but continue parsing.
7420 if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))
7421 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7422
7423 // Verify that the argument identifier has not already been mentioned.
7424 if (!ParamsSoFar.insert(Ptr: ParmII).second) {
7425 Diag(Tok, diag::err_param_redefinition) << ParmII;
7426 } else {
7427 // Remember this identifier in ParamInfo.
7428 ParamInfo.push_back(Elt: DeclaratorChunk::ParamInfo(ParmII,
7429 Tok.getLocation(),
7430 nullptr));
7431 }
7432
7433 // Eat the identifier.
7434 ConsumeToken();
7435 // The list continues if we see a comma.
7436 } while (TryConsumeToken(Expected: tok::comma));
7437}
7438
7439void Parser::ParseParameterDeclarationClause(
7440 DeclaratorContext DeclaratorCtx, ParsedAttributes &FirstArgAttrs,
7441 SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
7442 SourceLocation &EllipsisLoc, bool IsACXXFunctionDeclaration) {
7443
7444 // Avoid exceeding the maximum function scope depth.
7445 // See https://bugs.llvm.org/show_bug.cgi?id=19607
7446 // Note Sema::ActOnParamDeclarator calls ParmVarDecl::setScopeInfo with
7447 // getFunctionPrototypeDepth() - 1.
7448 if (getCurScope()->getFunctionPrototypeDepth() - 1 >
7449 ParmVarDecl::getMaxFunctionScopeDepth()) {
7450 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7451 << ParmVarDecl::getMaxFunctionScopeDepth();
7452 cutOffParsing();
7453 return;
7454 }
7455
7456 // C++2a [temp.res]p5
7457 // A qualified-id is assumed to name a type if
7458 // - [...]
7459 // - it is a decl-specifier of the decl-specifier-seq of a
7460 // - [...]
7461 // - parameter-declaration in a member-declaration [...]
7462 // - parameter-declaration in a declarator of a function or function
7463 // template declaration whose declarator-id is qualified [...]
7464 // - parameter-declaration in a lambda-declarator [...]
7465 auto AllowImplicitTypename = ImplicitTypenameContext::No;
7466 if (DeclaratorCtx == DeclaratorContext::Member ||
7467 DeclaratorCtx == DeclaratorContext::LambdaExpr ||
7468 DeclaratorCtx == DeclaratorContext::RequiresExpr ||
7469 IsACXXFunctionDeclaration) {
7470 AllowImplicitTypename = ImplicitTypenameContext::Yes;
7471 }
7472
7473 do {
7474 // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
7475 // before deciding this was a parameter-declaration-clause.
7476 if (TryConsumeToken(Expected: tok::ellipsis, Loc&: EllipsisLoc))
7477 break;
7478
7479 // Parse the declaration-specifiers.
7480 // Just use the ParsingDeclaration "scope" of the declarator.
7481 DeclSpec DS(AttrFactory);
7482
7483 ParsedAttributes ArgDeclAttrs(AttrFactory);
7484 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7485
7486 if (FirstArgAttrs.Range.isValid()) {
7487 // If the caller parsed attributes for the first argument, add them now.
7488 // Take them so that we only apply the attributes to the first parameter.
7489 // We have already started parsing the decl-specifier sequence, so don't
7490 // parse any parameter-declaration pieces that precede it.
7491 ArgDeclSpecAttrs.takeAllFrom(Other&: FirstArgAttrs);
7492 } else {
7493 // Parse any C++11 attributes.
7494 MaybeParseCXX11Attributes(Attrs&: ArgDeclAttrs);
7495
7496 // Skip any Microsoft attributes before a param.
7497 MaybeParseMicrosoftAttributes(Attrs&: ArgDeclSpecAttrs);
7498 }
7499
7500 SourceLocation DSStart = Tok.getLocation();
7501
7502 // Parse a C++23 Explicit Object Parameter
7503 // We do that in all language modes to produce a better diagnostic.
7504 SourceLocation ThisLoc;
7505 if (getLangOpts().CPlusPlus && Tok.is(K: tok::kw_this))
7506 ThisLoc = ConsumeToken();
7507
7508 ParsedTemplateInfo TemplateInfo;
7509 ParseDeclarationSpecifiers(DS, TemplateInfo, AS: AS_none,
7510 DSContext: DeclSpecContext::DSC_normal,
7511 /*LateAttrs=*/nullptr, AllowImplicitTypename);
7512
7513 DS.takeAttributesFrom(attrs&: ArgDeclSpecAttrs);
7514
7515 // Parse the declarator. This is "PrototypeContext" or
7516 // "LambdaExprParameterContext", because we must accept either
7517 // 'declarator' or 'abstract-declarator' here.
7518 Declarator ParmDeclarator(DS, ArgDeclAttrs,
7519 DeclaratorCtx == DeclaratorContext::RequiresExpr
7520 ? DeclaratorContext::RequiresExpr
7521 : DeclaratorCtx == DeclaratorContext::LambdaExpr
7522 ? DeclaratorContext::LambdaExprParameter
7523 : DeclaratorContext::Prototype);
7524 ParseDeclarator(D&: ParmDeclarator);
7525
7526 if (ThisLoc.isValid())
7527 ParmDeclarator.SetRangeBegin(ThisLoc);
7528
7529 // Parse GNU attributes, if present.
7530 MaybeParseGNUAttributes(D&: ParmDeclarator);
7531 if (getLangOpts().HLSL)
7532 MaybeParseHLSLAnnotations(Attrs&: DS.getAttributes());
7533
7534 if (Tok.is(K: tok::kw_requires)) {
7535 // User tried to define a requires clause in a parameter declaration,
7536 // which is surely not a function declaration.
7537 // void f(int (*g)(int, int) requires true);
7538 Diag(Tok,
7539 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7540 ConsumeToken();
7541 Actions.CorrectDelayedTyposInExpr(
7542 ER: ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true));
7543 }
7544
7545 // Remember this parsed parameter in ParamInfo.
7546 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7547
7548 // DefArgToks is used when the parsing of default arguments needs
7549 // to be delayed.
7550 std::unique_ptr<CachedTokens> DefArgToks;
7551
7552 // If no parameter was specified, verify that *something* was specified,
7553 // otherwise we have a missing type and identifier.
7554 if (DS.isEmpty() && ParmDeclarator.getIdentifier() == nullptr &&
7555 ParmDeclarator.getNumTypeObjects() == 0) {
7556 // Completely missing, emit error.
7557 Diag(DSStart, diag::err_missing_param);
7558 } else {
7559 // Otherwise, we have something. Add it and let semantic analysis try
7560 // to grok it and add the result to the ParamInfo we are building.
7561
7562 // Last chance to recover from a misplaced ellipsis in an attempted
7563 // parameter pack declaration.
7564 if (Tok.is(K: tok::ellipsis) &&
7565 (NextToken().isNot(K: tok::r_paren) ||
7566 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7567 !Actions.isUnexpandedParameterPackPermitted())) &&
7568 Actions.containsUnexpandedParameterPacks(D&: ParmDeclarator))
7569 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc: ConsumeToken(), D&: ParmDeclarator);
7570
7571 // Now we are at the point where declarator parsing is finished.
7572 //
7573 // Try to catch keywords in place of the identifier in a declarator, and
7574 // in particular the common case where:
7575 // 1 identifier comes at the end of the declarator
7576 // 2 if the identifier is dropped, the declarator is valid but anonymous
7577 // (no identifier)
7578 // 3 declarator parsing succeeds, and then we have a trailing keyword,
7579 // which is never valid in a param list (e.g. missing a ',')
7580 // And we can't handle this in ParseDeclarator because in general keywords
7581 // may be allowed to follow the declarator. (And in some cases there'd be
7582 // better recovery like inserting punctuation). ParseDeclarator is just
7583 // treating this as an anonymous parameter, and fortunately at this point
7584 // we've already almost done that.
7585 //
7586 // We care about case 1) where the declarator type should be known, and
7587 // the identifier should be null.
7588 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7589 Tok.isNot(K: tok::raw_identifier) && !Tok.isAnnotation() &&
7590 Tok.getIdentifierInfo() &&
7591 Tok.getIdentifierInfo()->isKeyword(LangOpts: getLangOpts())) {
7592 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7593 // Consume the keyword.
7594 ConsumeToken();
7595 }
7596
7597 // We can only store so many parameters
7598 // Skip until the the end of the parameter list, ignoring
7599 // parameters that would overflow.
7600 if (ParamInfo.size() == Type::FunctionTypeNumParamsLimit) {
7601 Diag(ParmDeclarator.getBeginLoc(),
7602 diag::err_function_parameter_limit_exceeded);
7603 SkipUntil(T: tok::r_paren, Flags: SkipUntilFlags::StopBeforeMatch);
7604 break;
7605 }
7606
7607 // Inform the actions module about the parameter declarator, so it gets
7608 // added to the current scope.
7609 Decl *Param =
7610 Actions.ActOnParamDeclarator(S: getCurScope(), D&: ParmDeclarator, ExplicitThisLoc: ThisLoc);
7611 // Parse the default argument, if any. We parse the default
7612 // arguments in all dialects; the semantic analysis in
7613 // ActOnParamDefaultArgument will reject the default argument in
7614 // C.
7615 if (Tok.is(K: tok::equal)) {
7616 SourceLocation EqualLoc = Tok.getLocation();
7617
7618 // Parse the default argument
7619 if (DeclaratorCtx == DeclaratorContext::Member) {
7620 // If we're inside a class definition, cache the tokens
7621 // corresponding to the default argument. We'll actually parse
7622 // them when we see the end of the class definition.
7623 DefArgToks.reset(p: new CachedTokens);
7624
7625 SourceLocation ArgStartLoc = NextToken().getLocation();
7626 ConsumeAndStoreInitializer(Toks&: *DefArgToks,
7627 CIK: CachedInitKind::DefaultArgument);
7628 Actions.ActOnParamUnparsedDefaultArgument(param: Param, EqualLoc,
7629 ArgLoc: ArgStartLoc);
7630 } else {
7631 // Consume the '='.
7632 ConsumeToken();
7633
7634 // The argument isn't actually potentially evaluated unless it is
7635 // used.
7636 EnterExpressionEvaluationContext Eval(
7637 Actions,
7638 Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed,
7639 Param);
7640
7641 ExprResult DefArgResult;
7642 if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::l_brace)) {
7643 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7644 DefArgResult = ParseBraceInitializer();
7645 } else {
7646 if (Tok.is(K: tok::l_paren) && NextToken().is(K: tok::l_brace)) {
7647 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7648 Actions.ActOnParamDefaultArgumentError(param: Param, EqualLoc,
7649 /*DefaultArg=*/nullptr);
7650 // Skip the statement expression and continue parsing
7651 SkipUntil(T: tok::comma, Flags: StopBeforeMatch);
7652 continue;
7653 }
7654 DefArgResult = ParseAssignmentExpression();
7655 }
7656 DefArgResult = Actions.CorrectDelayedTyposInExpr(ER: DefArgResult);
7657 if (DefArgResult.isInvalid()) {
7658 Actions.ActOnParamDefaultArgumentError(param: Param, EqualLoc,
7659 /*DefaultArg=*/nullptr);
7660 SkipUntil(T1: tok::comma, T2: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
7661 } else {
7662 // Inform the actions module about the default argument
7663 Actions.ActOnParamDefaultArgument(param: Param, EqualLoc,
7664 defarg: DefArgResult.get());
7665 }
7666 }
7667 }
7668
7669 ParamInfo.push_back(Elt: DeclaratorChunk::ParamInfo(ParmII,
7670 ParmDeclarator.getIdentifierLoc(),
7671 Param, std::move(DefArgToks)));
7672 }
7673
7674 if (TryConsumeToken(Expected: tok::ellipsis, Loc&: EllipsisLoc)) {
7675 if (getLangOpts().CPlusPlus26) {
7676 // C++26 [dcl.dcl.fct]p3:
7677 // A parameter-declaration-clause of the form
7678 // parameter-list '...' is deprecated.
7679 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7680 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
7681 }
7682
7683 if (!getLangOpts().CPlusPlus) {
7684 // We have ellipsis without a preceding ',', which is ill-formed
7685 // in C. Complain and provide the fix.
7686 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7687 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
7688 } else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7689 Actions.containsUnexpandedParameterPacks(D&: ParmDeclarator)) {
7690 // It looks like this was supposed to be a parameter pack. Warn and
7691 // point out where the ellipsis should have gone.
7692 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7693 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7694 << ParmEllipsis.isValid() << ParmEllipsis;
7695 if (ParmEllipsis.isValid()) {
7696 Diag(ParmEllipsis,
7697 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7698 } else {
7699 Diag(ParmDeclarator.getIdentifierLoc(),
7700 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7701 << FixItHint::CreateInsertion(ParmDeclarator.getIdentifierLoc(),
7702 "...")
7703 << !ParmDeclarator.hasName();
7704 }
7705 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7706 << FixItHint::CreateInsertion(EllipsisLoc, ", ");
7707 }
7708
7709 // We can't have any more parameters after an ellipsis.
7710 break;
7711 }
7712
7713 // If the next token is a comma, consume it and keep reading arguments.
7714 } while (TryConsumeToken(Expected: tok::comma));
7715}
7716
7717void Parser::ParseBracketDeclarator(Declarator &D) {
7718 if (CheckProhibitedCXX11Attribute())
7719 return;
7720
7721 BalancedDelimiterTracker T(*this, tok::l_square);
7722 T.consumeOpen();
7723
7724 // C array syntax has many features, but by-far the most common is [] and [4].
7725 // This code does a fast path to handle some of the most obvious cases.
7726 if (Tok.getKind() == tok::r_square) {
7727 T.consumeClose();
7728 ParsedAttributes attrs(AttrFactory);
7729 MaybeParseCXX11Attributes(Attrs&: attrs);
7730
7731 // Remember that we parsed the empty array type.
7732 D.AddTypeInfo(TI: DeclaratorChunk::getArray(TypeQuals: 0, isStatic: false, isStar: false, NumElts: nullptr,
7733 LBLoc: T.getOpenLocation(),
7734 RBLoc: T.getCloseLocation()),
7735 attrs: std::move(attrs), EndLoc: T.getCloseLocation());
7736 return;
7737 } else if (Tok.getKind() == tok::numeric_constant &&
7738 GetLookAheadToken(N: 1).is(K: tok::r_square)) {
7739 // [4] is very common. Parse the numeric constant expression.
7740 ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, UDLScope: getCurScope()));
7741 ConsumeToken();
7742
7743 T.consumeClose();
7744 ParsedAttributes attrs(AttrFactory);
7745 MaybeParseCXX11Attributes(Attrs&: attrs);
7746
7747 // Remember that we parsed a array type, and remember its features.
7748 D.AddTypeInfo(TI: DeclaratorChunk::getArray(TypeQuals: 0, isStatic: false, isStar: false, NumElts: ExprRes.get(),
7749 LBLoc: T.getOpenLocation(),
7750 RBLoc: T.getCloseLocation()),
7751 attrs: std::move(attrs), EndLoc: T.getCloseLocation());
7752 return;
7753 } else if (Tok.getKind() == tok::code_completion) {
7754 cutOffParsing();
7755 Actions.CodeCompletion().CodeCompleteBracketDeclarator(S: getCurScope());
7756 return;
7757 }
7758
7759 // If valid, this location is the position where we read the 'static' keyword.
7760 SourceLocation StaticLoc;
7761 TryConsumeToken(Expected: tok::kw_static, Loc&: StaticLoc);
7762
7763 // If there is a type-qualifier-list, read it now.
7764 // Type qualifiers in an array subscript are a C99 feature.
7765 DeclSpec DS(AttrFactory);
7766 ParseTypeQualifierListOpt(DS, AttrReqs: AR_CXX11AttributesParsed);
7767
7768 // If we haven't already read 'static', check to see if there is one after the
7769 // type-qualifier-list.
7770 if (!StaticLoc.isValid())
7771 TryConsumeToken(Expected: tok::kw_static, Loc&: StaticLoc);
7772
7773 // Handle "direct-declarator [ type-qual-list[opt] * ]".
7774 bool isStar = false;
7775 ExprResult NumElements;
7776
7777 // Handle the case where we have '[*]' as the array size. However, a leading
7778 // star could be the start of an expression, for example 'X[*p + 4]'. Verify
7779 // the token after the star is a ']'. Since stars in arrays are
7780 // infrequent, use of lookahead is not costly here.
7781 if (Tok.is(K: tok::star) && GetLookAheadToken(N: 1).is(K: tok::r_square)) {
7782 ConsumeToken(); // Eat the '*'.
7783
7784 if (StaticLoc.isValid()) {
7785 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7786 StaticLoc = SourceLocation(); // Drop the static.
7787 }
7788 isStar = true;
7789 } else if (Tok.isNot(K: tok::r_square)) {
7790 // Note, in C89, this production uses the constant-expr production instead
7791 // of assignment-expr. The only difference is that assignment-expr allows
7792 // things like '=' and '*='. Sema rejects these in C89 mode because they
7793 // are not i-c-e's, so we don't need to distinguish between the two here.
7794
7795 // Parse the constant-expression or assignment-expression now (depending
7796 // on dialect).
7797 if (getLangOpts().CPlusPlus) {
7798 NumElements = ParseArrayBoundExpression();
7799 } else {
7800 EnterExpressionEvaluationContext Unevaluated(
7801 Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7802 NumElements =
7803 Actions.CorrectDelayedTyposInExpr(ER: ParseAssignmentExpression());
7804 }
7805 } else {
7806 if (StaticLoc.isValid()) {
7807 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7808 StaticLoc = SourceLocation(); // Drop the static.
7809 }
7810 }
7811
7812 // If there was an error parsing the assignment-expression, recover.
7813 if (NumElements.isInvalid()) {
7814 D.setInvalidType(true);
7815 // If the expression was invalid, skip it.
7816 SkipUntil(T: tok::r_square, Flags: StopAtSemi);
7817 return;
7818 }
7819
7820 T.consumeClose();
7821
7822 MaybeParseCXX11Attributes(Attrs&: DS.getAttributes());
7823
7824 // Remember that we parsed a array type, and remember its features.
7825 D.AddTypeInfo(
7826 TI: DeclaratorChunk::getArray(TypeQuals: DS.getTypeQualifiers(), isStatic: StaticLoc.isValid(),
7827 isStar, NumElts: NumElements.get(), LBLoc: T.getOpenLocation(),
7828 RBLoc: T.getCloseLocation()),
7829 attrs: std::move(DS.getAttributes()), EndLoc: T.getCloseLocation());
7830}
7831
7832void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
7833 assert(Tok.is(tok::l_square) && "Missing opening bracket");
7834 assert(!D.mayOmitIdentifier() && "Declarator cannot omit identifier");
7835
7836 SourceLocation StartBracketLoc = Tok.getLocation();
7837 Declarator TempDeclarator(D.getDeclSpec(), ParsedAttributesView::none(),
7838 D.getContext());
7839
7840 while (Tok.is(K: tok::l_square)) {
7841 ParseBracketDeclarator(D&: TempDeclarator);
7842 }
7843
7844 // Stuff the location of the start of the brackets into the Declarator.
7845 // The diagnostics from ParseDirectDeclarator will make more sense if
7846 // they use this location instead.
7847 if (Tok.is(K: tok::semi))
7848 D.getName().EndLocation = StartBracketLoc;
7849
7850 SourceLocation SuggestParenLoc = Tok.getLocation();
7851
7852 // Now that the brackets are removed, try parsing the declarator again.
7853 ParseDeclaratorInternal(D, DirectDeclParser: &Parser::ParseDirectDeclarator);
7854
7855 // Something went wrong parsing the brackets, in which case,
7856 // ParseBracketDeclarator has emitted an error, and we don't need to emit
7857 // one here.
7858 if (TempDeclarator.getNumTypeObjects() == 0)
7859 return;
7860
7861 // Determine if parens will need to be suggested in the diagnostic.
7862 bool NeedParens = false;
7863 if (D.getNumTypeObjects() != 0) {
7864 switch (D.getTypeObject(i: D.getNumTypeObjects() - 1).Kind) {
7865 case DeclaratorChunk::Pointer:
7866 case DeclaratorChunk::Reference:
7867 case DeclaratorChunk::BlockPointer:
7868 case DeclaratorChunk::MemberPointer:
7869 case DeclaratorChunk::Pipe:
7870 NeedParens = true;
7871 break;
7872 case DeclaratorChunk::Array:
7873 case DeclaratorChunk::Function:
7874 case DeclaratorChunk::Paren:
7875 break;
7876 }
7877 }
7878
7879 if (NeedParens) {
7880 // Create a DeclaratorChunk for the inserted parens.
7881 SourceLocation EndLoc = PP.getLocForEndOfToken(Loc: D.getEndLoc());
7882 D.AddTypeInfo(TI: DeclaratorChunk::getParen(LParenLoc: SuggestParenLoc, RParenLoc: EndLoc),
7883 EndLoc: SourceLocation());
7884 }
7885
7886 // Adding back the bracket info to the end of the Declarator.
7887 for (unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7888 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7889 D.AddTypeInfo(TI: Chunk, OtherPool&: TempDeclarator.getAttributePool(), EndLoc: SourceLocation());
7890 }
7891
7892 // The missing identifier would have been diagnosed in ParseDirectDeclarator.
7893 // If parentheses are required, always suggest them.
7894 if (!D.getIdentifier() && !NeedParens)
7895 return;
7896
7897 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7898
7899 // Generate the move bracket error message.
7900 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7901 SourceLocation EndLoc = PP.getLocForEndOfToken(Loc: D.getEndLoc());
7902
7903 if (NeedParens) {
7904 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7905 << getLangOpts().CPlusPlus
7906 << FixItHint::CreateInsertion(SuggestParenLoc, "(")
7907 << FixItHint::CreateInsertion(EndLoc, ")")
7908 << FixItHint::CreateInsertionFromRange(
7909 EndLoc, CharSourceRange(BracketRange, true))
7910 << FixItHint::CreateRemoval(BracketRange);
7911 } else {
7912 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7913 << getLangOpts().CPlusPlus
7914 << FixItHint::CreateInsertionFromRange(
7915 EndLoc, CharSourceRange(BracketRange, true))
7916 << FixItHint::CreateRemoval(BracketRange);
7917 }
7918}
7919
7920void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
7921 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7922 "Not a typeof specifier");
7923
7924 bool IsUnqual = Tok.is(K: tok::kw_typeof_unqual);
7925 const IdentifierInfo *II = Tok.getIdentifierInfo();
7926 if (getLangOpts().C23 && !II->getName().starts_with("__"))
7927 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
7928
7929 Token OpTok = Tok;
7930 SourceLocation StartLoc = ConsumeToken();
7931 bool HasParens = Tok.is(K: tok::l_paren);
7932
7933 EnterExpressionEvaluationContext Unevaluated(
7934 Actions, Sema::ExpressionEvaluationContext::Unevaluated,
7935 Sema::ReuseLambdaContextDecl);
7936
7937 bool isCastExpr;
7938 ParsedType CastTy;
7939 SourceRange CastRange;
7940 ExprResult Operand = Actions.CorrectDelayedTyposInExpr(
7941 ER: ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
7942 if (HasParens)
7943 DS.setTypeArgumentRange(CastRange);
7944
7945 if (CastRange.getEnd().isInvalid())
7946 // FIXME: Not accurate, the range gets one token more than it should.
7947 DS.SetRangeEnd(Tok.getLocation());
7948 else
7949 DS.SetRangeEnd(CastRange.getEnd());
7950
7951 if (isCastExpr) {
7952 if (!CastTy) {
7953 DS.SetTypeSpecError();
7954 return;
7955 }
7956
7957 const char *PrevSpec = nullptr;
7958 unsigned DiagID;
7959 // Check for duplicate type specifiers (e.g. "int typeof(int)").
7960 if (DS.SetTypeSpecType(T: IsUnqual ? DeclSpec::TST_typeof_unqualType
7961 : DeclSpec::TST_typeofType,
7962 Loc: StartLoc, PrevSpec,
7963 DiagID, Rep: CastTy,
7964 Policy: Actions.getASTContext().getPrintingPolicy()))
7965 Diag(Loc: StartLoc, DiagID) << PrevSpec;
7966 return;
7967 }
7968
7969 // If we get here, the operand to the typeof was an expression.
7970 if (Operand.isInvalid()) {
7971 DS.SetTypeSpecError();
7972 return;
7973 }
7974
7975 // We might need to transform the operand if it is potentially evaluated.
7976 Operand = Actions.HandleExprEvaluationContextForTypeof(E: Operand.get());
7977 if (Operand.isInvalid()) {
7978 DS.SetTypeSpecError();
7979 return;
7980 }
7981
7982 const char *PrevSpec = nullptr;
7983 unsigned DiagID;
7984 // Check for duplicate type specifiers (e.g. "int typeof(int)").
7985 if (DS.SetTypeSpecType(T: IsUnqual ? DeclSpec::TST_typeof_unqualExpr
7986 : DeclSpec::TST_typeofExpr,
7987 Loc: StartLoc, PrevSpec,
7988 DiagID, Rep: Operand.get(),
7989 policy: Actions.getASTContext().getPrintingPolicy()))
7990 Diag(Loc: StartLoc, DiagID) << PrevSpec;
7991}
7992
7993void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
7994 assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) &&
7995 "Not an atomic specifier");
7996
7997 SourceLocation StartLoc = ConsumeToken();
7998 BalancedDelimiterTracker T(*this, tok::l_paren);
7999 if (T.consumeOpen())
8000 return;
8001
8002 TypeResult Result = ParseTypeName();
8003 if (Result.isInvalid()) {
8004 SkipUntil(T: tok::r_paren, Flags: StopAtSemi);
8005 return;
8006 }
8007
8008 // Match the ')'
8009 T.consumeClose();
8010
8011 if (T.getCloseLocation().isInvalid())
8012 return;
8013
8014 DS.setTypeArgumentRange(T.getRange());
8015 DS.SetRangeEnd(T.getCloseLocation());
8016
8017 const char *PrevSpec = nullptr;
8018 unsigned DiagID;
8019 if (DS.SetTypeSpecType(T: DeclSpec::TST_atomic, Loc: StartLoc, PrevSpec,
8020 DiagID, Rep: Result.get(),
8021 Policy: Actions.getASTContext().getPrintingPolicy()))
8022 Diag(Loc: StartLoc, DiagID) << PrevSpec;
8023}
8024
8025bool Parser::TryAltiVecVectorTokenOutOfLine() {
8026 Token Next = NextToken();
8027 switch (Next.getKind()) {
8028 default: return false;
8029 case tok::kw_short:
8030 case tok::kw_long:
8031 case tok::kw_signed:
8032 case tok::kw_unsigned:
8033 case tok::kw_void:
8034 case tok::kw_char:
8035 case tok::kw_int:
8036 case tok::kw_float:
8037 case tok::kw_double:
8038 case tok::kw_bool:
8039 case tok::kw__Bool:
8040 case tok::kw___bool:
8041 case tok::kw___pixel:
8042 Tok.setKind(tok::kw___vector);
8043 return true;
8044 case tok::identifier:
8045 if (Next.getIdentifierInfo() == Ident_pixel) {
8046 Tok.setKind(tok::kw___vector);
8047 return true;
8048 }
8049 if (Next.getIdentifierInfo() == Ident_bool ||
8050 Next.getIdentifierInfo() == Ident_Bool) {
8051 Tok.setKind(tok::kw___vector);
8052 return true;
8053 }
8054 return false;
8055 }
8056}
8057
8058bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
8059 const char *&PrevSpec, unsigned &DiagID,
8060 bool &isInvalid) {
8061 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8062 if (Tok.getIdentifierInfo() == Ident_vector) {
8063 Token Next = NextToken();
8064 switch (Next.getKind()) {
8065 case tok::kw_short:
8066 case tok::kw_long:
8067 case tok::kw_signed:
8068 case tok::kw_unsigned:
8069 case tok::kw_void:
8070 case tok::kw_char:
8071 case tok::kw_int:
8072 case tok::kw_float:
8073 case tok::kw_double:
8074 case tok::kw_bool:
8075 case tok::kw__Bool:
8076 case tok::kw___bool:
8077 case tok::kw___pixel:
8078 isInvalid = DS.SetTypeAltiVecVector(isAltiVecVector: true, Loc, PrevSpec, DiagID, Policy);
8079 return true;
8080 case tok::identifier:
8081 if (Next.getIdentifierInfo() == Ident_pixel) {
8082 isInvalid = DS.SetTypeAltiVecVector(isAltiVecVector: true, Loc, PrevSpec, DiagID,Policy);
8083 return true;
8084 }
8085 if (Next.getIdentifierInfo() == Ident_bool ||
8086 Next.getIdentifierInfo() == Ident_Bool) {
8087 isInvalid =
8088 DS.SetTypeAltiVecVector(isAltiVecVector: true, Loc, PrevSpec, DiagID, Policy);
8089 return true;
8090 }
8091 break;
8092 default:
8093 break;
8094 }
8095 } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8096 DS.isTypeAltiVecVector()) {
8097 isInvalid = DS.SetTypeAltiVecPixel(isAltiVecPixel: true, Loc, PrevSpec, DiagID, Policy);
8098 return true;
8099 } else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8100 DS.isTypeAltiVecVector()) {
8101 isInvalid = DS.SetTypeAltiVecBool(isAltiVecBool: true, Loc, PrevSpec, DiagID, Policy);
8102 return true;
8103 }
8104 return false;
8105}
8106
8107TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8108 SourceLocation IncludeLoc) {
8109 // Consume (unexpanded) tokens up to the end-of-directive.
8110 SmallVector<Token, 4> Tokens;
8111 {
8112 // Create a new buffer from which we will parse the type.
8113 auto &SourceMgr = PP.getSourceManager();
8114 FileID FID = SourceMgr.createFileID(
8115 Buffer: llvm::MemoryBuffer::getMemBufferCopy(InputData: TypeStr, BufferName: Context), FileCharacter: SrcMgr::C_User,
8116 LoadedID: 0, LoadedOffset: 0, IncludeLoc);
8117
8118 // Form a new lexer that references the buffer.
8119 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8120 L.setParsingPreprocessorDirective(true);
8121
8122 // Lex the tokens from that buffer.
8123 Token Tok;
8124 do {
8125 L.Lex(Result&: Tok);
8126 Tokens.push_back(Elt: Tok);
8127 } while (Tok.isNot(K: tok::eod));
8128 }
8129
8130 // Replace the "eod" token with an "eof" token identifying the end of
8131 // the provided string.
8132 Token &EndToken = Tokens.back();
8133 EndToken.startToken();
8134 EndToken.setKind(tok::eof);
8135 EndToken.setLocation(Tok.getLocation());
8136 EndToken.setEofData(TypeStr.data());
8137
8138 // Add the current token back.
8139 Tokens.push_back(Elt: Tok);
8140
8141 // Enter the tokens into the token stream.
8142 PP.EnterTokenStream(Toks: Tokens, /*DisableMacroExpansion=*/false,
8143 /*IsReinject=*/false);
8144
8145 // Consume the current token so that we'll start parsing the tokens we
8146 // added to the stream.
8147 ConsumeAnyToken();
8148
8149 // Enter a new scope.
8150 ParseScope LocalScope(this, 0);
8151
8152 // Parse the type.
8153 TypeResult Result = ParseTypeName(Range: nullptr);
8154
8155 // Check if we parsed the whole thing.
8156 if (Result.isUsable() &&
8157 (Tok.isNot(K: tok::eof) || Tok.getEofData() != TypeStr.data())) {
8158 Diag(Tok.getLocation(), diag::err_type_unparsed);
8159 }
8160
8161 // There could be leftover tokens (e.g. because of an error).
8162 // Skip through until we reach the 'end of directive' token.
8163 while (Tok.isNot(K: tok::eof))
8164 ConsumeAnyToken();
8165
8166 // Consume the end token.
8167 if (Tok.is(K: tok::eof) && Tok.getEofData() == TypeStr.data())
8168 ConsumeAnyToken();
8169 return Result;
8170}
8171
8172void Parser::DiagnoseBitIntUse(const Token &Tok) {
8173 // If the token is for _ExtInt, diagnose it as being deprecated. Otherwise,
8174 // the token is about _BitInt and gets (potentially) diagnosed as use of an
8175 // extension.
8176 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8177 "expected either an _ExtInt or _BitInt token!");
8178
8179 SourceLocation Loc = Tok.getLocation();
8180 if (Tok.is(K: tok::kw__ExtInt)) {
8181 Diag(Loc, diag::warn_ext_int_deprecated)
8182 << FixItHint::CreateReplacement(Loc, "_BitInt");
8183 } else {
8184 // In C23 mode, diagnose that the use is not compatible with pre-C23 modes.
8185 // Otherwise, diagnose that the use is a Clang extension.
8186 if (getLangOpts().C23)
8187 Diag(Loc, diag::warn_c23_compat_keyword) << Tok.getName();
8188 else
8189 Diag(Loc, diag::ext_bit_int) << getLangOpts().CPlusPlus;
8190 }
8191}
8192

source code of clang/lib/Parse/ParseDecl.cpp