Coverage Report

Created: 2024-01-17 10:31

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