xref: /freebsd-src/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- ParseDeclCXX.cpp - C++ Declaration Parsing -------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file implements the C++ Declaration portions of the Parser interfaces.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
140b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
150b57cec5SDimitry Andric #include "clang/AST/PrettyDeclStackTrace.h"
1681ad6265SDimitry Andric #include "clang/Basic/AttributeCommonInfo.h"
170b57cec5SDimitry Andric #include "clang/Basic/Attributes.h"
180b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
190b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h"
200b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
21bdd1243dSDimitry Andric #include "clang/Basic/TokenKinds.h"
225f757f3fSDimitry Andric #include "clang/Lex/LiteralSupport.h"
230b57cec5SDimitry Andric #include "clang/Parse/ParseDiagnostic.h"
2481ad6265SDimitry Andric #include "clang/Parse/Parser.h"
250b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h"
260b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h"
2706c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h"
280b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h"
290b57cec5SDimitry Andric #include "clang/Sema/Scope.h"
30*0fca6ea1SDimitry Andric #include "clang/Sema/SemaCodeCompletion.h"
310b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
320b57cec5SDimitry Andric #include "llvm/Support/TimeProfiler.h"
33bdd1243dSDimitry Andric #include <optional>
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric using namespace clang;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric /// ParseNamespace - We know that the current token is a namespace keyword. This
380b57cec5SDimitry Andric /// may either be a top level namespace or a block-level namespace alias. If
390b57cec5SDimitry Andric /// there was an inline keyword, it has already been parsed.
400b57cec5SDimitry Andric ///
410b57cec5SDimitry Andric ///       namespace-definition: [C++: namespace.def]
420b57cec5SDimitry Andric ///         named-namespace-definition
430b57cec5SDimitry Andric ///         unnamed-namespace-definition
440b57cec5SDimitry Andric ///         nested-namespace-definition
450b57cec5SDimitry Andric ///
460b57cec5SDimitry Andric ///       named-namespace-definition:
470b57cec5SDimitry Andric ///         'inline'[opt] 'namespace' attributes[opt] identifier '{'
480b57cec5SDimitry Andric ///         namespace-body '}'
490b57cec5SDimitry Andric ///
500b57cec5SDimitry Andric ///       unnamed-namespace-definition:
510b57cec5SDimitry Andric ///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
520b57cec5SDimitry Andric ///
530b57cec5SDimitry Andric ///       nested-namespace-definition:
540b57cec5SDimitry Andric ///         'namespace' enclosing-namespace-specifier '::' 'inline'[opt]
550b57cec5SDimitry Andric ///         identifier '{' namespace-body '}'
560b57cec5SDimitry Andric ///
570b57cec5SDimitry Andric ///       enclosing-namespace-specifier:
580b57cec5SDimitry Andric ///         identifier
590b57cec5SDimitry Andric ///         enclosing-namespace-specifier '::' 'inline'[opt] identifier
600b57cec5SDimitry Andric ///
610b57cec5SDimitry Andric ///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
620b57cec5SDimitry Andric ///         'namespace' identifier '=' qualified-namespace-specifier ';'
630b57cec5SDimitry Andric ///
640b57cec5SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
650b57cec5SDimitry Andric                                               SourceLocation &DeclEnd,
660b57cec5SDimitry Andric                                               SourceLocation InlineLoc) {
670b57cec5SDimitry Andric   assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
680b57cec5SDimitry Andric   SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
690b57cec5SDimitry Andric   ObjCDeclContextSwitch ObjCDC(*this);
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   if (Tok.is(tok::code_completion)) {
720b57cec5SDimitry Andric     cutOffParsing();
73*0fca6ea1SDimitry Andric     Actions.CodeCompletion().CodeCompleteNamespaceDecl(getCurScope());
740b57cec5SDimitry Andric     return nullptr;
750b57cec5SDimitry Andric   }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   SourceLocation IdentLoc;
780b57cec5SDimitry Andric   IdentifierInfo *Ident = nullptr;
790b57cec5SDimitry Andric   InnerNamespaceInfoList ExtraNSs;
800b57cec5SDimitry Andric   SourceLocation FirstNestedInlineLoc;
810b57cec5SDimitry Andric 
8281ad6265SDimitry Andric   ParsedAttributes attrs(AttrFactory);
8381ad6265SDimitry Andric 
8481ad6265SDimitry Andric   auto ReadAttributes = [&] {
8581ad6265SDimitry Andric     bool MoreToParse;
8681ad6265SDimitry Andric     do {
8781ad6265SDimitry Andric       MoreToParse = false;
8881ad6265SDimitry Andric       if (Tok.is(tok::kw___attribute)) {
8981ad6265SDimitry Andric         ParseGNUAttributes(attrs);
9081ad6265SDimitry Andric         MoreToParse = true;
9181ad6265SDimitry Andric       }
920b57cec5SDimitry Andric       if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
930b57cec5SDimitry Andric         Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
940b57cec5SDimitry Andric                                     ? diag::warn_cxx14_compat_ns_enum_attribute
950b57cec5SDimitry Andric                                     : diag::ext_ns_enum_attribute)
960b57cec5SDimitry Andric             << 0 /*namespace*/;
970b57cec5SDimitry Andric         ParseCXX11Attributes(attrs);
9881ad6265SDimitry Andric         MoreToParse = true;
990b57cec5SDimitry Andric       }
10081ad6265SDimitry Andric     } while (MoreToParse);
10181ad6265SDimitry Andric   };
10281ad6265SDimitry Andric 
10381ad6265SDimitry Andric   ReadAttributes();
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   if (Tok.is(tok::identifier)) {
1060b57cec5SDimitry Andric     Ident = Tok.getIdentifierInfo();
1070b57cec5SDimitry Andric     IdentLoc = ConsumeToken(); // eat the identifier.
1080b57cec5SDimitry Andric     while (Tok.is(tok::coloncolon) &&
1090b57cec5SDimitry Andric            (NextToken().is(tok::identifier) ||
1100b57cec5SDimitry Andric             (NextToken().is(tok::kw_inline) &&
1110b57cec5SDimitry Andric              GetLookAheadToken(2).is(tok::identifier)))) {
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric       InnerNamespaceInfo Info;
1140b57cec5SDimitry Andric       Info.NamespaceLoc = ConsumeToken();
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric       if (Tok.is(tok::kw_inline)) {
1170b57cec5SDimitry Andric         Info.InlineLoc = ConsumeToken();
1180b57cec5SDimitry Andric         if (FirstNestedInlineLoc.isInvalid())
1190b57cec5SDimitry Andric           FirstNestedInlineLoc = Info.InlineLoc;
1200b57cec5SDimitry Andric       }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric       Info.Ident = Tok.getIdentifierInfo();
1230b57cec5SDimitry Andric       Info.IdentLoc = ConsumeToken();
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric       ExtraNSs.push_back(Info);
1260b57cec5SDimitry Andric     }
1270b57cec5SDimitry Andric   }
1280b57cec5SDimitry Andric 
12981ad6265SDimitry Andric   ReadAttributes();
13081ad6265SDimitry Andric 
13181ad6265SDimitry Andric   SourceLocation attrLoc = attrs.Range.getBegin();
13281ad6265SDimitry Andric 
1330b57cec5SDimitry Andric   // A nested namespace definition cannot have attributes.
1340b57cec5SDimitry Andric   if (!ExtraNSs.empty() && attrLoc.isValid())
1350b57cec5SDimitry Andric     Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   if (Tok.is(tok::equal)) {
1380b57cec5SDimitry Andric     if (!Ident) {
1390b57cec5SDimitry Andric       Diag(Tok, diag::err_expected) << tok::identifier;
1400b57cec5SDimitry Andric       // Skip to end of the definition and eat the ';'.
1410b57cec5SDimitry Andric       SkipUntil(tok::semi);
1420b57cec5SDimitry Andric       return nullptr;
1430b57cec5SDimitry Andric     }
144*0fca6ea1SDimitry Andric     if (!ExtraNSs.empty()) {
145*0fca6ea1SDimitry Andric       Diag(ExtraNSs.front().NamespaceLoc,
146*0fca6ea1SDimitry Andric            diag::err_unexpected_qualified_namespace_alias)
147*0fca6ea1SDimitry Andric           << SourceRange(ExtraNSs.front().NamespaceLoc,
148*0fca6ea1SDimitry Andric                          ExtraNSs.back().IdentLoc);
149*0fca6ea1SDimitry Andric       SkipUntil(tok::semi);
150*0fca6ea1SDimitry Andric       return nullptr;
151*0fca6ea1SDimitry Andric     }
1520b57cec5SDimitry Andric     if (attrLoc.isValid())
1530b57cec5SDimitry Andric       Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);
1540b57cec5SDimitry Andric     if (InlineLoc.isValid())
1550b57cec5SDimitry Andric       Diag(InlineLoc, diag::err_inline_namespace_alias)
1560b57cec5SDimitry Andric           << FixItHint::CreateRemoval(InlineLoc);
1570b57cec5SDimitry Andric     Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
1580b57cec5SDimitry Andric     return Actions.ConvertDeclToDeclGroup(NSAlias);
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_brace);
1620b57cec5SDimitry Andric   if (T.consumeOpen()) {
1630b57cec5SDimitry Andric     if (Ident)
1640b57cec5SDimitry Andric       Diag(Tok, diag::err_expected) << tok::l_brace;
1650b57cec5SDimitry Andric     else
1660b57cec5SDimitry Andric       Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
1670b57cec5SDimitry Andric     return nullptr;
1680b57cec5SDimitry Andric   }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||
1710b57cec5SDimitry Andric       getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||
1720b57cec5SDimitry Andric       getCurScope()->getFnParent()) {
1730b57cec5SDimitry Andric     Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
1740b57cec5SDimitry Andric     SkipUntil(tok::r_brace);
1750b57cec5SDimitry Andric     return nullptr;
1760b57cec5SDimitry Andric   }
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   if (ExtraNSs.empty()) {
1790b57cec5SDimitry Andric     // Normal namespace definition, not a nested-namespace-definition.
1800b57cec5SDimitry Andric   } else if (InlineLoc.isValid()) {
1810b57cec5SDimitry Andric     Diag(InlineLoc, diag::err_inline_nested_namespace_definition);
1825ffd83dbSDimitry Andric   } else if (getLangOpts().CPlusPlus20) {
1830b57cec5SDimitry Andric     Diag(ExtraNSs[0].NamespaceLoc,
1840b57cec5SDimitry Andric          diag::warn_cxx14_compat_nested_namespace_definition);
1850b57cec5SDimitry Andric     if (FirstNestedInlineLoc.isValid())
1860b57cec5SDimitry Andric       Diag(FirstNestedInlineLoc,
1870b57cec5SDimitry Andric            diag::warn_cxx17_compat_inline_nested_namespace_definition);
1880b57cec5SDimitry Andric   } else if (getLangOpts().CPlusPlus17) {
1890b57cec5SDimitry Andric     Diag(ExtraNSs[0].NamespaceLoc,
1900b57cec5SDimitry Andric          diag::warn_cxx14_compat_nested_namespace_definition);
1910b57cec5SDimitry Andric     if (FirstNestedInlineLoc.isValid())
1920b57cec5SDimitry Andric       Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
1930b57cec5SDimitry Andric   } else {
1940b57cec5SDimitry Andric     TentativeParsingAction TPA(*this);
1950b57cec5SDimitry Andric     SkipUntil(tok::r_brace, StopBeforeMatch);
1960b57cec5SDimitry Andric     Token rBraceToken = Tok;
1970b57cec5SDimitry Andric     TPA.Revert();
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric     if (!rBraceToken.is(tok::r_brace)) {
2000b57cec5SDimitry Andric       Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
2010b57cec5SDimitry Andric           << SourceRange(ExtraNSs.front().NamespaceLoc,
2020b57cec5SDimitry Andric                          ExtraNSs.back().IdentLoc);
2030b57cec5SDimitry Andric     } else {
2040b57cec5SDimitry Andric       std::string NamespaceFix;
2050b57cec5SDimitry Andric       for (const auto &ExtraNS : ExtraNSs) {
2060b57cec5SDimitry Andric         NamespaceFix += " { ";
2070b57cec5SDimitry Andric         if (ExtraNS.InlineLoc.isValid())
2080b57cec5SDimitry Andric           NamespaceFix += "inline ";
2090b57cec5SDimitry Andric         NamespaceFix += "namespace ";
2100b57cec5SDimitry Andric         NamespaceFix += ExtraNS.Ident->getName();
2110b57cec5SDimitry Andric       }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric       std::string RBraces;
2140b57cec5SDimitry Andric       for (unsigned i = 0, e = ExtraNSs.size(); i != e; ++i)
2150b57cec5SDimitry Andric         RBraces += "} ";
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric       Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
2180b57cec5SDimitry Andric           << FixItHint::CreateReplacement(
2190b57cec5SDimitry Andric                  SourceRange(ExtraNSs.front().NamespaceLoc,
2200b57cec5SDimitry Andric                              ExtraNSs.back().IdentLoc),
2210b57cec5SDimitry Andric                  NamespaceFix)
2220b57cec5SDimitry Andric           << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces);
2230b57cec5SDimitry Andric     }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric     // Warn about nested inline namespaces.
2260b57cec5SDimitry Andric     if (FirstNestedInlineLoc.isValid())
2270b57cec5SDimitry Andric       Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
2280b57cec5SDimitry Andric   }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   // If we're still good, complain about inline namespaces in non-C++0x now.
2310b57cec5SDimitry Andric   if (InlineLoc.isValid())
232972a253aSDimitry Andric     Diag(InlineLoc, getLangOpts().CPlusPlus11
233972a253aSDimitry Andric                         ? diag::warn_cxx98_compat_inline_namespace
234972a253aSDimitry Andric                         : diag::ext_inline_namespace);
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   // Enter a scope for the namespace.
2370b57cec5SDimitry Andric   ParseScope NamespaceScope(this, Scope::DeclScope);
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
2400b57cec5SDimitry Andric   Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
2410b57cec5SDimitry Andric       getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
242bdd1243dSDimitry Andric       T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, false);
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl,
2450b57cec5SDimitry Andric                                       NamespaceLoc, "parsing namespace");
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   // Parse the contents of the namespace.  This includes parsing recovery on
2480b57cec5SDimitry Andric   // any improperly nested namespaces.
2490b57cec5SDimitry Andric   ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T);
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   // Leave the namespace scope.
2520b57cec5SDimitry Andric   NamespaceScope.Exit();
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   DeclEnd = T.getCloseLocation();
2550b57cec5SDimitry Andric   Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd);
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   return Actions.ConvertDeclToDeclGroup(NamespcDecl,
2580b57cec5SDimitry Andric                                         ImplicitUsingDirectiveDecl);
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric /// ParseInnerNamespace - Parse the contents of a namespace.
2620b57cec5SDimitry Andric void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
2630b57cec5SDimitry Andric                                  unsigned int index, SourceLocation &InlineLoc,
2640b57cec5SDimitry Andric                                  ParsedAttributes &attrs,
2650b57cec5SDimitry Andric                                  BalancedDelimiterTracker &Tracker) {
2660b57cec5SDimitry Andric   if (index == InnerNSs.size()) {
2670b57cec5SDimitry Andric     while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
2680b57cec5SDimitry Andric            Tok.isNot(tok::eof)) {
269bdd1243dSDimitry Andric       ParsedAttributes DeclAttrs(AttrFactory);
270bdd1243dSDimitry Andric       MaybeParseCXX11Attributes(DeclAttrs);
271bdd1243dSDimitry Andric       ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
272bdd1243dSDimitry Andric       ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
2730b57cec5SDimitry Andric     }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric     // The caller is what called check -- we are simply calling
2760b57cec5SDimitry Andric     // the close for it.
2770b57cec5SDimitry Andric     Tracker.consumeClose();
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric     return;
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   // Handle a nested namespace definition.
2830b57cec5SDimitry Andric   // FIXME: Preserve the source information through to the AST rather than
2840b57cec5SDimitry Andric   // desugaring it here.
2850b57cec5SDimitry Andric   ParseScope NamespaceScope(this, Scope::DeclScope);
2860b57cec5SDimitry Andric   UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;
2870b57cec5SDimitry Andric   Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(
2880b57cec5SDimitry Andric       getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc,
2890b57cec5SDimitry Andric       InnerNSs[index].IdentLoc, InnerNSs[index].Ident,
290bdd1243dSDimitry Andric       Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, true);
2910b57cec5SDimitry Andric   assert(!ImplicitUsingDirectiveDecl &&
2920b57cec5SDimitry Andric          "nested namespace definition cannot define anonymous namespace");
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker);
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   NamespaceScope.Exit();
2970b57cec5SDimitry Andric   Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation());
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric /// ParseNamespaceAlias - Parse the part after the '=' in a namespace
3010b57cec5SDimitry Andric /// alias definition.
3020b57cec5SDimitry Andric ///
3030b57cec5SDimitry Andric Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
3040b57cec5SDimitry Andric                                   SourceLocation AliasLoc,
3050b57cec5SDimitry Andric                                   IdentifierInfo *Alias,
3060b57cec5SDimitry Andric                                   SourceLocation &DeclEnd) {
3070b57cec5SDimitry Andric   assert(Tok.is(tok::equal) && "Not equal token");
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   ConsumeToken(); // eat the '='.
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   if (Tok.is(tok::code_completion)) {
3120b57cec5SDimitry Andric     cutOffParsing();
313*0fca6ea1SDimitry Andric     Actions.CodeCompletion().CodeCompleteNamespaceAliasDecl(getCurScope());
3140b57cec5SDimitry Andric     return nullptr;
3150b57cec5SDimitry Andric   }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric   CXXScopeSpec SS;
3180b57cec5SDimitry Andric   // Parse (optional) nested-name-specifier.
3195ffd83dbSDimitry Andric   ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
32004eeddc0SDimitry Andric                                  /*ObjectHasErrors=*/false,
3215ffd83dbSDimitry Andric                                  /*EnteringContext=*/false,
3220b57cec5SDimitry Andric                                  /*MayBePseudoDestructor=*/nullptr,
3230b57cec5SDimitry Andric                                  /*IsTypename=*/false,
3240b57cec5SDimitry Andric                                  /*LastII=*/nullptr,
3250b57cec5SDimitry Andric                                  /*OnlyNamespace=*/true);
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   if (Tok.isNot(tok::identifier)) {
3280b57cec5SDimitry Andric     Diag(Tok, diag::err_expected_namespace_name);
3290b57cec5SDimitry Andric     // Skip to end of the definition and eat the ';'.
3300b57cec5SDimitry Andric     SkipUntil(tok::semi);
3310b57cec5SDimitry Andric     return nullptr;
3320b57cec5SDimitry Andric   }
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric   if (SS.isInvalid()) {
3350b57cec5SDimitry Andric     // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier.
3360b57cec5SDimitry Andric     // Skip to end of the definition and eat the ';'.
3370b57cec5SDimitry Andric     SkipUntil(tok::semi);
3380b57cec5SDimitry Andric     return nullptr;
3390b57cec5SDimitry Andric   }
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   // Parse identifier.
3420b57cec5SDimitry Andric   IdentifierInfo *Ident = Tok.getIdentifierInfo();
3430b57cec5SDimitry Andric   SourceLocation IdentLoc = ConsumeToken();
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   // Eat the ';'.
3460b57cec5SDimitry Andric   DeclEnd = Tok.getLocation();
3470b57cec5SDimitry Andric   if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
3480b57cec5SDimitry Andric     SkipUntil(tok::semi);
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric   return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc,
3510b57cec5SDimitry Andric                                         Alias, SS, IdentLoc, Ident);
3520b57cec5SDimitry Andric }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric /// ParseLinkage - We know that the current token is a string_literal
3550b57cec5SDimitry Andric /// and just before that, that extern was seen.
3560b57cec5SDimitry Andric ///
3570b57cec5SDimitry Andric ///       linkage-specification: [C++ 7.5p2: dcl.link]
3580b57cec5SDimitry Andric ///         'extern' string-literal '{' declaration-seq[opt] '}'
3590b57cec5SDimitry Andric ///         'extern' string-literal declaration
3600b57cec5SDimitry Andric ///
3610b57cec5SDimitry Andric Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
3620b57cec5SDimitry Andric   assert(isTokenStringLiteral() && "Not a string literal!");
36306c3fb27SDimitry Andric   ExprResult Lang = ParseUnevaluatedStringLiteralExpression();
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric   ParseScope LinkageScope(this, Scope::DeclScope);
3660b57cec5SDimitry Andric   Decl *LinkageSpec =
3670b57cec5SDimitry Andric       Lang.isInvalid()
3680b57cec5SDimitry Andric           ? nullptr
3690b57cec5SDimitry Andric           : Actions.ActOnStartLinkageSpecification(
3700b57cec5SDimitry Andric                 getCurScope(), DS.getSourceRange().getBegin(), Lang.get(),
3710b57cec5SDimitry Andric                 Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());
3720b57cec5SDimitry Andric 
37381ad6265SDimitry Andric   ParsedAttributes DeclAttrs(AttrFactory);
374bdd1243dSDimitry Andric   ParsedAttributes DeclSpecAttrs(AttrFactory);
375bdd1243dSDimitry Andric 
376bdd1243dSDimitry Andric   while (MaybeParseCXX11Attributes(DeclAttrs) ||
377bdd1243dSDimitry Andric          MaybeParseGNUAttributes(DeclSpecAttrs))
378bdd1243dSDimitry Andric     ;
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   if (Tok.isNot(tok::l_brace)) {
3810b57cec5SDimitry Andric     // Reset the source range in DS, as the leading "extern"
3820b57cec5SDimitry Andric     // does not really belong to the inner declaration ...
3830b57cec5SDimitry Andric     DS.SetRangeStart(SourceLocation());
3840b57cec5SDimitry Andric     DS.SetRangeEnd(SourceLocation());
3850b57cec5SDimitry Andric     // ... but anyway remember that such an "extern" was seen.
3860b57cec5SDimitry Andric     DS.setExternInLinkageSpec(true);
387bdd1243dSDimitry Andric     ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS);
3880b57cec5SDimitry Andric     return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
3890b57cec5SDimitry Andric                              getCurScope(), LinkageSpec, SourceLocation())
3900b57cec5SDimitry Andric                        : nullptr;
3910b57cec5SDimitry Andric   }
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric   DS.abort();
3940b57cec5SDimitry Andric 
39581ad6265SDimitry Andric   ProhibitAttributes(DeclAttrs);
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_brace);
3980b57cec5SDimitry Andric   T.consumeOpen();
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   unsigned NestedModules = 0;
4010b57cec5SDimitry Andric   while (true) {
4020b57cec5SDimitry Andric     switch (Tok.getKind()) {
4030b57cec5SDimitry Andric     case tok::annot_module_begin:
4040b57cec5SDimitry Andric       ++NestedModules;
4050b57cec5SDimitry Andric       ParseTopLevelDecl();
4060b57cec5SDimitry Andric       continue;
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric     case tok::annot_module_end:
4090b57cec5SDimitry Andric       if (!NestedModules)
4100b57cec5SDimitry Andric         break;
4110b57cec5SDimitry Andric       --NestedModules;
4120b57cec5SDimitry Andric       ParseTopLevelDecl();
4130b57cec5SDimitry Andric       continue;
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric     case tok::annot_module_include:
4160b57cec5SDimitry Andric       ParseTopLevelDecl();
4170b57cec5SDimitry Andric       continue;
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric     case tok::eof:
4200b57cec5SDimitry Andric       break;
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric     case tok::r_brace:
4230b57cec5SDimitry Andric       if (!NestedModules)
4240b57cec5SDimitry Andric         break;
425bdd1243dSDimitry Andric       [[fallthrough]];
4260b57cec5SDimitry Andric     default:
427bdd1243dSDimitry Andric       ParsedAttributes DeclAttrs(AttrFactory);
428bdd1243dSDimitry Andric       MaybeParseCXX11Attributes(DeclAttrs);
429bdd1243dSDimitry Andric       ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
4300b57cec5SDimitry Andric       continue;
4310b57cec5SDimitry Andric     }
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric     break;
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   T.consumeClose();
4370b57cec5SDimitry Andric   return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
4380b57cec5SDimitry Andric                            getCurScope(), LinkageSpec, T.getCloseLocation())
4390b57cec5SDimitry Andric                      : nullptr;
4400b57cec5SDimitry Andric }
4410b57cec5SDimitry Andric 
44206c3fb27SDimitry Andric /// Parse a standard C++ Modules export-declaration.
4430b57cec5SDimitry Andric ///
4440b57cec5SDimitry Andric ///       export-declaration:
4450b57cec5SDimitry Andric ///         'export' declaration
4460b57cec5SDimitry Andric ///         'export' '{' declaration-seq[opt] '}'
4470b57cec5SDimitry Andric ///
448*0fca6ea1SDimitry Andric /// HLSL: Parse export function declaration.
449*0fca6ea1SDimitry Andric ///
450*0fca6ea1SDimitry Andric ///      export-function-declaration:
451*0fca6ea1SDimitry Andric ///         'export' function-declaration
452*0fca6ea1SDimitry Andric ///
453*0fca6ea1SDimitry Andric ///      export-declaration-group:
454*0fca6ea1SDimitry Andric ///         'export' '{' function-declaration-seq[opt] '}'
455*0fca6ea1SDimitry Andric ///
4560b57cec5SDimitry Andric Decl *Parser::ParseExportDeclaration() {
4570b57cec5SDimitry Andric   assert(Tok.is(tok::kw_export));
4580b57cec5SDimitry Andric   SourceLocation ExportLoc = ConsumeToken();
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   ParseScope ExportScope(this, Scope::DeclScope);
4610b57cec5SDimitry Andric   Decl *ExportDecl = Actions.ActOnStartExportDecl(
4620b57cec5SDimitry Andric       getCurScope(), ExportLoc,
4630b57cec5SDimitry Andric       Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   if (Tok.isNot(tok::l_brace)) {
4660b57cec5SDimitry Andric     // FIXME: Factor out a ParseExternalDeclarationWithAttrs.
467bdd1243dSDimitry Andric     ParsedAttributes DeclAttrs(AttrFactory);
468bdd1243dSDimitry Andric     MaybeParseCXX11Attributes(DeclAttrs);
469bdd1243dSDimitry Andric     ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
470bdd1243dSDimitry Andric     ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
4710b57cec5SDimitry Andric     return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl,
4720b57cec5SDimitry Andric                                          SourceLocation());
4730b57cec5SDimitry Andric   }
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_brace);
4760b57cec5SDimitry Andric   T.consumeOpen();
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric   while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4790b57cec5SDimitry Andric          Tok.isNot(tok::eof)) {
480bdd1243dSDimitry Andric     ParsedAttributes DeclAttrs(AttrFactory);
481bdd1243dSDimitry Andric     MaybeParseCXX11Attributes(DeclAttrs);
482bdd1243dSDimitry Andric     ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
483bdd1243dSDimitry Andric     ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
4840b57cec5SDimitry Andric   }
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric   T.consumeClose();
4870b57cec5SDimitry Andric   return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl,
4880b57cec5SDimitry Andric                                        T.getCloseLocation());
4890b57cec5SDimitry Andric }
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
4920b57cec5SDimitry Andric /// using-directive. Assumes that current token is 'using'.
49381ad6265SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseUsingDirectiveOrDeclaration(
49481ad6265SDimitry Andric     DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
49581ad6265SDimitry Andric     SourceLocation &DeclEnd, ParsedAttributes &Attrs) {
4960b57cec5SDimitry Andric   assert(Tok.is(tok::kw_using) && "Not using token");
4970b57cec5SDimitry Andric   ObjCDeclContextSwitch ObjCDC(*this);
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric   // Eat 'using'.
5000b57cec5SDimitry Andric   SourceLocation UsingLoc = ConsumeToken();
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   if (Tok.is(tok::code_completion)) {
5030b57cec5SDimitry Andric     cutOffParsing();
504*0fca6ea1SDimitry Andric     Actions.CodeCompletion().CodeCompleteUsing(getCurScope());
5050b57cec5SDimitry Andric     return nullptr;
5060b57cec5SDimitry Andric   }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   // Consume unexpected 'template' keywords.
5090b57cec5SDimitry Andric   while (Tok.is(tok::kw_template)) {
5100b57cec5SDimitry Andric     SourceLocation TemplateLoc = ConsumeToken();
5110b57cec5SDimitry Andric     Diag(TemplateLoc, diag::err_unexpected_template_after_using)
5120b57cec5SDimitry Andric         << FixItHint::CreateRemoval(TemplateLoc);
5130b57cec5SDimitry Andric   }
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   // 'using namespace' means this is a using-directive.
5160b57cec5SDimitry Andric   if (Tok.is(tok::kw_namespace)) {
5170b57cec5SDimitry Andric     // Template parameters are always an error here.
5180b57cec5SDimitry Andric     if (TemplateInfo.Kind) {
5190b57cec5SDimitry Andric       SourceRange R = TemplateInfo.getSourceRange();
5200b57cec5SDimitry Andric       Diag(UsingLoc, diag::err_templated_using_directive_declaration)
5210b57cec5SDimitry Andric           << 0 /* directive */ << R << FixItHint::CreateRemoval(R);
5220b57cec5SDimitry Andric     }
5230b57cec5SDimitry Andric 
52481ad6265SDimitry Andric     Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, Attrs);
5250b57cec5SDimitry Andric     return Actions.ConvertDeclToDeclGroup(UsingDir);
5260b57cec5SDimitry Andric   }
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric   // Otherwise, it must be a using-declaration or an alias-declaration.
52981ad6265SDimitry Andric   return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, Attrs,
5300b57cec5SDimitry Andric                                AS_none);
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric /// ParseUsingDirective - Parse C++ using-directive, assumes
5340b57cec5SDimitry Andric /// that current token is 'namespace' and 'using' was already parsed.
5350b57cec5SDimitry Andric ///
5360b57cec5SDimitry Andric ///       using-directive: [C++ 7.3.p4: namespace.udir]
5370b57cec5SDimitry Andric ///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
5380b57cec5SDimitry Andric ///                 namespace-name ;
5390b57cec5SDimitry Andric /// [GNU] using-directive:
5400b57cec5SDimitry Andric ///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
5410b57cec5SDimitry Andric ///                 namespace-name attributes[opt] ;
5420b57cec5SDimitry Andric ///
5430b57cec5SDimitry Andric Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
5440b57cec5SDimitry Andric                                   SourceLocation UsingLoc,
5450b57cec5SDimitry Andric                                   SourceLocation &DeclEnd,
5460b57cec5SDimitry Andric                                   ParsedAttributes &attrs) {
5470b57cec5SDimitry Andric   assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   // Eat 'namespace'.
5500b57cec5SDimitry Andric   SourceLocation NamespcLoc = ConsumeToken();
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   if (Tok.is(tok::code_completion)) {
5530b57cec5SDimitry Andric     cutOffParsing();
554*0fca6ea1SDimitry Andric     Actions.CodeCompletion().CodeCompleteUsingDirective(getCurScope());
5550b57cec5SDimitry Andric     return nullptr;
5560b57cec5SDimitry Andric   }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric   CXXScopeSpec SS;
5590b57cec5SDimitry Andric   // Parse (optional) nested-name-specifier.
5605ffd83dbSDimitry Andric   ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
56104eeddc0SDimitry Andric                                  /*ObjectHasErrors=*/false,
5625ffd83dbSDimitry Andric                                  /*EnteringContext=*/false,
5630b57cec5SDimitry Andric                                  /*MayBePseudoDestructor=*/nullptr,
5640b57cec5SDimitry Andric                                  /*IsTypename=*/false,
5650b57cec5SDimitry Andric                                  /*LastII=*/nullptr,
5660b57cec5SDimitry Andric                                  /*OnlyNamespace=*/true);
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   IdentifierInfo *NamespcName = nullptr;
5690b57cec5SDimitry Andric   SourceLocation IdentLoc = SourceLocation();
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric   // Parse namespace-name.
5720b57cec5SDimitry Andric   if (Tok.isNot(tok::identifier)) {
5730b57cec5SDimitry Andric     Diag(Tok, diag::err_expected_namespace_name);
5740b57cec5SDimitry Andric     // If there was invalid namespace name, skip to end of decl, and eat ';'.
5750b57cec5SDimitry Andric     SkipUntil(tok::semi);
5760b57cec5SDimitry Andric     // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
5770b57cec5SDimitry Andric     return nullptr;
5780b57cec5SDimitry Andric   }
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   if (SS.isInvalid()) {
5810b57cec5SDimitry Andric     // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier.
5820b57cec5SDimitry Andric     // Skip to end of the definition and eat the ';'.
5830b57cec5SDimitry Andric     SkipUntil(tok::semi);
5840b57cec5SDimitry Andric     return nullptr;
5850b57cec5SDimitry Andric   }
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric   // Parse identifier.
5880b57cec5SDimitry Andric   NamespcName = Tok.getIdentifierInfo();
5890b57cec5SDimitry Andric   IdentLoc = ConsumeToken();
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric   // Parse (optional) attributes (most likely GNU strong-using extension).
5920b57cec5SDimitry Andric   bool GNUAttr = false;
5930b57cec5SDimitry Andric   if (Tok.is(tok::kw___attribute)) {
5940b57cec5SDimitry Andric     GNUAttr = true;
5950b57cec5SDimitry Andric     ParseGNUAttributes(attrs);
5960b57cec5SDimitry Andric   }
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric   // Eat ';'.
5990b57cec5SDimitry Andric   DeclEnd = Tok.getLocation();
6000b57cec5SDimitry Andric   if (ExpectAndConsume(tok::semi,
6010b57cec5SDimitry Andric                        GNUAttr ? diag::err_expected_semi_after_attribute_list
6020b57cec5SDimitry Andric                                : diag::err_expected_semi_after_namespace_name))
6030b57cec5SDimitry Andric     SkipUntil(tok::semi);
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric   return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
6060b57cec5SDimitry Andric                                      IdentLoc, NamespcName, attrs);
6070b57cec5SDimitry Andric }
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric /// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
6100b57cec5SDimitry Andric ///
6110b57cec5SDimitry Andric ///     using-declarator:
6120b57cec5SDimitry Andric ///       'typename'[opt] nested-name-specifier unqualified-id
6130b57cec5SDimitry Andric ///
6140b57cec5SDimitry Andric bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
6150b57cec5SDimitry Andric                                   UsingDeclarator &D) {
6160b57cec5SDimitry Andric   D.clear();
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric   // Ignore optional 'typename'.
6190b57cec5SDimitry Andric   // FIXME: This is wrong; we should parse this as a typename-specifier.
6200b57cec5SDimitry Andric   TryConsumeToken(tok::kw_typename, D.TypenameLoc);
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric   if (Tok.is(tok::kw___super)) {
6230b57cec5SDimitry Andric     Diag(Tok.getLocation(), diag::err_super_in_using_declaration);
6240b57cec5SDimitry Andric     return true;
6250b57cec5SDimitry Andric   }
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric   // Parse nested-name-specifier.
628*0fca6ea1SDimitry Andric   const IdentifierInfo *LastII = nullptr;
6295ffd83dbSDimitry Andric   if (ParseOptionalCXXScopeSpecifier(D.SS, /*ObjectType=*/nullptr,
63004eeddc0SDimitry Andric                                      /*ObjectHasErrors=*/false,
6315ffd83dbSDimitry Andric                                      /*EnteringContext=*/false,
6320b57cec5SDimitry Andric                                      /*MayBePseudoDtor=*/nullptr,
6330b57cec5SDimitry Andric                                      /*IsTypename=*/false,
634480093f4SDimitry Andric                                      /*LastII=*/&LastII,
635480093f4SDimitry Andric                                      /*OnlyNamespace=*/false,
636480093f4SDimitry Andric                                      /*InUsingDeclaration=*/true))
637480093f4SDimitry Andric 
6380b57cec5SDimitry Andric     return true;
6390b57cec5SDimitry Andric   if (D.SS.isInvalid())
6400b57cec5SDimitry Andric     return true;
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   // Parse the unqualified-id. We allow parsing of both constructor and
6430b57cec5SDimitry Andric   // destructor names and allow the action module to diagnose any semantic
6440b57cec5SDimitry Andric   // errors.
6450b57cec5SDimitry Andric   //
6460b57cec5SDimitry Andric   // C++11 [class.qual]p2:
6470b57cec5SDimitry Andric   //   [...] in a using-declaration that is a member-declaration, if the name
6480b57cec5SDimitry Andric   //   specified after the nested-name-specifier is the same as the identifier
6490b57cec5SDimitry Andric   //   or the simple-template-id's template-name in the last component of the
6500b57cec5SDimitry Andric   //   nested-name-specifier, the name is [...] considered to name the
6510b57cec5SDimitry Andric   //   constructor.
652e8d8bef9SDimitry Andric   if (getLangOpts().CPlusPlus11 && Context == DeclaratorContext::Member &&
6530b57cec5SDimitry Andric       Tok.is(tok::identifier) &&
6540b57cec5SDimitry Andric       (NextToken().is(tok::semi) || NextToken().is(tok::comma) ||
655fe6060f1SDimitry Andric        NextToken().is(tok::ellipsis) || NextToken().is(tok::l_square) ||
65606c3fb27SDimitry Andric        NextToken().isRegularKeywordAttribute() ||
657fe6060f1SDimitry Andric        NextToken().is(tok::kw___attribute)) &&
6580b57cec5SDimitry Andric       D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&
6590b57cec5SDimitry Andric       !D.SS.getScopeRep()->getAsNamespace() &&
6600b57cec5SDimitry Andric       !D.SS.getScopeRep()->getAsNamespaceAlias()) {
6610b57cec5SDimitry Andric     SourceLocation IdLoc = ConsumeToken();
6620b57cec5SDimitry Andric     ParsedType Type =
6630b57cec5SDimitry Andric         Actions.getInheritingConstructorName(D.SS, IdLoc, *LastII);
6640b57cec5SDimitry Andric     D.Name.setConstructorName(Type, IdLoc, IdLoc);
6650b57cec5SDimitry Andric   } else {
6660b57cec5SDimitry Andric     if (ParseUnqualifiedId(
6675ffd83dbSDimitry Andric             D.SS, /*ObjectType=*/nullptr,
6685ffd83dbSDimitry Andric             /*ObjectHadErrors=*/false, /*EnteringContext=*/false,
6690b57cec5SDimitry Andric             /*AllowDestructorName=*/true,
6705ffd83dbSDimitry Andric             /*AllowConstructorName=*/
6715ffd83dbSDimitry Andric             !(Tok.is(tok::identifier) && NextToken().is(tok::equal)),
6725ffd83dbSDimitry Andric             /*AllowDeductionGuide=*/false, nullptr, D.Name))
6730b57cec5SDimitry Andric       return true;
6740b57cec5SDimitry Andric   }
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric   if (TryConsumeToken(tok::ellipsis, D.EllipsisLoc))
677972a253aSDimitry Andric     Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
678972a253aSDimitry Andric                                 ? diag::warn_cxx17_compat_using_declaration_pack
679972a253aSDimitry Andric                                 : diag::ext_using_declaration_pack);
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric   return false;
6820b57cec5SDimitry Andric }
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric /// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
6850b57cec5SDimitry Andric /// Assumes that 'using' was already seen.
6860b57cec5SDimitry Andric ///
6870b57cec5SDimitry Andric ///     using-declaration: [C++ 7.3.p3: namespace.udecl]
6880b57cec5SDimitry Andric ///       'using' using-declarator-list[opt] ;
6890b57cec5SDimitry Andric ///
6900b57cec5SDimitry Andric ///     using-declarator-list: [C++1z]
6910b57cec5SDimitry Andric ///       using-declarator '...'[opt]
6920b57cec5SDimitry Andric ///       using-declarator-list ',' using-declarator '...'[opt]
6930b57cec5SDimitry Andric ///
6940b57cec5SDimitry Andric ///     using-declarator-list: [C++98-14]
6950b57cec5SDimitry Andric ///       using-declarator
6960b57cec5SDimitry Andric ///
6970b57cec5SDimitry Andric ///     alias-declaration: C++11 [dcl.dcl]p1
6980b57cec5SDimitry Andric ///       'using' identifier attribute-specifier-seq[opt] = type-id ;
6990b57cec5SDimitry Andric ///
700fe6060f1SDimitry Andric ///     using-enum-declaration: [C++20, dcl.enum]
701fe6060f1SDimitry Andric ///       'using' elaborated-enum-specifier ;
702bdd1243dSDimitry Andric ///       The terminal name of the elaborated-enum-specifier undergoes
703*0fca6ea1SDimitry Andric ///       type-only lookup
704fe6060f1SDimitry Andric ///
705fe6060f1SDimitry Andric ///     elaborated-enum-specifier:
706fe6060f1SDimitry Andric ///       'enum' nested-name-specifier[opt] identifier
70781ad6265SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
708fe6060f1SDimitry Andric     DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
7090b57cec5SDimitry Andric     SourceLocation UsingLoc, SourceLocation &DeclEnd,
71081ad6265SDimitry Andric     ParsedAttributes &PrefixAttrs, AccessSpecifier AS) {
711fe6060f1SDimitry Andric   SourceLocation UELoc;
712349cc55cSDimitry Andric   bool InInitStatement = Context == DeclaratorContext::SelectionInit ||
713349cc55cSDimitry Andric                          Context == DeclaratorContext::ForInit;
714349cc55cSDimitry Andric 
715349cc55cSDimitry Andric   if (TryConsumeToken(tok::kw_enum, UELoc) && !InInitStatement) {
716fe6060f1SDimitry Andric     // C++20 using-enum
717fe6060f1SDimitry Andric     Diag(UELoc, getLangOpts().CPlusPlus20
718fe6060f1SDimitry Andric                     ? diag::warn_cxx17_compat_using_enum_declaration
719fe6060f1SDimitry Andric                     : diag::ext_using_enum_declaration);
720fe6060f1SDimitry Andric 
721fe6060f1SDimitry Andric     DiagnoseCXX11AttributeExtension(PrefixAttrs);
722fe6060f1SDimitry Andric 
723fe6060f1SDimitry Andric     if (TemplateInfo.Kind) {
724fe6060f1SDimitry Andric       SourceRange R = TemplateInfo.getSourceRange();
725fe6060f1SDimitry Andric       Diag(UsingLoc, diag::err_templated_using_directive_declaration)
726fe6060f1SDimitry Andric           << 1 /* declaration */ << R << FixItHint::CreateRemoval(R);
727bdd1243dSDimitry Andric       SkipUntil(tok::semi);
728bdd1243dSDimitry Andric       return nullptr;
729bdd1243dSDimitry Andric     }
730bdd1243dSDimitry Andric     CXXScopeSpec SS;
731bdd1243dSDimitry Andric     if (ParseOptionalCXXScopeSpecifier(SS, /*ParsedType=*/nullptr,
732bdd1243dSDimitry Andric                                        /*ObectHasErrors=*/false,
733bdd1243dSDimitry Andric                                        /*EnteringConttext=*/false,
734bdd1243dSDimitry Andric                                        /*MayBePseudoDestructor=*/nullptr,
735*0fca6ea1SDimitry Andric                                        /*IsTypename=*/true,
736bdd1243dSDimitry Andric                                        /*IdentifierInfo=*/nullptr,
737bdd1243dSDimitry Andric                                        /*OnlyNamespace=*/false,
738bdd1243dSDimitry Andric                                        /*InUsingDeclaration=*/true)) {
739bdd1243dSDimitry Andric       SkipUntil(tok::semi);
740fe6060f1SDimitry Andric       return nullptr;
741fe6060f1SDimitry Andric     }
742fe6060f1SDimitry Andric 
743bdd1243dSDimitry Andric     if (Tok.is(tok::code_completion)) {
744bdd1243dSDimitry Andric       cutOffParsing();
745*0fca6ea1SDimitry Andric       Actions.CodeCompletion().CodeCompleteUsing(getCurScope());
746bdd1243dSDimitry Andric       return nullptr;
747bdd1243dSDimitry Andric     }
748bdd1243dSDimitry Andric 
749*0fca6ea1SDimitry Andric     Decl *UED = nullptr;
750*0fca6ea1SDimitry Andric 
751*0fca6ea1SDimitry Andric     // FIXME: identifier and annot_template_id handling is very similar to
752*0fca6ea1SDimitry Andric     // ParseBaseTypeSpecifier. It should be factored out into a function.
753*0fca6ea1SDimitry Andric     if (Tok.is(tok::identifier)) {
754*0fca6ea1SDimitry Andric       IdentifierInfo *IdentInfo = Tok.getIdentifierInfo();
755*0fca6ea1SDimitry Andric       SourceLocation IdentLoc = ConsumeToken();
756*0fca6ea1SDimitry Andric 
757*0fca6ea1SDimitry Andric       ParsedType Type = Actions.getTypeName(
758*0fca6ea1SDimitry Andric           *IdentInfo, IdentLoc, getCurScope(), &SS, /*isClassName=*/true,
759*0fca6ea1SDimitry Andric           /*HasTrailingDot=*/false,
760*0fca6ea1SDimitry Andric           /*ObjectType=*/nullptr, /*IsCtorOrDtorName=*/false,
761*0fca6ea1SDimitry Andric           /*WantNontrivialTypeSourceInfo=*/true);
762*0fca6ea1SDimitry Andric 
763*0fca6ea1SDimitry Andric       UED = Actions.ActOnUsingEnumDeclaration(
764*0fca6ea1SDimitry Andric           getCurScope(), AS, UsingLoc, UELoc, IdentLoc, *IdentInfo, Type, &SS);
765*0fca6ea1SDimitry Andric     } else if (Tok.is(tok::annot_template_id)) {
766*0fca6ea1SDimitry Andric       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
767*0fca6ea1SDimitry Andric 
768*0fca6ea1SDimitry Andric       if (TemplateId->mightBeType()) {
769*0fca6ea1SDimitry Andric         AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,
770*0fca6ea1SDimitry Andric                                       /*IsClassName=*/true);
771*0fca6ea1SDimitry Andric 
772*0fca6ea1SDimitry Andric         assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
773*0fca6ea1SDimitry Andric         TypeResult Type = getTypeAnnotation(Tok);
774*0fca6ea1SDimitry Andric         SourceRange Loc = Tok.getAnnotationRange();
775*0fca6ea1SDimitry Andric         ConsumeAnnotationToken();
776*0fca6ea1SDimitry Andric 
777*0fca6ea1SDimitry Andric         UED = Actions.ActOnUsingEnumDeclaration(getCurScope(), AS, UsingLoc,
778*0fca6ea1SDimitry Andric                                                 UELoc, Loc, *TemplateId->Name,
779*0fca6ea1SDimitry Andric                                                 Type.get(), &SS);
780*0fca6ea1SDimitry Andric       } else {
781*0fca6ea1SDimitry Andric         Diag(Tok.getLocation(), diag::err_using_enum_not_enum)
782*0fca6ea1SDimitry Andric             << TemplateId->Name->getName()
783*0fca6ea1SDimitry Andric             << SourceRange(TemplateId->TemplateNameLoc, TemplateId->RAngleLoc);
784*0fca6ea1SDimitry Andric       }
785*0fca6ea1SDimitry Andric     } else {
786bdd1243dSDimitry Andric       Diag(Tok.getLocation(), diag::err_using_enum_expect_identifier)
787bdd1243dSDimitry Andric           << Tok.is(tok::kw_enum);
788bdd1243dSDimitry Andric       SkipUntil(tok::semi);
789bdd1243dSDimitry Andric       return nullptr;
790bdd1243dSDimitry Andric     }
791*0fca6ea1SDimitry Andric 
792bdd1243dSDimitry Andric     if (!UED) {
793bdd1243dSDimitry Andric       SkipUntil(tok::semi);
794bdd1243dSDimitry Andric       return nullptr;
795bdd1243dSDimitry Andric     }
796bdd1243dSDimitry Andric 
797fe6060f1SDimitry Andric     DeclEnd = Tok.getLocation();
798fe6060f1SDimitry Andric     if (ExpectAndConsume(tok::semi, diag::err_expected_after,
799fe6060f1SDimitry Andric                          "using-enum declaration"))
800fe6060f1SDimitry Andric       SkipUntil(tok::semi);
801fe6060f1SDimitry Andric 
802fe6060f1SDimitry Andric     return Actions.ConvertDeclToDeclGroup(UED);
803fe6060f1SDimitry Andric   }
804fe6060f1SDimitry Andric 
8050b57cec5SDimitry Andric   // Check for misplaced attributes before the identifier in an
8060b57cec5SDimitry Andric   // alias-declaration.
80781ad6265SDimitry Andric   ParsedAttributes MisplacedAttrs(AttrFactory);
8080b57cec5SDimitry Andric   MaybeParseCXX11Attributes(MisplacedAttrs);
8090b57cec5SDimitry Andric 
810349cc55cSDimitry Andric   if (InInitStatement && Tok.isNot(tok::identifier))
811349cc55cSDimitry Andric     return nullptr;
812349cc55cSDimitry Andric 
8130b57cec5SDimitry Andric   UsingDeclarator D;
8140b57cec5SDimitry Andric   bool InvalidDeclarator = ParseUsingDeclarator(Context, D);
8150b57cec5SDimitry Andric 
81681ad6265SDimitry Andric   ParsedAttributes Attrs(AttrFactory);
817fe6060f1SDimitry Andric   MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   // If we had any misplaced attributes from earlier, this is where they
8200b57cec5SDimitry Andric   // should have been written.
8210b57cec5SDimitry Andric   if (MisplacedAttrs.Range.isValid()) {
82206c3fb27SDimitry Andric     auto *FirstAttr =
82306c3fb27SDimitry Andric         MisplacedAttrs.empty() ? nullptr : &MisplacedAttrs.front();
82406c3fb27SDimitry Andric     auto &Range = MisplacedAttrs.Range;
82506c3fb27SDimitry Andric     (FirstAttr && FirstAttr->isRegularKeywordAttribute()
82606c3fb27SDimitry Andric          ? Diag(Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
82706c3fb27SDimitry Andric          : Diag(Range.getBegin(), diag::err_attributes_not_allowed))
8280b57cec5SDimitry Andric         << FixItHint::CreateInsertionFromRange(
82906c3fb27SDimitry Andric                Tok.getLocation(), CharSourceRange::getTokenRange(Range))
83006c3fb27SDimitry Andric         << FixItHint::CreateRemoval(Range);
8310b57cec5SDimitry Andric     Attrs.takeAllFrom(MisplacedAttrs);
8320b57cec5SDimitry Andric   }
8330b57cec5SDimitry Andric 
834fe6060f1SDimitry Andric   // Maybe this is an alias-declaration.
835349cc55cSDimitry Andric   if (Tok.is(tok::equal) || InInitStatement) {
836fe6060f1SDimitry Andric     if (InvalidDeclarator) {
837fe6060f1SDimitry Andric       SkipUntil(tok::semi);
838fe6060f1SDimitry Andric       return nullptr;
839fe6060f1SDimitry Andric     }
840fe6060f1SDimitry Andric 
841fe6060f1SDimitry Andric     ProhibitAttributes(PrefixAttrs);
842fe6060f1SDimitry Andric 
8430b57cec5SDimitry Andric     Decl *DeclFromDeclSpec = nullptr;
844*0fca6ea1SDimitry Andric     Scope *CurScope = getCurScope();
845*0fca6ea1SDimitry Andric     if (CurScope)
846*0fca6ea1SDimitry Andric       CurScope->setFlags(Scope::ScopeFlags::TypeAliasScope |
847*0fca6ea1SDimitry Andric                          CurScope->getFlags());
848*0fca6ea1SDimitry Andric 
8490b57cec5SDimitry Andric     Decl *AD = ParseAliasDeclarationAfterDeclarator(
8500b57cec5SDimitry Andric         TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);
8510b57cec5SDimitry Andric     return Actions.ConvertDeclToDeclGroup(AD, DeclFromDeclSpec);
8520b57cec5SDimitry Andric   }
8530b57cec5SDimitry Andric 
854fe6060f1SDimitry Andric   DiagnoseCXX11AttributeExtension(PrefixAttrs);
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric   // Diagnose an attempt to declare a templated using-declaration.
8570b57cec5SDimitry Andric   // In C++11, alias-declarations can be templates:
8580b57cec5SDimitry Andric   //   template <...> using id = type;
8590b57cec5SDimitry Andric   if (TemplateInfo.Kind) {
8600b57cec5SDimitry Andric     SourceRange R = TemplateInfo.getSourceRange();
8610b57cec5SDimitry Andric     Diag(UsingLoc, diag::err_templated_using_directive_declaration)
8620b57cec5SDimitry Andric         << 1 /* declaration */ << R << FixItHint::CreateRemoval(R);
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric     // Unfortunately, we have to bail out instead of recovering by
8650b57cec5SDimitry Andric     // ignoring the parameters, just in case the nested name specifier
8660b57cec5SDimitry Andric     // depends on the parameters.
8670b57cec5SDimitry Andric     return nullptr;
8680b57cec5SDimitry Andric   }
8690b57cec5SDimitry Andric 
8700b57cec5SDimitry Andric   SmallVector<Decl *, 8> DeclsInGroup;
8710b57cec5SDimitry Andric   while (true) {
872fe6060f1SDimitry Andric     // Parse (optional) attributes.
873fe6060f1SDimitry Andric     MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
874fe6060f1SDimitry Andric     DiagnoseCXX11AttributeExtension(Attrs);
875fe6060f1SDimitry Andric     Attrs.addAll(PrefixAttrs.begin(), PrefixAttrs.end());
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric     if (InvalidDeclarator)
8780b57cec5SDimitry Andric       SkipUntil(tok::comma, tok::semi, StopBeforeMatch);
8790b57cec5SDimitry Andric     else {
8800b57cec5SDimitry Andric       // "typename" keyword is allowed for identifiers only,
8810b57cec5SDimitry Andric       // because it may be a type definition.
8820b57cec5SDimitry Andric       if (D.TypenameLoc.isValid() &&
8830b57cec5SDimitry Andric           D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {
8840b57cec5SDimitry Andric         Diag(D.Name.getSourceRange().getBegin(),
8850b57cec5SDimitry Andric              diag::err_typename_identifiers_only)
8860b57cec5SDimitry Andric             << FixItHint::CreateRemoval(SourceRange(D.TypenameLoc));
8870b57cec5SDimitry Andric         // Proceed parsing, but discard the typename keyword.
8880b57cec5SDimitry Andric         D.TypenameLoc = SourceLocation();
8890b57cec5SDimitry Andric       }
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric       Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc,
8920b57cec5SDimitry Andric                                                D.TypenameLoc, D.SS, D.Name,
8930b57cec5SDimitry Andric                                                D.EllipsisLoc, Attrs);
8940b57cec5SDimitry Andric       if (UD)
8950b57cec5SDimitry Andric         DeclsInGroup.push_back(UD);
8960b57cec5SDimitry Andric     }
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric     if (!TryConsumeToken(tok::comma))
8990b57cec5SDimitry Andric       break;
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric     // Parse another using-declarator.
9020b57cec5SDimitry Andric     Attrs.clear();
9030b57cec5SDimitry Andric     InvalidDeclarator = ParseUsingDeclarator(Context, D);
9040b57cec5SDimitry Andric   }
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   if (DeclsInGroup.size() > 1)
907972a253aSDimitry Andric     Diag(Tok.getLocation(),
908972a253aSDimitry Andric          getLangOpts().CPlusPlus17
909972a253aSDimitry Andric              ? diag::warn_cxx17_compat_multi_using_declaration
910972a253aSDimitry Andric              : diag::ext_multi_using_declaration);
9110b57cec5SDimitry Andric 
9120b57cec5SDimitry Andric   // Eat ';'.
9130b57cec5SDimitry Andric   DeclEnd = Tok.getLocation();
9140b57cec5SDimitry Andric   if (ExpectAndConsume(tok::semi, diag::err_expected_after,
9150b57cec5SDimitry Andric                        !Attrs.empty()    ? "attributes list"
916fe6060f1SDimitry Andric                        : UELoc.isValid() ? "using-enum declaration"
9170b57cec5SDimitry Andric                                          : "using declaration"))
9180b57cec5SDimitry Andric     SkipUntil(tok::semi);
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric   return Actions.BuildDeclaratorGroup(DeclsInGroup);
9210b57cec5SDimitry Andric }
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric Decl *Parser::ParseAliasDeclarationAfterDeclarator(
9240b57cec5SDimitry Andric     const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
9250b57cec5SDimitry Andric     UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
9260b57cec5SDimitry Andric     ParsedAttributes &Attrs, Decl **OwnedType) {
9270b57cec5SDimitry Andric   if (ExpectAndConsume(tok::equal)) {
9280b57cec5SDimitry Andric     SkipUntil(tok::semi);
9290b57cec5SDimitry Andric     return nullptr;
9300b57cec5SDimitry Andric   }
9310b57cec5SDimitry Andric 
932972a253aSDimitry Andric   Diag(Tok.getLocation(), getLangOpts().CPlusPlus11
933972a253aSDimitry Andric                               ? diag::warn_cxx98_compat_alias_declaration
934972a253aSDimitry Andric                               : diag::ext_alias_declaration);
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric   // Type alias templates cannot be specialized.
9370b57cec5SDimitry Andric   int SpecKind = -1;
9380b57cec5SDimitry Andric   if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
9390b57cec5SDimitry Andric       D.Name.getKind() == UnqualifiedIdKind::IK_TemplateId)
9400b57cec5SDimitry Andric     SpecKind = 0;
9410b57cec5SDimitry Andric   if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
9420b57cec5SDimitry Andric     SpecKind = 1;
9430b57cec5SDimitry Andric   if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
9440b57cec5SDimitry Andric     SpecKind = 2;
9450b57cec5SDimitry Andric   if (SpecKind != -1) {
9460b57cec5SDimitry Andric     SourceRange Range;
9470b57cec5SDimitry Andric     if (SpecKind == 0)
9480b57cec5SDimitry Andric       Range = SourceRange(D.Name.TemplateId->LAngleLoc,
9490b57cec5SDimitry Andric                           D.Name.TemplateId->RAngleLoc);
9500b57cec5SDimitry Andric     else
9510b57cec5SDimitry Andric       Range = TemplateInfo.getSourceRange();
9520b57cec5SDimitry Andric     Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
9530b57cec5SDimitry Andric         << SpecKind << Range;
9540b57cec5SDimitry Andric     SkipUntil(tok::semi);
9550b57cec5SDimitry Andric     return nullptr;
9560b57cec5SDimitry Andric   }
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   // Name must be an identifier.
9590b57cec5SDimitry Andric   if (D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {
9600b57cec5SDimitry Andric     Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);
9610b57cec5SDimitry Andric     // No removal fixit: can't recover from this.
9620b57cec5SDimitry Andric     SkipUntil(tok::semi);
9630b57cec5SDimitry Andric     return nullptr;
9640b57cec5SDimitry Andric   } else if (D.TypenameLoc.isValid())
9650b57cec5SDimitry Andric     Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier)
966972a253aSDimitry Andric         << FixItHint::CreateRemoval(
967972a253aSDimitry Andric                SourceRange(D.TypenameLoc, D.SS.isNotEmpty() ? D.SS.getEndLoc()
968972a253aSDimitry Andric                                                             : D.TypenameLoc));
9690b57cec5SDimitry Andric   else if (D.SS.isNotEmpty())
9700b57cec5SDimitry Andric     Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
9710b57cec5SDimitry Andric         << FixItHint::CreateRemoval(D.SS.getRange());
9720b57cec5SDimitry Andric   if (D.EllipsisLoc.isValid())
9730b57cec5SDimitry Andric     Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion)
9740b57cec5SDimitry Andric         << FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc));
9750b57cec5SDimitry Andric 
9760b57cec5SDimitry Andric   Decl *DeclFromDeclSpec = nullptr;
977e8d8bef9SDimitry Andric   TypeResult TypeAlias =
978e8d8bef9SDimitry Andric       ParseTypeName(nullptr,
979e8d8bef9SDimitry Andric                     TemplateInfo.Kind ? DeclaratorContext::AliasTemplate
980e8d8bef9SDimitry Andric                                       : DeclaratorContext::AliasDecl,
9810b57cec5SDimitry Andric                     AS, &DeclFromDeclSpec, &Attrs);
9820b57cec5SDimitry Andric   if (OwnedType)
9830b57cec5SDimitry Andric     *OwnedType = DeclFromDeclSpec;
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   // Eat ';'.
9860b57cec5SDimitry Andric   DeclEnd = Tok.getLocation();
9870b57cec5SDimitry Andric   if (ExpectAndConsume(tok::semi, diag::err_expected_after,
9880b57cec5SDimitry Andric                        !Attrs.empty() ? "attributes list"
9890b57cec5SDimitry Andric                                       : "alias declaration"))
9900b57cec5SDimitry Andric     SkipUntil(tok::semi);
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric   TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
9930b57cec5SDimitry Andric   MultiTemplateParamsArg TemplateParamsArg(
9940b57cec5SDimitry Andric       TemplateParams ? TemplateParams->data() : nullptr,
9950b57cec5SDimitry Andric       TemplateParams ? TemplateParams->size() : 0);
9960b57cec5SDimitry Andric   return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
9970b57cec5SDimitry Andric                                        UsingLoc, D.Name, Attrs, TypeAlias,
9980b57cec5SDimitry Andric                                        DeclFromDeclSpec);
9990b57cec5SDimitry Andric }
10000b57cec5SDimitry Andric 
1001fe6060f1SDimitry Andric static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr,
1002fe6060f1SDimitry Andric                                                SourceLocation EndExprLoc) {
1003fe6060f1SDimitry Andric   if (const auto *BO = dyn_cast_or_null<BinaryOperator>(AssertExpr)) {
1004fe6060f1SDimitry Andric     if (BO->getOpcode() == BO_LAnd &&
1005fe6060f1SDimitry Andric         isa<StringLiteral>(BO->getRHS()->IgnoreImpCasts()))
1006fe6060f1SDimitry Andric       return FixItHint::CreateReplacement(BO->getOperatorLoc(), ",");
1007fe6060f1SDimitry Andric   }
1008fe6060f1SDimitry Andric   return FixItHint::CreateInsertion(EndExprLoc, ", \"\"");
1009fe6060f1SDimitry Andric }
1010fe6060f1SDimitry Andric 
10110b57cec5SDimitry Andric /// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
10120b57cec5SDimitry Andric ///
10130b57cec5SDimitry Andric /// [C++0x] static_assert-declaration:
10140b57cec5SDimitry Andric ///           static_assert ( constant-expression  ,  string-literal  ) ;
10150b57cec5SDimitry Andric ///
10160b57cec5SDimitry Andric /// [C11]   static_assert-declaration:
10170b57cec5SDimitry Andric ///           _Static_assert ( constant-expression  ,  string-literal  ) ;
10180b57cec5SDimitry Andric ///
10190b57cec5SDimitry Andric Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
10200b57cec5SDimitry Andric   assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
10210b57cec5SDimitry Andric          "Not a static_assert declaration");
10220b57cec5SDimitry Andric 
102306c3fb27SDimitry Andric   // Save the token name used for static assertion.
102406c3fb27SDimitry Andric   const char *TokName = Tok.getName();
1025972a253aSDimitry Andric 
1026*0fca6ea1SDimitry Andric   if (Tok.is(tok::kw__Static_assert))
1027*0fca6ea1SDimitry Andric     diagnoseUseOfC11Keyword(Tok);
1028*0fca6ea1SDimitry Andric   else if (Tok.is(tok::kw_static_assert)) {
1029bdd1243dSDimitry Andric     if (!getLangOpts().CPlusPlus) {
10305f757f3fSDimitry Andric       if (getLangOpts().C23)
10315f757f3fSDimitry Andric         Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
103206c3fb27SDimitry Andric       else
1033bdd1243dSDimitry Andric         Diag(Tok, diag::ext_ms_static_assert) << FixItHint::CreateReplacement(
1034bdd1243dSDimitry Andric             Tok.getLocation(), "_Static_assert");
1035bdd1243dSDimitry Andric     } else
10360b57cec5SDimitry Andric       Diag(Tok, diag::warn_cxx98_compat_static_assert);
1037fe6060f1SDimitry Andric   }
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric   SourceLocation StaticAssertLoc = ConsumeToken();
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_paren);
10420b57cec5SDimitry Andric   if (T.consumeOpen()) {
10430b57cec5SDimitry Andric     Diag(Tok, diag::err_expected) << tok::l_paren;
10440b57cec5SDimitry Andric     SkipMalformedDecl();
10450b57cec5SDimitry Andric     return nullptr;
10460b57cec5SDimitry Andric   }
10470b57cec5SDimitry Andric 
10480b57cec5SDimitry Andric   EnterExpressionEvaluationContext ConstantEvaluated(
10490b57cec5SDimitry Andric       Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
10500b57cec5SDimitry Andric   ExprResult AssertExpr(ParseConstantExpressionInExprEvalContext());
10510b57cec5SDimitry Andric   if (AssertExpr.isInvalid()) {
10520b57cec5SDimitry Andric     SkipMalformedDecl();
10530b57cec5SDimitry Andric     return nullptr;
10540b57cec5SDimitry Andric   }
10550b57cec5SDimitry Andric 
10560b57cec5SDimitry Andric   ExprResult AssertMessage;
10570b57cec5SDimitry Andric   if (Tok.is(tok::r_paren)) {
1058fe6060f1SDimitry Andric     unsigned DiagVal;
1059fe6060f1SDimitry Andric     if (getLangOpts().CPlusPlus17)
1060fe6060f1SDimitry Andric       DiagVal = diag::warn_cxx14_compat_static_assert_no_message;
1061fe6060f1SDimitry Andric     else if (getLangOpts().CPlusPlus)
1062fe6060f1SDimitry Andric       DiagVal = diag::ext_cxx_static_assert_no_message;
10635f757f3fSDimitry Andric     else if (getLangOpts().C23)
1064fe6060f1SDimitry Andric       DiagVal = diag::warn_c17_compat_static_assert_no_message;
1065fe6060f1SDimitry Andric     else
1066fe6060f1SDimitry Andric       DiagVal = diag::ext_c_static_assert_no_message;
1067fe6060f1SDimitry Andric     Diag(Tok, DiagVal) << getStaticAssertNoMessageFixIt(AssertExpr.get(),
1068fe6060f1SDimitry Andric                                                         Tok.getLocation());
10690b57cec5SDimitry Andric   } else {
10700b57cec5SDimitry Andric     if (ExpectAndConsume(tok::comma)) {
10710b57cec5SDimitry Andric       SkipUntil(tok::semi);
10720b57cec5SDimitry Andric       return nullptr;
10730b57cec5SDimitry Andric     }
10740b57cec5SDimitry Andric 
10758a4dda33SDimitry Andric     bool ParseAsExpression = false;
10768a4dda33SDimitry Andric     if (getLangOpts().CPlusPlus26) {
10778a4dda33SDimitry Andric       for (unsigned I = 0;; ++I) {
10788a4dda33SDimitry Andric         const Token &T = GetLookAheadToken(I);
10798a4dda33SDimitry Andric         if (T.is(tok::r_paren))
10808a4dda33SDimitry Andric           break;
10815f757f3fSDimitry Andric         if (!tokenIsLikeStringLiteral(T, getLangOpts()) || T.hasUDSuffix()) {
10828a4dda33SDimitry Andric           ParseAsExpression = true;
10838a4dda33SDimitry Andric           break;
10848a4dda33SDimitry Andric         }
10858a4dda33SDimitry Andric       }
10868a4dda33SDimitry Andric     }
10878a4dda33SDimitry Andric 
10888a4dda33SDimitry Andric     if (ParseAsExpression)
108906c3fb27SDimitry Andric       AssertMessage = ParseConstantExpressionInExprEvalContext();
10905f757f3fSDimitry Andric     else if (tokenIsLikeStringLiteral(Tok, getLangOpts()))
10918a4dda33SDimitry Andric       AssertMessage = ParseUnevaluatedStringLiteralExpression();
109206c3fb27SDimitry Andric     else {
10930b57cec5SDimitry Andric       Diag(Tok, diag::err_expected_string_literal)
10940b57cec5SDimitry Andric           << /*Source='static_assert'*/ 1;
10950b57cec5SDimitry Andric       SkipMalformedDecl();
10960b57cec5SDimitry Andric       return nullptr;
10970b57cec5SDimitry Andric     }
10980b57cec5SDimitry Andric 
10990b57cec5SDimitry Andric     if (AssertMessage.isInvalid()) {
11000b57cec5SDimitry Andric       SkipMalformedDecl();
11010b57cec5SDimitry Andric       return nullptr;
11020b57cec5SDimitry Andric     }
11030b57cec5SDimitry Andric   }
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   T.consumeClose();
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric   DeclEnd = Tok.getLocation();
110806c3fb27SDimitry Andric   ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
11090b57cec5SDimitry Andric 
1110972a253aSDimitry Andric   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.get(),
11110b57cec5SDimitry Andric                                               AssertMessage.get(),
11120b57cec5SDimitry Andric                                               T.getCloseLocation());
11130b57cec5SDimitry Andric }
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric /// ParseDecltypeSpecifier - Parse a C++11 decltype specifier.
11160b57cec5SDimitry Andric ///
11170b57cec5SDimitry Andric /// 'decltype' ( expression )
11180b57cec5SDimitry Andric /// 'decltype' ( 'auto' )      [C++1y]
11190b57cec5SDimitry Andric ///
11200b57cec5SDimitry Andric SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
1121972a253aSDimitry Andric   assert(Tok.isOneOf(tok::kw_decltype, tok::annot_decltype) &&
1122972a253aSDimitry Andric          "Not a decltype specifier");
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric   ExprResult Result;
11250b57cec5SDimitry Andric   SourceLocation StartLoc = Tok.getLocation();
11260b57cec5SDimitry Andric   SourceLocation EndLoc;
11270b57cec5SDimitry Andric 
11280b57cec5SDimitry Andric   if (Tok.is(tok::annot_decltype)) {
11290b57cec5SDimitry Andric     Result = getExprAnnotation(Tok);
11300b57cec5SDimitry Andric     EndLoc = Tok.getAnnotationEndLoc();
113104eeddc0SDimitry Andric     // Unfortunately, we don't know the LParen source location as the annotated
113204eeddc0SDimitry Andric     // token doesn't have it.
1133bdd1243dSDimitry Andric     DS.setTypeArgumentRange(SourceRange(SourceLocation(), EndLoc));
11340b57cec5SDimitry Andric     ConsumeAnnotationToken();
11350b57cec5SDimitry Andric     if (Result.isInvalid()) {
11360b57cec5SDimitry Andric       DS.SetTypeSpecError();
11370b57cec5SDimitry Andric       return EndLoc;
11380b57cec5SDimitry Andric     }
11390b57cec5SDimitry Andric   } else {
11400b57cec5SDimitry Andric     if (Tok.getIdentifierInfo()->isStr("decltype"))
11410b57cec5SDimitry Andric       Diag(Tok, diag::warn_cxx98_compat_decltype);
11420b57cec5SDimitry Andric 
11430b57cec5SDimitry Andric     ConsumeToken();
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric     BalancedDelimiterTracker T(*this, tok::l_paren);
1146972a253aSDimitry Andric     if (T.expectAndConsume(diag::err_expected_lparen_after, "decltype",
1147972a253aSDimitry Andric                            tok::r_paren)) {
11480b57cec5SDimitry Andric       DS.SetTypeSpecError();
1149972a253aSDimitry Andric       return T.getOpenLocation() == Tok.getLocation() ? StartLoc
1150972a253aSDimitry Andric                                                       : T.getOpenLocation();
11510b57cec5SDimitry Andric     }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric     // Check for C++1y 'decltype(auto)'.
115481ad6265SDimitry Andric     if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) {
115581ad6265SDimitry Andric       // the typename-specifier in a function-style cast expression may
115606c3fb27SDimitry Andric       // be 'auto' since C++23.
11570b57cec5SDimitry Andric       Diag(Tok.getLocation(),
11580b57cec5SDimitry Andric            getLangOpts().CPlusPlus14
11590b57cec5SDimitry Andric                ? diag::warn_cxx11_compat_decltype_auto_type_specifier
11600b57cec5SDimitry Andric                : diag::ext_decltype_auto_type_specifier);
11610b57cec5SDimitry Andric       ConsumeToken();
11620b57cec5SDimitry Andric     } else {
11630b57cec5SDimitry Andric       // Parse the expression
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric       // C++11 [dcl.type.simple]p4:
11660b57cec5SDimitry Andric       //   The operand of the decltype specifier is an unevaluated operand.
11670b57cec5SDimitry Andric       EnterExpressionEvaluationContext Unevaluated(
11680b57cec5SDimitry Andric           Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
11690b57cec5SDimitry Andric           Sema::ExpressionEvaluationContextRecord::EK_Decltype);
11705ffd83dbSDimitry Andric       Result = Actions.CorrectDelayedTyposInExpr(
11715ffd83dbSDimitry Andric           ParseExpression(), /*InitDecl=*/nullptr,
11725ffd83dbSDimitry Andric           /*RecoverUncorrectedTypos=*/false,
11735ffd83dbSDimitry Andric           [](Expr *E) { return E->hasPlaceholderType() ? ExprError() : E; });
11740b57cec5SDimitry Andric       if (Result.isInvalid()) {
11750b57cec5SDimitry Andric         DS.SetTypeSpecError();
11760b57cec5SDimitry Andric         if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
11770b57cec5SDimitry Andric           EndLoc = ConsumeParen();
11780b57cec5SDimitry Andric         } else {
11790b57cec5SDimitry Andric           if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) {
11800b57cec5SDimitry Andric             // Backtrack to get the location of the last token before the semi.
11810b57cec5SDimitry Andric             PP.RevertCachedTokens(2);
11820b57cec5SDimitry Andric             ConsumeToken(); // the semi.
11830b57cec5SDimitry Andric             EndLoc = ConsumeAnyToken();
11840b57cec5SDimitry Andric             assert(Tok.is(tok::semi));
11850b57cec5SDimitry Andric           } else {
11860b57cec5SDimitry Andric             EndLoc = Tok.getLocation();
11870b57cec5SDimitry Andric           }
11880b57cec5SDimitry Andric         }
11890b57cec5SDimitry Andric         return EndLoc;
11900b57cec5SDimitry Andric       }
11910b57cec5SDimitry Andric 
11920b57cec5SDimitry Andric       Result = Actions.ActOnDecltypeExpression(Result.get());
11930b57cec5SDimitry Andric     }
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric     // Match the ')'
11960b57cec5SDimitry Andric     T.consumeClose();
1197bdd1243dSDimitry Andric     DS.setTypeArgumentRange(T.getRange());
11980b57cec5SDimitry Andric     if (T.getCloseLocation().isInvalid()) {
11990b57cec5SDimitry Andric       DS.SetTypeSpecError();
12000b57cec5SDimitry Andric       // FIXME: this should return the location of the last token
12010b57cec5SDimitry Andric       //        that was consumed (by "consumeClose()")
12020b57cec5SDimitry Andric       return T.getCloseLocation();
12030b57cec5SDimitry Andric     }
12040b57cec5SDimitry Andric 
12050b57cec5SDimitry Andric     if (Result.isInvalid()) {
12060b57cec5SDimitry Andric       DS.SetTypeSpecError();
12070b57cec5SDimitry Andric       return T.getCloseLocation();
12080b57cec5SDimitry Andric     }
12090b57cec5SDimitry Andric 
12100b57cec5SDimitry Andric     EndLoc = T.getCloseLocation();
12110b57cec5SDimitry Andric   }
12120b57cec5SDimitry Andric   assert(!Result.isInvalid());
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric   const char *PrevSpec = nullptr;
12150b57cec5SDimitry Andric   unsigned DiagID;
12160b57cec5SDimitry Andric   const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
12170b57cec5SDimitry Andric   // Check for duplicate type specifiers (e.g. "int decltype(a)").
1218972a253aSDimitry Andric   if (Result.get() ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc,
1219972a253aSDimitry Andric                                         PrevSpec, DiagID, Result.get(), Policy)
1220972a253aSDimitry Andric                    : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc,
1221972a253aSDimitry Andric                                         PrevSpec, DiagID, Policy)) {
12220b57cec5SDimitry Andric     Diag(StartLoc, DiagID) << PrevSpec;
12230b57cec5SDimitry Andric     DS.SetTypeSpecError();
12240b57cec5SDimitry Andric   }
12250b57cec5SDimitry Andric   return EndLoc;
12260b57cec5SDimitry Andric }
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
12290b57cec5SDimitry Andric                                                SourceLocation StartLoc,
12300b57cec5SDimitry Andric                                                SourceLocation EndLoc) {
12310b57cec5SDimitry Andric   // make sure we have a token we can turn into an annotation token
1232e8d8bef9SDimitry Andric   if (PP.isBacktrackEnabled()) {
12330b57cec5SDimitry Andric     PP.RevertCachedTokens(1);
1234e8d8bef9SDimitry Andric     if (DS.getTypeSpecType() == TST_error) {
1235e8d8bef9SDimitry Andric       // We encountered an error in parsing 'decltype(...)' so lets annotate all
1236e8d8bef9SDimitry Andric       // the tokens in the backtracking cache - that we likely had to skip over
1237e8d8bef9SDimitry Andric       // to get to a token that allows us to resume parsing, such as a
1238e8d8bef9SDimitry Andric       // semi-colon.
1239e8d8bef9SDimitry Andric       EndLoc = PP.getLastCachedTokenLocation();
1240e8d8bef9SDimitry Andric     }
1241972a253aSDimitry Andric   } else
12420b57cec5SDimitry Andric     PP.EnterToken(Tok, /*IsReinject*/ true);
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric   Tok.setKind(tok::annot_decltype);
12450b57cec5SDimitry Andric   setExprAnnotation(Tok,
1246972a253aSDimitry Andric                     DS.getTypeSpecType() == TST_decltype ? DS.getRepAsExpr()
1247972a253aSDimitry Andric                     : DS.getTypeSpecType() == TST_decltype_auto ? ExprResult()
1248972a253aSDimitry Andric                                                                 : ExprError());
12490b57cec5SDimitry Andric   Tok.setAnnotationEndLoc(EndLoc);
12500b57cec5SDimitry Andric   Tok.setLocation(StartLoc);
12510b57cec5SDimitry Andric   PP.AnnotateCachedTokens(Tok);
12520b57cec5SDimitry Andric }
12530b57cec5SDimitry Andric 
1254*0fca6ea1SDimitry Andric SourceLocation Parser::ParsePackIndexingType(DeclSpec &DS) {
1255*0fca6ea1SDimitry Andric   assert(Tok.isOneOf(tok::annot_pack_indexing_type, tok::identifier) &&
1256*0fca6ea1SDimitry Andric          "Expected an identifier");
1257*0fca6ea1SDimitry Andric 
1258*0fca6ea1SDimitry Andric   TypeResult Type;
1259*0fca6ea1SDimitry Andric   SourceLocation StartLoc;
1260*0fca6ea1SDimitry Andric   SourceLocation EllipsisLoc;
1261*0fca6ea1SDimitry Andric   const char *PrevSpec;
1262*0fca6ea1SDimitry Andric   unsigned DiagID;
1263*0fca6ea1SDimitry Andric   const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
1264*0fca6ea1SDimitry Andric 
1265*0fca6ea1SDimitry Andric   if (Tok.is(tok::annot_pack_indexing_type)) {
1266*0fca6ea1SDimitry Andric     StartLoc = Tok.getLocation();
1267*0fca6ea1SDimitry Andric     SourceLocation EndLoc;
1268*0fca6ea1SDimitry Andric     Type = getTypeAnnotation(Tok);
1269*0fca6ea1SDimitry Andric     EndLoc = Tok.getAnnotationEndLoc();
1270*0fca6ea1SDimitry Andric     // Unfortunately, we don't know the LParen source location as the annotated
1271*0fca6ea1SDimitry Andric     // token doesn't have it.
1272*0fca6ea1SDimitry Andric     DS.setTypeArgumentRange(SourceRange(SourceLocation(), EndLoc));
1273*0fca6ea1SDimitry Andric     ConsumeAnnotationToken();
1274*0fca6ea1SDimitry Andric     if (Type.isInvalid()) {
1275*0fca6ea1SDimitry Andric       DS.SetTypeSpecError();
1276*0fca6ea1SDimitry Andric       return EndLoc;
1277*0fca6ea1SDimitry Andric     }
1278*0fca6ea1SDimitry Andric     DS.SetTypeSpecType(DeclSpec::TST_typename_pack_indexing, StartLoc, PrevSpec,
1279*0fca6ea1SDimitry Andric                        DiagID, Type, Policy);
1280*0fca6ea1SDimitry Andric     return EndLoc;
1281*0fca6ea1SDimitry Andric   }
1282*0fca6ea1SDimitry Andric   if (!NextToken().is(tok::ellipsis) ||
1283*0fca6ea1SDimitry Andric       !GetLookAheadToken(2).is(tok::l_square)) {
1284*0fca6ea1SDimitry Andric     DS.SetTypeSpecError();
1285*0fca6ea1SDimitry Andric     return Tok.getEndLoc();
1286*0fca6ea1SDimitry Andric   }
1287*0fca6ea1SDimitry Andric 
1288*0fca6ea1SDimitry Andric   ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
1289*0fca6ea1SDimitry Andric                                       Tok.getLocation(), getCurScope());
1290*0fca6ea1SDimitry Andric   if (!Ty) {
1291*0fca6ea1SDimitry Andric     DS.SetTypeSpecError();
1292*0fca6ea1SDimitry Andric     return Tok.getEndLoc();
1293*0fca6ea1SDimitry Andric   }
1294*0fca6ea1SDimitry Andric   Type = Ty;
1295*0fca6ea1SDimitry Andric 
1296*0fca6ea1SDimitry Andric   StartLoc = ConsumeToken();
1297*0fca6ea1SDimitry Andric   EllipsisLoc = ConsumeToken();
1298*0fca6ea1SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_square);
1299*0fca6ea1SDimitry Andric   T.consumeOpen();
1300*0fca6ea1SDimitry Andric   ExprResult IndexExpr = ParseConstantExpression();
1301*0fca6ea1SDimitry Andric   T.consumeClose();
1302*0fca6ea1SDimitry Andric 
1303*0fca6ea1SDimitry Andric   DS.SetRangeStart(StartLoc);
1304*0fca6ea1SDimitry Andric   DS.SetRangeEnd(T.getCloseLocation());
1305*0fca6ea1SDimitry Andric 
1306*0fca6ea1SDimitry Andric   if (!IndexExpr.isUsable()) {
1307*0fca6ea1SDimitry Andric     ASTContext &C = Actions.getASTContext();
1308*0fca6ea1SDimitry Andric     IndexExpr = IntegerLiteral::Create(C, C.MakeIntValue(0, C.getSizeType()),
1309*0fca6ea1SDimitry Andric                                        C.getSizeType(), SourceLocation());
1310*0fca6ea1SDimitry Andric   }
1311*0fca6ea1SDimitry Andric 
1312*0fca6ea1SDimitry Andric   DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, PrevSpec, DiagID, Type,
1313*0fca6ea1SDimitry Andric                      Policy);
1314*0fca6ea1SDimitry Andric   DS.SetPackIndexingExpr(EllipsisLoc, IndexExpr.get());
1315*0fca6ea1SDimitry Andric   return T.getCloseLocation();
1316*0fca6ea1SDimitry Andric }
1317*0fca6ea1SDimitry Andric 
1318*0fca6ea1SDimitry Andric void Parser::AnnotateExistingIndexedTypeNamePack(ParsedType T,
1319*0fca6ea1SDimitry Andric                                                  SourceLocation StartLoc,
1320*0fca6ea1SDimitry Andric                                                  SourceLocation EndLoc) {
1321*0fca6ea1SDimitry Andric   // make sure we have a token we can turn into an annotation token
1322*0fca6ea1SDimitry Andric   if (PP.isBacktrackEnabled()) {
1323*0fca6ea1SDimitry Andric     PP.RevertCachedTokens(1);
1324*0fca6ea1SDimitry Andric     if (!T) {
1325*0fca6ea1SDimitry Andric       // We encountered an error in parsing 'decltype(...)' so lets annotate all
1326*0fca6ea1SDimitry Andric       // the tokens in the backtracking cache - that we likely had to skip over
1327*0fca6ea1SDimitry Andric       // to get to a token that allows us to resume parsing, such as a
1328*0fca6ea1SDimitry Andric       // semi-colon.
1329*0fca6ea1SDimitry Andric       EndLoc = PP.getLastCachedTokenLocation();
1330*0fca6ea1SDimitry Andric     }
1331*0fca6ea1SDimitry Andric   } else
1332*0fca6ea1SDimitry Andric     PP.EnterToken(Tok, /*IsReinject*/ true);
1333*0fca6ea1SDimitry Andric 
1334*0fca6ea1SDimitry Andric   Tok.setKind(tok::annot_pack_indexing_type);
1335*0fca6ea1SDimitry Andric   setTypeAnnotation(Tok, T);
1336*0fca6ea1SDimitry Andric   Tok.setAnnotationEndLoc(EndLoc);
1337*0fca6ea1SDimitry Andric   Tok.setLocation(StartLoc);
1338*0fca6ea1SDimitry Andric   PP.AnnotateCachedTokens(Tok);
1339*0fca6ea1SDimitry Andric }
1340*0fca6ea1SDimitry Andric 
1341bdd1243dSDimitry Andric DeclSpec::TST Parser::TypeTransformTokToDeclSpec() {
1342bdd1243dSDimitry Andric   switch (Tok.getKind()) {
1343bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait)                                     \
1344bdd1243dSDimitry Andric   case tok::kw___##Trait:                                                      \
1345bdd1243dSDimitry Andric     return DeclSpec::TST_##Trait;
1346bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def"
1347bdd1243dSDimitry Andric   default:
1348bdd1243dSDimitry Andric     llvm_unreachable("passed in an unhandled type transformation built-in");
13490b57cec5SDimitry Andric   }
1350bdd1243dSDimitry Andric }
1351bdd1243dSDimitry Andric 
1352bdd1243dSDimitry Andric bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {
1353bdd1243dSDimitry Andric   if (!NextToken().is(tok::l_paren)) {
1354bdd1243dSDimitry Andric     Tok.setKind(tok::identifier);
1355bdd1243dSDimitry Andric     return false;
1356bdd1243dSDimitry Andric   }
1357bdd1243dSDimitry Andric   DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();
1358bdd1243dSDimitry Andric   SourceLocation StartLoc = ConsumeToken();
1359bdd1243dSDimitry Andric 
1360bdd1243dSDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_paren);
1361bdd1243dSDimitry Andric   if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.getName(),
1362bdd1243dSDimitry Andric                          tok::r_paren))
1363bdd1243dSDimitry Andric     return true;
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric   TypeResult Result = ParseTypeName();
13660b57cec5SDimitry Andric   if (Result.isInvalid()) {
13670b57cec5SDimitry Andric     SkipUntil(tok::r_paren, StopAtSemi);
1368bdd1243dSDimitry Andric     return true;
13690b57cec5SDimitry Andric   }
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   T.consumeClose();
13720b57cec5SDimitry Andric   if (T.getCloseLocation().isInvalid())
1373bdd1243dSDimitry Andric     return true;
13740b57cec5SDimitry Andric 
13750b57cec5SDimitry Andric   const char *PrevSpec = nullptr;
13760b57cec5SDimitry Andric   unsigned DiagID;
1377bdd1243dSDimitry Andric   if (DS.SetTypeSpecType(TypeTransformTST, StartLoc, PrevSpec, DiagID,
1378bdd1243dSDimitry Andric                          Result.get(),
13790b57cec5SDimitry Andric                          Actions.getASTContext().getPrintingPolicy()))
13800b57cec5SDimitry Andric     Diag(StartLoc, DiagID) << PrevSpec;
1381bdd1243dSDimitry Andric   DS.setTypeArgumentRange(T.getRange());
1382bdd1243dSDimitry Andric   return true;
13830b57cec5SDimitry Andric }
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric /// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a
13860b57cec5SDimitry Andric /// class name or decltype-specifier. Note that we only check that the result
13870b57cec5SDimitry Andric /// names a type; semantic analysis will need to verify that the type names a
13880b57cec5SDimitry Andric /// class. The result is either a type or null, depending on whether a type
13890b57cec5SDimitry Andric /// name was found.
13900b57cec5SDimitry Andric ///
13910b57cec5SDimitry Andric ///       base-type-specifier: [C++11 class.derived]
13920b57cec5SDimitry Andric ///         class-or-decltype
13930b57cec5SDimitry Andric ///       class-or-decltype: [C++11 class.derived]
13940b57cec5SDimitry Andric ///         nested-name-specifier[opt] class-name
13950b57cec5SDimitry Andric ///         decltype-specifier
13960b57cec5SDimitry Andric ///       class-name: [C++ class.name]
13970b57cec5SDimitry Andric ///         identifier
13980b57cec5SDimitry Andric ///         simple-template-id
13990b57cec5SDimitry Andric ///
14000b57cec5SDimitry Andric /// In C++98, instead of base-type-specifier, we have:
14010b57cec5SDimitry Andric ///
14020b57cec5SDimitry Andric ///         ::[opt] nested-name-specifier[opt] class-name
14030b57cec5SDimitry Andric TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
14040b57cec5SDimitry Andric                                           SourceLocation &EndLocation) {
14050b57cec5SDimitry Andric   // Ignore attempts to use typename
14060b57cec5SDimitry Andric   if (Tok.is(tok::kw_typename)) {
14070b57cec5SDimitry Andric     Diag(Tok, diag::err_expected_class_name_not_template)
14080b57cec5SDimitry Andric         << FixItHint::CreateRemoval(Tok.getLocation());
14090b57cec5SDimitry Andric     ConsumeToken();
14100b57cec5SDimitry Andric   }
14110b57cec5SDimitry Andric 
14120b57cec5SDimitry Andric   // Parse optional nested-name-specifier
14130b57cec5SDimitry Andric   CXXScopeSpec SS;
14145ffd83dbSDimitry Andric   if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
141504eeddc0SDimitry Andric                                      /*ObjectHasErrors=*/false,
14165ffd83dbSDimitry Andric                                      /*EnteringContext=*/false))
14170b57cec5SDimitry Andric     return true;
14180b57cec5SDimitry Andric 
14190b57cec5SDimitry Andric   BaseLoc = Tok.getLocation();
14200b57cec5SDimitry Andric 
14210b57cec5SDimitry Andric   // Parse decltype-specifier
14220b57cec5SDimitry Andric   // tok == kw_decltype is just error recovery, it can only happen when SS
14230b57cec5SDimitry Andric   // isn't empty
14240b57cec5SDimitry Andric   if (Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {
14250b57cec5SDimitry Andric     if (SS.isNotEmpty())
14260b57cec5SDimitry Andric       Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
14270b57cec5SDimitry Andric           << FixItHint::CreateRemoval(SS.getRange());
14280b57cec5SDimitry Andric     // Fake up a Declarator to use with ActOnTypeName.
14290b57cec5SDimitry Andric     DeclSpec DS(AttrFactory);
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric     EndLocation = ParseDecltypeSpecifier(DS);
14320b57cec5SDimitry Andric 
143381ad6265SDimitry Andric     Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
143481ad6265SDimitry Andric                               DeclaratorContext::TypeName);
14357a6dacacSDimitry Andric     return Actions.ActOnTypeName(DeclaratorInfo);
14360b57cec5SDimitry Andric   }
14370b57cec5SDimitry Andric 
1438*0fca6ea1SDimitry Andric   if (Tok.is(tok::annot_pack_indexing_type)) {
1439*0fca6ea1SDimitry Andric     DeclSpec DS(AttrFactory);
1440*0fca6ea1SDimitry Andric     ParsePackIndexingType(DS);
1441*0fca6ea1SDimitry Andric     Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
1442*0fca6ea1SDimitry Andric                               DeclaratorContext::TypeName);
1443*0fca6ea1SDimitry Andric     return Actions.ActOnTypeName(DeclaratorInfo);
1444*0fca6ea1SDimitry Andric   }
1445*0fca6ea1SDimitry Andric 
14460b57cec5SDimitry Andric   // Check whether we have a template-id that names a type.
1447*0fca6ea1SDimitry Andric   // FIXME: identifier and annot_template_id handling in ParseUsingDeclaration
1448*0fca6ea1SDimitry Andric   // work very similarly. It should be refactored into a separate function.
14490b57cec5SDimitry Andric   if (Tok.is(tok::annot_template_id)) {
14500b57cec5SDimitry Andric     TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
14515ffd83dbSDimitry Andric     if (TemplateId->mightBeType()) {
1452bdd1243dSDimitry Andric       AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,
1453bdd1243dSDimitry Andric                                     /*IsClassName=*/true);
14540b57cec5SDimitry Andric 
14550b57cec5SDimitry Andric       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
14565ffd83dbSDimitry Andric       TypeResult Type = getTypeAnnotation(Tok);
14570b57cec5SDimitry Andric       EndLocation = Tok.getAnnotationEndLoc();
14580b57cec5SDimitry Andric       ConsumeAnnotationToken();
14590b57cec5SDimitry Andric       return Type;
14600b57cec5SDimitry Andric     }
14610b57cec5SDimitry Andric 
14620b57cec5SDimitry Andric     // Fall through to produce an error below.
14630b57cec5SDimitry Andric   }
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric   if (Tok.isNot(tok::identifier)) {
14660b57cec5SDimitry Andric     Diag(Tok, diag::err_expected_class_name);
14670b57cec5SDimitry Andric     return true;
14680b57cec5SDimitry Andric   }
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric   IdentifierInfo *Id = Tok.getIdentifierInfo();
14710b57cec5SDimitry Andric   SourceLocation IdLoc = ConsumeToken();
14720b57cec5SDimitry Andric 
14730b57cec5SDimitry Andric   if (Tok.is(tok::less)) {
14740b57cec5SDimitry Andric     // It looks the user intended to write a template-id here, but the
14750b57cec5SDimitry Andric     // template-name was wrong. Try to fix that.
14765ffd83dbSDimitry Andric     // FIXME: Invoke ParseOptionalCXXScopeSpecifier in a "'template' is neither
14775ffd83dbSDimitry Andric     // required nor permitted" mode, and do this there.
14785ffd83dbSDimitry Andric     TemplateNameKind TNK = TNK_Non_template;
14790b57cec5SDimitry Andric     TemplateTy Template;
1480972a253aSDimitry Andric     if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(), &SS,
1481972a253aSDimitry Andric                                              Template, TNK)) {
1482972a253aSDimitry Andric       Diag(IdLoc, diag::err_unknown_template_name) << Id;
14830b57cec5SDimitry Andric     }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric     // Form the template name
14860b57cec5SDimitry Andric     UnqualifiedId TemplateName;
14870b57cec5SDimitry Andric     TemplateName.setIdentifier(Id, IdLoc);
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric     // Parse the full template-id, then turn it into a type.
14900b57cec5SDimitry Andric     if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
14910b57cec5SDimitry Andric                                 TemplateName))
14920b57cec5SDimitry Andric       return true;
14935ffd83dbSDimitry Andric     if (Tok.is(tok::annot_template_id) &&
14945ffd83dbSDimitry Andric         takeTemplateIdAnnotation(Tok)->mightBeType())
1495bdd1243dSDimitry Andric       AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,
1496bdd1243dSDimitry Andric                                     /*IsClassName=*/true);
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric     // If we didn't end up with a typename token, there's nothing more we
14990b57cec5SDimitry Andric     // can do.
15000b57cec5SDimitry Andric     if (Tok.isNot(tok::annot_typename))
15010b57cec5SDimitry Andric       return true;
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric     // Retrieve the type from the annotation token, consume that token, and
15040b57cec5SDimitry Andric     // return.
15050b57cec5SDimitry Andric     EndLocation = Tok.getAnnotationEndLoc();
15065ffd83dbSDimitry Andric     TypeResult Type = getTypeAnnotation(Tok);
15070b57cec5SDimitry Andric     ConsumeAnnotationToken();
15080b57cec5SDimitry Andric     return Type;
15090b57cec5SDimitry Andric   }
15100b57cec5SDimitry Andric 
15110b57cec5SDimitry Andric   // We have an identifier; check whether it is actually a type.
15120b57cec5SDimitry Andric   IdentifierInfo *CorrectedII = nullptr;
15130b57cec5SDimitry Andric   ParsedType Type = Actions.getTypeName(
15140b57cec5SDimitry Andric       *Id, IdLoc, getCurScope(), &SS, /*isClassName=*/true, false, nullptr,
15150b57cec5SDimitry Andric       /*IsCtorOrDtorName=*/false,
15160b57cec5SDimitry Andric       /*WantNontrivialTypeSourceInfo=*/true,
1517bdd1243dSDimitry Andric       /*IsClassTemplateDeductionContext=*/false, ImplicitTypenameContext::No,
1518bdd1243dSDimitry Andric       &CorrectedII);
15190b57cec5SDimitry Andric   if (!Type) {
15200b57cec5SDimitry Andric     Diag(IdLoc, diag::err_expected_class_name);
15210b57cec5SDimitry Andric     return true;
15220b57cec5SDimitry Andric   }
15230b57cec5SDimitry Andric 
15240b57cec5SDimitry Andric   // Consume the identifier.
15250b57cec5SDimitry Andric   EndLocation = IdLoc;
15260b57cec5SDimitry Andric 
15270b57cec5SDimitry Andric   // Fake up a Declarator to use with ActOnTypeName.
15280b57cec5SDimitry Andric   DeclSpec DS(AttrFactory);
15290b57cec5SDimitry Andric   DS.SetRangeStart(IdLoc);
15300b57cec5SDimitry Andric   DS.SetRangeEnd(EndLocation);
15310b57cec5SDimitry Andric   DS.getTypeSpecScope() = SS;
15320b57cec5SDimitry Andric 
15330b57cec5SDimitry Andric   const char *PrevSpec = nullptr;
15340b57cec5SDimitry Andric   unsigned DiagID;
15350b57cec5SDimitry Andric   DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type,
15360b57cec5SDimitry Andric                      Actions.getASTContext().getPrintingPolicy());
15370b57cec5SDimitry Andric 
153881ad6265SDimitry Andric   Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
153981ad6265SDimitry Andric                             DeclaratorContext::TypeName);
15407a6dacacSDimitry Andric   return Actions.ActOnTypeName(DeclaratorInfo);
15410b57cec5SDimitry Andric }
15420b57cec5SDimitry Andric 
15430b57cec5SDimitry Andric void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
15440b57cec5SDimitry Andric   while (Tok.isOneOf(tok::kw___single_inheritance,
15450b57cec5SDimitry Andric                      tok::kw___multiple_inheritance,
15460b57cec5SDimitry Andric                      tok::kw___virtual_inheritance)) {
15470b57cec5SDimitry Andric     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
154806c3fb27SDimitry Andric     auto Kind = Tok.getKind();
15490b57cec5SDimitry Andric     SourceLocation AttrNameLoc = ConsumeToken();
155006c3fb27SDimitry Andric     attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
15510b57cec5SDimitry Andric   }
15520b57cec5SDimitry Andric }
15530b57cec5SDimitry Andric 
1554*0fca6ea1SDimitry Andric void Parser::ParseNullabilityClassAttributes(ParsedAttributes &attrs) {
1555*0fca6ea1SDimitry Andric   while (Tok.is(tok::kw__Nullable)) {
1556*0fca6ea1SDimitry Andric     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1557*0fca6ea1SDimitry Andric     auto Kind = Tok.getKind();
1558*0fca6ea1SDimitry Andric     SourceLocation AttrNameLoc = ConsumeToken();
1559*0fca6ea1SDimitry Andric     attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);
1560*0fca6ea1SDimitry Andric   }
1561*0fca6ea1SDimitry Andric }
1562*0fca6ea1SDimitry Andric 
15630b57cec5SDimitry Andric /// Determine whether the following tokens are valid after a type-specifier
15640b57cec5SDimitry Andric /// which could be a standalone declaration. This will conservatively return
15650b57cec5SDimitry Andric /// true if there's any doubt, and is appropriate for insert-';' fixits.
15660b57cec5SDimitry Andric bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
15670b57cec5SDimitry Andric   // This switch enumerates the valid "follow" set for type-specifiers.
15680b57cec5SDimitry Andric   switch (Tok.getKind()) {
1569972a253aSDimitry Andric   default:
157006c3fb27SDimitry Andric     if (Tok.isRegularKeywordAttribute())
157106c3fb27SDimitry Andric       return true;
1572972a253aSDimitry Andric     break;
15730b57cec5SDimitry Andric   case tok::semi:              // struct foo {...} ;
15740b57cec5SDimitry Andric   case tok::star:              // struct foo {...} *         P;
15750b57cec5SDimitry Andric   case tok::amp:               // struct foo {...} &         R = ...
15760b57cec5SDimitry Andric   case tok::ampamp:            // struct foo {...} &&        R = ...
15770b57cec5SDimitry Andric   case tok::identifier:        // struct foo {...} V         ;
15780b57cec5SDimitry Andric   case tok::r_paren:           //(struct foo {...} )         {4}
15790b57cec5SDimitry Andric   case tok::coloncolon:        // struct foo {...} ::        a::b;
15800b57cec5SDimitry Andric   case tok::annot_cxxscope:    // struct foo {...} a::       b;
15810b57cec5SDimitry Andric   case tok::annot_typename:    // struct foo {...} a         ::b;
15820b57cec5SDimitry Andric   case tok::annot_template_id: // struct foo {...} a<int>    ::b;
15830b57cec5SDimitry Andric   case tok::kw_decltype:       // struct foo {...} decltype  (a)::b;
15840b57cec5SDimitry Andric   case tok::l_paren:           // struct foo {...} (         x);
15850b57cec5SDimitry Andric   case tok::comma:             // __builtin_offsetof(struct foo{...} ,
15860b57cec5SDimitry Andric   case tok::kw_operator:       // struct foo       operator  ++() {...}
15870b57cec5SDimitry Andric   case tok::kw___declspec:     // struct foo {...} __declspec(...)
15880b57cec5SDimitry Andric   case tok::l_square:          // void f(struct f  [         3])
15890b57cec5SDimitry Andric   case tok::ellipsis:          // void f(struct f  ...       [Ns])
15900b57cec5SDimitry Andric   // FIXME: we should emit semantic diagnostic when declaration
15910b57cec5SDimitry Andric   // attribute is in type attribute position.
15920b57cec5SDimitry Andric   case tok::kw___attribute:    // struct foo __attribute__((used)) x;
15930b57cec5SDimitry Andric   case tok::annot_pragma_pack: // struct foo {...} _Pragma(pack(pop));
15940b57cec5SDimitry Andric   // struct foo {...} _Pragma(section(...));
15950b57cec5SDimitry Andric   case tok::annot_pragma_ms_pragma:
15960b57cec5SDimitry Andric   // struct foo {...} _Pragma(vtordisp(pop));
15970b57cec5SDimitry Andric   case tok::annot_pragma_ms_vtordisp:
15980b57cec5SDimitry Andric   // struct foo {...} _Pragma(pointers_to_members(...));
15990b57cec5SDimitry Andric   case tok::annot_pragma_ms_pointers_to_members:
16000b57cec5SDimitry Andric     return true;
16010b57cec5SDimitry Andric   case tok::colon:
16025ffd83dbSDimitry Andric     return CouldBeBitfield || // enum E { ... }   :         2;
16035ffd83dbSDimitry Andric            ColonIsSacred;     // _Generic(..., enum E :     2);
16040b57cec5SDimitry Andric   // Microsoft compatibility
16050b57cec5SDimitry Andric   case tok::kw___cdecl:      // struct foo {...} __cdecl      x;
16060b57cec5SDimitry Andric   case tok::kw___fastcall:   // struct foo {...} __fastcall   x;
16070b57cec5SDimitry Andric   case tok::kw___stdcall:    // struct foo {...} __stdcall    x;
16080b57cec5SDimitry Andric   case tok::kw___thiscall:   // struct foo {...} __thiscall   x;
16090b57cec5SDimitry Andric   case tok::kw___vectorcall: // struct foo {...} __vectorcall x;
16100b57cec5SDimitry Andric     // We will diagnose these calling-convention specifiers on non-function
16110b57cec5SDimitry Andric     // declarations later, so claim they are valid after a type specifier.
16120b57cec5SDimitry Andric     return getLangOpts().MicrosoftExt;
16130b57cec5SDimitry Andric   // Type qualifiers
16140b57cec5SDimitry Andric   case tok::kw_const:       // struct foo {...} const     x;
16150b57cec5SDimitry Andric   case tok::kw_volatile:    // struct foo {...} volatile  x;
16160b57cec5SDimitry Andric   case tok::kw_restrict:    // struct foo {...} restrict  x;
16170b57cec5SDimitry Andric   case tok::kw__Atomic:     // struct foo {...} _Atomic   x;
16180b57cec5SDimitry Andric   case tok::kw___unaligned: // struct foo {...} __unaligned *x;
16190b57cec5SDimitry Andric   // Function specifiers
16200b57cec5SDimitry Andric   // Note, no 'explicit'. An explicit function must be either a conversion
16210b57cec5SDimitry Andric   // operator or a constructor. Either way, it can't have a return type.
16220b57cec5SDimitry Andric   case tok::kw_inline:  // struct foo       inline    f();
16230b57cec5SDimitry Andric   case tok::kw_virtual: // struct foo       virtual   f();
16240b57cec5SDimitry Andric   case tok::kw_friend:  // struct foo       friend    f();
16250b57cec5SDimitry Andric   // Storage-class specifiers
16260b57cec5SDimitry Andric   case tok::kw_static:       // struct foo {...} static    x;
16270b57cec5SDimitry Andric   case tok::kw_extern:       // struct foo {...} extern    x;
16280b57cec5SDimitry Andric   case tok::kw_typedef:      // struct foo {...} typedef   x;
16290b57cec5SDimitry Andric   case tok::kw_register:     // struct foo {...} register  x;
16300b57cec5SDimitry Andric   case tok::kw_auto:         // struct foo {...} auto      x;
16310b57cec5SDimitry Andric   case tok::kw_mutable:      // struct foo {...} mutable   x;
16320b57cec5SDimitry Andric   case tok::kw_thread_local: // struct foo {...} thread_local x;
16330b57cec5SDimitry Andric   case tok::kw_constexpr:    // struct foo {...} constexpr x;
1634a7dea167SDimitry Andric   case tok::kw_consteval:    // struct foo {...} consteval x;
1635a7dea167SDimitry Andric   case tok::kw_constinit:    // struct foo {...} constinit x;
16360b57cec5SDimitry Andric     // As shown above, type qualifiers and storage class specifiers absolutely
16370b57cec5SDimitry Andric     // can occur after class specifiers according to the grammar.  However,
16380b57cec5SDimitry Andric     // almost no one actually writes code like this.  If we see one of these,
16390b57cec5SDimitry Andric     // it is much more likely that someone missed a semi colon and the
16400b57cec5SDimitry Andric     // type/storage class specifier we're seeing is part of the *next*
16410b57cec5SDimitry Andric     // intended declaration, as in:
16420b57cec5SDimitry Andric     //
16430b57cec5SDimitry Andric     //   struct foo { ... }
16440b57cec5SDimitry Andric     //   typedef int X;
16450b57cec5SDimitry Andric     //
16460b57cec5SDimitry Andric     // We'd really like to emit a missing semicolon error instead of emitting
16470b57cec5SDimitry Andric     // an error on the 'int' saying that you can't have two type specifiers in
16480b57cec5SDimitry Andric     // the same declaration of X.  Because of this, we look ahead past this
16490b57cec5SDimitry Andric     // token to see if it's a type specifier.  If so, we know the code is
16500b57cec5SDimitry Andric     // otherwise invalid, so we can produce the expected semi error.
16510b57cec5SDimitry Andric     if (!isKnownToBeTypeSpecifier(NextToken()))
16520b57cec5SDimitry Andric       return true;
16530b57cec5SDimitry Andric     break;
16540b57cec5SDimitry Andric   case tok::r_brace: // struct bar { struct foo {...} }
16550b57cec5SDimitry Andric     // Missing ';' at end of struct is accepted as an extension in C mode.
16560b57cec5SDimitry Andric     if (!getLangOpts().CPlusPlus)
16570b57cec5SDimitry Andric       return true;
16580b57cec5SDimitry Andric     break;
16590b57cec5SDimitry Andric   case tok::greater:
16600b57cec5SDimitry Andric     // template<class T = class X>
16610b57cec5SDimitry Andric     return getLangOpts().CPlusPlus;
16620b57cec5SDimitry Andric   }
16630b57cec5SDimitry Andric   return false;
16640b57cec5SDimitry Andric }
16650b57cec5SDimitry Andric 
16660b57cec5SDimitry Andric /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
16670b57cec5SDimitry Andric /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
16680b57cec5SDimitry Andric /// until we reach the start of a definition or see a token that
16690b57cec5SDimitry Andric /// cannot start a definition.
16700b57cec5SDimitry Andric ///
16710b57cec5SDimitry Andric ///       class-specifier: [C++ class]
16720b57cec5SDimitry Andric ///         class-head '{' member-specification[opt] '}'
16730b57cec5SDimitry Andric ///         class-head '{' member-specification[opt] '}' attributes[opt]
16740b57cec5SDimitry Andric ///       class-head:
16750b57cec5SDimitry Andric ///         class-key identifier[opt] base-clause[opt]
16760b57cec5SDimitry Andric ///         class-key nested-name-specifier identifier base-clause[opt]
16770b57cec5SDimitry Andric ///         class-key nested-name-specifier[opt] simple-template-id
16780b57cec5SDimitry Andric ///                          base-clause[opt]
16790b57cec5SDimitry Andric /// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
16800b57cec5SDimitry Andric /// [GNU]   class-key attributes[opt] nested-name-specifier
16810b57cec5SDimitry Andric ///                          identifier base-clause[opt]
16820b57cec5SDimitry Andric /// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
16830b57cec5SDimitry Andric ///                          simple-template-id base-clause[opt]
16840b57cec5SDimitry Andric ///       class-key:
16850b57cec5SDimitry Andric ///         'class'
16860b57cec5SDimitry Andric ///         'struct'
16870b57cec5SDimitry Andric ///         'union'
16880b57cec5SDimitry Andric ///
16890b57cec5SDimitry Andric ///       elaborated-type-specifier: [C++ dcl.type.elab]
16900b57cec5SDimitry Andric ///         class-key ::[opt] nested-name-specifier[opt] identifier
16910b57cec5SDimitry Andric ///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
16920b57cec5SDimitry Andric ///                          simple-template-id
16930b57cec5SDimitry Andric ///
16940b57cec5SDimitry Andric ///  Note that the C++ class-specifier and elaborated-type-specifier,
16950b57cec5SDimitry Andric ///  together, subsume the C99 struct-or-union-specifier:
16960b57cec5SDimitry Andric ///
16970b57cec5SDimitry Andric ///       struct-or-union-specifier: [C99 6.7.2.1]
16980b57cec5SDimitry Andric ///         struct-or-union identifier[opt] '{' struct-contents '}'
16990b57cec5SDimitry Andric ///         struct-or-union identifier
17000b57cec5SDimitry Andric /// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
17010b57cec5SDimitry Andric ///                                                         '}' attributes[opt]
17020b57cec5SDimitry Andric /// [GNU]   struct-or-union attributes[opt] identifier
17030b57cec5SDimitry Andric ///       struct-or-union:
17040b57cec5SDimitry Andric ///         'struct'
17050b57cec5SDimitry Andric ///         'union'
17060b57cec5SDimitry Andric void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
17070b57cec5SDimitry Andric                                  SourceLocation StartLoc, DeclSpec &DS,
1708*0fca6ea1SDimitry Andric                                  ParsedTemplateInfo &TemplateInfo,
170981ad6265SDimitry Andric                                  AccessSpecifier AS, bool EnteringContext,
171081ad6265SDimitry Andric                                  DeclSpecContext DSC,
171181ad6265SDimitry Andric                                  ParsedAttributes &Attributes) {
17120b57cec5SDimitry Andric   DeclSpec::TST TagType;
17130b57cec5SDimitry Andric   if (TagTokKind == tok::kw_struct)
17140b57cec5SDimitry Andric     TagType = DeclSpec::TST_struct;
17150b57cec5SDimitry Andric   else if (TagTokKind == tok::kw___interface)
17160b57cec5SDimitry Andric     TagType = DeclSpec::TST_interface;
17170b57cec5SDimitry Andric   else if (TagTokKind == tok::kw_class)
17180b57cec5SDimitry Andric     TagType = DeclSpec::TST_class;
17190b57cec5SDimitry Andric   else {
17200b57cec5SDimitry Andric     assert(TagTokKind == tok::kw_union && "Not a class specifier");
17210b57cec5SDimitry Andric     TagType = DeclSpec::TST_union;
17220b57cec5SDimitry Andric   }
17230b57cec5SDimitry Andric 
17240b57cec5SDimitry Andric   if (Tok.is(tok::code_completion)) {
17250b57cec5SDimitry Andric     // Code completion for a struct, class, or union name.
1726fe6060f1SDimitry Andric     cutOffParsing();
1727*0fca6ea1SDimitry Andric     Actions.CodeCompletion().CodeCompleteTag(getCurScope(), TagType);
1728fe6060f1SDimitry Andric     return;
17290b57cec5SDimitry Andric   }
17300b57cec5SDimitry Andric 
1731349cc55cSDimitry Andric   // C++20 [temp.class.spec] 13.7.5/10
1732349cc55cSDimitry Andric   //   The usual access checking rules do not apply to non-dependent names
1733349cc55cSDimitry Andric   //   used to specify template arguments of the simple-template-id of the
1734349cc55cSDimitry Andric   //   partial specialization.
1735349cc55cSDimitry Andric   // C++20 [temp.spec] 13.9/6:
1736349cc55cSDimitry Andric   //   The usual access checking rules do not apply to names in a declaration
1737349cc55cSDimitry Andric   //   of an explicit instantiation or explicit specialization...
1738349cc55cSDimitry Andric   const bool shouldDelayDiagsInTag =
1739349cc55cSDimitry Andric       (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate);
17400b57cec5SDimitry Andric   SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
17410b57cec5SDimitry Andric 
174281ad6265SDimitry Andric   ParsedAttributes attrs(AttrFactory);
17430b57cec5SDimitry Andric   // If attributes exist after tag, parse them.
1744*0fca6ea1SDimitry Andric   for (;;) {
1745fe6060f1SDimitry Andric     MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
17460b57cec5SDimitry Andric     // Parse inheritance specifiers.
1747*0fca6ea1SDimitry Andric     if (Tok.isOneOf(tok::kw___single_inheritance,
1748*0fca6ea1SDimitry Andric                     tok::kw___multiple_inheritance,
1749*0fca6ea1SDimitry Andric                     tok::kw___virtual_inheritance)) {
17500b57cec5SDimitry Andric       ParseMicrosoftInheritanceClassAttributes(attrs);
1751*0fca6ea1SDimitry Andric       continue;
1752*0fca6ea1SDimitry Andric     }
1753*0fca6ea1SDimitry Andric     if (Tok.is(tok::kw__Nullable)) {
1754*0fca6ea1SDimitry Andric       ParseNullabilityClassAttributes(attrs);
1755*0fca6ea1SDimitry Andric       continue;
1756*0fca6ea1SDimitry Andric     }
1757*0fca6ea1SDimitry Andric     break;
1758*0fca6ea1SDimitry Andric   }
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric   // Source location used by FIXIT to insert misplaced
17610b57cec5SDimitry Andric   // C++11 attributes
17620b57cec5SDimitry Andric   SourceLocation AttrFixitLoc = Tok.getLocation();
17630b57cec5SDimitry Andric 
1764972a253aSDimitry Andric   if (TagType == DeclSpec::TST_struct && Tok.isNot(tok::identifier) &&
1765972a253aSDimitry Andric       !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
1766972a253aSDimitry Andric       Tok.isOneOf(
1767bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
1768bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def"
1769bdd1243dSDimitry Andric           tok::kw___is_abstract,
1770bdd1243dSDimitry Andric           tok::kw___is_aggregate,
1771bdd1243dSDimitry Andric           tok::kw___is_arithmetic,
1772bdd1243dSDimitry Andric           tok::kw___is_array,
1773bdd1243dSDimitry Andric           tok::kw___is_assignable,
1774bdd1243dSDimitry Andric           tok::kw___is_base_of,
1775bdd1243dSDimitry Andric           tok::kw___is_bounded_array,
1776bdd1243dSDimitry Andric           tok::kw___is_class,
1777bdd1243dSDimitry Andric           tok::kw___is_complete_type,
1778bdd1243dSDimitry Andric           tok::kw___is_compound,
1779bdd1243dSDimitry Andric           tok::kw___is_const,
1780bdd1243dSDimitry Andric           tok::kw___is_constructible,
1781bdd1243dSDimitry Andric           tok::kw___is_convertible,
1782bdd1243dSDimitry Andric           tok::kw___is_convertible_to,
1783bdd1243dSDimitry Andric           tok::kw___is_destructible,
1784bdd1243dSDimitry Andric           tok::kw___is_empty,
1785bdd1243dSDimitry Andric           tok::kw___is_enum,
1786bdd1243dSDimitry Andric           tok::kw___is_floating_point,
1787bdd1243dSDimitry Andric           tok::kw___is_final,
1788bdd1243dSDimitry Andric           tok::kw___is_function,
1789bdd1243dSDimitry Andric           tok::kw___is_fundamental,
1790bdd1243dSDimitry Andric           tok::kw___is_integral,
1791bdd1243dSDimitry Andric           tok::kw___is_interface_class,
1792bdd1243dSDimitry Andric           tok::kw___is_literal,
1793bdd1243dSDimitry Andric           tok::kw___is_lvalue_expr,
1794bdd1243dSDimitry Andric           tok::kw___is_lvalue_reference,
1795bdd1243dSDimitry Andric           tok::kw___is_member_function_pointer,
1796bdd1243dSDimitry Andric           tok::kw___is_member_object_pointer,
1797bdd1243dSDimitry Andric           tok::kw___is_member_pointer,
1798bdd1243dSDimitry Andric           tok::kw___is_nothrow_assignable,
1799bdd1243dSDimitry Andric           tok::kw___is_nothrow_constructible,
1800*0fca6ea1SDimitry Andric           tok::kw___is_nothrow_convertible,
1801bdd1243dSDimitry Andric           tok::kw___is_nothrow_destructible,
1802bdd1243dSDimitry Andric           tok::kw___is_nullptr,
1803bdd1243dSDimitry Andric           tok::kw___is_object,
1804bdd1243dSDimitry Andric           tok::kw___is_pod,
1805bdd1243dSDimitry Andric           tok::kw___is_pointer,
1806bdd1243dSDimitry Andric           tok::kw___is_polymorphic,
1807bdd1243dSDimitry Andric           tok::kw___is_reference,
1808bdd1243dSDimitry Andric           tok::kw___is_referenceable,
1809bdd1243dSDimitry Andric           tok::kw___is_rvalue_expr,
1810bdd1243dSDimitry Andric           tok::kw___is_rvalue_reference,
1811bdd1243dSDimitry Andric           tok::kw___is_same,
1812bdd1243dSDimitry Andric           tok::kw___is_scalar,
1813bdd1243dSDimitry Andric           tok::kw___is_scoped_enum,
1814bdd1243dSDimitry Andric           tok::kw___is_sealed,
1815bdd1243dSDimitry Andric           tok::kw___is_signed,
1816bdd1243dSDimitry Andric           tok::kw___is_standard_layout,
1817bdd1243dSDimitry Andric           tok::kw___is_trivial,
181806c3fb27SDimitry Andric           tok::kw___is_trivially_equality_comparable,
18190b57cec5SDimitry Andric           tok::kw___is_trivially_assignable,
1820bdd1243dSDimitry Andric           tok::kw___is_trivially_constructible,
1821bdd1243dSDimitry Andric           tok::kw___is_trivially_copyable,
1822bdd1243dSDimitry Andric           tok::kw___is_unbounded_array,
1823bdd1243dSDimitry Andric           tok::kw___is_union,
1824bdd1243dSDimitry Andric           tok::kw___is_unsigned,
1825bdd1243dSDimitry Andric           tok::kw___is_void,
1826*0fca6ea1SDimitry Andric           tok::kw___is_volatile
1827*0fca6ea1SDimitry Andric       ))
18280b57cec5SDimitry Andric     // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
18290b57cec5SDimitry Andric     // name of struct templates, but some are keywords in GCC >= 4.3
18300b57cec5SDimitry Andric     // and Clang. Therefore, when we see the token sequence "struct
18310b57cec5SDimitry Andric     // X", make X into a normal identifier rather than a keyword, to
18320b57cec5SDimitry Andric     // allow libstdc++ 4.2 and libc++ to work properly.
18330b57cec5SDimitry Andric     TryKeywordIdentFallback(true);
18340b57cec5SDimitry Andric 
18350b57cec5SDimitry Andric   struct PreserveAtomicIdentifierInfoRAII {
18360b57cec5SDimitry Andric     PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled)
18370b57cec5SDimitry Andric         : AtomicII(nullptr) {
18380b57cec5SDimitry Andric       if (!Enabled)
18390b57cec5SDimitry Andric         return;
18400b57cec5SDimitry Andric       assert(Tok.is(tok::kw__Atomic));
18410b57cec5SDimitry Andric       AtomicII = Tok.getIdentifierInfo();
18420b57cec5SDimitry Andric       AtomicII->revertTokenIDToIdentifier();
18430b57cec5SDimitry Andric       Tok.setKind(tok::identifier);
18440b57cec5SDimitry Andric     }
18450b57cec5SDimitry Andric     ~PreserveAtomicIdentifierInfoRAII() {
18460b57cec5SDimitry Andric       if (!AtomicII)
18470b57cec5SDimitry Andric         return;
18480b57cec5SDimitry Andric       AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);
18490b57cec5SDimitry Andric     }
18500b57cec5SDimitry Andric     IdentifierInfo *AtomicII;
18510b57cec5SDimitry Andric   };
18520b57cec5SDimitry Andric 
18530b57cec5SDimitry Andric   // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL
18540b57cec5SDimitry Andric   // implementation for VS2013 uses _Atomic as an identifier for one of the
18550b57cec5SDimitry Andric   // classes in <atomic>.  When we are parsing 'struct _Atomic', don't consider
18560b57cec5SDimitry Andric   // '_Atomic' to be a keyword.  We are careful to undo this so that clang can
18570b57cec5SDimitry Andric   // use '_Atomic' in its own header files.
18580b57cec5SDimitry Andric   bool ShouldChangeAtomicToIdentifier = getLangOpts().MSVCCompat &&
18590b57cec5SDimitry Andric                                         Tok.is(tok::kw__Atomic) &&
18600b57cec5SDimitry Andric                                         TagType == DeclSpec::TST_struct;
18610b57cec5SDimitry Andric   PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(
18620b57cec5SDimitry Andric       Tok, ShouldChangeAtomicToIdentifier);
18630b57cec5SDimitry Andric 
18640b57cec5SDimitry Andric   // Parse the (optional) nested-name-specifier.
18650b57cec5SDimitry Andric   CXXScopeSpec &SS = DS.getTypeSpecScope();
18660b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus) {
18670b57cec5SDimitry Andric     // "FOO : BAR" is not a potential typo for "FOO::BAR".  In this context it
18680b57cec5SDimitry Andric     // is a base-specifier-list.
18690b57cec5SDimitry Andric     ColonProtectionRAIIObject X(*this);
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric     CXXScopeSpec Spec;
187206c3fb27SDimitry Andric     if (TemplateInfo.TemplateParams)
187306c3fb27SDimitry Andric       Spec.setTemplateParamLists(*TemplateInfo.TemplateParams);
187406c3fb27SDimitry Andric 
18750b57cec5SDimitry Andric     bool HasValidSpec = true;
18765ffd83dbSDimitry Andric     if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr,
187704eeddc0SDimitry Andric                                        /*ObjectHasErrors=*/false,
18785ffd83dbSDimitry Andric                                        EnteringContext)) {
18790b57cec5SDimitry Andric       DS.SetTypeSpecError();
18800b57cec5SDimitry Andric       HasValidSpec = false;
18810b57cec5SDimitry Andric     }
18820b57cec5SDimitry Andric     if (Spec.isSet())
18830b57cec5SDimitry Andric       if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) {
18840b57cec5SDimitry Andric         Diag(Tok, diag::err_expected) << tok::identifier;
18850b57cec5SDimitry Andric         HasValidSpec = false;
18860b57cec5SDimitry Andric       }
18870b57cec5SDimitry Andric     if (HasValidSpec)
18880b57cec5SDimitry Andric       SS = Spec;
18890b57cec5SDimitry Andric   }
18900b57cec5SDimitry Andric 
18910b57cec5SDimitry Andric   TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
18920b57cec5SDimitry Andric 
18930b57cec5SDimitry Andric   auto RecoverFromUndeclaredTemplateName = [&](IdentifierInfo *Name,
18940b57cec5SDimitry Andric                                                SourceLocation NameLoc,
18950b57cec5SDimitry Andric                                                SourceRange TemplateArgRange,
18960b57cec5SDimitry Andric                                                bool KnownUndeclared) {
18970b57cec5SDimitry Andric     Diag(NameLoc, diag::err_explicit_spec_non_template)
18980b57cec5SDimitry Andric         << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
18990b57cec5SDimitry Andric         << TagTokKind << Name << TemplateArgRange << KnownUndeclared;
19000b57cec5SDimitry Andric 
19010b57cec5SDimitry Andric     // Strip off the last template parameter list if it was empty, since
19020b57cec5SDimitry Andric     // we've removed its template argument list.
19030b57cec5SDimitry Andric     if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
19040b57cec5SDimitry Andric       if (TemplateParams->size() > 1) {
19050b57cec5SDimitry Andric         TemplateParams->pop_back();
19060b57cec5SDimitry Andric       } else {
19070b57cec5SDimitry Andric         TemplateParams = nullptr;
1908*0fca6ea1SDimitry Andric         TemplateInfo.Kind = ParsedTemplateInfo::NonTemplate;
19090b57cec5SDimitry Andric       }
19100b57cec5SDimitry Andric     } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
19110b57cec5SDimitry Andric       // Pretend this is just a forward declaration.
19120b57cec5SDimitry Andric       TemplateParams = nullptr;
1913*0fca6ea1SDimitry Andric       TemplateInfo.Kind = ParsedTemplateInfo::NonTemplate;
1914*0fca6ea1SDimitry Andric       TemplateInfo.TemplateLoc = SourceLocation();
1915*0fca6ea1SDimitry Andric       TemplateInfo.ExternLoc = SourceLocation();
19160b57cec5SDimitry Andric     }
19170b57cec5SDimitry Andric   };
19180b57cec5SDimitry Andric 
19190b57cec5SDimitry Andric   // Parse the (optional) class name or simple-template-id.
19200b57cec5SDimitry Andric   IdentifierInfo *Name = nullptr;
19210b57cec5SDimitry Andric   SourceLocation NameLoc;
19220b57cec5SDimitry Andric   TemplateIdAnnotation *TemplateId = nullptr;
19230b57cec5SDimitry Andric   if (Tok.is(tok::identifier)) {
19240b57cec5SDimitry Andric     Name = Tok.getIdentifierInfo();
19250b57cec5SDimitry Andric     NameLoc = ConsumeToken();
1926*0fca6ea1SDimitry Andric     DS.SetRangeEnd(NameLoc);
19270b57cec5SDimitry Andric 
19280b57cec5SDimitry Andric     if (Tok.is(tok::less) && getLangOpts().CPlusPlus) {
19290b57cec5SDimitry Andric       // The name was supposed to refer to a template, but didn't.
19300b57cec5SDimitry Andric       // Eat the template argument list and try to continue parsing this as
19310b57cec5SDimitry Andric       // a class (or template thereof).
19320b57cec5SDimitry Andric       TemplateArgList TemplateArgs;
19330b57cec5SDimitry Andric       SourceLocation LAngleLoc, RAngleLoc;
19340b57cec5SDimitry Andric       if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs,
19350b57cec5SDimitry Andric                                            RAngleLoc)) {
19360b57cec5SDimitry Andric         // We couldn't parse the template argument list at all, so don't
19370b57cec5SDimitry Andric         // try to give any location information for the list.
19380b57cec5SDimitry Andric         LAngleLoc = RAngleLoc = SourceLocation();
19390b57cec5SDimitry Andric       }
19400b57cec5SDimitry Andric       RecoverFromUndeclaredTemplateName(
19410b57cec5SDimitry Andric           Name, NameLoc, SourceRange(LAngleLoc, RAngleLoc), false);
19420b57cec5SDimitry Andric     }
19430b57cec5SDimitry Andric   } else if (Tok.is(tok::annot_template_id)) {
19440b57cec5SDimitry Andric     TemplateId = takeTemplateIdAnnotation(Tok);
19450b57cec5SDimitry Andric     NameLoc = ConsumeAnnotationToken();
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric     if (TemplateId->Kind == TNK_Undeclared_template) {
19485ffd83dbSDimitry Andric       // Try to resolve the template name to a type template. May update Kind.
19495ffd83dbSDimitry Andric       Actions.ActOnUndeclaredTypeTemplateName(
19505ffd83dbSDimitry Andric           getCurScope(), TemplateId->Template, TemplateId->Kind, NameLoc, Name);
19510b57cec5SDimitry Andric       if (TemplateId->Kind == TNK_Undeclared_template) {
19520b57cec5SDimitry Andric         RecoverFromUndeclaredTemplateName(
19530b57cec5SDimitry Andric             Name, NameLoc,
19540b57cec5SDimitry Andric             SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc), true);
19550b57cec5SDimitry Andric         TemplateId = nullptr;
19560b57cec5SDimitry Andric       }
19570b57cec5SDimitry Andric     }
19580b57cec5SDimitry Andric 
19595ffd83dbSDimitry Andric     if (TemplateId && !TemplateId->mightBeType()) {
19600b57cec5SDimitry Andric       // The template-name in the simple-template-id refers to
19615ffd83dbSDimitry Andric       // something other than a type template. Give an appropriate
19620b57cec5SDimitry Andric       // error message and skip to the ';'.
19630b57cec5SDimitry Andric       SourceRange Range(NameLoc);
19640b57cec5SDimitry Andric       if (SS.isNotEmpty())
19650b57cec5SDimitry Andric         Range.setBegin(SS.getBeginLoc());
19660b57cec5SDimitry Andric 
19670b57cec5SDimitry Andric       // FIXME: Name may be null here.
19680b57cec5SDimitry Andric       Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
19690b57cec5SDimitry Andric           << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;
19700b57cec5SDimitry Andric 
19710b57cec5SDimitry Andric       DS.SetTypeSpecError();
19720b57cec5SDimitry Andric       SkipUntil(tok::semi, StopBeforeMatch);
19730b57cec5SDimitry Andric       return;
19740b57cec5SDimitry Andric     }
19750b57cec5SDimitry Andric   }
19760b57cec5SDimitry Andric 
19770b57cec5SDimitry Andric   // There are four options here.
19780b57cec5SDimitry Andric   //  - If we are in a trailing return type, this is always just a reference,
19790b57cec5SDimitry Andric   //    and we must not try to parse a definition. For instance,
19800b57cec5SDimitry Andric   //      [] () -> struct S { };
19810b57cec5SDimitry Andric   //    does not define a type.
19820b57cec5SDimitry Andric   //  - If we have 'struct foo {...', 'struct foo :...',
19830b57cec5SDimitry Andric   //    'struct foo final :' or 'struct foo final {', then this is a definition.
19840b57cec5SDimitry Andric   //  - If we have 'struct foo;', then this is either a forward declaration
19850b57cec5SDimitry Andric   //    or a friend declaration, which have to be treated differently.
19860b57cec5SDimitry Andric   //  - Otherwise we have something like 'struct foo xyz', a reference.
19870b57cec5SDimitry Andric   //
19880b57cec5SDimitry Andric   //  We also detect these erroneous cases to provide better diagnostic for
19890b57cec5SDimitry Andric   //  C++11 attributes parsing.
19900b57cec5SDimitry Andric   //  - attributes follow class name:
19910b57cec5SDimitry Andric   //    struct foo [[]] {};
19920b57cec5SDimitry Andric   //  - attributes appear before or after 'final':
19930b57cec5SDimitry Andric   //    struct foo [[]] final [[]] {};
19940b57cec5SDimitry Andric   //
19950b57cec5SDimitry Andric   // However, in type-specifier-seq's, things look like declarations but are
19960b57cec5SDimitry Andric   // just references, e.g.
19970b57cec5SDimitry Andric   //   new struct s;
19980b57cec5SDimitry Andric   // or
19990b57cec5SDimitry Andric   //   &T::operator struct s;
20000b57cec5SDimitry Andric   // For these, DSC is DeclSpecContext::DSC_type_specifier or
20010b57cec5SDimitry Andric   // DeclSpecContext::DSC_alias_declaration.
20020b57cec5SDimitry Andric 
20030b57cec5SDimitry Andric   // If there are attributes after class name, parse them.
20040b57cec5SDimitry Andric   MaybeParseCXX11Attributes(Attributes);
20050b57cec5SDimitry Andric 
20060b57cec5SDimitry Andric   const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
2007*0fca6ea1SDimitry Andric   TagUseKind TUK;
200881ad6265SDimitry Andric   if (isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus) ==
200981ad6265SDimitry Andric           AllowDefiningTypeSpec::No ||
20105ffd83dbSDimitry Andric       (getLangOpts().OpenMP && OpenMPDirectiveParsing))
2011*0fca6ea1SDimitry Andric     TUK = TagUseKind::Reference;
20120b57cec5SDimitry Andric   else if (Tok.is(tok::l_brace) ||
201381ad6265SDimitry Andric            (DSC != DeclSpecContext::DSC_association &&
201481ad6265SDimitry Andric             getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
2015fe6060f1SDimitry Andric            (isClassCompatibleKeyword() &&
20160b57cec5SDimitry Andric             (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) {
20170b57cec5SDimitry Andric     if (DS.isFriendSpecified()) {
20180b57cec5SDimitry Andric       // C++ [class.friend]p2:
20190b57cec5SDimitry Andric       //   A class shall not be defined in a friend declaration.
20200b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
20210b57cec5SDimitry Andric           << SourceRange(DS.getFriendSpecLoc());
20220b57cec5SDimitry Andric 
20230b57cec5SDimitry Andric       // Skip everything up to the semicolon, so that this looks like a proper
20240b57cec5SDimitry Andric       // friend class (or template thereof) declaration.
20250b57cec5SDimitry Andric       SkipUntil(tok::semi, StopBeforeMatch);
2026*0fca6ea1SDimitry Andric       TUK = TagUseKind::Friend;
20270b57cec5SDimitry Andric     } else {
20280b57cec5SDimitry Andric       // Okay, this is a class definition.
2029*0fca6ea1SDimitry Andric       TUK = TagUseKind::Definition;
20300b57cec5SDimitry Andric     }
2031fe6060f1SDimitry Andric   } else if (isClassCompatibleKeyword() &&
2032fe6060f1SDimitry Andric              (NextToken().is(tok::l_square) ||
2033fe6060f1SDimitry Andric               NextToken().is(tok::kw_alignas) ||
203406c3fb27SDimitry Andric               NextToken().isRegularKeywordAttribute() ||
2035fe6060f1SDimitry Andric               isCXX11VirtSpecifier(NextToken()) != VirtSpecifiers::VS_None)) {
20360b57cec5SDimitry Andric     // We can't tell if this is a definition or reference
20370b57cec5SDimitry Andric     // until we skipped the 'final' and C++11 attribute specifiers.
20380b57cec5SDimitry Andric     TentativeParsingAction PA(*this);
20390b57cec5SDimitry Andric 
2040fe6060f1SDimitry Andric     // Skip the 'final', abstract'... keywords.
2041fe6060f1SDimitry Andric     while (isClassCompatibleKeyword()) {
20420b57cec5SDimitry Andric       ConsumeToken();
2043fe6060f1SDimitry Andric     }
20440b57cec5SDimitry Andric 
20450b57cec5SDimitry Andric     // Skip C++11 attribute specifiers.
20460b57cec5SDimitry Andric     while (true) {
20470b57cec5SDimitry Andric       if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
20480b57cec5SDimitry Andric         ConsumeBracket();
20490b57cec5SDimitry Andric         if (!SkipUntil(tok::r_square, StopAtSemi))
20500b57cec5SDimitry Andric           break;
20510b57cec5SDimitry Andric       } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {
20520b57cec5SDimitry Andric         ConsumeToken();
20530b57cec5SDimitry Andric         ConsumeParen();
20540b57cec5SDimitry Andric         if (!SkipUntil(tok::r_paren, StopAtSemi))
20550b57cec5SDimitry Andric           break;
205606c3fb27SDimitry Andric       } else if (Tok.isRegularKeywordAttribute()) {
20577a6dacacSDimitry Andric         bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());
205806c3fb27SDimitry Andric         ConsumeToken();
20597a6dacacSDimitry Andric         if (TakesArgs) {
20607a6dacacSDimitry Andric           BalancedDelimiterTracker T(*this, tok::l_paren);
20617a6dacacSDimitry Andric           if (!T.consumeOpen())
20627a6dacacSDimitry Andric             T.skipToEnd();
20637a6dacacSDimitry Andric         }
20640b57cec5SDimitry Andric       } else {
20650b57cec5SDimitry Andric         break;
20660b57cec5SDimitry Andric       }
20670b57cec5SDimitry Andric     }
20680b57cec5SDimitry Andric 
20690b57cec5SDimitry Andric     if (Tok.isOneOf(tok::l_brace, tok::colon))
2070*0fca6ea1SDimitry Andric       TUK = TagUseKind::Definition;
20710b57cec5SDimitry Andric     else
2072*0fca6ea1SDimitry Andric       TUK = TagUseKind::Reference;
20730b57cec5SDimitry Andric 
20740b57cec5SDimitry Andric     PA.Revert();
20750b57cec5SDimitry Andric   } else if (!isTypeSpecifier(DSC) &&
20760b57cec5SDimitry Andric              (Tok.is(tok::semi) ||
20770b57cec5SDimitry Andric               (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
2078*0fca6ea1SDimitry Andric     TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration;
20790b57cec5SDimitry Andric     if (Tok.isNot(tok::semi)) {
20800b57cec5SDimitry Andric       const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
20810b57cec5SDimitry Andric       // A semicolon was missing after this declaration. Diagnose and recover.
20820b57cec5SDimitry Andric       ExpectAndConsume(tok::semi, diag::err_expected_after,
20830b57cec5SDimitry Andric                        DeclSpec::getSpecifierName(TagType, PPol));
20840b57cec5SDimitry Andric       PP.EnterToken(Tok, /*IsReinject*/ true);
20850b57cec5SDimitry Andric       Tok.setKind(tok::semi);
20860b57cec5SDimitry Andric     }
20870b57cec5SDimitry Andric   } else
2088*0fca6ea1SDimitry Andric     TUK = TagUseKind::Reference;
20890b57cec5SDimitry Andric 
20900b57cec5SDimitry Andric   // Forbid misplaced attributes. In cases of a reference, we pass attributes
20910b57cec5SDimitry Andric   // to caller to handle.
2092*0fca6ea1SDimitry Andric   if (TUK != TagUseKind::Reference) {
20930b57cec5SDimitry Andric     // If this is not a reference, then the only possible
20940b57cec5SDimitry Andric     // valid place for C++11 attributes to appear here
20950b57cec5SDimitry Andric     // is between class-key and class-name. If there are
20960b57cec5SDimitry Andric     // any attributes after class-name, we try a fixit to move
20970b57cec5SDimitry Andric     // them to the right place.
20980b57cec5SDimitry Andric     SourceRange AttrRange = Attributes.Range;
20990b57cec5SDimitry Andric     if (AttrRange.isValid()) {
210006c3fb27SDimitry Andric       auto *FirstAttr = Attributes.empty() ? nullptr : &Attributes.front();
210106c3fb27SDimitry Andric       auto Loc = AttrRange.getBegin();
210206c3fb27SDimitry Andric       (FirstAttr && FirstAttr->isRegularKeywordAttribute()
210306c3fb27SDimitry Andric            ? Diag(Loc, diag::err_keyword_not_allowed) << FirstAttr
210406c3fb27SDimitry Andric            : Diag(Loc, diag::err_attributes_not_allowed))
21050b57cec5SDimitry Andric           << AttrRange
2106972a253aSDimitry Andric           << FixItHint::CreateInsertionFromRange(
2107972a253aSDimitry Andric                  AttrFixitLoc, CharSourceRange(AttrRange, true))
21080b57cec5SDimitry Andric           << FixItHint::CreateRemoval(AttrRange);
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric       // Recover by adding misplaced attributes to the attribute list
21110b57cec5SDimitry Andric       // of the class so they can be applied on the class later.
21120b57cec5SDimitry Andric       attrs.takeAllFrom(Attributes);
21130b57cec5SDimitry Andric     }
21140b57cec5SDimitry Andric   }
21150b57cec5SDimitry Andric 
2116972a253aSDimitry Andric   if (!Name && !TemplateId &&
2117972a253aSDimitry Andric       (DS.getTypeSpecType() == DeclSpec::TST_error ||
2118*0fca6ea1SDimitry Andric        TUK != TagUseKind::Definition)) {
21190b57cec5SDimitry Andric     if (DS.getTypeSpecType() != DeclSpec::TST_error) {
21200b57cec5SDimitry Andric       // We have a declaration or reference to an anonymous class.
21210b57cec5SDimitry Andric       Diag(StartLoc, diag::err_anon_type_definition)
21220b57cec5SDimitry Andric           << DeclSpec::getSpecifierName(TagType, Policy);
21230b57cec5SDimitry Andric     }
21240b57cec5SDimitry Andric 
21250b57cec5SDimitry Andric     // If we are parsing a definition and stop at a base-clause, continue on
21260b57cec5SDimitry Andric     // until the semicolon.  Continuing from the comma will just trick us into
21270b57cec5SDimitry Andric     // thinking we are seeing a variable declaration.
2128*0fca6ea1SDimitry Andric     if (TUK == TagUseKind::Definition && Tok.is(tok::colon))
21290b57cec5SDimitry Andric       SkipUntil(tok::semi, StopBeforeMatch);
21300b57cec5SDimitry Andric     else
21310b57cec5SDimitry Andric       SkipUntil(tok::comma, StopAtSemi);
21320b57cec5SDimitry Andric     return;
21330b57cec5SDimitry Andric   }
21340b57cec5SDimitry Andric 
21350b57cec5SDimitry Andric   // Create the tag portion of the class or class template.
21360b57cec5SDimitry Andric   DeclResult TagOrTempResult = true; // invalid
21370b57cec5SDimitry Andric   TypeResult TypeResult = true;      // invalid
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric   bool Owned = false;
2140*0fca6ea1SDimitry Andric   SkipBodyInfo SkipBody;
21410b57cec5SDimitry Andric   if (TemplateId) {
21420b57cec5SDimitry Andric     // Explicit specialization, class template partial specialization,
21430b57cec5SDimitry Andric     // or explicit instantiation.
21440b57cec5SDimitry Andric     ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
21450b57cec5SDimitry Andric                                        TemplateId->NumArgs);
21465ffd83dbSDimitry Andric     if (TemplateId->isInvalid()) {
21475ffd83dbSDimitry Andric       // Can't build the declaration.
21485ffd83dbSDimitry Andric     } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2149*0fca6ea1SDimitry Andric                TUK == TagUseKind::Declaration) {
21500b57cec5SDimitry Andric       // This is an explicit instantiation of a class template.
2151fe6060f1SDimitry Andric       ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
215206c3fb27SDimitry Andric                               diag::err_keyword_not_allowed,
2153fe6060f1SDimitry Andric                               /*DiagnoseEmptyAttrs=*/true);
21540b57cec5SDimitry Andric 
21550b57cec5SDimitry Andric       TagOrTempResult = Actions.ActOnExplicitInstantiation(
21560b57cec5SDimitry Andric           getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
21570b57cec5SDimitry Andric           TagType, StartLoc, SS, TemplateId->Template,
21580b57cec5SDimitry Andric           TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr,
21590b57cec5SDimitry Andric           TemplateId->RAngleLoc, attrs);
21600b57cec5SDimitry Andric 
21610b57cec5SDimitry Andric       // Friend template-ids are treated as references unless
21620b57cec5SDimitry Andric       // they have template headers, in which case they're ill-formed
21630b57cec5SDimitry Andric       // (FIXME: "template <class T> friend class A<T>::B<int>;").
21640b57cec5SDimitry Andric       // We diagnose this error in ActOnClassTemplateSpecialization.
2165*0fca6ea1SDimitry Andric     } else if (TUK == TagUseKind::Reference ||
2166*0fca6ea1SDimitry Andric                (TUK == TagUseKind::Friend &&
21670b57cec5SDimitry Andric                 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
2168fe6060f1SDimitry Andric       ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
216906c3fb27SDimitry Andric                               diag::err_keyword_not_allowed,
2170fe6060f1SDimitry Andric                               /*DiagnoseEmptyAttrs=*/true);
2171972a253aSDimitry Andric       TypeResult = Actions.ActOnTagTemplateIdType(
2172972a253aSDimitry Andric           TUK, TagType, StartLoc, SS, TemplateId->TemplateKWLoc,
2173972a253aSDimitry Andric           TemplateId->Template, TemplateId->TemplateNameLoc,
2174972a253aSDimitry Andric           TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc);
21750b57cec5SDimitry Andric     } else {
21760b57cec5SDimitry Andric       // This is an explicit specialization or a class template
21770b57cec5SDimitry Andric       // partial specialization.
21780b57cec5SDimitry Andric       TemplateParameterLists FakedParamLists;
21790b57cec5SDimitry Andric       if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
21800b57cec5SDimitry Andric         // This looks like an explicit instantiation, because we have
21810b57cec5SDimitry Andric         // something like
21820b57cec5SDimitry Andric         //
21830b57cec5SDimitry Andric         //   template class Foo<X>
21840b57cec5SDimitry Andric         //
21850b57cec5SDimitry Andric         // but it actually has a definition. Most likely, this was
21860b57cec5SDimitry Andric         // meant to be an explicit specialization, but the user forgot
21870b57cec5SDimitry Andric         // the '<>' after 'template'.
21880b57cec5SDimitry Andric         // It this is friend declaration however, since it cannot have a
21890b57cec5SDimitry Andric         // template header, it is most likely that the user meant to
21900b57cec5SDimitry Andric         // remove the 'template' keyword.
2191*0fca6ea1SDimitry Andric         assert((TUK == TagUseKind::Definition || TUK == TagUseKind::Friend) &&
21920b57cec5SDimitry Andric                "Expected a definition here");
21930b57cec5SDimitry Andric 
2194*0fca6ea1SDimitry Andric         if (TUK == TagUseKind::Friend) {
21950b57cec5SDimitry Andric           Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation);
21960b57cec5SDimitry Andric           TemplateParams = nullptr;
21970b57cec5SDimitry Andric         } else {
21980b57cec5SDimitry Andric           SourceLocation LAngleLoc =
21990b57cec5SDimitry Andric               PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
22000b57cec5SDimitry Andric           Diag(TemplateId->TemplateNameLoc,
22010b57cec5SDimitry Andric                diag::err_explicit_instantiation_with_definition)
22020b57cec5SDimitry Andric               << SourceRange(TemplateInfo.TemplateLoc)
22030b57cec5SDimitry Andric               << FixItHint::CreateInsertion(LAngleLoc, "<>");
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric           // Create a fake template parameter list that contains only
22060b57cec5SDimitry Andric           // "template<>", so that we treat this construct as a class
22070b57cec5SDimitry Andric           // template specialization.
22080b57cec5SDimitry Andric           FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2209bdd1243dSDimitry Andric               0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc,
2210bdd1243dSDimitry Andric               std::nullopt, LAngleLoc, nullptr));
22110b57cec5SDimitry Andric           TemplateParams = &FakedParamLists;
22120b57cec5SDimitry Andric         }
22130b57cec5SDimitry Andric       }
22140b57cec5SDimitry Andric 
22150b57cec5SDimitry Andric       // Build the class template specialization.
22160b57cec5SDimitry Andric       TagOrTempResult = Actions.ActOnClassTemplateSpecialization(
22170b57cec5SDimitry Andric           getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(),
221855e4f9d5SDimitry Andric           SS, *TemplateId, attrs,
22190b57cec5SDimitry Andric           MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]
22200b57cec5SDimitry Andric                                                 : nullptr,
22210b57cec5SDimitry Andric                                  TemplateParams ? TemplateParams->size() : 0),
22220b57cec5SDimitry Andric           &SkipBody);
22230b57cec5SDimitry Andric     }
22240b57cec5SDimitry Andric   } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2225*0fca6ea1SDimitry Andric              TUK == TagUseKind::Declaration) {
22260b57cec5SDimitry Andric     // Explicit instantiation of a member of a class template
22270b57cec5SDimitry Andric     // specialization, e.g.,
22280b57cec5SDimitry Andric     //
22290b57cec5SDimitry Andric     //   template struct Outer<int>::Inner;
22300b57cec5SDimitry Andric     //
22310b57cec5SDimitry Andric     ProhibitAttributes(attrs);
22320b57cec5SDimitry Andric 
22330b57cec5SDimitry Andric     TagOrTempResult = Actions.ActOnExplicitInstantiation(
22340b57cec5SDimitry Andric         getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
22350b57cec5SDimitry Andric         TagType, StartLoc, SS, Name, NameLoc, attrs);
2236*0fca6ea1SDimitry Andric   } else if (TUK == TagUseKind::Friend &&
22370b57cec5SDimitry Andric              TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
2238fe6060f1SDimitry Andric     ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
223906c3fb27SDimitry Andric                             diag::err_keyword_not_allowed,
2240fe6060f1SDimitry Andric                             /*DiagnoseEmptyAttrs=*/true);
22410b57cec5SDimitry Andric 
22420b57cec5SDimitry Andric     TagOrTempResult = Actions.ActOnTemplatedFriendTag(
22430b57cec5SDimitry Andric         getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name,
22440b57cec5SDimitry Andric         NameLoc, attrs,
22450b57cec5SDimitry Andric         MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,
22460b57cec5SDimitry Andric                                TemplateParams ? TemplateParams->size() : 0));
22470b57cec5SDimitry Andric   } else {
2248*0fca6ea1SDimitry Andric     if (TUK != TagUseKind::Declaration && TUK != TagUseKind::Definition)
2249fe6060f1SDimitry Andric       ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
225006c3fb27SDimitry Andric                               diag::err_keyword_not_allowed,
2251fe6060f1SDimitry Andric                               /* DiagnoseEmptyAttrs=*/true);
22520b57cec5SDimitry Andric 
2253*0fca6ea1SDimitry Andric     if (TUK == TagUseKind::Definition &&
22540b57cec5SDimitry Andric         TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
22550b57cec5SDimitry Andric       // If the declarator-id is not a template-id, issue a diagnostic and
22560b57cec5SDimitry Andric       // recover by ignoring the 'template' keyword.
22570b57cec5SDimitry Andric       Diag(Tok, diag::err_template_defn_explicit_instantiation)
22580b57cec5SDimitry Andric           << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
22590b57cec5SDimitry Andric       TemplateParams = nullptr;
22600b57cec5SDimitry Andric     }
22610b57cec5SDimitry Andric 
22620b57cec5SDimitry Andric     bool IsDependent = false;
22630b57cec5SDimitry Andric 
22640b57cec5SDimitry Andric     // Don't pass down template parameter lists if this is just a tag
22650b57cec5SDimitry Andric     // reference.  For example, we don't need the template parameters here:
22660b57cec5SDimitry Andric     //   template <class T> class A *makeA(T t);
22670b57cec5SDimitry Andric     MultiTemplateParamsArg TParams;
2268*0fca6ea1SDimitry Andric     if (TUK != TagUseKind::Reference && TemplateParams)
22690b57cec5SDimitry Andric       TParams =
22700b57cec5SDimitry Andric           MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
22710b57cec5SDimitry Andric 
22720b57cec5SDimitry Andric     stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
22730b57cec5SDimitry Andric 
22740b57cec5SDimitry Andric     // Declaration or definition of a class type
22750b57cec5SDimitry Andric     TagOrTempResult = Actions.ActOnTag(
22760b57cec5SDimitry Andric         getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS,
22770b57cec5SDimitry Andric         DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
22780b57cec5SDimitry Andric         SourceLocation(), false, clang::TypeResult(),
22790b57cec5SDimitry Andric         DSC == DeclSpecContext::DSC_type_specifier,
22800b57cec5SDimitry Andric         DSC == DeclSpecContext::DSC_template_param ||
22810b57cec5SDimitry Andric             DSC == DeclSpecContext::DSC_template_type_arg,
22821ac55f4cSDimitry Andric         OffsetOfState, &SkipBody);
22830b57cec5SDimitry Andric 
22840b57cec5SDimitry Andric     // If ActOnTag said the type was dependent, try again with the
22850b57cec5SDimitry Andric     // less common call.
22860b57cec5SDimitry Andric     if (IsDependent) {
2287*0fca6ea1SDimitry Andric       assert(TUK == TagUseKind::Reference || TUK == TagUseKind::Friend);
2288972a253aSDimitry Andric       TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, SS,
2289972a253aSDimitry Andric                                              Name, StartLoc, NameLoc);
22900b57cec5SDimitry Andric     }
22910b57cec5SDimitry Andric   }
22920b57cec5SDimitry Andric 
2293349cc55cSDimitry Andric   // If this is an elaborated type specifier in function template,
2294349cc55cSDimitry Andric   // and we delayed diagnostics before,
2295349cc55cSDimitry Andric   // just merge them into the current pool.
2296349cc55cSDimitry Andric   if (shouldDelayDiagsInTag) {
2297349cc55cSDimitry Andric     diagsFromTag.done();
2298*0fca6ea1SDimitry Andric     if (TUK == TagUseKind::Reference &&
2299349cc55cSDimitry Andric         TemplateInfo.Kind == ParsedTemplateInfo::Template)
2300349cc55cSDimitry Andric       diagsFromTag.redelay();
2301349cc55cSDimitry Andric   }
2302349cc55cSDimitry Andric 
23030b57cec5SDimitry Andric   // If there is a body, parse it and inform the actions module.
2304*0fca6ea1SDimitry Andric   if (TUK == TagUseKind::Definition) {
23050b57cec5SDimitry Andric     assert(Tok.is(tok::l_brace) ||
23060b57cec5SDimitry Andric            (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
2307fe6060f1SDimitry Andric            isClassCompatibleKeyword());
23080b57cec5SDimitry Andric     if (SkipBody.ShouldSkip)
23090b57cec5SDimitry Andric       SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,
23100b57cec5SDimitry Andric                                  TagOrTempResult.get());
23110b57cec5SDimitry Andric     else if (getLangOpts().CPlusPlus)
23120b57cec5SDimitry Andric       ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
23130b57cec5SDimitry Andric                                   TagOrTempResult.get());
23140b57cec5SDimitry Andric     else {
23150b57cec5SDimitry Andric       Decl *D =
23160b57cec5SDimitry Andric           SkipBody.CheckSameAsPrevious ? SkipBody.New : TagOrTempResult.get();
23170b57cec5SDimitry Andric       // Parse the definition body.
23185ffd83dbSDimitry Andric       ParseStructUnionBody(StartLoc, TagType, cast<RecordDecl>(D));
23190b57cec5SDimitry Andric       if (SkipBody.CheckSameAsPrevious &&
232081ad6265SDimitry Andric           !Actions.ActOnDuplicateDefinition(TagOrTempResult.get(), SkipBody)) {
23210b57cec5SDimitry Andric         DS.SetTypeSpecError();
23220b57cec5SDimitry Andric         return;
23230b57cec5SDimitry Andric       }
23240b57cec5SDimitry Andric     }
23250b57cec5SDimitry Andric   }
23260b57cec5SDimitry Andric 
23270b57cec5SDimitry Andric   if (!TagOrTempResult.isInvalid())
23280b57cec5SDimitry Andric     // Delayed processing of attributes.
23290b57cec5SDimitry Andric     Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs);
23300b57cec5SDimitry Andric 
23310b57cec5SDimitry Andric   const char *PrevSpec = nullptr;
23320b57cec5SDimitry Andric   unsigned DiagID;
23330b57cec5SDimitry Andric   bool Result;
23340b57cec5SDimitry Andric   if (!TypeResult.isInvalid()) {
23350b57cec5SDimitry Andric     Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
23360b57cec5SDimitry Andric                                 NameLoc.isValid() ? NameLoc : StartLoc,
23370b57cec5SDimitry Andric                                 PrevSpec, DiagID, TypeResult.get(), Policy);
23380b57cec5SDimitry Andric   } else if (!TagOrTempResult.isInvalid()) {
2339972a253aSDimitry Andric     Result = DS.SetTypeSpecType(
2340972a253aSDimitry Andric         TagType, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
23411ac55f4cSDimitry Andric         DiagID, TagOrTempResult.get(), Owned, Policy);
23420b57cec5SDimitry Andric   } else {
23430b57cec5SDimitry Andric     DS.SetTypeSpecError();
23440b57cec5SDimitry Andric     return;
23450b57cec5SDimitry Andric   }
23460b57cec5SDimitry Andric 
23470b57cec5SDimitry Andric   if (Result)
23480b57cec5SDimitry Andric     Diag(StartLoc, DiagID) << PrevSpec;
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric   // At this point, we've successfully parsed a class-specifier in 'definition'
23510b57cec5SDimitry Andric   // form (e.g. "struct foo { int x; }".  While we could just return here, we're
23520b57cec5SDimitry Andric   // going to look at what comes after it to improve error recovery.  If an
23530b57cec5SDimitry Andric   // impossible token occurs next, we assume that the programmer forgot a ; at
23540b57cec5SDimitry Andric   // the end of the declaration and recover that way.
23550b57cec5SDimitry Andric   //
23560b57cec5SDimitry Andric   // Also enforce C++ [temp]p3:
23570b57cec5SDimitry Andric   //   In a template-declaration which defines a class, no declarator
23580b57cec5SDimitry Andric   //   is permitted.
23590b57cec5SDimitry Andric   //
23600b57cec5SDimitry Andric   // After a type-specifier, we don't expect a semicolon. This only happens in
23610b57cec5SDimitry Andric   // C, since definitions are not permitted in this context in C++.
2362*0fca6ea1SDimitry Andric   if (TUK == TagUseKind::Definition &&
23630b57cec5SDimitry Andric       (getLangOpts().CPlusPlus || !isTypeSpecifier(DSC)) &&
23640b57cec5SDimitry Andric       (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
23650b57cec5SDimitry Andric     if (Tok.isNot(tok::semi)) {
23660b57cec5SDimitry Andric       const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
23670b57cec5SDimitry Andric       ExpectAndConsume(tok::semi, diag::err_expected_after,
23680b57cec5SDimitry Andric                        DeclSpec::getSpecifierName(TagType, PPol));
23690b57cec5SDimitry Andric       // Push this token back into the preprocessor and change our current token
23700b57cec5SDimitry Andric       // to ';' so that the rest of the code recovers as though there were an
23710b57cec5SDimitry Andric       // ';' after the definition.
23720b57cec5SDimitry Andric       PP.EnterToken(Tok, /*IsReinject=*/true);
23730b57cec5SDimitry Andric       Tok.setKind(tok::semi);
23740b57cec5SDimitry Andric     }
23750b57cec5SDimitry Andric   }
23760b57cec5SDimitry Andric }
23770b57cec5SDimitry Andric 
23780b57cec5SDimitry Andric /// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
23790b57cec5SDimitry Andric ///
23800b57cec5SDimitry Andric ///       base-clause : [C++ class.derived]
23810b57cec5SDimitry Andric ///         ':' base-specifier-list
23820b57cec5SDimitry Andric ///       base-specifier-list:
23830b57cec5SDimitry Andric ///         base-specifier '...'[opt]
23840b57cec5SDimitry Andric ///         base-specifier-list ',' base-specifier '...'[opt]
23850b57cec5SDimitry Andric void Parser::ParseBaseClause(Decl *ClassDecl) {
23860b57cec5SDimitry Andric   assert(Tok.is(tok::colon) && "Not a base clause");
23870b57cec5SDimitry Andric   ConsumeToken();
23880b57cec5SDimitry Andric 
23890b57cec5SDimitry Andric   // Build up an array of parsed base specifiers.
23900b57cec5SDimitry Andric   SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
23910b57cec5SDimitry Andric 
23920b57cec5SDimitry Andric   while (true) {
23930b57cec5SDimitry Andric     // Parse a base-specifier.
23940b57cec5SDimitry Andric     BaseResult Result = ParseBaseSpecifier(ClassDecl);
23950b57cec5SDimitry Andric     if (Result.isInvalid()) {
23960b57cec5SDimitry Andric       // Skip the rest of this base specifier, up until the comma or
23970b57cec5SDimitry Andric       // opening brace.
23980b57cec5SDimitry Andric       SkipUntil(tok::comma, tok::l_brace, StopAtSemi | StopBeforeMatch);
23990b57cec5SDimitry Andric     } else {
24000b57cec5SDimitry Andric       // Add this to our array of base specifiers.
24010b57cec5SDimitry Andric       BaseInfo.push_back(Result.get());
24020b57cec5SDimitry Andric     }
24030b57cec5SDimitry Andric 
24040b57cec5SDimitry Andric     // If the next token is a comma, consume it and keep reading
24050b57cec5SDimitry Andric     // base-specifiers.
24060b57cec5SDimitry Andric     if (!TryConsumeToken(tok::comma))
24070b57cec5SDimitry Andric       break;
24080b57cec5SDimitry Andric   }
24090b57cec5SDimitry Andric 
24100b57cec5SDimitry Andric   // Attach the base specifiers
24110b57cec5SDimitry Andric   Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo);
24120b57cec5SDimitry Andric }
24130b57cec5SDimitry Andric 
24140b57cec5SDimitry Andric /// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
24150b57cec5SDimitry Andric /// one entry in the base class list of a class specifier, for example:
24160b57cec5SDimitry Andric ///    class foo : public bar, virtual private baz {
24170b57cec5SDimitry Andric /// 'public bar' and 'virtual private baz' are each base-specifiers.
24180b57cec5SDimitry Andric ///
24190b57cec5SDimitry Andric ///       base-specifier: [C++ class.derived]
24200b57cec5SDimitry Andric ///         attribute-specifier-seq[opt] base-type-specifier
24210b57cec5SDimitry Andric ///         attribute-specifier-seq[opt] 'virtual' access-specifier[opt]
24220b57cec5SDimitry Andric ///                 base-type-specifier
24230b57cec5SDimitry Andric ///         attribute-specifier-seq[opt] access-specifier 'virtual'[opt]
24240b57cec5SDimitry Andric ///                 base-type-specifier
24250b57cec5SDimitry Andric BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
24260b57cec5SDimitry Andric   bool IsVirtual = false;
24270b57cec5SDimitry Andric   SourceLocation StartLoc = Tok.getLocation();
24280b57cec5SDimitry Andric 
242981ad6265SDimitry Andric   ParsedAttributes Attributes(AttrFactory);
24300b57cec5SDimitry Andric   MaybeParseCXX11Attributes(Attributes);
24310b57cec5SDimitry Andric 
24320b57cec5SDimitry Andric   // Parse the 'virtual' keyword.
24330b57cec5SDimitry Andric   if (TryConsumeToken(tok::kw_virtual))
24340b57cec5SDimitry Andric     IsVirtual = true;
24350b57cec5SDimitry Andric 
24360b57cec5SDimitry Andric   CheckMisplacedCXX11Attribute(Attributes, StartLoc);
24370b57cec5SDimitry Andric 
24380b57cec5SDimitry Andric   // Parse an (optional) access specifier.
24390b57cec5SDimitry Andric   AccessSpecifier Access = getAccessSpecifierIfPresent();
244081ad6265SDimitry Andric   if (Access != AS_none) {
24410b57cec5SDimitry Andric     ConsumeToken();
244281ad6265SDimitry Andric     if (getLangOpts().HLSL)
244381ad6265SDimitry Andric       Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);
244481ad6265SDimitry Andric   }
24450b57cec5SDimitry Andric 
24460b57cec5SDimitry Andric   CheckMisplacedCXX11Attribute(Attributes, StartLoc);
24470b57cec5SDimitry Andric 
24480b57cec5SDimitry Andric   // Parse the 'virtual' keyword (again!), in case it came after the
24490b57cec5SDimitry Andric   // access specifier.
24500b57cec5SDimitry Andric   if (Tok.is(tok::kw_virtual)) {
24510b57cec5SDimitry Andric     SourceLocation VirtualLoc = ConsumeToken();
24520b57cec5SDimitry Andric     if (IsVirtual) {
24530b57cec5SDimitry Andric       // Complain about duplicate 'virtual'
24540b57cec5SDimitry Andric       Diag(VirtualLoc, diag::err_dup_virtual)
24550b57cec5SDimitry Andric           << FixItHint::CreateRemoval(VirtualLoc);
24560b57cec5SDimitry Andric     }
24570b57cec5SDimitry Andric 
24580b57cec5SDimitry Andric     IsVirtual = true;
24590b57cec5SDimitry Andric   }
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric   CheckMisplacedCXX11Attribute(Attributes, StartLoc);
24620b57cec5SDimitry Andric 
24630b57cec5SDimitry Andric   // Parse the class-name.
24640b57cec5SDimitry Andric 
24650b57cec5SDimitry Andric   // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL
24660b57cec5SDimitry Andric   // implementation for VS2013 uses _Atomic as an identifier for one of the
24670b57cec5SDimitry Andric   // classes in <atomic>.  Treat '_Atomic' to be an identifier when we are
24680b57cec5SDimitry Andric   // parsing the class-name for a base specifier.
24690b57cec5SDimitry Andric   if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
24700b57cec5SDimitry Andric       NextToken().is(tok::less))
24710b57cec5SDimitry Andric     Tok.setKind(tok::identifier);
24720b57cec5SDimitry Andric 
24730b57cec5SDimitry Andric   SourceLocation EndLocation;
24740b57cec5SDimitry Andric   SourceLocation BaseLoc;
24750b57cec5SDimitry Andric   TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
24760b57cec5SDimitry Andric   if (BaseType.isInvalid())
24770b57cec5SDimitry Andric     return true;
24780b57cec5SDimitry Andric 
24790b57cec5SDimitry Andric   // Parse the optional ellipsis (for a pack expansion). The ellipsis is
24800b57cec5SDimitry Andric   // actually part of the base-specifier-list grammar productions, but we
24810b57cec5SDimitry Andric   // parse it here for convenience.
24820b57cec5SDimitry Andric   SourceLocation EllipsisLoc;
24830b57cec5SDimitry Andric   TryConsumeToken(tok::ellipsis, EllipsisLoc);
24840b57cec5SDimitry Andric 
24850b57cec5SDimitry Andric   // Find the complete source range for the base-specifier.
24860b57cec5SDimitry Andric   SourceRange Range(StartLoc, EndLocation);
24870b57cec5SDimitry Andric 
24880b57cec5SDimitry Andric   // Notify semantic analysis that we have parsed a complete
24890b57cec5SDimitry Andric   // base-specifier.
24900b57cec5SDimitry Andric   return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual,
24910b57cec5SDimitry Andric                                     Access, BaseType.get(), BaseLoc,
24920b57cec5SDimitry Andric                                     EllipsisLoc);
24930b57cec5SDimitry Andric }
24940b57cec5SDimitry Andric 
24950b57cec5SDimitry Andric /// getAccessSpecifierIfPresent - Determine whether the next token is
24960b57cec5SDimitry Andric /// a C++ access-specifier.
24970b57cec5SDimitry Andric ///
24980b57cec5SDimitry Andric ///       access-specifier: [C++ class.derived]
24990b57cec5SDimitry Andric ///         'private'
25000b57cec5SDimitry Andric ///         'protected'
25010b57cec5SDimitry Andric ///         'public'
25020b57cec5SDimitry Andric AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
25030b57cec5SDimitry Andric   switch (Tok.getKind()) {
2504972a253aSDimitry Andric   default:
2505972a253aSDimitry Andric     return AS_none;
2506972a253aSDimitry Andric   case tok::kw_private:
2507972a253aSDimitry Andric     return AS_private;
2508972a253aSDimitry Andric   case tok::kw_protected:
2509972a253aSDimitry Andric     return AS_protected;
2510972a253aSDimitry Andric   case tok::kw_public:
2511972a253aSDimitry Andric     return AS_public;
25120b57cec5SDimitry Andric   }
25130b57cec5SDimitry Andric }
25140b57cec5SDimitry Andric 
25150b57cec5SDimitry Andric /// If the given declarator has any parts for which parsing has to be
25160b57cec5SDimitry Andric /// delayed, e.g., default arguments or an exception-specification, create a
25170b57cec5SDimitry Andric /// late-parsed method declaration record to handle the parsing at the end of
25180b57cec5SDimitry Andric /// the class definition.
25190b57cec5SDimitry Andric void Parser::HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo,
25200b57cec5SDimitry Andric                                             Decl *ThisDecl) {
2521972a253aSDimitry Andric   DeclaratorChunk::FunctionTypeInfo &FTI = DeclaratorInfo.getFunctionTypeInfo();
25220b57cec5SDimitry Andric   // If there was a late-parsed exception-specification, we'll need a
25230b57cec5SDimitry Andric   // late parse
25240b57cec5SDimitry Andric   bool NeedLateParse = FTI.getExceptionSpecType() == EST_Unparsed;
25250b57cec5SDimitry Andric 
25260b57cec5SDimitry Andric   if (!NeedLateParse) {
25270b57cec5SDimitry Andric     // Look ahead to see if there are any default args
25280b57cec5SDimitry Andric     for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) {
2529*0fca6ea1SDimitry Andric       const auto *Param = cast<ParmVarDecl>(FTI.Params[ParamIdx].Param);
25300b57cec5SDimitry Andric       if (Param->hasUnparsedDefaultArg()) {
25310b57cec5SDimitry Andric         NeedLateParse = true;
25320b57cec5SDimitry Andric         break;
25330b57cec5SDimitry Andric       }
25340b57cec5SDimitry Andric     }
25350b57cec5SDimitry Andric   }
25360b57cec5SDimitry Andric 
25370b57cec5SDimitry Andric   if (NeedLateParse) {
25380b57cec5SDimitry Andric     // Push this method onto the stack of late-parsed method
25390b57cec5SDimitry Andric     // declarations.
25400b57cec5SDimitry Andric     auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
25410b57cec5SDimitry Andric     getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
25420b57cec5SDimitry Andric 
2543e8d8bef9SDimitry Andric     // Push tokens for each parameter. Those that do not have defaults will be
2544e8d8bef9SDimitry Andric     // NULL. We need to track all the parameters so that we can push them into
2545e8d8bef9SDimitry Andric     // scope for later parameters and perhaps for the exception specification.
25460b57cec5SDimitry Andric     LateMethod->DefaultArgs.reserve(FTI.NumParams);
25470b57cec5SDimitry Andric     for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx)
25480b57cec5SDimitry Andric       LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
25490b57cec5SDimitry Andric           FTI.Params[ParamIdx].Param,
25500b57cec5SDimitry Andric           std::move(FTI.Params[ParamIdx].DefaultArgTokens)));
2551e8d8bef9SDimitry Andric 
2552e8d8bef9SDimitry Andric     // Stash the exception-specification tokens in the late-pased method.
2553e8d8bef9SDimitry Andric     if (FTI.getExceptionSpecType() == EST_Unparsed) {
2554e8d8bef9SDimitry Andric       LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens;
2555e8d8bef9SDimitry Andric       FTI.ExceptionSpecTokens = nullptr;
2556e8d8bef9SDimitry Andric     }
25570b57cec5SDimitry Andric   }
25580b57cec5SDimitry Andric }
25590b57cec5SDimitry Andric 
25600b57cec5SDimitry Andric /// isCXX11VirtSpecifier - Determine whether the given token is a C++11
25610b57cec5SDimitry Andric /// virt-specifier.
25620b57cec5SDimitry Andric ///
25630b57cec5SDimitry Andric ///       virt-specifier:
25640b57cec5SDimitry Andric ///         override
25650b57cec5SDimitry Andric ///         final
25660b57cec5SDimitry Andric ///         __final
25670b57cec5SDimitry Andric VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
25680b57cec5SDimitry Andric   if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier))
25690b57cec5SDimitry Andric     return VirtSpecifiers::VS_None;
25700b57cec5SDimitry Andric 
2571*0fca6ea1SDimitry Andric   const IdentifierInfo *II = Tok.getIdentifierInfo();
25720b57cec5SDimitry Andric 
25730b57cec5SDimitry Andric   // Initialize the contextual keywords.
25740b57cec5SDimitry Andric   if (!Ident_final) {
25750b57cec5SDimitry Andric     Ident_final = &PP.getIdentifierTable().get("final");
25760b57cec5SDimitry Andric     if (getLangOpts().GNUKeywords)
25770b57cec5SDimitry Andric       Ident_GNU_final = &PP.getIdentifierTable().get("__final");
2578fe6060f1SDimitry Andric     if (getLangOpts().MicrosoftExt) {
25790b57cec5SDimitry Andric       Ident_sealed = &PP.getIdentifierTable().get("sealed");
2580fe6060f1SDimitry Andric       Ident_abstract = &PP.getIdentifierTable().get("abstract");
2581fe6060f1SDimitry Andric     }
25820b57cec5SDimitry Andric     Ident_override = &PP.getIdentifierTable().get("override");
25830b57cec5SDimitry Andric   }
25840b57cec5SDimitry Andric 
25850b57cec5SDimitry Andric   if (II == Ident_override)
25860b57cec5SDimitry Andric     return VirtSpecifiers::VS_Override;
25870b57cec5SDimitry Andric 
25880b57cec5SDimitry Andric   if (II == Ident_sealed)
25890b57cec5SDimitry Andric     return VirtSpecifiers::VS_Sealed;
25900b57cec5SDimitry Andric 
2591fe6060f1SDimitry Andric   if (II == Ident_abstract)
2592fe6060f1SDimitry Andric     return VirtSpecifiers::VS_Abstract;
2593fe6060f1SDimitry Andric 
25940b57cec5SDimitry Andric   if (II == Ident_final)
25950b57cec5SDimitry Andric     return VirtSpecifiers::VS_Final;
25960b57cec5SDimitry Andric 
25970b57cec5SDimitry Andric   if (II == Ident_GNU_final)
25980b57cec5SDimitry Andric     return VirtSpecifiers::VS_GNU_Final;
25990b57cec5SDimitry Andric 
26000b57cec5SDimitry Andric   return VirtSpecifiers::VS_None;
26010b57cec5SDimitry Andric }
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric /// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq.
26040b57cec5SDimitry Andric ///
26050b57cec5SDimitry Andric ///       virt-specifier-seq:
26060b57cec5SDimitry Andric ///         virt-specifier
26070b57cec5SDimitry Andric ///         virt-specifier-seq virt-specifier
26080b57cec5SDimitry Andric void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
26090b57cec5SDimitry Andric                                                 bool IsInterface,
26100b57cec5SDimitry Andric                                                 SourceLocation FriendLoc) {
26110b57cec5SDimitry Andric   while (true) {
26120b57cec5SDimitry Andric     VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
26130b57cec5SDimitry Andric     if (Specifier == VirtSpecifiers::VS_None)
26140b57cec5SDimitry Andric       return;
26150b57cec5SDimitry Andric 
26160b57cec5SDimitry Andric     if (FriendLoc.isValid()) {
26170b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::err_friend_decl_spec)
26180b57cec5SDimitry Andric           << VirtSpecifiers::getSpecifierName(Specifier)
26190b57cec5SDimitry Andric           << FixItHint::CreateRemoval(Tok.getLocation())
26200b57cec5SDimitry Andric           << SourceRange(FriendLoc, FriendLoc);
26210b57cec5SDimitry Andric       ConsumeToken();
26220b57cec5SDimitry Andric       continue;
26230b57cec5SDimitry Andric     }
26240b57cec5SDimitry Andric 
26250b57cec5SDimitry Andric     // C++ [class.mem]p8:
26260b57cec5SDimitry Andric     //   A virt-specifier-seq shall contain at most one of each virt-specifier.
26270b57cec5SDimitry Andric     const char *PrevSpec = nullptr;
26280b57cec5SDimitry Andric     if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
26290b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
2630972a253aSDimitry Andric           << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
26310b57cec5SDimitry Andric 
26320b57cec5SDimitry Andric     if (IsInterface && (Specifier == VirtSpecifiers::VS_Final ||
26330b57cec5SDimitry Andric                         Specifier == VirtSpecifiers::VS_Sealed)) {
26340b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::err_override_control_interface)
26350b57cec5SDimitry Andric           << VirtSpecifiers::getSpecifierName(Specifier);
26360b57cec5SDimitry Andric     } else if (Specifier == VirtSpecifiers::VS_Sealed) {
26370b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::ext_ms_sealed_keyword);
2638fe6060f1SDimitry Andric     } else if (Specifier == VirtSpecifiers::VS_Abstract) {
2639fe6060f1SDimitry Andric       Diag(Tok.getLocation(), diag::ext_ms_abstract_keyword);
26400b57cec5SDimitry Andric     } else if (Specifier == VirtSpecifiers::VS_GNU_Final) {
26410b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::ext_warn_gnu_final);
26420b57cec5SDimitry Andric     } else {
26430b57cec5SDimitry Andric       Diag(Tok.getLocation(),
26440b57cec5SDimitry Andric            getLangOpts().CPlusPlus11
26450b57cec5SDimitry Andric                ? diag::warn_cxx98_compat_override_control_keyword
26460b57cec5SDimitry Andric                : diag::ext_override_control_keyword)
26470b57cec5SDimitry Andric           << VirtSpecifiers::getSpecifierName(Specifier);
26480b57cec5SDimitry Andric     }
26490b57cec5SDimitry Andric     ConsumeToken();
26500b57cec5SDimitry Andric   }
26510b57cec5SDimitry Andric }
26520b57cec5SDimitry Andric 
26530b57cec5SDimitry Andric /// isCXX11FinalKeyword - Determine whether the next token is a C++11
26540b57cec5SDimitry Andric /// 'final' or Microsoft 'sealed' contextual keyword.
26550b57cec5SDimitry Andric bool Parser::isCXX11FinalKeyword() const {
26560b57cec5SDimitry Andric   VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
26570b57cec5SDimitry Andric   return Specifier == VirtSpecifiers::VS_Final ||
26580b57cec5SDimitry Andric          Specifier == VirtSpecifiers::VS_GNU_Final ||
26590b57cec5SDimitry Andric          Specifier == VirtSpecifiers::VS_Sealed;
26600b57cec5SDimitry Andric }
26610b57cec5SDimitry Andric 
2662fe6060f1SDimitry Andric /// isClassCompatibleKeyword - Determine whether the next token is a C++11
2663fe6060f1SDimitry Andric /// 'final' or Microsoft 'sealed' or 'abstract' contextual keywords.
2664fe6060f1SDimitry Andric bool Parser::isClassCompatibleKeyword() const {
2665fe6060f1SDimitry Andric   VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
2666fe6060f1SDimitry Andric   return Specifier == VirtSpecifiers::VS_Final ||
2667fe6060f1SDimitry Andric          Specifier == VirtSpecifiers::VS_GNU_Final ||
2668fe6060f1SDimitry Andric          Specifier == VirtSpecifiers::VS_Sealed ||
2669fe6060f1SDimitry Andric          Specifier == VirtSpecifiers::VS_Abstract;
2670fe6060f1SDimitry Andric }
2671fe6060f1SDimitry Andric 
26720b57cec5SDimitry Andric /// Parse a C++ member-declarator up to, but not including, the optional
26730b57cec5SDimitry Andric /// brace-or-equal-initializer or pure-specifier.
26740b57cec5SDimitry Andric bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
26750b57cec5SDimitry Andric     Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,
26760b57cec5SDimitry Andric     LateParsedAttrList &LateParsedAttrs) {
26770b57cec5SDimitry Andric   // member-declarator:
2678e8d8bef9SDimitry Andric   //   declarator virt-specifier-seq[opt] pure-specifier[opt]
2679480093f4SDimitry Andric   //   declarator requires-clause
26800b57cec5SDimitry Andric   //   declarator brace-or-equal-initializer[opt]
2681e8d8bef9SDimitry Andric   //   identifier attribute-specifier-seq[opt] ':' constant-expression
2682e8d8bef9SDimitry Andric   //       brace-or-equal-initializer[opt]
2683e8d8bef9SDimitry Andric   //   ':' constant-expression
2684e8d8bef9SDimitry Andric   //
2685e8d8bef9SDimitry Andric   // NOTE: the latter two productions are a proposed bugfix rather than the
2686e8d8bef9SDimitry Andric   // current grammar rules as of C++20.
26870b57cec5SDimitry Andric   if (Tok.isNot(tok::colon))
26880b57cec5SDimitry Andric     ParseDeclarator(DeclaratorInfo);
26890b57cec5SDimitry Andric   else
26900b57cec5SDimitry Andric     DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
26910b57cec5SDimitry Andric 
2692*0fca6ea1SDimitry Andric   if (getLangOpts().HLSL)
2693*0fca6ea1SDimitry Andric     MaybeParseHLSLAnnotations(DeclaratorInfo, nullptr,
2694*0fca6ea1SDimitry Andric                               /*CouldBeBitField*/ true);
2695*0fca6ea1SDimitry Andric 
26960b57cec5SDimitry Andric   if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {
26970b57cec5SDimitry Andric     assert(DeclaratorInfo.isPastIdentifier() &&
26980b57cec5SDimitry Andric            "don't know where identifier would go yet?");
26990b57cec5SDimitry Andric     BitfieldSize = ParseConstantExpression();
27000b57cec5SDimitry Andric     if (BitfieldSize.isInvalid())
27010b57cec5SDimitry Andric       SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
2702480093f4SDimitry Andric   } else if (Tok.is(tok::kw_requires)) {
2703480093f4SDimitry Andric     ParseTrailingRequiresClause(DeclaratorInfo);
27040b57cec5SDimitry Andric   } else {
27050b57cec5SDimitry Andric     ParseOptionalCXX11VirtSpecifierSeq(
27060b57cec5SDimitry Andric         VS, getCurrentClass().IsInterface,
27070b57cec5SDimitry Andric         DeclaratorInfo.getDeclSpec().getFriendSpecLoc());
27080b57cec5SDimitry Andric     if (!VS.isUnset())
2709972a253aSDimitry Andric       MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2710972a253aSDimitry Andric                                                               VS);
27110b57cec5SDimitry Andric   }
27120b57cec5SDimitry Andric 
27130b57cec5SDimitry Andric   // If a simple-asm-expr is present, parse it.
27140b57cec5SDimitry Andric   if (Tok.is(tok::kw_asm)) {
27150b57cec5SDimitry Andric     SourceLocation Loc;
2716480093f4SDimitry Andric     ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, &Loc));
27170b57cec5SDimitry Andric     if (AsmLabel.isInvalid())
27180b57cec5SDimitry Andric       SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
27190b57cec5SDimitry Andric 
27200b57cec5SDimitry Andric     DeclaratorInfo.setAsmLabel(AsmLabel.get());
27210b57cec5SDimitry Andric     DeclaratorInfo.SetRangeEnd(Loc);
27220b57cec5SDimitry Andric   }
27230b57cec5SDimitry Andric 
27240b57cec5SDimitry Andric   // If attributes exist after the declarator, but before an '{', parse them.
2725e8d8bef9SDimitry Andric   // However, this does not apply for [[]] attributes (which could show up
2726e8d8bef9SDimitry Andric   // before or after the __attribute__ attributes).
2727e8d8bef9SDimitry Andric   DiagnoseAndSkipCXX11Attributes();
27280b57cec5SDimitry Andric   MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
2729e8d8bef9SDimitry Andric   DiagnoseAndSkipCXX11Attributes();
27300b57cec5SDimitry Andric 
27310b57cec5SDimitry Andric   // For compatibility with code written to older Clang, also accept a
27320b57cec5SDimitry Andric   // virt-specifier *after* the GNU attributes.
27330b57cec5SDimitry Andric   if (BitfieldSize.isUnset() && VS.isUnset()) {
27340b57cec5SDimitry Andric     ParseOptionalCXX11VirtSpecifierSeq(
27350b57cec5SDimitry Andric         VS, getCurrentClass().IsInterface,
27360b57cec5SDimitry Andric         DeclaratorInfo.getDeclSpec().getFriendSpecLoc());
27370b57cec5SDimitry Andric     if (!VS.isUnset()) {
27380b57cec5SDimitry Andric       // If we saw any GNU-style attributes that are known to GCC followed by a
27390b57cec5SDimitry Andric       // virt-specifier, issue a GCC-compat warning.
27400b57cec5SDimitry Andric       for (const ParsedAttr &AL : DeclaratorInfo.getAttributes())
27410b57cec5SDimitry Andric         if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
27420b57cec5SDimitry Andric           Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
27430b57cec5SDimitry Andric 
2744972a253aSDimitry Andric       MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2745972a253aSDimitry Andric                                                               VS);
27460b57cec5SDimitry Andric     }
27470b57cec5SDimitry Andric   }
27480b57cec5SDimitry Andric 
27490b57cec5SDimitry Andric   // If this has neither a name nor a bit width, something has gone seriously
27500b57cec5SDimitry Andric   // wrong. Skip until the semi-colon or }.
27510b57cec5SDimitry Andric   if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {
27520b57cec5SDimitry Andric     // If so, skip until the semi-colon or a }.
27530b57cec5SDimitry Andric     SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
27540b57cec5SDimitry Andric     return true;
27550b57cec5SDimitry Andric   }
27560b57cec5SDimitry Andric   return false;
27570b57cec5SDimitry Andric }
27580b57cec5SDimitry Andric 
27590b57cec5SDimitry Andric /// Look for declaration specifiers possibly occurring after C++11
27600b57cec5SDimitry Andric /// virt-specifier-seq and diagnose them.
27610b57cec5SDimitry Andric void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
2762972a253aSDimitry Andric     Declarator &D, VirtSpecifiers &VS) {
27630b57cec5SDimitry Andric   DeclSpec DS(AttrFactory);
27640b57cec5SDimitry Andric 
27650b57cec5SDimitry Andric   // GNU-style and C++11 attributes are not allowed here, but they will be
27660b57cec5SDimitry Andric   // handled by the caller.  Diagnose everything else.
27670b57cec5SDimitry Andric   ParseTypeQualifierListOpt(
27680b57cec5SDimitry Andric       DS, AR_NoAttributesParsed, false,
27690b57cec5SDimitry Andric       /*IdentifierRequired=*/false, llvm::function_ref<void()>([&]() {
2770*0fca6ea1SDimitry Andric         Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D, &VS);
27710b57cec5SDimitry Andric       }));
27720b57cec5SDimitry Andric   D.ExtendWithDeclSpec(DS);
27730b57cec5SDimitry Andric 
27740b57cec5SDimitry Andric   if (D.isFunctionDeclarator()) {
27750b57cec5SDimitry Andric     auto &Function = D.getFunctionTypeInfo();
27760b57cec5SDimitry Andric     if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
27770b57cec5SDimitry Andric       auto DeclSpecCheck = [&](DeclSpec::TQ TypeQual, StringRef FixItName,
27780b57cec5SDimitry Andric                                SourceLocation SpecLoc) {
27790b57cec5SDimitry Andric         FixItHint Insertion;
27800b57cec5SDimitry Andric         auto &MQ = Function.getOrCreateMethodQualifiers();
27810b57cec5SDimitry Andric         if (!(MQ.getTypeQualifiers() & TypeQual)) {
27820b57cec5SDimitry Andric           std::string Name(FixItName.data());
27830b57cec5SDimitry Andric           Name += " ";
27840b57cec5SDimitry Andric           Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name);
27850b57cec5SDimitry Andric           MQ.SetTypeQual(TypeQual, SpecLoc);
27860b57cec5SDimitry Andric         }
27870b57cec5SDimitry Andric         Diag(SpecLoc, diag::err_declspec_after_virtspec)
27880b57cec5SDimitry Andric             << FixItName
27890b57cec5SDimitry Andric             << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
27900b57cec5SDimitry Andric             << FixItHint::CreateRemoval(SpecLoc) << Insertion;
27910b57cec5SDimitry Andric       };
27920b57cec5SDimitry Andric       DS.forEachQualifier(DeclSpecCheck);
27930b57cec5SDimitry Andric     }
27940b57cec5SDimitry Andric 
27950b57cec5SDimitry Andric     // Parse ref-qualifiers.
27960b57cec5SDimitry Andric     bool RefQualifierIsLValueRef = true;
27970b57cec5SDimitry Andric     SourceLocation RefQualifierLoc;
27980b57cec5SDimitry Andric     if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
27990b57cec5SDimitry Andric       const char *Name = (RefQualifierIsLValueRef ? "& " : "&& ");
2800972a253aSDimitry Andric       FixItHint Insertion =
2801972a253aSDimitry Andric           FixItHint::CreateInsertion(VS.getFirstLocation(), Name);
28020b57cec5SDimitry Andric       Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
2803e8d8bef9SDimitry Andric       Function.RefQualifierLoc = RefQualifierLoc;
28040b57cec5SDimitry Andric 
28050b57cec5SDimitry Andric       Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
28060b57cec5SDimitry Andric           << (RefQualifierIsLValueRef ? "&" : "&&")
28070b57cec5SDimitry Andric           << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())
2808972a253aSDimitry Andric           << FixItHint::CreateRemoval(RefQualifierLoc) << Insertion;
28090b57cec5SDimitry Andric       D.SetRangeEnd(RefQualifierLoc);
28100b57cec5SDimitry Andric     }
28110b57cec5SDimitry Andric   }
28120b57cec5SDimitry Andric }
28130b57cec5SDimitry Andric 
28140b57cec5SDimitry Andric /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
28150b57cec5SDimitry Andric ///
28160b57cec5SDimitry Andric ///       member-declaration:
28170b57cec5SDimitry Andric ///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
28180b57cec5SDimitry Andric ///         function-definition ';'[opt]
28190b57cec5SDimitry Andric ///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
28200b57cec5SDimitry Andric ///         using-declaration                                            [TODO]
28210b57cec5SDimitry Andric /// [C++0x] static_assert-declaration
28220b57cec5SDimitry Andric ///         template-declaration
28230b57cec5SDimitry Andric /// [GNU]   '__extension__' member-declaration
28240b57cec5SDimitry Andric ///
28250b57cec5SDimitry Andric ///       member-declarator-list:
28260b57cec5SDimitry Andric ///         member-declarator
28270b57cec5SDimitry Andric ///         member-declarator-list ',' member-declarator
28280b57cec5SDimitry Andric ///
28290b57cec5SDimitry Andric ///       member-declarator:
28300b57cec5SDimitry Andric ///         declarator virt-specifier-seq[opt] pure-specifier[opt]
2831480093f4SDimitry Andric /// [C++2a] declarator requires-clause
28320b57cec5SDimitry Andric ///         declarator constant-initializer[opt]
28330b57cec5SDimitry Andric /// [C++11] declarator brace-or-equal-initializer[opt]
28340b57cec5SDimitry Andric ///         identifier[opt] ':' constant-expression
28350b57cec5SDimitry Andric ///
28360b57cec5SDimitry Andric ///       virt-specifier-seq:
28370b57cec5SDimitry Andric ///         virt-specifier
28380b57cec5SDimitry Andric ///         virt-specifier-seq virt-specifier
28390b57cec5SDimitry Andric ///
28400b57cec5SDimitry Andric ///       virt-specifier:
28410b57cec5SDimitry Andric ///         override
28420b57cec5SDimitry Andric ///         final
28430b57cec5SDimitry Andric /// [MS]    sealed
28440b57cec5SDimitry Andric ///
28450b57cec5SDimitry Andric ///       pure-specifier:
28460b57cec5SDimitry Andric ///         '= 0'
28470b57cec5SDimitry Andric ///
28480b57cec5SDimitry Andric ///       constant-initializer:
28490b57cec5SDimitry Andric ///         '=' constant-expression
28500b57cec5SDimitry Andric ///
2851*0fca6ea1SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
2852*0fca6ea1SDimitry Andric     AccessSpecifier AS, ParsedAttributes &AccessAttrs,
2853*0fca6ea1SDimitry Andric     ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject *TemplateDiags) {
28541db9f3b2SDimitry Andric   assert(getLangOpts().CPlusPlus &&
28551db9f3b2SDimitry Andric          "ParseCXXClassMemberDeclaration should only be called in C++ mode");
28560b57cec5SDimitry Andric   if (Tok.is(tok::at)) {
28570b57cec5SDimitry Andric     if (getLangOpts().ObjC && NextToken().isObjCAtKeyword(tok::objc_defs))
28580b57cec5SDimitry Andric       Diag(Tok, diag::err_at_defs_cxx);
28590b57cec5SDimitry Andric     else
28600b57cec5SDimitry Andric       Diag(Tok, diag::err_at_in_class);
28610b57cec5SDimitry Andric 
28620b57cec5SDimitry Andric     ConsumeToken();
28630b57cec5SDimitry Andric     SkipUntil(tok::r_brace, StopAtSemi);
28640b57cec5SDimitry Andric     return nullptr;
28650b57cec5SDimitry Andric   }
28660b57cec5SDimitry Andric 
28670b57cec5SDimitry Andric   // Turn on colon protection early, while parsing declspec, although there is
28680b57cec5SDimitry Andric   // nothing to protect there. It prevents from false errors if error recovery
28690b57cec5SDimitry Andric   // incorrectly determines where the declspec ends, as in the example:
28700b57cec5SDimitry Andric   //   struct A { enum class B { C }; };
28710b57cec5SDimitry Andric   //   const int C = 4;
28720b57cec5SDimitry Andric   //   struct D { A::B : C; };
28730b57cec5SDimitry Andric   ColonProtectionRAIIObject X(*this);
28740b57cec5SDimitry Andric 
28750b57cec5SDimitry Andric   // Access declarations.
28760b57cec5SDimitry Andric   bool MalformedTypeSpec = false;
28770b57cec5SDimitry Andric   if (!TemplateInfo.Kind &&
28780b57cec5SDimitry Andric       Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {
28790b57cec5SDimitry Andric     if (TryAnnotateCXXScopeToken())
28800b57cec5SDimitry Andric       MalformedTypeSpec = true;
28810b57cec5SDimitry Andric 
28820b57cec5SDimitry Andric     bool isAccessDecl;
28830b57cec5SDimitry Andric     if (Tok.isNot(tok::annot_cxxscope))
28840b57cec5SDimitry Andric       isAccessDecl = false;
28850b57cec5SDimitry Andric     else if (NextToken().is(tok::identifier))
28860b57cec5SDimitry Andric       isAccessDecl = GetLookAheadToken(2).is(tok::semi);
28870b57cec5SDimitry Andric     else
28880b57cec5SDimitry Andric       isAccessDecl = NextToken().is(tok::kw_operator);
28890b57cec5SDimitry Andric 
28900b57cec5SDimitry Andric     if (isAccessDecl) {
28910b57cec5SDimitry Andric       // Collect the scope specifier token we annotated earlier.
28920b57cec5SDimitry Andric       CXXScopeSpec SS;
28935ffd83dbSDimitry Andric       ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
289404eeddc0SDimitry Andric                                      /*ObjectHasErrors=*/false,
28950b57cec5SDimitry Andric                                      /*EnteringContext=*/false);
28960b57cec5SDimitry Andric 
28970b57cec5SDimitry Andric       if (SS.isInvalid()) {
28980b57cec5SDimitry Andric         SkipUntil(tok::semi);
28990b57cec5SDimitry Andric         return nullptr;
29000b57cec5SDimitry Andric       }
29010b57cec5SDimitry Andric 
29020b57cec5SDimitry Andric       // Try to parse an unqualified-id.
29030b57cec5SDimitry Andric       SourceLocation TemplateKWLoc;
29040b57cec5SDimitry Andric       UnqualifiedId Name;
29055ffd83dbSDimitry Andric       if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
29065ffd83dbSDimitry Andric                              /*ObjectHadErrors=*/false, false, true, true,
29075ffd83dbSDimitry Andric                              false, &TemplateKWLoc, Name)) {
29080b57cec5SDimitry Andric         SkipUntil(tok::semi);
29090b57cec5SDimitry Andric         return nullptr;
29100b57cec5SDimitry Andric       }
29110b57cec5SDimitry Andric 
29120b57cec5SDimitry Andric       // TODO: recover from mistakenly-qualified operator declarations.
29130b57cec5SDimitry Andric       if (ExpectAndConsume(tok::semi, diag::err_expected_after,
29140b57cec5SDimitry Andric                            "access declaration")) {
29150b57cec5SDimitry Andric         SkipUntil(tok::semi);
29160b57cec5SDimitry Andric         return nullptr;
29170b57cec5SDimitry Andric       }
29180b57cec5SDimitry Andric 
29190b57cec5SDimitry Andric       // FIXME: We should do something with the 'template' keyword here.
29200b57cec5SDimitry Andric       return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration(
29210b57cec5SDimitry Andric           getCurScope(), AS, /*UsingLoc*/ SourceLocation(),
29220b57cec5SDimitry Andric           /*TypenameLoc*/ SourceLocation(), SS, Name,
29230b57cec5SDimitry Andric           /*EllipsisLoc*/ SourceLocation(),
29240b57cec5SDimitry Andric           /*AttrList*/ ParsedAttributesView())));
29250b57cec5SDimitry Andric     }
29260b57cec5SDimitry Andric   }
29270b57cec5SDimitry Andric 
29280b57cec5SDimitry Andric   // static_assert-declaration. A templated static_assert declaration is
2929*0fca6ea1SDimitry Andric   // diagnosed in Parser::ParseDeclarationAfterTemplate.
29300b57cec5SDimitry Andric   if (!TemplateInfo.Kind &&
29310b57cec5SDimitry Andric       Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
29320b57cec5SDimitry Andric     SourceLocation DeclEnd;
29330b57cec5SDimitry Andric     return DeclGroupPtrTy::make(
29340b57cec5SDimitry Andric         DeclGroupRef(ParseStaticAssertDeclaration(DeclEnd)));
29350b57cec5SDimitry Andric   }
29360b57cec5SDimitry Andric 
29370b57cec5SDimitry Andric   if (Tok.is(tok::kw_template)) {
29380b57cec5SDimitry Andric     assert(!TemplateInfo.TemplateParams &&
29390b57cec5SDimitry Andric            "Nested template improperly parsed?");
29400b57cec5SDimitry Andric     ObjCDeclContextSwitch ObjCDC(*this);
29410b57cec5SDimitry Andric     SourceLocation DeclEnd;
2942*0fca6ea1SDimitry Andric     return ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Member,
2943*0fca6ea1SDimitry Andric                                                     DeclEnd, AccessAttrs, AS);
29440b57cec5SDimitry Andric   }
29450b57cec5SDimitry Andric 
29460b57cec5SDimitry Andric   // Handle:  member-declaration ::= '__extension__' member-declaration
29470b57cec5SDimitry Andric   if (Tok.is(tok::kw___extension__)) {
29480b57cec5SDimitry Andric     // __extension__ silences extension warnings in the subexpression.
29490b57cec5SDimitry Andric     ExtensionRAIIObject O(Diags); // Use RAII to do this.
29500b57cec5SDimitry Andric     ConsumeToken();
2951972a253aSDimitry Andric     return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
2952972a253aSDimitry Andric                                           TemplateDiags);
29530b57cec5SDimitry Andric   }
29540b57cec5SDimitry Andric 
295581ad6265SDimitry Andric   ParsedAttributes DeclAttrs(AttrFactory);
29560b57cec5SDimitry Andric   // Optional C++11 attribute-specifier
295781ad6265SDimitry Andric   MaybeParseCXX11Attributes(DeclAttrs);
2958fe6060f1SDimitry Andric 
2959fe6060f1SDimitry Andric   // The next token may be an OpenMP pragma annotation token. That would
2960fe6060f1SDimitry Andric   // normally be handled from ParseCXXClassMemberDeclarationWithPragmas, but in
2961fe6060f1SDimitry Andric   // this case, it came from an *attribute* rather than a pragma. Handle it now.
2962fe6060f1SDimitry Andric   if (Tok.is(tok::annot_attr_openmp))
296381ad6265SDimitry Andric     return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, DeclAttrs);
29640b57cec5SDimitry Andric 
29650b57cec5SDimitry Andric   if (Tok.is(tok::kw_using)) {
29660b57cec5SDimitry Andric     // Eat 'using'.
29670b57cec5SDimitry Andric     SourceLocation UsingLoc = ConsumeToken();
29680b57cec5SDimitry Andric 
29690b57cec5SDimitry Andric     // Consume unexpected 'template' keywords.
29700b57cec5SDimitry Andric     while (Tok.is(tok::kw_template)) {
29710b57cec5SDimitry Andric       SourceLocation TemplateLoc = ConsumeToken();
29720b57cec5SDimitry Andric       Diag(TemplateLoc, diag::err_unexpected_template_after_using)
29730b57cec5SDimitry Andric           << FixItHint::CreateRemoval(TemplateLoc);
29740b57cec5SDimitry Andric     }
29750b57cec5SDimitry Andric 
29760b57cec5SDimitry Andric     if (Tok.is(tok::kw_namespace)) {
29770b57cec5SDimitry Andric       Diag(UsingLoc, diag::err_using_namespace_in_class);
29780b57cec5SDimitry Andric       SkipUntil(tok::semi, StopBeforeMatch);
29790b57cec5SDimitry Andric       return nullptr;
29800b57cec5SDimitry Andric     }
29810b57cec5SDimitry Andric     SourceLocation DeclEnd;
29820b57cec5SDimitry Andric     // Otherwise, it must be a using-declaration or an alias-declaration.
2983e8d8bef9SDimitry Andric     return ParseUsingDeclaration(DeclaratorContext::Member, TemplateInfo,
298481ad6265SDimitry Andric                                  UsingLoc, DeclEnd, DeclAttrs, AS);
29850b57cec5SDimitry Andric   }
29860b57cec5SDimitry Andric 
298781ad6265SDimitry Andric   ParsedAttributes DeclSpecAttrs(AttrFactory);
298881ad6265SDimitry Andric   MaybeParseMicrosoftAttributes(DeclSpecAttrs);
298981ad6265SDimitry Andric 
29900b57cec5SDimitry Andric   // Hold late-parsed attributes so we can attach a Decl to them later.
29910b57cec5SDimitry Andric   LateParsedAttrList CommonLateParsedAttrs;
29920b57cec5SDimitry Andric 
29930b57cec5SDimitry Andric   // decl-specifier-seq:
29940b57cec5SDimitry Andric   // Parse the common declaration-specifiers piece.
29950b57cec5SDimitry Andric   ParsingDeclSpec DS(*this, TemplateDiags);
299681ad6265SDimitry Andric   DS.takeAttributesFrom(DeclSpecAttrs);
299781ad6265SDimitry Andric 
29980b57cec5SDimitry Andric   if (MalformedTypeSpec)
29990b57cec5SDimitry Andric     DS.SetTypeSpecError();
30000b57cec5SDimitry Andric 
3001349cc55cSDimitry Andric   // Turn off usual access checking for templates explicit specialization
3002349cc55cSDimitry Andric   // and instantiation.
3003349cc55cSDimitry Andric   // C++20 [temp.spec] 13.9/6.
3004349cc55cSDimitry Andric   // This disables the access checking rules for member function template
3005349cc55cSDimitry Andric   // explicit instantiation and explicit specialization.
3006349cc55cSDimitry Andric   bool IsTemplateSpecOrInst =
3007349cc55cSDimitry Andric       (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3008349cc55cSDimitry Andric        TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3009349cc55cSDimitry Andric   SuppressAccessChecks diagsFromTag(*this, IsTemplateSpecOrInst);
3010349cc55cSDimitry Andric 
30110b57cec5SDimitry Andric   ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
30120b57cec5SDimitry Andric                              &CommonLateParsedAttrs);
30130b57cec5SDimitry Andric 
3014349cc55cSDimitry Andric   if (IsTemplateSpecOrInst)
3015349cc55cSDimitry Andric     diagsFromTag.done();
3016349cc55cSDimitry Andric 
30170b57cec5SDimitry Andric   // Turn off colon protection that was set for declspec.
30180b57cec5SDimitry Andric   X.restore();
30190b57cec5SDimitry Andric 
30200b57cec5SDimitry Andric   // If we had a free-standing type definition with a missing semicolon, we
30210b57cec5SDimitry Andric   // may get this far before the problem becomes obvious.
30220b57cec5SDimitry Andric   if (DS.hasTagDefinition() &&
30230b57cec5SDimitry Andric       TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
30240b57cec5SDimitry Andric       DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,
30250b57cec5SDimitry Andric                                             &CommonLateParsedAttrs))
30260b57cec5SDimitry Andric     return nullptr;
30270b57cec5SDimitry Andric 
30280b57cec5SDimitry Andric   MultiTemplateParamsArg TemplateParams(
30290b57cec5SDimitry Andric       TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
30300b57cec5SDimitry Andric                                   : nullptr,
30310b57cec5SDimitry Andric       TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
30320b57cec5SDimitry Andric 
30330b57cec5SDimitry Andric   if (TryConsumeToken(tok::semi)) {
30340b57cec5SDimitry Andric     if (DS.isFriendSpecified())
303581ad6265SDimitry Andric       ProhibitAttributes(DeclAttrs);
30360b57cec5SDimitry Andric 
30370b57cec5SDimitry Andric     RecordDecl *AnonRecord = nullptr;
30380b57cec5SDimitry Andric     Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
303981ad6265SDimitry Andric         getCurScope(), AS, DS, DeclAttrs, TemplateParams, false, AnonRecord);
30405f757f3fSDimitry Andric     Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
30410b57cec5SDimitry Andric     DS.complete(TheDecl);
30420b57cec5SDimitry Andric     if (AnonRecord) {
30430b57cec5SDimitry Andric       Decl *decls[] = {AnonRecord, TheDecl};
30440b57cec5SDimitry Andric       return Actions.BuildDeclaratorGroup(decls);
30450b57cec5SDimitry Andric     }
30460b57cec5SDimitry Andric     return Actions.ConvertDeclToDeclGroup(TheDecl);
30470b57cec5SDimitry Andric   }
30480b57cec5SDimitry Andric 
30495f757f3fSDimitry Andric   if (DS.hasTagDefinition())
30505f757f3fSDimitry Andric     Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());
30515f757f3fSDimitry Andric 
305281ad6265SDimitry Andric   ParsingDeclarator DeclaratorInfo(*this, DS, DeclAttrs,
305381ad6265SDimitry Andric                                    DeclaratorContext::Member);
305455e4f9d5SDimitry Andric   if (TemplateInfo.TemplateParams)
305555e4f9d5SDimitry Andric     DeclaratorInfo.setTemplateParameterLists(TemplateParams);
30560b57cec5SDimitry Andric   VirtSpecifiers VS;
30570b57cec5SDimitry Andric 
30580b57cec5SDimitry Andric   // Hold late-parsed attributes so we can attach a Decl to them later.
30590b57cec5SDimitry Andric   LateParsedAttrList LateParsedAttrs;
30600b57cec5SDimitry Andric 
30610b57cec5SDimitry Andric   SourceLocation EqualLoc;
30620b57cec5SDimitry Andric   SourceLocation PureSpecLoc;
30630b57cec5SDimitry Andric 
30640b57cec5SDimitry Andric   auto TryConsumePureSpecifier = [&](bool AllowDefinition) {
30650b57cec5SDimitry Andric     if (Tok.isNot(tok::equal))
30660b57cec5SDimitry Andric       return false;
30670b57cec5SDimitry Andric 
30680b57cec5SDimitry Andric     auto &Zero = NextToken();
30690b57cec5SDimitry Andric     SmallString<8> Buffer;
30705ffd83dbSDimitry Andric     if (Zero.isNot(tok::numeric_constant) ||
30710b57cec5SDimitry Andric         PP.getSpelling(Zero, Buffer) != "0")
30720b57cec5SDimitry Andric       return false;
30730b57cec5SDimitry Andric 
30740b57cec5SDimitry Andric     auto &After = GetLookAheadToken(2);
30750b57cec5SDimitry Andric     if (!After.isOneOf(tok::semi, tok::comma) &&
30760b57cec5SDimitry Andric         !(AllowDefinition &&
30770b57cec5SDimitry Andric           After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))
30780b57cec5SDimitry Andric       return false;
30790b57cec5SDimitry Andric 
30800b57cec5SDimitry Andric     EqualLoc = ConsumeToken();
30810b57cec5SDimitry Andric     PureSpecLoc = ConsumeToken();
30820b57cec5SDimitry Andric     return true;
30830b57cec5SDimitry Andric   };
30840b57cec5SDimitry Andric 
30850b57cec5SDimitry Andric   SmallVector<Decl *, 8> DeclsInGroup;
30860b57cec5SDimitry Andric   ExprResult BitfieldSize;
3087480093f4SDimitry Andric   ExprResult TrailingRequiresClause;
30880b57cec5SDimitry Andric   bool ExpectSemi = true;
30890b57cec5SDimitry Andric 
3090349cc55cSDimitry Andric   // C++20 [temp.spec] 13.9/6.
3091349cc55cSDimitry Andric   // This disables the access checking rules for member function template
3092349cc55cSDimitry Andric   // explicit instantiation and explicit specialization.
3093349cc55cSDimitry Andric   SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);
3094349cc55cSDimitry Andric 
30950b57cec5SDimitry Andric   // Parse the first declarator.
30960b57cec5SDimitry Andric   if (ParseCXXMemberDeclaratorBeforeInitializer(
30970b57cec5SDimitry Andric           DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {
30980b57cec5SDimitry Andric     TryConsumeToken(tok::semi);
30990b57cec5SDimitry Andric     return nullptr;
31000b57cec5SDimitry Andric   }
31010b57cec5SDimitry Andric 
3102349cc55cSDimitry Andric   if (IsTemplateSpecOrInst)
3103349cc55cSDimitry Andric     SAC.done();
3104349cc55cSDimitry Andric 
31050b57cec5SDimitry Andric   // Check for a member function definition.
31060b57cec5SDimitry Andric   if (BitfieldSize.isUnset()) {
31070b57cec5SDimitry Andric     // MSVC permits pure specifier on inline functions defined at class scope.
31080b57cec5SDimitry Andric     // Hence check for =0 before checking for function definition.
31090b57cec5SDimitry Andric     if (getLangOpts().MicrosoftExt && DeclaratorInfo.isDeclarationOfFunction())
31100b57cec5SDimitry Andric       TryConsumePureSpecifier(/*AllowDefinition*/ true);
31110b57cec5SDimitry Andric 
3112e8d8bef9SDimitry Andric     FunctionDefinitionKind DefinitionKind = FunctionDefinitionKind::Declaration;
31130b57cec5SDimitry Andric     // function-definition:
31140b57cec5SDimitry Andric     //
31150b57cec5SDimitry Andric     // In C++11, a non-function declarator followed by an open brace is a
31160b57cec5SDimitry Andric     // braced-init-list for an in-class member initialization, not an
31170b57cec5SDimitry Andric     // erroneous function definition.
31180b57cec5SDimitry Andric     if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) {
3119e8d8bef9SDimitry Andric       DefinitionKind = FunctionDefinitionKind::Definition;
31200b57cec5SDimitry Andric     } else if (DeclaratorInfo.isFunctionDeclarator()) {
31210b57cec5SDimitry Andric       if (Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {
3122e8d8bef9SDimitry Andric         DefinitionKind = FunctionDefinitionKind::Definition;
31230b57cec5SDimitry Andric       } else if (Tok.is(tok::equal)) {
31240b57cec5SDimitry Andric         const Token &KW = NextToken();
31250b57cec5SDimitry Andric         if (KW.is(tok::kw_default))
3126e8d8bef9SDimitry Andric           DefinitionKind = FunctionDefinitionKind::Defaulted;
31270b57cec5SDimitry Andric         else if (KW.is(tok::kw_delete))
3128e8d8bef9SDimitry Andric           DefinitionKind = FunctionDefinitionKind::Deleted;
31295ffd83dbSDimitry Andric         else if (KW.is(tok::code_completion)) {
31305ffd83dbSDimitry Andric           cutOffParsing();
3131*0fca6ea1SDimitry Andric           Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(
3132*0fca6ea1SDimitry Andric               DeclaratorInfo);
31335ffd83dbSDimitry Andric           return nullptr;
31345ffd83dbSDimitry Andric         }
31350b57cec5SDimitry Andric       }
31360b57cec5SDimitry Andric     }
31370b57cec5SDimitry Andric     DeclaratorInfo.setFunctionDefinitionKind(DefinitionKind);
31380b57cec5SDimitry Andric 
31390b57cec5SDimitry Andric     // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
31400b57cec5SDimitry Andric     // to a friend declaration, that declaration shall be a definition.
31410b57cec5SDimitry Andric     if (DeclaratorInfo.isFunctionDeclarator() &&
3142e8d8bef9SDimitry Andric         DefinitionKind == FunctionDefinitionKind::Declaration &&
3143e8d8bef9SDimitry Andric         DS.isFriendSpecified()) {
31440b57cec5SDimitry Andric       // Diagnose attributes that appear before decl specifier:
31450b57cec5SDimitry Andric       // [[]] friend int foo();
314681ad6265SDimitry Andric       ProhibitAttributes(DeclAttrs);
31470b57cec5SDimitry Andric     }
31480b57cec5SDimitry Andric 
3149e8d8bef9SDimitry Andric     if (DefinitionKind != FunctionDefinitionKind::Declaration) {
31500b57cec5SDimitry Andric       if (!DeclaratorInfo.isFunctionDeclarator()) {
31510b57cec5SDimitry Andric         Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
31520b57cec5SDimitry Andric         ConsumeBrace();
31530b57cec5SDimitry Andric         SkipUntil(tok::r_brace);
31540b57cec5SDimitry Andric 
31550b57cec5SDimitry Andric         // Consume the optional ';'
31560b57cec5SDimitry Andric         TryConsumeToken(tok::semi);
31570b57cec5SDimitry Andric 
31580b57cec5SDimitry Andric         return nullptr;
31590b57cec5SDimitry Andric       }
31600b57cec5SDimitry Andric 
31610b57cec5SDimitry Andric       if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
31620b57cec5SDimitry Andric         Diag(DeclaratorInfo.getIdentifierLoc(),
31630b57cec5SDimitry Andric              diag::err_function_declared_typedef);
31640b57cec5SDimitry Andric 
31650b57cec5SDimitry Andric         // Recover by treating the 'typedef' as spurious.
31660b57cec5SDimitry Andric         DS.ClearStorageClassSpecs();
31670b57cec5SDimitry Andric       }
31680b57cec5SDimitry Andric 
3169972a253aSDimitry Andric       Decl *FunDecl = ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo,
3170972a253aSDimitry Andric                                               TemplateInfo, VS, PureSpecLoc);
31710b57cec5SDimitry Andric 
31720b57cec5SDimitry Andric       if (FunDecl) {
31730b57cec5SDimitry Andric         for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
31740b57cec5SDimitry Andric           CommonLateParsedAttrs[i]->addDecl(FunDecl);
31750b57cec5SDimitry Andric         }
31760b57cec5SDimitry Andric         for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
31770b57cec5SDimitry Andric           LateParsedAttrs[i]->addDecl(FunDecl);
31780b57cec5SDimitry Andric         }
31790b57cec5SDimitry Andric       }
31800b57cec5SDimitry Andric       LateParsedAttrs.clear();
31810b57cec5SDimitry Andric 
31820b57cec5SDimitry Andric       // Consume the ';' - it's optional unless we have a delete or default
31830b57cec5SDimitry Andric       if (Tok.is(tok::semi))
31840b57cec5SDimitry Andric         ConsumeExtraSemi(AfterMemberFunctionDefinition);
31850b57cec5SDimitry Andric 
31860b57cec5SDimitry Andric       return DeclGroupPtrTy::make(DeclGroupRef(FunDecl));
31870b57cec5SDimitry Andric     }
31880b57cec5SDimitry Andric   }
31890b57cec5SDimitry Andric 
31900b57cec5SDimitry Andric   // member-declarator-list:
31910b57cec5SDimitry Andric   //   member-declarator
31920b57cec5SDimitry Andric   //   member-declarator-list ',' member-declarator
31930b57cec5SDimitry Andric 
319404eeddc0SDimitry Andric   while (true) {
31950b57cec5SDimitry Andric     InClassInitStyle HasInClassInit = ICIS_NoInit;
31960b57cec5SDimitry Andric     bool HasStaticInitializer = false;
31970b57cec5SDimitry Andric     if (Tok.isOneOf(tok::equal, tok::l_brace) && PureSpecLoc.isInvalid()) {
3198e8d8bef9SDimitry Andric       // DRXXXX: Anonymous bit-fields cannot have a brace-or-equal-initializer.
3199e8d8bef9SDimitry Andric       if (BitfieldSize.isUsable() && !DeclaratorInfo.hasName()) {
3200e8d8bef9SDimitry Andric         // Diagnose the error and pretend there is no in-class initializer.
3201e8d8bef9SDimitry Andric         Diag(Tok, diag::err_anon_bitfield_member_init);
3202e8d8bef9SDimitry Andric         SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
3203e8d8bef9SDimitry Andric       } else if (DeclaratorInfo.isDeclarationOfFunction()) {
32040b57cec5SDimitry Andric         // It's a pure-specifier.
32050b57cec5SDimitry Andric         if (!TryConsumePureSpecifier(/*AllowFunctionDefinition*/ false))
32060b57cec5SDimitry Andric           // Parse it as an expression so that Sema can diagnose it.
32070b57cec5SDimitry Andric           HasStaticInitializer = true;
32080b57cec5SDimitry Andric       } else if (DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
32090b57cec5SDimitry Andric                      DeclSpec::SCS_static &&
32100b57cec5SDimitry Andric                  DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
32110b57cec5SDimitry Andric                      DeclSpec::SCS_typedef &&
3212*0fca6ea1SDimitry Andric                  !DS.isFriendSpecified() &&
3213*0fca6ea1SDimitry Andric                  TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate) {
32140b57cec5SDimitry Andric         // It's a default member initializer.
32150b57cec5SDimitry Andric         if (BitfieldSize.get())
32165ffd83dbSDimitry Andric           Diag(Tok, getLangOpts().CPlusPlus20
32170b57cec5SDimitry Andric                         ? diag::warn_cxx17_compat_bitfield_member_init
32180b57cec5SDimitry Andric                         : diag::ext_bitfield_member_init);
32190b57cec5SDimitry Andric         HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit;
32200b57cec5SDimitry Andric       } else {
32210b57cec5SDimitry Andric         HasStaticInitializer = true;
32220b57cec5SDimitry Andric       }
32230b57cec5SDimitry Andric     }
32240b57cec5SDimitry Andric 
32250b57cec5SDimitry Andric     // NOTE: If Sema is the Action module and declarator is an instance field,
32260b57cec5SDimitry Andric     // this call will *not* return the created decl; It will return null.
32270b57cec5SDimitry Andric     // See Sema::ActOnCXXMemberDeclarator for details.
32280b57cec5SDimitry Andric 
32290b57cec5SDimitry Andric     NamedDecl *ThisDecl = nullptr;
32300b57cec5SDimitry Andric     if (DS.isFriendSpecified()) {
32310b57cec5SDimitry Andric       // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
32320b57cec5SDimitry Andric       // to a friend declaration, that declaration shall be a definition.
32330b57cec5SDimitry Andric       //
32340b57cec5SDimitry Andric       // Diagnose attributes that appear in a friend member function declarator:
32350b57cec5SDimitry Andric       //   friend int foo [[]] ();
323606c3fb27SDimitry Andric       for (const ParsedAttr &AL : DeclaratorInfo.getAttributes())
323706c3fb27SDimitry Andric         if (AL.isCXX11Attribute() || AL.isRegularKeywordAttribute()) {
323806c3fb27SDimitry Andric           auto Loc = AL.getRange().getBegin();
323906c3fb27SDimitry Andric           (AL.isRegularKeywordAttribute()
324006c3fb27SDimitry Andric                ? Diag(Loc, diag::err_keyword_not_allowed) << AL
324106c3fb27SDimitry Andric                : Diag(Loc, diag::err_attributes_not_allowed))
324206c3fb27SDimitry Andric               << AL.getRange();
324306c3fb27SDimitry Andric         }
32440b57cec5SDimitry Andric 
32450b57cec5SDimitry Andric       ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
32460b57cec5SDimitry Andric                                                  TemplateParams);
32470b57cec5SDimitry Andric     } else {
3248972a253aSDimitry Andric       ThisDecl = Actions.ActOnCXXMemberDeclarator(
3249972a253aSDimitry Andric           getCurScope(), AS, DeclaratorInfo, TemplateParams, BitfieldSize.get(),
32500b57cec5SDimitry Andric           VS, HasInClassInit);
32510b57cec5SDimitry Andric 
32520b57cec5SDimitry Andric       if (VarTemplateDecl *VT =
32530b57cec5SDimitry Andric               ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : nullptr)
32540b57cec5SDimitry Andric         // Re-direct this decl to refer to the templated decl so that we can
32550b57cec5SDimitry Andric         // initialize it.
32560b57cec5SDimitry Andric         ThisDecl = VT->getTemplatedDecl();
32570b57cec5SDimitry Andric 
32580b57cec5SDimitry Andric       if (ThisDecl)
32590b57cec5SDimitry Andric         Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
32600b57cec5SDimitry Andric     }
32610b57cec5SDimitry Andric 
32620b57cec5SDimitry Andric     // Error recovery might have converted a non-static member into a static
32630b57cec5SDimitry Andric     // member.
32640b57cec5SDimitry Andric     if (HasInClassInit != ICIS_NoInit &&
32650b57cec5SDimitry Andric         DeclaratorInfo.getDeclSpec().getStorageClassSpec() ==
32660b57cec5SDimitry Andric             DeclSpec::SCS_static) {
32670b57cec5SDimitry Andric       HasInClassInit = ICIS_NoInit;
32680b57cec5SDimitry Andric       HasStaticInitializer = true;
32690b57cec5SDimitry Andric     }
32700b57cec5SDimitry Andric 
3271fe6060f1SDimitry Andric     if (PureSpecLoc.isValid() && VS.getAbstractLoc().isValid()) {
3272fe6060f1SDimitry Andric       Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) << "abstract";
3273fe6060f1SDimitry Andric     }
32740b57cec5SDimitry Andric     if (ThisDecl && PureSpecLoc.isValid())
32750b57cec5SDimitry Andric       Actions.ActOnPureSpecifier(ThisDecl, PureSpecLoc);
3276fe6060f1SDimitry Andric     else if (ThisDecl && VS.getAbstractLoc().isValid())
3277fe6060f1SDimitry Andric       Actions.ActOnPureSpecifier(ThisDecl, VS.getAbstractLoc());
32780b57cec5SDimitry Andric 
32790b57cec5SDimitry Andric     // Handle the initializer.
32800b57cec5SDimitry Andric     if (HasInClassInit != ICIS_NoInit) {
32810b57cec5SDimitry Andric       // The initializer was deferred; parse it and cache the tokens.
32820b57cec5SDimitry Andric       Diag(Tok, getLangOpts().CPlusPlus11
32830b57cec5SDimitry Andric                     ? diag::warn_cxx98_compat_nonstatic_member_init
32840b57cec5SDimitry Andric                     : diag::ext_nonstatic_member_init);
32850b57cec5SDimitry Andric 
32860b57cec5SDimitry Andric       if (DeclaratorInfo.isArrayOfUnknownBound()) {
32870b57cec5SDimitry Andric         // C++11 [dcl.array]p3: An array bound may also be omitted when the
32880b57cec5SDimitry Andric         // declarator is followed by an initializer.
32890b57cec5SDimitry Andric         //
32900b57cec5SDimitry Andric         // A brace-or-equal-initializer for a member-declarator is not an
32910b57cec5SDimitry Andric         // initializer in the grammar, so this is ill-formed.
32920b57cec5SDimitry Andric         Diag(Tok, diag::err_incomplete_array_member_init);
32930b57cec5SDimitry Andric         SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
32940b57cec5SDimitry Andric 
32950b57cec5SDimitry Andric         // Avoid later warnings about a class member of incomplete type.
32960b57cec5SDimitry Andric         if (ThisDecl)
32970b57cec5SDimitry Andric           ThisDecl->setInvalidDecl();
32980b57cec5SDimitry Andric       } else
32990b57cec5SDimitry Andric         ParseCXXNonStaticMemberInitializer(ThisDecl);
33000b57cec5SDimitry Andric     } else if (HasStaticInitializer) {
33010b57cec5SDimitry Andric       // Normal initializer.
33020b57cec5SDimitry Andric       ExprResult Init = ParseCXXMemberInitializer(
33030b57cec5SDimitry Andric           ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
33040b57cec5SDimitry Andric 
3305349cc55cSDimitry Andric       if (Init.isInvalid()) {
3306349cc55cSDimitry Andric         if (ThisDecl)
3307349cc55cSDimitry Andric           Actions.ActOnUninitializedDecl(ThisDecl);
33080b57cec5SDimitry Andric         SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
3309349cc55cSDimitry Andric       } else if (ThisDecl)
3310972a253aSDimitry Andric         Actions.AddInitializerToDecl(ThisDecl, Init.get(),
3311972a253aSDimitry Andric                                      EqualLoc.isInvalid());
3312*0fca6ea1SDimitry Andric     } else if (ThisDecl && DeclaratorInfo.isStaticMember())
33130b57cec5SDimitry Andric       // No initializer.
33140b57cec5SDimitry Andric       Actions.ActOnUninitializedDecl(ThisDecl);
33150b57cec5SDimitry Andric 
33160b57cec5SDimitry Andric     if (ThisDecl) {
33170b57cec5SDimitry Andric       if (!ThisDecl->isInvalidDecl()) {
33180b57cec5SDimitry Andric         // Set the Decl for any late parsed attributes
33190b57cec5SDimitry Andric         for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
33200b57cec5SDimitry Andric           CommonLateParsedAttrs[i]->addDecl(ThisDecl);
33210b57cec5SDimitry Andric 
33220b57cec5SDimitry Andric         for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
33230b57cec5SDimitry Andric           LateParsedAttrs[i]->addDecl(ThisDecl);
33240b57cec5SDimitry Andric       }
33250b57cec5SDimitry Andric       Actions.FinalizeDeclaration(ThisDecl);
33260b57cec5SDimitry Andric       DeclsInGroup.push_back(ThisDecl);
33270b57cec5SDimitry Andric 
33280b57cec5SDimitry Andric       if (DeclaratorInfo.isFunctionDeclarator() &&
33290b57cec5SDimitry Andric           DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
33300b57cec5SDimitry Andric               DeclSpec::SCS_typedef)
33310b57cec5SDimitry Andric         HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
33320b57cec5SDimitry Andric     }
33330b57cec5SDimitry Andric     LateParsedAttrs.clear();
33340b57cec5SDimitry Andric 
33350b57cec5SDimitry Andric     DeclaratorInfo.complete(ThisDecl);
33360b57cec5SDimitry Andric 
33370b57cec5SDimitry Andric     // If we don't have a comma, it is either the end of the list (a ';')
33380b57cec5SDimitry Andric     // or an error, bail out.
33390b57cec5SDimitry Andric     SourceLocation CommaLoc;
33400b57cec5SDimitry Andric     if (!TryConsumeToken(tok::comma, CommaLoc))
33410b57cec5SDimitry Andric       break;
33420b57cec5SDimitry Andric 
33430b57cec5SDimitry Andric     if (Tok.isAtStartOfLine() &&
3344e8d8bef9SDimitry Andric         !MightBeDeclarator(DeclaratorContext::Member)) {
33450b57cec5SDimitry Andric       // This comma was followed by a line-break and something which can't be
33460b57cec5SDimitry Andric       // the start of a declarator. The comma was probably a typo for a
33470b57cec5SDimitry Andric       // semicolon.
33480b57cec5SDimitry Andric       Diag(CommaLoc, diag::err_expected_semi_declaration)
33490b57cec5SDimitry Andric           << FixItHint::CreateReplacement(CommaLoc, ";");
33500b57cec5SDimitry Andric       ExpectSemi = false;
33510b57cec5SDimitry Andric       break;
33520b57cec5SDimitry Andric     }
33530b57cec5SDimitry Andric 
3354*0fca6ea1SDimitry Andric     // C++23 [temp.pre]p5:
3355*0fca6ea1SDimitry Andric     //   In a template-declaration, explicit specialization, or explicit
3356*0fca6ea1SDimitry Andric     //   instantiation the init-declarator-list in the declaration shall
3357*0fca6ea1SDimitry Andric     //   contain at most one declarator.
3358*0fca6ea1SDimitry Andric     if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
3359*0fca6ea1SDimitry Andric         DeclaratorInfo.isFirstDeclarator()) {
3360*0fca6ea1SDimitry Andric       Diag(CommaLoc, diag::err_multiple_template_declarators)
3361*0fca6ea1SDimitry Andric           << TemplateInfo.Kind;
3362*0fca6ea1SDimitry Andric     }
3363*0fca6ea1SDimitry Andric 
33640b57cec5SDimitry Andric     // Parse the next declarator.
33650b57cec5SDimitry Andric     DeclaratorInfo.clear();
33660b57cec5SDimitry Andric     VS.clear();
33670b57cec5SDimitry Andric     BitfieldSize = ExprResult(/*Invalid=*/false);
33680b57cec5SDimitry Andric     EqualLoc = PureSpecLoc = SourceLocation();
33690b57cec5SDimitry Andric     DeclaratorInfo.setCommaLoc(CommaLoc);
33700b57cec5SDimitry Andric 
33710b57cec5SDimitry Andric     // GNU attributes are allowed before the second and subsequent declarator.
3372e8d8bef9SDimitry Andric     // However, this does not apply for [[]] attributes (which could show up
3373e8d8bef9SDimitry Andric     // before or after the __attribute__ attributes).
3374e8d8bef9SDimitry Andric     DiagnoseAndSkipCXX11Attributes();
33750b57cec5SDimitry Andric     MaybeParseGNUAttributes(DeclaratorInfo);
3376e8d8bef9SDimitry Andric     DiagnoseAndSkipCXX11Attributes();
33770b57cec5SDimitry Andric 
33780b57cec5SDimitry Andric     if (ParseCXXMemberDeclaratorBeforeInitializer(
33790b57cec5SDimitry Andric             DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))
33800b57cec5SDimitry Andric       break;
33810b57cec5SDimitry Andric   }
33820b57cec5SDimitry Andric 
33830b57cec5SDimitry Andric   if (ExpectSemi &&
33840b57cec5SDimitry Andric       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
33850b57cec5SDimitry Andric     // Skip to end of block or statement.
33860b57cec5SDimitry Andric     SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
33870b57cec5SDimitry Andric     // If we stopped at a ';', eat it.
33880b57cec5SDimitry Andric     TryConsumeToken(tok::semi);
33890b57cec5SDimitry Andric     return nullptr;
33900b57cec5SDimitry Andric   }
33910b57cec5SDimitry Andric 
33920b57cec5SDimitry Andric   return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
33930b57cec5SDimitry Andric }
33940b57cec5SDimitry Andric 
33950b57cec5SDimitry Andric /// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer.
33960b57cec5SDimitry Andric /// Also detect and reject any attempted defaulted/deleted function definition.
33970b57cec5SDimitry Andric /// The location of the '=', if any, will be placed in EqualLoc.
33980b57cec5SDimitry Andric ///
33990b57cec5SDimitry Andric /// This does not check for a pure-specifier; that's handled elsewhere.
34000b57cec5SDimitry Andric ///
34010b57cec5SDimitry Andric ///   brace-or-equal-initializer:
34020b57cec5SDimitry Andric ///     '=' initializer-expression
34030b57cec5SDimitry Andric ///     braced-init-list
34040b57cec5SDimitry Andric ///
34050b57cec5SDimitry Andric ///   initializer-clause:
34060b57cec5SDimitry Andric ///     assignment-expression
34070b57cec5SDimitry Andric ///     braced-init-list
34080b57cec5SDimitry Andric ///
34090b57cec5SDimitry Andric ///   defaulted/deleted function-definition:
34100b57cec5SDimitry Andric ///     '=' 'default'
34110b57cec5SDimitry Andric ///     '=' 'delete'
34120b57cec5SDimitry Andric ///
34130b57cec5SDimitry Andric /// Prior to C++0x, the assignment-expression in an initializer-clause must
34140b57cec5SDimitry Andric /// be a constant-expression.
34150b57cec5SDimitry Andric ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
34160b57cec5SDimitry Andric                                              SourceLocation &EqualLoc) {
3417972a253aSDimitry Andric   assert(Tok.isOneOf(tok::equal, tok::l_brace) &&
3418972a253aSDimitry Andric          "Data member initializer not starting with '=' or '{'");
34190b57cec5SDimitry Andric 
34205f757f3fSDimitry Andric   bool IsFieldInitialization = isa_and_present<FieldDecl>(D);
34215f757f3fSDimitry Andric 
34220b57cec5SDimitry Andric   EnterExpressionEvaluationContext Context(
3423bdd1243dSDimitry Andric       Actions,
34245f757f3fSDimitry Andric       IsFieldInitialization
3425bdd1243dSDimitry Andric           ? Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed
3426bdd1243dSDimitry Andric           : Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
3427bdd1243dSDimitry Andric       D);
34285f757f3fSDimitry Andric 
34295f757f3fSDimitry Andric   // CWG2760
34305f757f3fSDimitry Andric   // Default member initializers used to initialize a base or member subobject
34315f757f3fSDimitry Andric   // [...] are considered to be part of the function body
34325f757f3fSDimitry Andric   Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext =
34335f757f3fSDimitry Andric       IsFieldInitialization;
34345f757f3fSDimitry Andric 
34350b57cec5SDimitry Andric   if (TryConsumeToken(tok::equal, EqualLoc)) {
34360b57cec5SDimitry Andric     if (Tok.is(tok::kw_delete)) {
34370b57cec5SDimitry Andric       // In principle, an initializer of '= delete p;' is legal, but it will
3438972a253aSDimitry Andric       // never type-check. It's better to diagnose it as an ill-formed
3439972a253aSDimitry Andric       // expression than as an ill-formed deleted non-function member. An
3440972a253aSDimitry Andric       // initializer of '= delete p, foo' will never be parsed, because a
3441972a253aSDimitry Andric       // top-level comma always ends the initializer expression.
34420b57cec5SDimitry Andric       const Token &Next = NextToken();
34430b57cec5SDimitry Andric       if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {
34440b57cec5SDimitry Andric         if (IsFunction)
34450b57cec5SDimitry Andric           Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
34460b57cec5SDimitry Andric               << 1 /* delete */;
34470b57cec5SDimitry Andric         else
34480b57cec5SDimitry Andric           Diag(ConsumeToken(), diag::err_deleted_non_function);
3449*0fca6ea1SDimitry Andric         SkipDeletedFunctionBody();
34500b57cec5SDimitry Andric         return ExprError();
34510b57cec5SDimitry Andric       }
34520b57cec5SDimitry Andric     } else if (Tok.is(tok::kw_default)) {
34530b57cec5SDimitry Andric       if (IsFunction)
34540b57cec5SDimitry Andric         Diag(Tok, diag::err_default_delete_in_multiple_declaration)
34550b57cec5SDimitry Andric             << 0 /* default */;
34560b57cec5SDimitry Andric       else
3457480093f4SDimitry Andric         Diag(ConsumeToken(), diag::err_default_special_members)
34585ffd83dbSDimitry Andric             << getLangOpts().CPlusPlus20;
34590b57cec5SDimitry Andric       return ExprError();
34600b57cec5SDimitry Andric     }
34610b57cec5SDimitry Andric   }
34620b57cec5SDimitry Andric   if (const auto *PD = dyn_cast_or_null<MSPropertyDecl>(D)) {
34630b57cec5SDimitry Andric     Diag(Tok, diag::err_ms_property_initializer) << PD;
34640b57cec5SDimitry Andric     return ExprError();
34650b57cec5SDimitry Andric   }
34660b57cec5SDimitry Andric   return ParseInitializer();
34670b57cec5SDimitry Andric }
34680b57cec5SDimitry Andric 
34690b57cec5SDimitry Andric void Parser::SkipCXXMemberSpecification(SourceLocation RecordLoc,
34700b57cec5SDimitry Andric                                         SourceLocation AttrFixitLoc,
34710b57cec5SDimitry Andric                                         unsigned TagType, Decl *TagDecl) {
34720b57cec5SDimitry Andric   // Skip the optional 'final' keyword.
34730b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
34740b57cec5SDimitry Andric     assert(isCXX11FinalKeyword() && "not a class definition");
34750b57cec5SDimitry Andric     ConsumeToken();
34760b57cec5SDimitry Andric 
34770b57cec5SDimitry Andric     // Diagnose any C++11 attributes after 'final' keyword.
34780b57cec5SDimitry Andric     // We deliberately discard these attributes.
347981ad6265SDimitry Andric     ParsedAttributes Attrs(AttrFactory);
34800b57cec5SDimitry Andric     CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
34810b57cec5SDimitry Andric 
34820b57cec5SDimitry Andric     // This can only happen if we had malformed misplaced attributes;
34830b57cec5SDimitry Andric     // we only get called if there is a colon or left-brace after the
34840b57cec5SDimitry Andric     // attributes.
34850b57cec5SDimitry Andric     if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_brace))
34860b57cec5SDimitry Andric       return;
34870b57cec5SDimitry Andric   }
34880b57cec5SDimitry Andric 
34890b57cec5SDimitry Andric   // Skip the base clauses. This requires actually parsing them, because
34900b57cec5SDimitry Andric   // otherwise we can't be sure where they end (a left brace may appear
34910b57cec5SDimitry Andric   // within a template argument).
34920b57cec5SDimitry Andric   if (Tok.is(tok::colon)) {
34930b57cec5SDimitry Andric     // Enter the scope of the class so that we can correctly parse its bases.
34940b57cec5SDimitry Andric     ParseScope ClassScope(this, Scope::ClassScope | Scope::DeclScope);
34950b57cec5SDimitry Andric     ParsingClassDefinition ParsingDef(*this, TagDecl, /*NonNestedClass*/ true,
34960b57cec5SDimitry Andric                                       TagType == DeclSpec::TST_interface);
34970b57cec5SDimitry Andric     auto OldContext =
34980b57cec5SDimitry Andric         Actions.ActOnTagStartSkippedDefinition(getCurScope(), TagDecl);
34990b57cec5SDimitry Andric 
35000b57cec5SDimitry Andric     // Parse the bases but don't attach them to the class.
35010b57cec5SDimitry Andric     ParseBaseClause(nullptr);
35020b57cec5SDimitry Andric 
35030b57cec5SDimitry Andric     Actions.ActOnTagFinishSkippedDefinition(OldContext);
35040b57cec5SDimitry Andric 
35050b57cec5SDimitry Andric     if (!Tok.is(tok::l_brace)) {
35060b57cec5SDimitry Andric       Diag(PP.getLocForEndOfToken(PrevTokLocation),
35070b57cec5SDimitry Andric            diag::err_expected_lbrace_after_base_specifiers);
35080b57cec5SDimitry Andric       return;
35090b57cec5SDimitry Andric     }
35100b57cec5SDimitry Andric   }
35110b57cec5SDimitry Andric 
35120b57cec5SDimitry Andric   // Skip the body.
35130b57cec5SDimitry Andric   assert(Tok.is(tok::l_brace));
35140b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_brace);
35150b57cec5SDimitry Andric   T.consumeOpen();
35160b57cec5SDimitry Andric   T.skipToEnd();
35170b57cec5SDimitry Andric 
35180b57cec5SDimitry Andric   // Parse and discard any trailing attributes.
351981ad6265SDimitry Andric   if (Tok.is(tok::kw___attribute)) {
35200b57cec5SDimitry Andric     ParsedAttributes Attrs(AttrFactory);
35210b57cec5SDimitry Andric     MaybeParseGNUAttributes(Attrs);
35220b57cec5SDimitry Andric   }
352381ad6265SDimitry Andric }
35240b57cec5SDimitry Andric 
35250b57cec5SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
352681ad6265SDimitry Andric     AccessSpecifier &AS, ParsedAttributes &AccessAttrs, DeclSpec::TST TagType,
352781ad6265SDimitry Andric     Decl *TagDecl) {
35280b57cec5SDimitry Andric   ParenBraceBracketBalancer BalancerRAIIObj(*this);
35290b57cec5SDimitry Andric 
35300b57cec5SDimitry Andric   switch (Tok.getKind()) {
35310b57cec5SDimitry Andric   case tok::kw___if_exists:
35320b57cec5SDimitry Andric   case tok::kw___if_not_exists:
35330b57cec5SDimitry Andric     ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS);
35340b57cec5SDimitry Andric     return nullptr;
35350b57cec5SDimitry Andric 
35360b57cec5SDimitry Andric   case tok::semi:
35370b57cec5SDimitry Andric     // Check for extraneous top-level semicolon.
35380b57cec5SDimitry Andric     ConsumeExtraSemi(InsideStruct, TagType);
35390b57cec5SDimitry Andric     return nullptr;
35400b57cec5SDimitry Andric 
35410b57cec5SDimitry Andric     // Handle pragmas that can appear as member declarations.
35420b57cec5SDimitry Andric   case tok::annot_pragma_vis:
35430b57cec5SDimitry Andric     HandlePragmaVisibility();
35440b57cec5SDimitry Andric     return nullptr;
35450b57cec5SDimitry Andric   case tok::annot_pragma_pack:
35460b57cec5SDimitry Andric     HandlePragmaPack();
35470b57cec5SDimitry Andric     return nullptr;
35480b57cec5SDimitry Andric   case tok::annot_pragma_align:
35490b57cec5SDimitry Andric     HandlePragmaAlign();
35500b57cec5SDimitry Andric     return nullptr;
35510b57cec5SDimitry Andric   case tok::annot_pragma_ms_pointers_to_members:
35520b57cec5SDimitry Andric     HandlePragmaMSPointersToMembers();
35530b57cec5SDimitry Andric     return nullptr;
35540b57cec5SDimitry Andric   case tok::annot_pragma_ms_pragma:
35550b57cec5SDimitry Andric     HandlePragmaMSPragma();
35560b57cec5SDimitry Andric     return nullptr;
35570b57cec5SDimitry Andric   case tok::annot_pragma_ms_vtordisp:
35580b57cec5SDimitry Andric     HandlePragmaMSVtorDisp();
35590b57cec5SDimitry Andric     return nullptr;
35600b57cec5SDimitry Andric   case tok::annot_pragma_dump:
35610b57cec5SDimitry Andric     HandlePragmaDump();
35620b57cec5SDimitry Andric     return nullptr;
35630b57cec5SDimitry Andric 
35640b57cec5SDimitry Andric   case tok::kw_namespace:
35650b57cec5SDimitry Andric     // If we see a namespace here, a close brace was missing somewhere.
35660b57cec5SDimitry Andric     DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
35670b57cec5SDimitry Andric     return nullptr;
35680b57cec5SDimitry Andric 
35690b57cec5SDimitry Andric   case tok::kw_private:
35700b57cec5SDimitry Andric     // FIXME: We don't accept GNU attributes on access specifiers in OpenCL mode
35710b57cec5SDimitry Andric     // yet.
3572*0fca6ea1SDimitry Andric     if (getLangOpts().OpenCL && !NextToken().is(tok::colon)) {
3573*0fca6ea1SDimitry Andric       ParsedTemplateInfo TemplateInfo;
3574*0fca6ea1SDimitry Andric       return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);
3575*0fca6ea1SDimitry Andric     }
3576bdd1243dSDimitry Andric     [[fallthrough]];
35770b57cec5SDimitry Andric   case tok::kw_public:
35780b57cec5SDimitry Andric   case tok::kw_protected: {
357981ad6265SDimitry Andric     if (getLangOpts().HLSL)
358081ad6265SDimitry Andric       Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);
35810b57cec5SDimitry Andric     AccessSpecifier NewAS = getAccessSpecifierIfPresent();
35820b57cec5SDimitry Andric     assert(NewAS != AS_none);
35830b57cec5SDimitry Andric     // Current token is a C++ access specifier.
35840b57cec5SDimitry Andric     AS = NewAS;
35850b57cec5SDimitry Andric     SourceLocation ASLoc = Tok.getLocation();
35860b57cec5SDimitry Andric     unsigned TokLength = Tok.getLength();
35870b57cec5SDimitry Andric     ConsumeToken();
35880b57cec5SDimitry Andric     AccessAttrs.clear();
35890b57cec5SDimitry Andric     MaybeParseGNUAttributes(AccessAttrs);
35900b57cec5SDimitry Andric 
35910b57cec5SDimitry Andric     SourceLocation EndLoc;
35920b57cec5SDimitry Andric     if (TryConsumeToken(tok::colon, EndLoc)) {
35930b57cec5SDimitry Andric     } else if (TryConsumeToken(tok::semi, EndLoc)) {
35940b57cec5SDimitry Andric       Diag(EndLoc, diag::err_expected)
35950b57cec5SDimitry Andric           << tok::colon << FixItHint::CreateReplacement(EndLoc, ":");
35960b57cec5SDimitry Andric     } else {
35970b57cec5SDimitry Andric       EndLoc = ASLoc.getLocWithOffset(TokLength);
35980b57cec5SDimitry Andric       Diag(EndLoc, diag::err_expected)
35990b57cec5SDimitry Andric           << tok::colon << FixItHint::CreateInsertion(EndLoc, ":");
36000b57cec5SDimitry Andric     }
36010b57cec5SDimitry Andric 
36020b57cec5SDimitry Andric     // The Microsoft extension __interface does not permit non-public
36030b57cec5SDimitry Andric     // access specifiers.
36040b57cec5SDimitry Andric     if (TagType == DeclSpec::TST_interface && AS != AS_public) {
36050b57cec5SDimitry Andric       Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);
36060b57cec5SDimitry Andric     }
36070b57cec5SDimitry Andric 
36080b57cec5SDimitry Andric     if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, AccessAttrs)) {
36090b57cec5SDimitry Andric       // found another attribute than only annotations
36100b57cec5SDimitry Andric       AccessAttrs.clear();
36110b57cec5SDimitry Andric     }
36120b57cec5SDimitry Andric 
36130b57cec5SDimitry Andric     return nullptr;
36140b57cec5SDimitry Andric   }
36150b57cec5SDimitry Andric 
3616fe6060f1SDimitry Andric   case tok::annot_attr_openmp:
36170b57cec5SDimitry Andric   case tok::annot_pragma_openmp:
3618480093f4SDimitry Andric     return ParseOpenMPDeclarativeDirectiveWithExtDecl(
3619480093f4SDimitry Andric         AS, AccessAttrs, /*Delayed=*/true, TagType, TagDecl);
36205f757f3fSDimitry Andric   case tok::annot_pragma_openacc:
36215f757f3fSDimitry Andric     return ParseOpenACCDirectiveDecl();
36220b57cec5SDimitry Andric 
36230b57cec5SDimitry Andric   default:
3624a7dea167SDimitry Andric     if (tok::isPragmaAnnotation(Tok.getKind())) {
3625a7dea167SDimitry Andric       Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
3626972a253aSDimitry Andric           << DeclSpec::getSpecifierName(
3627972a253aSDimitry Andric                  TagType, Actions.getASTContext().getPrintingPolicy());
3628a7dea167SDimitry Andric       ConsumeAnnotationToken();
3629a7dea167SDimitry Andric       return nullptr;
3630a7dea167SDimitry Andric     }
3631*0fca6ea1SDimitry Andric     ParsedTemplateInfo TemplateInfo;
3632*0fca6ea1SDimitry Andric     return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);
36330b57cec5SDimitry Andric   }
36340b57cec5SDimitry Andric }
36350b57cec5SDimitry Andric 
36360b57cec5SDimitry Andric /// ParseCXXMemberSpecification - Parse the class definition.
36370b57cec5SDimitry Andric ///
36380b57cec5SDimitry Andric ///       member-specification:
36390b57cec5SDimitry Andric ///         member-declaration member-specification[opt]
36400b57cec5SDimitry Andric ///         access-specifier ':' member-specification[opt]
36410b57cec5SDimitry Andric ///
36420b57cec5SDimitry Andric void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
36430b57cec5SDimitry Andric                                          SourceLocation AttrFixitLoc,
364481ad6265SDimitry Andric                                          ParsedAttributes &Attrs,
36450b57cec5SDimitry Andric                                          unsigned TagType, Decl *TagDecl) {
36460b57cec5SDimitry Andric   assert((TagType == DeclSpec::TST_struct ||
36470b57cec5SDimitry Andric           TagType == DeclSpec::TST_interface ||
3648972a253aSDimitry Andric           TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) &&
3649972a253aSDimitry Andric          "Invalid TagType!");
36500b57cec5SDimitry Andric 
36510b57cec5SDimitry Andric   llvm::TimeTraceScope TimeScope("ParseClass", [&]() {
36520b57cec5SDimitry Andric     if (auto *TD = dyn_cast_or_null<NamedDecl>(TagDecl))
36530b57cec5SDimitry Andric       return TD->getQualifiedNameAsString();
36540b57cec5SDimitry Andric     return std::string("<anonymous>");
36550b57cec5SDimitry Andric   });
36560b57cec5SDimitry Andric 
36570b57cec5SDimitry Andric   PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
36580b57cec5SDimitry Andric                                       "parsing struct/union/class body");
36590b57cec5SDimitry Andric 
36600b57cec5SDimitry Andric   // Determine whether this is a non-nested class. Note that local
36610b57cec5SDimitry Andric   // classes are *not* considered to be nested classes.
36620b57cec5SDimitry Andric   bool NonNestedClass = true;
36630b57cec5SDimitry Andric   if (!ClassStack.empty()) {
36640b57cec5SDimitry Andric     for (const Scope *S = getCurScope(); S; S = S->getParent()) {
36650b57cec5SDimitry Andric       if (S->isClassScope()) {
36660b57cec5SDimitry Andric         // We're inside a class scope, so this is a nested class.
36670b57cec5SDimitry Andric         NonNestedClass = false;
36680b57cec5SDimitry Andric 
36690b57cec5SDimitry Andric         // The Microsoft extension __interface does not permit nested classes.
36700b57cec5SDimitry Andric         if (getCurrentClass().IsInterface) {
36710b57cec5SDimitry Andric           Diag(RecordLoc, diag::err_invalid_member_in_interface)
36720b57cec5SDimitry Andric               << /*ErrorType=*/6
36730b57cec5SDimitry Andric               << (isa<NamedDecl>(TagDecl)
36740b57cec5SDimitry Andric                       ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString()
36750b57cec5SDimitry Andric                       : "(anonymous)");
36760b57cec5SDimitry Andric         }
36770b57cec5SDimitry Andric         break;
36780b57cec5SDimitry Andric       }
36790b57cec5SDimitry Andric 
368081ad6265SDimitry Andric       if (S->isFunctionScope())
36810b57cec5SDimitry Andric         // If we're in a function or function template then this is a local
36820b57cec5SDimitry Andric         // class rather than a nested class.
36830b57cec5SDimitry Andric         break;
36840b57cec5SDimitry Andric     }
36850b57cec5SDimitry Andric   }
36860b57cec5SDimitry Andric 
36870b57cec5SDimitry Andric   // Enter a scope for the class.
36880b57cec5SDimitry Andric   ParseScope ClassScope(this, Scope::ClassScope | Scope::DeclScope);
36890b57cec5SDimitry Andric 
36900b57cec5SDimitry Andric   // Note that we are parsing a new (potentially-nested) class definition.
36910b57cec5SDimitry Andric   ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass,
36920b57cec5SDimitry Andric                                     TagType == DeclSpec::TST_interface);
36930b57cec5SDimitry Andric 
36940b57cec5SDimitry Andric   if (TagDecl)
36950b57cec5SDimitry Andric     Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
36960b57cec5SDimitry Andric 
36970b57cec5SDimitry Andric   SourceLocation FinalLoc;
3698fe6060f1SDimitry Andric   SourceLocation AbstractLoc;
36990b57cec5SDimitry Andric   bool IsFinalSpelledSealed = false;
3700fe6060f1SDimitry Andric   bool IsAbstract = false;
37010b57cec5SDimitry Andric 
37020b57cec5SDimitry Andric   // Parse the optional 'final' keyword.
37030b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
3704fe6060f1SDimitry Andric     while (true) {
37050b57cec5SDimitry Andric       VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);
3706fe6060f1SDimitry Andric       if (Specifier == VirtSpecifiers::VS_None)
3707fe6060f1SDimitry Andric         break;
3708fe6060f1SDimitry Andric       if (isCXX11FinalKeyword()) {
3709fe6060f1SDimitry Andric         if (FinalLoc.isValid()) {
3710fe6060f1SDimitry Andric           auto Skipped = ConsumeToken();
3711fe6060f1SDimitry Andric           Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3712fe6060f1SDimitry Andric               << VirtSpecifiers::getSpecifierName(Specifier);
3713fe6060f1SDimitry Andric         } else {
37140b57cec5SDimitry Andric           FinalLoc = ConsumeToken();
3715fe6060f1SDimitry Andric           if (Specifier == VirtSpecifiers::VS_Sealed)
3716fe6060f1SDimitry Andric             IsFinalSpelledSealed = true;
3717fe6060f1SDimitry Andric         }
3718fe6060f1SDimitry Andric       } else {
3719fe6060f1SDimitry Andric         if (AbstractLoc.isValid()) {
3720fe6060f1SDimitry Andric           auto Skipped = ConsumeToken();
3721fe6060f1SDimitry Andric           Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3722fe6060f1SDimitry Andric               << VirtSpecifiers::getSpecifierName(Specifier);
3723fe6060f1SDimitry Andric         } else {
3724fe6060f1SDimitry Andric           AbstractLoc = ConsumeToken();
3725fe6060f1SDimitry Andric           IsAbstract = true;
3726fe6060f1SDimitry Andric         }
3727fe6060f1SDimitry Andric       }
37280b57cec5SDimitry Andric       if (TagType == DeclSpec::TST_interface)
37290b57cec5SDimitry Andric         Diag(FinalLoc, diag::err_override_control_interface)
37300b57cec5SDimitry Andric             << VirtSpecifiers::getSpecifierName(Specifier);
37310b57cec5SDimitry Andric       else if (Specifier == VirtSpecifiers::VS_Final)
37320b57cec5SDimitry Andric         Diag(FinalLoc, getLangOpts().CPlusPlus11
37330b57cec5SDimitry Andric                            ? diag::warn_cxx98_compat_override_control_keyword
37340b57cec5SDimitry Andric                            : diag::ext_override_control_keyword)
37350b57cec5SDimitry Andric             << VirtSpecifiers::getSpecifierName(Specifier);
37360b57cec5SDimitry Andric       else if (Specifier == VirtSpecifiers::VS_Sealed)
37370b57cec5SDimitry Andric         Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3738fe6060f1SDimitry Andric       else if (Specifier == VirtSpecifiers::VS_Abstract)
3739fe6060f1SDimitry Andric         Diag(AbstractLoc, diag::ext_ms_abstract_keyword);
37400b57cec5SDimitry Andric       else if (Specifier == VirtSpecifiers::VS_GNU_Final)
37410b57cec5SDimitry Andric         Diag(FinalLoc, diag::ext_warn_gnu_final);
3742fe6060f1SDimitry Andric     }
3743fe6060f1SDimitry Andric     assert((FinalLoc.isValid() || AbstractLoc.isValid()) &&
3744fe6060f1SDimitry Andric            "not a class definition");
37450b57cec5SDimitry Andric 
37460b57cec5SDimitry Andric     // Parse any C++11 attributes after 'final' keyword.
37470b57cec5SDimitry Andric     // These attributes are not allowed to appear here,
37480b57cec5SDimitry Andric     // and the only possible place for them to appertain
37490b57cec5SDimitry Andric     // to the class would be between class-key and class-name.
37500b57cec5SDimitry Andric     CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
37510b57cec5SDimitry Andric 
37520b57cec5SDimitry Andric     // ParseClassSpecifier() does only a superficial check for attributes before
37530b57cec5SDimitry Andric     // deciding to call this method.  For example, for
37540b57cec5SDimitry Andric     // `class C final alignas ([l) {` it will decide that this looks like a
37550b57cec5SDimitry Andric     // misplaced attribute since it sees `alignas '(' ')'`.  But the actual
37560b57cec5SDimitry Andric     // attribute parsing code will try to parse the '[' as a constexpr lambda
37570b57cec5SDimitry Andric     // and consume enough tokens that the alignas parsing code will eat the
37580b57cec5SDimitry Andric     // opening '{'.  So bail out if the next token isn't one we expect.
37590b57cec5SDimitry Andric     if (!Tok.is(tok::colon) && !Tok.is(tok::l_brace)) {
37600b57cec5SDimitry Andric       if (TagDecl)
37610b57cec5SDimitry Andric         Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
37620b57cec5SDimitry Andric       return;
37630b57cec5SDimitry Andric     }
37640b57cec5SDimitry Andric   }
37650b57cec5SDimitry Andric 
37660b57cec5SDimitry Andric   if (Tok.is(tok::colon)) {
37670b57cec5SDimitry Andric     ParseScope InheritanceScope(this, getCurScope()->getFlags() |
37680b57cec5SDimitry Andric                                           Scope::ClassInheritanceScope);
37690b57cec5SDimitry Andric 
37700b57cec5SDimitry Andric     ParseBaseClause(TagDecl);
37710b57cec5SDimitry Andric     if (!Tok.is(tok::l_brace)) {
37720b57cec5SDimitry Andric       bool SuggestFixIt = false;
37730b57cec5SDimitry Andric       SourceLocation BraceLoc = PP.getLocForEndOfToken(PrevTokLocation);
37740b57cec5SDimitry Andric       if (Tok.isAtStartOfLine()) {
37750b57cec5SDimitry Andric         switch (Tok.getKind()) {
37760b57cec5SDimitry Andric         case tok::kw_private:
37770b57cec5SDimitry Andric         case tok::kw_protected:
37780b57cec5SDimitry Andric         case tok::kw_public:
37790b57cec5SDimitry Andric           SuggestFixIt = NextToken().getKind() == tok::colon;
37800b57cec5SDimitry Andric           break;
37810b57cec5SDimitry Andric         case tok::kw_static_assert:
37820b57cec5SDimitry Andric         case tok::r_brace:
37830b57cec5SDimitry Andric         case tok::kw_using:
37840b57cec5SDimitry Andric         // base-clause can have simple-template-id; 'template' can't be there
37850b57cec5SDimitry Andric         case tok::kw_template:
37860b57cec5SDimitry Andric           SuggestFixIt = true;
37870b57cec5SDimitry Andric           break;
37880b57cec5SDimitry Andric         case tok::identifier:
37890b57cec5SDimitry Andric           SuggestFixIt = isConstructorDeclarator(true);
37900b57cec5SDimitry Andric           break;
37910b57cec5SDimitry Andric         default:
37920b57cec5SDimitry Andric           SuggestFixIt = isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
37930b57cec5SDimitry Andric           break;
37940b57cec5SDimitry Andric         }
37950b57cec5SDimitry Andric       }
37960b57cec5SDimitry Andric       DiagnosticBuilder LBraceDiag =
37970b57cec5SDimitry Andric           Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);
37980b57cec5SDimitry Andric       if (SuggestFixIt) {
37990b57cec5SDimitry Andric         LBraceDiag << FixItHint::CreateInsertion(BraceLoc, " {");
38000b57cec5SDimitry Andric         // Try recovering from missing { after base-clause.
38010b57cec5SDimitry Andric         PP.EnterToken(Tok, /*IsReinject*/ true);
38020b57cec5SDimitry Andric         Tok.setKind(tok::l_brace);
38030b57cec5SDimitry Andric       } else {
38040b57cec5SDimitry Andric         if (TagDecl)
38050b57cec5SDimitry Andric           Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
38060b57cec5SDimitry Andric         return;
38070b57cec5SDimitry Andric       }
38080b57cec5SDimitry Andric     }
38090b57cec5SDimitry Andric   }
38100b57cec5SDimitry Andric 
38110b57cec5SDimitry Andric   assert(Tok.is(tok::l_brace));
38120b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_brace);
38130b57cec5SDimitry Andric   T.consumeOpen();
38140b57cec5SDimitry Andric 
38150b57cec5SDimitry Andric   if (TagDecl)
38160b57cec5SDimitry Andric     Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
3817fe6060f1SDimitry Andric                                             IsFinalSpelledSealed, IsAbstract,
38180b57cec5SDimitry Andric                                             T.getOpenLocation());
38190b57cec5SDimitry Andric 
38200b57cec5SDimitry Andric   // C++ 11p3: Members of a class defined with the keyword class are private
38210b57cec5SDimitry Andric   // by default. Members of a class defined with the keywords struct or union
38220b57cec5SDimitry Andric   // are public by default.
382381ad6265SDimitry Andric   // HLSL: In HLSL members of a class are public by default.
38240b57cec5SDimitry Andric   AccessSpecifier CurAS;
382581ad6265SDimitry Andric   if (TagType == DeclSpec::TST_class && !getLangOpts().HLSL)
38260b57cec5SDimitry Andric     CurAS = AS_private;
38270b57cec5SDimitry Andric   else
38280b57cec5SDimitry Andric     CurAS = AS_public;
382981ad6265SDimitry Andric   ParsedAttributes AccessAttrs(AttrFactory);
38300b57cec5SDimitry Andric 
38310b57cec5SDimitry Andric   if (TagDecl) {
38320b57cec5SDimitry Andric     // While we still have something to read, read the member-declarations.
38330b57cec5SDimitry Andric     while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
38340b57cec5SDimitry Andric            Tok.isNot(tok::eof)) {
38350b57cec5SDimitry Andric       // Each iteration of this loop reads one member-declaration.
38360b57cec5SDimitry Andric       ParseCXXClassMemberDeclarationWithPragmas(
38370b57cec5SDimitry Andric           CurAS, AccessAttrs, static_cast<DeclSpec::TST>(TagType), TagDecl);
38385ffd83dbSDimitry Andric       MaybeDestroyTemplateIds();
38390b57cec5SDimitry Andric     }
38400b57cec5SDimitry Andric     T.consumeClose();
38410b57cec5SDimitry Andric   } else {
38420b57cec5SDimitry Andric     SkipUntil(tok::r_brace);
38430b57cec5SDimitry Andric   }
38440b57cec5SDimitry Andric 
38450b57cec5SDimitry Andric   // If attributes exist after class contents, parse them.
38460b57cec5SDimitry Andric   ParsedAttributes attrs(AttrFactory);
38470b57cec5SDimitry Andric   MaybeParseGNUAttributes(attrs);
38480b57cec5SDimitry Andric 
38490b57cec5SDimitry Andric   if (TagDecl)
38500b57cec5SDimitry Andric     Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
38510b57cec5SDimitry Andric                                               T.getOpenLocation(),
38520b57cec5SDimitry Andric                                               T.getCloseLocation(), attrs);
38530b57cec5SDimitry Andric 
38540b57cec5SDimitry Andric   // C++11 [class.mem]p2:
38550b57cec5SDimitry Andric   //   Within the class member-specification, the class is regarded as complete
38560b57cec5SDimitry Andric   //   within function bodies, default arguments, exception-specifications, and
38570b57cec5SDimitry Andric   //   brace-or-equal-initializers for non-static data members (including such
38580b57cec5SDimitry Andric   //   things in nested classes).
38590b57cec5SDimitry Andric   if (TagDecl && NonNestedClass) {
38600b57cec5SDimitry Andric     // We are not inside a nested class. This class and its nested classes
38610b57cec5SDimitry Andric     // are complete and we can parse the delayed portions of method
38620b57cec5SDimitry Andric     // declarations and the lexed inline method definitions, along with any
38630b57cec5SDimitry Andric     // delayed attributes.
38645ffd83dbSDimitry Andric 
38650b57cec5SDimitry Andric     SourceLocation SavedPrevTokLocation = PrevTokLocation;
3866480093f4SDimitry Andric     ParseLexedPragmas(getCurrentClass());
38670b57cec5SDimitry Andric     ParseLexedAttributes(getCurrentClass());
38680b57cec5SDimitry Andric     ParseLexedMethodDeclarations(getCurrentClass());
38690b57cec5SDimitry Andric 
38700b57cec5SDimitry Andric     // We've finished with all pending member declarations.
38710b57cec5SDimitry Andric     Actions.ActOnFinishCXXMemberDecls();
38720b57cec5SDimitry Andric 
38730b57cec5SDimitry Andric     ParseLexedMemberInitializers(getCurrentClass());
38740b57cec5SDimitry Andric     ParseLexedMethodDefs(getCurrentClass());
38750b57cec5SDimitry Andric     PrevTokLocation = SavedPrevTokLocation;
38760b57cec5SDimitry Andric 
38770b57cec5SDimitry Andric     // We've finished parsing everything, including default argument
38780b57cec5SDimitry Andric     // initializers.
3879480093f4SDimitry Andric     Actions.ActOnFinishCXXNonNestedClass();
38800b57cec5SDimitry Andric   }
38810b57cec5SDimitry Andric 
38820b57cec5SDimitry Andric   if (TagDecl)
38830b57cec5SDimitry Andric     Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());
38840b57cec5SDimitry Andric 
38850b57cec5SDimitry Andric   // Leave the class scope.
38860b57cec5SDimitry Andric   ParsingDef.Pop();
38870b57cec5SDimitry Andric   ClassScope.Exit();
38880b57cec5SDimitry Andric }
38890b57cec5SDimitry Andric 
38900b57cec5SDimitry Andric void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {
38910b57cec5SDimitry Andric   assert(Tok.is(tok::kw_namespace));
38920b57cec5SDimitry Andric 
38930b57cec5SDimitry Andric   // FIXME: Suggest where the close brace should have gone by looking
38940b57cec5SDimitry Andric   // at indentation changes within the definition body.
3895972a253aSDimitry Andric   Diag(D->getLocation(), diag::err_missing_end_of_definition) << D;
3896972a253aSDimitry Andric   Diag(Tok.getLocation(), diag::note_missing_end_of_definition_before) << D;
38970b57cec5SDimitry Andric 
38980b57cec5SDimitry Andric   // Push '};' onto the token stream to recover.
38990b57cec5SDimitry Andric   PP.EnterToken(Tok, /*IsReinject*/ true);
39000b57cec5SDimitry Andric 
39010b57cec5SDimitry Andric   Tok.startToken();
39020b57cec5SDimitry Andric   Tok.setLocation(PP.getLocForEndOfToken(PrevTokLocation));
39030b57cec5SDimitry Andric   Tok.setKind(tok::semi);
39040b57cec5SDimitry Andric   PP.EnterToken(Tok, /*IsReinject*/ true);
39050b57cec5SDimitry Andric 
39060b57cec5SDimitry Andric   Tok.setKind(tok::r_brace);
39070b57cec5SDimitry Andric }
39080b57cec5SDimitry Andric 
39090b57cec5SDimitry Andric /// ParseConstructorInitializer - Parse a C++ constructor initializer,
39100b57cec5SDimitry Andric /// which explicitly initializes the members or base classes of a
39110b57cec5SDimitry Andric /// class (C++ [class.base.init]). For example, the three initializers
39120b57cec5SDimitry Andric /// after the ':' in the Derived constructor below:
39130b57cec5SDimitry Andric ///
39140b57cec5SDimitry Andric /// @code
39150b57cec5SDimitry Andric /// class Base { };
39160b57cec5SDimitry Andric /// class Derived : Base {
39170b57cec5SDimitry Andric ///   int x;
39180b57cec5SDimitry Andric ///   float f;
39190b57cec5SDimitry Andric /// public:
39200b57cec5SDimitry Andric ///   Derived(float f) : Base(), x(17), f(f) { }
39210b57cec5SDimitry Andric /// };
39220b57cec5SDimitry Andric /// @endcode
39230b57cec5SDimitry Andric ///
39240b57cec5SDimitry Andric /// [C++]  ctor-initializer:
39250b57cec5SDimitry Andric ///          ':' mem-initializer-list
39260b57cec5SDimitry Andric ///
39270b57cec5SDimitry Andric /// [C++]  mem-initializer-list:
39280b57cec5SDimitry Andric ///          mem-initializer ...[opt]
39290b57cec5SDimitry Andric ///          mem-initializer ...[opt] , mem-initializer-list
39300b57cec5SDimitry Andric void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
39310b57cec5SDimitry Andric   assert(Tok.is(tok::colon) &&
39320b57cec5SDimitry Andric          "Constructor initializer always starts with ':'");
39330b57cec5SDimitry Andric 
39340b57cec5SDimitry Andric   // Poison the SEH identifiers so they are flagged as illegal in constructor
39350b57cec5SDimitry Andric   // initializers.
39360b57cec5SDimitry Andric   PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
39370b57cec5SDimitry Andric   SourceLocation ColonLoc = ConsumeToken();
39380b57cec5SDimitry Andric 
39390b57cec5SDimitry Andric   SmallVector<CXXCtorInitializer *, 4> MemInitializers;
39400b57cec5SDimitry Andric   bool AnyErrors = false;
39410b57cec5SDimitry Andric 
39420b57cec5SDimitry Andric   do {
39430b57cec5SDimitry Andric     if (Tok.is(tok::code_completion)) {
3944fe6060f1SDimitry Andric       cutOffParsing();
3945*0fca6ea1SDimitry Andric       Actions.CodeCompletion().CodeCompleteConstructorInitializer(
3946*0fca6ea1SDimitry Andric           ConstructorDecl, MemInitializers);
3947fe6060f1SDimitry Andric       return;
39480b57cec5SDimitry Andric     }
39490b57cec5SDimitry Andric 
39500b57cec5SDimitry Andric     MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
39510b57cec5SDimitry Andric     if (!MemInit.isInvalid())
39520b57cec5SDimitry Andric       MemInitializers.push_back(MemInit.get());
39530b57cec5SDimitry Andric     else
39540b57cec5SDimitry Andric       AnyErrors = true;
39550b57cec5SDimitry Andric 
39560b57cec5SDimitry Andric     if (Tok.is(tok::comma))
39570b57cec5SDimitry Andric       ConsumeToken();
39580b57cec5SDimitry Andric     else if (Tok.is(tok::l_brace))
39590b57cec5SDimitry Andric       break;
39600b57cec5SDimitry Andric     // If the previous initializer was valid and the next token looks like a
39610b57cec5SDimitry Andric     // base or member initializer, assume that we're just missing a comma.
39620b57cec5SDimitry Andric     else if (!MemInit.isInvalid() &&
39630b57cec5SDimitry Andric              Tok.isOneOf(tok::identifier, tok::coloncolon)) {
39640b57cec5SDimitry Andric       SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
39650b57cec5SDimitry Andric       Diag(Loc, diag::err_ctor_init_missing_comma)
39660b57cec5SDimitry Andric           << FixItHint::CreateInsertion(Loc, ", ");
39670b57cec5SDimitry Andric     } else {
39680b57cec5SDimitry Andric       // Skip over garbage, until we get to '{'.  Don't eat the '{'.
39690b57cec5SDimitry Andric       if (!MemInit.isInvalid())
3970972a253aSDimitry Andric         Diag(Tok.getLocation(), diag::err_expected_either)
3971972a253aSDimitry Andric             << tok::l_brace << tok::comma;
39720b57cec5SDimitry Andric       SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
39730b57cec5SDimitry Andric       break;
39740b57cec5SDimitry Andric     }
39750b57cec5SDimitry Andric   } while (true);
39760b57cec5SDimitry Andric 
39770b57cec5SDimitry Andric   Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers,
39780b57cec5SDimitry Andric                                AnyErrors);
39790b57cec5SDimitry Andric }
39800b57cec5SDimitry Andric 
39810b57cec5SDimitry Andric /// ParseMemInitializer - Parse a C++ member initializer, which is
39820b57cec5SDimitry Andric /// part of a constructor initializer that explicitly initializes one
39830b57cec5SDimitry Andric /// member or base class (C++ [class.base.init]). See
39840b57cec5SDimitry Andric /// ParseConstructorInitializer for an example.
39850b57cec5SDimitry Andric ///
39860b57cec5SDimitry Andric /// [C++] mem-initializer:
39870b57cec5SDimitry Andric ///         mem-initializer-id '(' expression-list[opt] ')'
39880b57cec5SDimitry Andric /// [C++0x] mem-initializer-id braced-init-list
39890b57cec5SDimitry Andric ///
39900b57cec5SDimitry Andric /// [C++] mem-initializer-id:
39910b57cec5SDimitry Andric ///         '::'[opt] nested-name-specifier[opt] class-name
39920b57cec5SDimitry Andric ///         identifier
39930b57cec5SDimitry Andric MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
39940b57cec5SDimitry Andric   // parse '::'[opt] nested-name-specifier[opt]
39950b57cec5SDimitry Andric   CXXScopeSpec SS;
39965ffd83dbSDimitry Andric   if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
399704eeddc0SDimitry Andric                                      /*ObjectHasErrors=*/false,
39985ffd83dbSDimitry Andric                                      /*EnteringContext=*/false))
39990b57cec5SDimitry Andric     return true;
40000b57cec5SDimitry Andric 
40010b57cec5SDimitry Andric   // : identifier
40020b57cec5SDimitry Andric   IdentifierInfo *II = nullptr;
40030b57cec5SDimitry Andric   SourceLocation IdLoc = Tok.getLocation();
40040b57cec5SDimitry Andric   // : declype(...)
40050b57cec5SDimitry Andric   DeclSpec DS(AttrFactory);
40060b57cec5SDimitry Andric   // : template_name<...>
40075ffd83dbSDimitry Andric   TypeResult TemplateTypeTy;
40080b57cec5SDimitry Andric 
40090b57cec5SDimitry Andric   if (Tok.is(tok::identifier)) {
40100b57cec5SDimitry Andric     // Get the identifier. This may be a member name or a class name,
40110b57cec5SDimitry Andric     // but we'll let the semantic analysis determine which it is.
40120b57cec5SDimitry Andric     II = Tok.getIdentifierInfo();
40130b57cec5SDimitry Andric     ConsumeToken();
40140b57cec5SDimitry Andric   } else if (Tok.is(tok::annot_decltype)) {
40150b57cec5SDimitry Andric     // Get the decltype expression, if there is one.
40160b57cec5SDimitry Andric     // Uses of decltype will already have been converted to annot_decltype by
40170b57cec5SDimitry Andric     // ParseOptionalCXXScopeSpecifier at this point.
40180b57cec5SDimitry Andric     // FIXME: Can we get here with a scope specifier?
40190b57cec5SDimitry Andric     ParseDecltypeSpecifier(DS);
4020*0fca6ea1SDimitry Andric   } else if (Tok.is(tok::annot_pack_indexing_type)) {
4021*0fca6ea1SDimitry Andric     // Uses of T...[N] will already have been converted to
4022*0fca6ea1SDimitry Andric     // annot_pack_indexing_type by ParseOptionalCXXScopeSpecifier at this point.
4023*0fca6ea1SDimitry Andric     ParsePackIndexingType(DS);
40240b57cec5SDimitry Andric   } else {
40250b57cec5SDimitry Andric     TemplateIdAnnotation *TemplateId = Tok.is(tok::annot_template_id)
40260b57cec5SDimitry Andric                                            ? takeTemplateIdAnnotation(Tok)
40270b57cec5SDimitry Andric                                            : nullptr;
40285ffd83dbSDimitry Andric     if (TemplateId && TemplateId->mightBeType()) {
4029bdd1243dSDimitry Andric       AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,
4030bdd1243dSDimitry Andric                                     /*IsClassName=*/true);
40310b57cec5SDimitry Andric       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
40320b57cec5SDimitry Andric       TemplateTypeTy = getTypeAnnotation(Tok);
40330b57cec5SDimitry Andric       ConsumeAnnotationToken();
40340b57cec5SDimitry Andric     } else {
40350b57cec5SDimitry Andric       Diag(Tok, diag::err_expected_member_or_base_name);
40360b57cec5SDimitry Andric       return true;
40370b57cec5SDimitry Andric     }
40380b57cec5SDimitry Andric   }
40390b57cec5SDimitry Andric 
40400b57cec5SDimitry Andric   // Parse the '('.
40410b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
40420b57cec5SDimitry Andric     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
40430b57cec5SDimitry Andric 
40440b57cec5SDimitry Andric     // FIXME: Add support for signature help inside initializer lists.
40450b57cec5SDimitry Andric     ExprResult InitList = ParseBraceInitializer();
40460b57cec5SDimitry Andric     if (InitList.isInvalid())
40470b57cec5SDimitry Andric       return true;
40480b57cec5SDimitry Andric 
40490b57cec5SDimitry Andric     SourceLocation EllipsisLoc;
40500b57cec5SDimitry Andric     TryConsumeToken(tok::ellipsis, EllipsisLoc);
40510b57cec5SDimitry Andric 
40525ffd83dbSDimitry Andric     if (TemplateTypeTy.isInvalid())
40535ffd83dbSDimitry Andric       return true;
40540b57cec5SDimitry Andric     return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
40555ffd83dbSDimitry Andric                                        TemplateTypeTy.get(), DS, IdLoc,
40560b57cec5SDimitry Andric                                        InitList.get(), EllipsisLoc);
40570b57cec5SDimitry Andric   } else if (Tok.is(tok::l_paren)) {
40580b57cec5SDimitry Andric     BalancedDelimiterTracker T(*this, tok::l_paren);
40590b57cec5SDimitry Andric     T.consumeOpen();
40600b57cec5SDimitry Andric 
40610b57cec5SDimitry Andric     // Parse the optional expression-list.
40620b57cec5SDimitry Andric     ExprVector ArgExprs;
40630b57cec5SDimitry Andric     auto RunSignatureHelp = [&] {
40645ffd83dbSDimitry Andric       if (TemplateTypeTy.isInvalid())
40655ffd83dbSDimitry Andric         return QualType();
4066*0fca6ea1SDimitry Andric       QualType PreferredType =
4067*0fca6ea1SDimitry Andric           Actions.CodeCompletion().ProduceCtorInitMemberSignatureHelp(
406804eeddc0SDimitry Andric               ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II,
406904eeddc0SDimitry Andric               T.getOpenLocation(), /*Braced=*/false);
40700b57cec5SDimitry Andric       CalledSignatureHelp = true;
40710b57cec5SDimitry Andric       return PreferredType;
40720b57cec5SDimitry Andric     };
4073bdd1243dSDimitry Andric     if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {
40740b57cec5SDimitry Andric           PreferredType.enterFunctionArgument(Tok.getLocation(),
40750b57cec5SDimitry Andric                                               RunSignatureHelp);
40760b57cec5SDimitry Andric         })) {
40770b57cec5SDimitry Andric       if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
40780b57cec5SDimitry Andric         RunSignatureHelp();
40790b57cec5SDimitry Andric       SkipUntil(tok::r_paren, StopAtSemi);
40800b57cec5SDimitry Andric       return true;
40810b57cec5SDimitry Andric     }
40820b57cec5SDimitry Andric 
40830b57cec5SDimitry Andric     T.consumeClose();
40840b57cec5SDimitry Andric 
40850b57cec5SDimitry Andric     SourceLocation EllipsisLoc;
40860b57cec5SDimitry Andric     TryConsumeToken(tok::ellipsis, EllipsisLoc);
40870b57cec5SDimitry Andric 
40885ffd83dbSDimitry Andric     if (TemplateTypeTy.isInvalid())
40895ffd83dbSDimitry Andric       return true;
4090972a253aSDimitry Andric     return Actions.ActOnMemInitializer(
4091972a253aSDimitry Andric         ConstructorDecl, getCurScope(), SS, II, TemplateTypeTy.get(), DS, IdLoc,
4092972a253aSDimitry Andric         T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc);
40930b57cec5SDimitry Andric   }
40940b57cec5SDimitry Andric 
40955ffd83dbSDimitry Andric   if (TemplateTypeTy.isInvalid())
40965ffd83dbSDimitry Andric     return true;
40975ffd83dbSDimitry Andric 
40980b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus11)
40990b57cec5SDimitry Andric     return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
41000b57cec5SDimitry Andric   else
41010b57cec5SDimitry Andric     return Diag(Tok, diag::err_expected) << tok::l_paren;
41020b57cec5SDimitry Andric }
41030b57cec5SDimitry Andric 
41040b57cec5SDimitry Andric /// Parse a C++ exception-specification if present (C++0x [except.spec]).
41050b57cec5SDimitry Andric ///
41060b57cec5SDimitry Andric ///       exception-specification:
41070b57cec5SDimitry Andric ///         dynamic-exception-specification
41080b57cec5SDimitry Andric ///         noexcept-specification
41090b57cec5SDimitry Andric ///
41100b57cec5SDimitry Andric ///       noexcept-specification:
41110b57cec5SDimitry Andric ///         'noexcept'
41120b57cec5SDimitry Andric ///         'noexcept' '(' constant-expression ')'
4113972a253aSDimitry Andric ExceptionSpecificationType Parser::tryParseExceptionSpecification(
4114972a253aSDimitry Andric     bool Delayed, SourceRange &SpecificationRange,
41150b57cec5SDimitry Andric     SmallVectorImpl<ParsedType> &DynamicExceptions,
41160b57cec5SDimitry Andric     SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
4117972a253aSDimitry Andric     ExprResult &NoexceptExpr, CachedTokens *&ExceptionSpecTokens) {
41180b57cec5SDimitry Andric   ExceptionSpecificationType Result = EST_None;
41190b57cec5SDimitry Andric   ExceptionSpecTokens = nullptr;
41200b57cec5SDimitry Andric 
41210b57cec5SDimitry Andric   // Handle delayed parsing of exception-specifications.
41220b57cec5SDimitry Andric   if (Delayed) {
41230b57cec5SDimitry Andric     if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))
41240b57cec5SDimitry Andric       return EST_None;
41250b57cec5SDimitry Andric 
41260b57cec5SDimitry Andric     // Consume and cache the starting token.
41270b57cec5SDimitry Andric     bool IsNoexcept = Tok.is(tok::kw_noexcept);
41280b57cec5SDimitry Andric     Token StartTok = Tok;
41290b57cec5SDimitry Andric     SpecificationRange = SourceRange(ConsumeToken());
41300b57cec5SDimitry Andric 
41310b57cec5SDimitry Andric     // Check for a '('.
41320b57cec5SDimitry Andric     if (!Tok.is(tok::l_paren)) {
41330b57cec5SDimitry Andric       // If this is a bare 'noexcept', we're done.
41340b57cec5SDimitry Andric       if (IsNoexcept) {
41350b57cec5SDimitry Andric         Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
41360b57cec5SDimitry Andric         NoexceptExpr = nullptr;
41370b57cec5SDimitry Andric         return EST_BasicNoexcept;
41380b57cec5SDimitry Andric       }
41390b57cec5SDimitry Andric 
41400b57cec5SDimitry Andric       Diag(Tok, diag::err_expected_lparen_after) << "throw";
41410b57cec5SDimitry Andric       return EST_DynamicNone;
41420b57cec5SDimitry Andric     }
41430b57cec5SDimitry Andric 
41440b57cec5SDimitry Andric     // Cache the tokens for the exception-specification.
41450b57cec5SDimitry Andric     ExceptionSpecTokens = new CachedTokens;
41460b57cec5SDimitry Andric     ExceptionSpecTokens->push_back(StartTok);  // 'throw' or 'noexcept'
41470b57cec5SDimitry Andric     ExceptionSpecTokens->push_back(Tok);       // '('
41480b57cec5SDimitry Andric     SpecificationRange.setEnd(ConsumeParen()); // '('
41490b57cec5SDimitry Andric 
41500b57cec5SDimitry Andric     ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
41510b57cec5SDimitry Andric                          /*StopAtSemi=*/true,
41520b57cec5SDimitry Andric                          /*ConsumeFinalToken=*/true);
41530b57cec5SDimitry Andric     SpecificationRange.setEnd(ExceptionSpecTokens->back().getLocation());
41540b57cec5SDimitry Andric 
41550b57cec5SDimitry Andric     return EST_Unparsed;
41560b57cec5SDimitry Andric   }
41570b57cec5SDimitry Andric 
41580b57cec5SDimitry Andric   // See if there's a dynamic specification.
41590b57cec5SDimitry Andric   if (Tok.is(tok::kw_throw)) {
4160972a253aSDimitry Andric     Result = ParseDynamicExceptionSpecification(
4161972a253aSDimitry Andric         SpecificationRange, DynamicExceptions, DynamicExceptionRanges);
41620b57cec5SDimitry Andric     assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
41630b57cec5SDimitry Andric            "Produced different number of exception types and ranges.");
41640b57cec5SDimitry Andric   }
41650b57cec5SDimitry Andric 
41660b57cec5SDimitry Andric   // If there's no noexcept specification, we're done.
41670b57cec5SDimitry Andric   if (Tok.isNot(tok::kw_noexcept))
41680b57cec5SDimitry Andric     return Result;
41690b57cec5SDimitry Andric 
41700b57cec5SDimitry Andric   Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
41710b57cec5SDimitry Andric 
41720b57cec5SDimitry Andric   // If we already had a dynamic specification, parse the noexcept for,
41730b57cec5SDimitry Andric   // recovery, but emit a diagnostic and don't store the results.
41740b57cec5SDimitry Andric   SourceRange NoexceptRange;
41750b57cec5SDimitry Andric   ExceptionSpecificationType NoexceptType = EST_None;
41760b57cec5SDimitry Andric 
41770b57cec5SDimitry Andric   SourceLocation KeywordLoc = ConsumeToken();
41780b57cec5SDimitry Andric   if (Tok.is(tok::l_paren)) {
41790b57cec5SDimitry Andric     // There is an argument.
41800b57cec5SDimitry Andric     BalancedDelimiterTracker T(*this, tok::l_paren);
41810b57cec5SDimitry Andric     T.consumeOpen();
41825f757f3fSDimitry Andric 
41835f757f3fSDimitry Andric     EnterExpressionEvaluationContext ConstantEvaluated(
41845f757f3fSDimitry Andric         Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
41855f757f3fSDimitry Andric     NoexceptExpr = ParseConstantExpressionInExprEvalContext();
41865f757f3fSDimitry Andric 
41870b57cec5SDimitry Andric     T.consumeClose();
41880b57cec5SDimitry Andric     if (!NoexceptExpr.isInvalid()) {
4189972a253aSDimitry Andric       NoexceptExpr =
4190972a253aSDimitry Andric           Actions.ActOnNoexceptSpec(NoexceptExpr.get(), NoexceptType);
41910b57cec5SDimitry Andric       NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
41920b57cec5SDimitry Andric     } else {
41930b57cec5SDimitry Andric       NoexceptType = EST_BasicNoexcept;
41940b57cec5SDimitry Andric     }
41950b57cec5SDimitry Andric   } else {
41960b57cec5SDimitry Andric     // There is no argument.
41970b57cec5SDimitry Andric     NoexceptType = EST_BasicNoexcept;
41980b57cec5SDimitry Andric     NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
41990b57cec5SDimitry Andric   }
42000b57cec5SDimitry Andric 
42010b57cec5SDimitry Andric   if (Result == EST_None) {
42020b57cec5SDimitry Andric     SpecificationRange = NoexceptRange;
42030b57cec5SDimitry Andric     Result = NoexceptType;
42040b57cec5SDimitry Andric 
42050b57cec5SDimitry Andric     // If there's a dynamic specification after a noexcept specification,
42060b57cec5SDimitry Andric     // parse that and ignore the results.
42070b57cec5SDimitry Andric     if (Tok.is(tok::kw_throw)) {
42080b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
42090b57cec5SDimitry Andric       ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
42100b57cec5SDimitry Andric                                          DynamicExceptionRanges);
42110b57cec5SDimitry Andric     }
42120b57cec5SDimitry Andric   } else {
42130b57cec5SDimitry Andric     Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
42140b57cec5SDimitry Andric   }
42150b57cec5SDimitry Andric 
42160b57cec5SDimitry Andric   return Result;
42170b57cec5SDimitry Andric }
42180b57cec5SDimitry Andric 
4219972a253aSDimitry Andric static void diagnoseDynamicExceptionSpecification(Parser &P, SourceRange Range,
4220972a253aSDimitry Andric                                                   bool IsNoexcept) {
42210b57cec5SDimitry Andric   if (P.getLangOpts().CPlusPlus11) {
42220b57cec5SDimitry Andric     const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";
4223972a253aSDimitry Andric     P.Diag(Range.getBegin(), P.getLangOpts().CPlusPlus17 && !IsNoexcept
42240b57cec5SDimitry Andric                                  ? diag::ext_dynamic_exception_spec
42250b57cec5SDimitry Andric                                  : diag::warn_exception_spec_deprecated)
42260b57cec5SDimitry Andric         << Range;
42270b57cec5SDimitry Andric     P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
42280b57cec5SDimitry Andric         << Replacement << FixItHint::CreateReplacement(Range, Replacement);
42290b57cec5SDimitry Andric   }
42300b57cec5SDimitry Andric }
42310b57cec5SDimitry Andric 
42320b57cec5SDimitry Andric /// ParseDynamicExceptionSpecification - Parse a C++
42330b57cec5SDimitry Andric /// dynamic-exception-specification (C++ [except.spec]).
42340b57cec5SDimitry Andric ///
42350b57cec5SDimitry Andric ///       dynamic-exception-specification:
42360b57cec5SDimitry Andric ///         'throw' '(' type-id-list [opt] ')'
42370b57cec5SDimitry Andric /// [MS]    'throw' '(' '...' ')'
42380b57cec5SDimitry Andric ///
42390b57cec5SDimitry Andric ///       type-id-list:
42400b57cec5SDimitry Andric ///         type-id ... [opt]
42410b57cec5SDimitry Andric ///         type-id-list ',' type-id ... [opt]
42420b57cec5SDimitry Andric ///
42430b57cec5SDimitry Andric ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
4244972a253aSDimitry Andric     SourceRange &SpecificationRange, SmallVectorImpl<ParsedType> &Exceptions,
42450b57cec5SDimitry Andric     SmallVectorImpl<SourceRange> &Ranges) {
42460b57cec5SDimitry Andric   assert(Tok.is(tok::kw_throw) && "expected throw");
42470b57cec5SDimitry Andric 
42480b57cec5SDimitry Andric   SpecificationRange.setBegin(ConsumeToken());
42490b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_paren);
42500b57cec5SDimitry Andric   if (T.consumeOpen()) {
42510b57cec5SDimitry Andric     Diag(Tok, diag::err_expected_lparen_after) << "throw";
42520b57cec5SDimitry Andric     SpecificationRange.setEnd(SpecificationRange.getBegin());
42530b57cec5SDimitry Andric     return EST_DynamicNone;
42540b57cec5SDimitry Andric   }
42550b57cec5SDimitry Andric 
42560b57cec5SDimitry Andric   // Parse throw(...), a Microsoft extension that means "this function
42570b57cec5SDimitry Andric   // can throw anything".
42580b57cec5SDimitry Andric   if (Tok.is(tok::ellipsis)) {
42590b57cec5SDimitry Andric     SourceLocation EllipsisLoc = ConsumeToken();
42600b57cec5SDimitry Andric     if (!getLangOpts().MicrosoftExt)
42610b57cec5SDimitry Andric       Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
42620b57cec5SDimitry Andric     T.consumeClose();
42630b57cec5SDimitry Andric     SpecificationRange.setEnd(T.getCloseLocation());
42640b57cec5SDimitry Andric     diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false);
42650b57cec5SDimitry Andric     return EST_MSAny;
42660b57cec5SDimitry Andric   }
42670b57cec5SDimitry Andric 
42680b57cec5SDimitry Andric   // Parse the sequence of type-ids.
42690b57cec5SDimitry Andric   SourceRange Range;
42700b57cec5SDimitry Andric   while (Tok.isNot(tok::r_paren)) {
42710b57cec5SDimitry Andric     TypeResult Res(ParseTypeName(&Range));
42720b57cec5SDimitry Andric 
42730b57cec5SDimitry Andric     if (Tok.is(tok::ellipsis)) {
42740b57cec5SDimitry Andric       // C++0x [temp.variadic]p5:
42750b57cec5SDimitry Andric       //   - In a dynamic-exception-specification (15.4); the pattern is a
42760b57cec5SDimitry Andric       //     type-id.
42770b57cec5SDimitry Andric       SourceLocation Ellipsis = ConsumeToken();
42780b57cec5SDimitry Andric       Range.setEnd(Ellipsis);
42790b57cec5SDimitry Andric       if (!Res.isInvalid())
42800b57cec5SDimitry Andric         Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);
42810b57cec5SDimitry Andric     }
42820b57cec5SDimitry Andric 
42830b57cec5SDimitry Andric     if (!Res.isInvalid()) {
42840b57cec5SDimitry Andric       Exceptions.push_back(Res.get());
42850b57cec5SDimitry Andric       Ranges.push_back(Range);
42860b57cec5SDimitry Andric     }
42870b57cec5SDimitry Andric 
42880b57cec5SDimitry Andric     if (!TryConsumeToken(tok::comma))
42890b57cec5SDimitry Andric       break;
42900b57cec5SDimitry Andric   }
42910b57cec5SDimitry Andric 
42920b57cec5SDimitry Andric   T.consumeClose();
42930b57cec5SDimitry Andric   SpecificationRange.setEnd(T.getCloseLocation());
42940b57cec5SDimitry Andric   diagnoseDynamicExceptionSpecification(*this, SpecificationRange,
42950b57cec5SDimitry Andric                                         Exceptions.empty());
42960b57cec5SDimitry Andric   return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
42970b57cec5SDimitry Andric }
42980b57cec5SDimitry Andric 
42990b57cec5SDimitry Andric /// ParseTrailingReturnType - Parse a trailing return type on a new-style
43000b57cec5SDimitry Andric /// function declaration.
43010b57cec5SDimitry Andric TypeResult Parser::ParseTrailingReturnType(SourceRange &Range,
43020b57cec5SDimitry Andric                                            bool MayBeFollowedByDirectInit) {
43030b57cec5SDimitry Andric   assert(Tok.is(tok::arrow) && "expected arrow");
43040b57cec5SDimitry Andric 
43050b57cec5SDimitry Andric   ConsumeToken();
43060b57cec5SDimitry Andric 
43070b57cec5SDimitry Andric   return ParseTypeName(&Range, MayBeFollowedByDirectInit
4308e8d8bef9SDimitry Andric                                    ? DeclaratorContext::TrailingReturnVar
4309e8d8bef9SDimitry Andric                                    : DeclaratorContext::TrailingReturn);
43100b57cec5SDimitry Andric }
43110b57cec5SDimitry Andric 
4312480093f4SDimitry Andric /// Parse a requires-clause as part of a function declaration.
4313480093f4SDimitry Andric void Parser::ParseTrailingRequiresClause(Declarator &D) {
4314480093f4SDimitry Andric   assert(Tok.is(tok::kw_requires) && "expected requires");
4315480093f4SDimitry Andric 
4316480093f4SDimitry Andric   SourceLocation RequiresKWLoc = ConsumeToken();
4317480093f4SDimitry Andric 
4318*0fca6ea1SDimitry Andric   // C++23 [basic.scope.namespace]p1:
4319*0fca6ea1SDimitry Andric   //   For each non-friend redeclaration or specialization whose target scope
4320*0fca6ea1SDimitry Andric   //   is or is contained by the scope, the portion after the declarator-id,
4321*0fca6ea1SDimitry Andric   //   class-head-name, or enum-head-name is also included in the scope.
4322*0fca6ea1SDimitry Andric   // C++23 [basic.scope.class]p1:
4323*0fca6ea1SDimitry Andric   //   For each non-friend redeclaration or specialization whose target scope
4324*0fca6ea1SDimitry Andric   //   is or is contained by the scope, the portion after the declarator-id,
4325*0fca6ea1SDimitry Andric   //   class-head-name, or enum-head-name is also included in the scope.
4326*0fca6ea1SDimitry Andric   //
4327*0fca6ea1SDimitry Andric   // FIXME: We should really be calling ParseTrailingRequiresClause in
4328*0fca6ea1SDimitry Andric   // ParseDirectDeclarator, when we are already in the declarator scope.
4329*0fca6ea1SDimitry Andric   // This would also correctly suppress access checks for specializations
4330*0fca6ea1SDimitry Andric   // and explicit instantiations, which we currently do not do.
4331*0fca6ea1SDimitry Andric   CXXScopeSpec &SS = D.getCXXScopeSpec();
4332*0fca6ea1SDimitry Andric   DeclaratorScopeObj DeclScopeObj(*this, SS);
4333*0fca6ea1SDimitry Andric   if (SS.isValid() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))
4334*0fca6ea1SDimitry Andric     DeclScopeObj.EnterDeclaratorScope();
4335*0fca6ea1SDimitry Andric 
4336480093f4SDimitry Andric   ExprResult TrailingRequiresClause;
4337972a253aSDimitry Andric   ParseScope ParamScope(this, Scope::DeclScope |
4338480093f4SDimitry Andric                                   Scope::FunctionDeclarationScope |
4339480093f4SDimitry Andric                                   Scope::FunctionPrototypeScope);
4340480093f4SDimitry Andric 
4341480093f4SDimitry Andric   Actions.ActOnStartTrailingRequiresClause(getCurScope(), D);
4342480093f4SDimitry Andric 
4343bdd1243dSDimitry Andric   std::optional<Sema::CXXThisScopeRAII> ThisScope;
4344480093f4SDimitry Andric   InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope);
4345480093f4SDimitry Andric 
4346480093f4SDimitry Andric   TrailingRequiresClause =
4347480093f4SDimitry Andric       ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true);
4348480093f4SDimitry Andric 
4349480093f4SDimitry Andric   TrailingRequiresClause =
4350480093f4SDimitry Andric       Actions.ActOnFinishTrailingRequiresClause(TrailingRequiresClause);
4351480093f4SDimitry Andric 
4352480093f4SDimitry Andric   if (!D.isDeclarationOfFunction()) {
4353480093f4SDimitry Andric     Diag(RequiresKWLoc,
4354480093f4SDimitry Andric          diag::err_requires_clause_on_declarator_not_declaring_a_function);
4355480093f4SDimitry Andric     return;
4356480093f4SDimitry Andric   }
4357480093f4SDimitry Andric 
4358480093f4SDimitry Andric   if (TrailingRequiresClause.isInvalid())
4359480093f4SDimitry Andric     SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon},
4360480093f4SDimitry Andric               StopAtSemi | StopBeforeMatch);
4361480093f4SDimitry Andric   else
4362480093f4SDimitry Andric     D.setTrailingRequiresClause(TrailingRequiresClause.get());
4363480093f4SDimitry Andric 
4364480093f4SDimitry Andric   // Did the user swap the trailing return type and requires clause?
4365480093f4SDimitry Andric   if (D.isFunctionDeclarator() && Tok.is(tok::arrow) &&
4366480093f4SDimitry Andric       D.getDeclSpec().getTypeSpecType() == TST_auto) {
4367480093f4SDimitry Andric     SourceLocation ArrowLoc = Tok.getLocation();
4368480093f4SDimitry Andric     SourceRange Range;
4369480093f4SDimitry Andric     TypeResult TrailingReturnType =
4370480093f4SDimitry Andric         ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit=*/false);
4371480093f4SDimitry Andric 
4372480093f4SDimitry Andric     if (!TrailingReturnType.isInvalid()) {
4373480093f4SDimitry Andric       Diag(ArrowLoc,
4374480093f4SDimitry Andric            diag::err_requires_clause_must_appear_after_trailing_return)
4375480093f4SDimitry Andric           << Range;
4376480093f4SDimitry Andric       auto &FunctionChunk = D.getFunctionTypeInfo();
4377480093f4SDimitry Andric       FunctionChunk.HasTrailingReturnType = TrailingReturnType.isUsable();
4378480093f4SDimitry Andric       FunctionChunk.TrailingReturnType = TrailingReturnType.get();
4379e8d8bef9SDimitry Andric       FunctionChunk.TrailingReturnTypeLoc = Range.getBegin();
4380480093f4SDimitry Andric     } else
4381480093f4SDimitry Andric       SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma},
4382480093f4SDimitry Andric                 StopAtSemi | StopBeforeMatch);
4383480093f4SDimitry Andric   }
4384480093f4SDimitry Andric }
4385480093f4SDimitry Andric 
43860b57cec5SDimitry Andric /// We have just started parsing the definition of a new class,
43870b57cec5SDimitry Andric /// so push that class onto our stack of classes that is currently
43880b57cec5SDimitry Andric /// being parsed.
4389972a253aSDimitry Andric Sema::ParsingClassState Parser::PushParsingClass(Decl *ClassDecl,
4390972a253aSDimitry Andric                                                  bool NonNestedClass,
43910b57cec5SDimitry Andric                                                  bool IsInterface) {
43920b57cec5SDimitry Andric   assert((NonNestedClass || !ClassStack.empty()) &&
43930b57cec5SDimitry Andric          "Nested class without outer class");
43940b57cec5SDimitry Andric   ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
43950b57cec5SDimitry Andric   return Actions.PushParsingClass();
43960b57cec5SDimitry Andric }
43970b57cec5SDimitry Andric 
43980b57cec5SDimitry Andric /// Deallocate the given parsed class and all of its nested
43990b57cec5SDimitry Andric /// classes.
44000b57cec5SDimitry Andric void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
44010b57cec5SDimitry Andric   for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
44020b57cec5SDimitry Andric     delete Class->LateParsedDeclarations[I];
44030b57cec5SDimitry Andric   delete Class;
44040b57cec5SDimitry Andric }
44050b57cec5SDimitry Andric 
44060b57cec5SDimitry Andric /// Pop the top class of the stack of classes that are
44070b57cec5SDimitry Andric /// currently being parsed.
44080b57cec5SDimitry Andric ///
44090b57cec5SDimitry Andric /// This routine should be called when we have finished parsing the
44100b57cec5SDimitry Andric /// definition of a class, but have not yet popped the Scope
44110b57cec5SDimitry Andric /// associated with the class's definition.
44120b57cec5SDimitry Andric void Parser::PopParsingClass(Sema::ParsingClassState state) {
44130b57cec5SDimitry Andric   assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
44140b57cec5SDimitry Andric 
44150b57cec5SDimitry Andric   Actions.PopParsingClass(state);
44160b57cec5SDimitry Andric 
44170b57cec5SDimitry Andric   ParsingClass *Victim = ClassStack.top();
44180b57cec5SDimitry Andric   ClassStack.pop();
44190b57cec5SDimitry Andric   if (Victim->TopLevelClass) {
44200b57cec5SDimitry Andric     // Deallocate all of the nested classes of this class,
44210b57cec5SDimitry Andric     // recursively: we don't need to keep any of this information.
44220b57cec5SDimitry Andric     DeallocateParsedClasses(Victim);
44230b57cec5SDimitry Andric     return;
44240b57cec5SDimitry Andric   }
44250b57cec5SDimitry Andric   assert(!ClassStack.empty() && "Missing top-level class?");
44260b57cec5SDimitry Andric 
44270b57cec5SDimitry Andric   if (Victim->LateParsedDeclarations.empty()) {
44280b57cec5SDimitry Andric     // The victim is a nested class, but we will not need to perform
44290b57cec5SDimitry Andric     // any processing after the definition of this class since it has
44300b57cec5SDimitry Andric     // no members whose handling was delayed. Therefore, we can just
44310b57cec5SDimitry Andric     // remove this nested class.
44320b57cec5SDimitry Andric     DeallocateParsedClasses(Victim);
44330b57cec5SDimitry Andric     return;
44340b57cec5SDimitry Andric   }
44350b57cec5SDimitry Andric 
44360b57cec5SDimitry Andric   // This nested class has some members that will need to be processed
44370b57cec5SDimitry Andric   // after the top-level class is completely defined. Therefore, add
44380b57cec5SDimitry Andric   // it to the list of nested classes within its parent.
4439972a253aSDimitry Andric   assert(getCurScope()->isClassScope() &&
4440972a253aSDimitry Andric          "Nested class outside of class scope?");
44415ffd83dbSDimitry Andric   ClassStack.top()->LateParsedDeclarations.push_back(
44425ffd83dbSDimitry Andric       new LateParsedClass(this, Victim));
44430b57cec5SDimitry Andric }
44440b57cec5SDimitry Andric 
44450b57cec5SDimitry Andric /// Try to parse an 'identifier' which appears within an attribute-token.
44460b57cec5SDimitry Andric ///
44470b57cec5SDimitry Andric /// \return the parsed identifier on success, and 0 if the next token is not an
44480b57cec5SDimitry Andric /// attribute-token.
44490b57cec5SDimitry Andric ///
44500b57cec5SDimitry Andric /// C++11 [dcl.attr.grammar]p3:
44510b57cec5SDimitry Andric ///   If a keyword or an alternative token that satisfies the syntactic
44520b57cec5SDimitry Andric ///   requirements of an identifier is contained in an attribute-token,
44530b57cec5SDimitry Andric ///   it is considered an identifier.
4454*0fca6ea1SDimitry Andric IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(
4455*0fca6ea1SDimitry Andric     SourceLocation &Loc, SemaCodeCompletion::AttributeCompletion Completion,
4456349cc55cSDimitry Andric     const IdentifierInfo *Scope) {
44570b57cec5SDimitry Andric   switch (Tok.getKind()) {
44580b57cec5SDimitry Andric   default:
44590b57cec5SDimitry Andric     // Identifiers and keywords have identifier info attached.
44600b57cec5SDimitry Andric     if (!Tok.isAnnotation()) {
44610b57cec5SDimitry Andric       if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
44620b57cec5SDimitry Andric         Loc = ConsumeToken();
44630b57cec5SDimitry Andric         return II;
44640b57cec5SDimitry Andric       }
44650b57cec5SDimitry Andric     }
44660b57cec5SDimitry Andric     return nullptr;
44670b57cec5SDimitry Andric 
4468349cc55cSDimitry Andric   case tok::code_completion:
4469349cc55cSDimitry Andric     cutOffParsing();
4470*0fca6ea1SDimitry Andric     Actions.CodeCompletion().CodeCompleteAttribute(
4471*0fca6ea1SDimitry Andric         getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C23,
4472349cc55cSDimitry Andric         Completion, Scope);
4473349cc55cSDimitry Andric     return nullptr;
4474349cc55cSDimitry Andric 
44750b57cec5SDimitry Andric   case tok::numeric_constant: {
44760b57cec5SDimitry Andric     // If we got a numeric constant, check to see if it comes from a macro that
44770b57cec5SDimitry Andric     // corresponds to the predefined __clang__ macro. If it does, warn the user
44780b57cec5SDimitry Andric     // and recover by pretending they said _Clang instead.
44790b57cec5SDimitry Andric     if (Tok.getLocation().isMacroID()) {
44800b57cec5SDimitry Andric       SmallString<8> ExpansionBuf;
44810b57cec5SDimitry Andric       SourceLocation ExpansionLoc =
44820b57cec5SDimitry Andric           PP.getSourceManager().getExpansionLoc(Tok.getLocation());
44830b57cec5SDimitry Andric       StringRef Spelling = PP.getSpelling(ExpansionLoc, ExpansionBuf);
44840b57cec5SDimitry Andric       if (Spelling == "__clang__") {
44850b57cec5SDimitry Andric         SourceRange TokRange(
44860b57cec5SDimitry Andric             ExpansionLoc,
44870b57cec5SDimitry Andric             PP.getSourceManager().getExpansionLoc(Tok.getEndLoc()));
44880b57cec5SDimitry Andric         Diag(Tok, diag::warn_wrong_clang_attr_namespace)
44890b57cec5SDimitry Andric             << FixItHint::CreateReplacement(TokRange, "_Clang");
44900b57cec5SDimitry Andric         Loc = ConsumeToken();
44910b57cec5SDimitry Andric         return &PP.getIdentifierTable().get("_Clang");
44920b57cec5SDimitry Andric       }
44930b57cec5SDimitry Andric     }
44940b57cec5SDimitry Andric     return nullptr;
44950b57cec5SDimitry Andric   }
44960b57cec5SDimitry Andric 
44970b57cec5SDimitry Andric   case tok::ampamp:       // 'and'
44980b57cec5SDimitry Andric   case tok::pipe:         // 'bitor'
44990b57cec5SDimitry Andric   case tok::pipepipe:     // 'or'
45000b57cec5SDimitry Andric   case tok::caret:        // 'xor'
45010b57cec5SDimitry Andric   case tok::tilde:        // 'compl'
45020b57cec5SDimitry Andric   case tok::amp:          // 'bitand'
45030b57cec5SDimitry Andric   case tok::ampequal:     // 'and_eq'
45040b57cec5SDimitry Andric   case tok::pipeequal:    // 'or_eq'
45050b57cec5SDimitry Andric   case tok::caretequal:   // 'xor_eq'
45060b57cec5SDimitry Andric   case tok::exclaim:      // 'not'
45070b57cec5SDimitry Andric   case tok::exclaimequal: // 'not_eq'
45080b57cec5SDimitry Andric     // Alternative tokens do not have identifier info, but their spelling
45090b57cec5SDimitry Andric     // starts with an alphabetical character.
45100b57cec5SDimitry Andric     SmallString<8> SpellingBuf;
45110b57cec5SDimitry Andric     SourceLocation SpellingLoc =
45120b57cec5SDimitry Andric         PP.getSourceManager().getSpellingLoc(Tok.getLocation());
45130b57cec5SDimitry Andric     StringRef Spelling = PP.getSpelling(SpellingLoc, SpellingBuf);
45140b57cec5SDimitry Andric     if (isLetter(Spelling[0])) {
45150b57cec5SDimitry Andric       Loc = ConsumeToken();
45160b57cec5SDimitry Andric       return &PP.getIdentifierTable().get(Spelling);
45170b57cec5SDimitry Andric     }
45180b57cec5SDimitry Andric     return nullptr;
45190b57cec5SDimitry Andric   }
45200b57cec5SDimitry Andric }
45210b57cec5SDimitry Andric 
45225f757f3fSDimitry Andric void Parser::ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,
4523fe6060f1SDimitry Andric                                       CachedTokens &OpenMPTokens) {
4524fe6060f1SDimitry Andric   // Both 'sequence' and 'directive' attributes require arguments, so parse the
4525fe6060f1SDimitry Andric   // open paren for the argument list.
4526fe6060f1SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_paren);
4527fe6060f1SDimitry Andric   if (T.consumeOpen()) {
4528fe6060f1SDimitry Andric     Diag(Tok, diag::err_expected) << tok::l_paren;
4529fe6060f1SDimitry Andric     return;
4530fe6060f1SDimitry Andric   }
4531fe6060f1SDimitry Andric 
4532fe6060f1SDimitry Andric   if (AttrName->isStr("directive")) {
4533fe6060f1SDimitry Andric     // If the attribute is named `directive`, we can consume its argument list
4534fe6060f1SDimitry Andric     // and push the tokens from it into the cached token stream for a new OpenMP
4535fe6060f1SDimitry Andric     // pragma directive.
4536fe6060f1SDimitry Andric     Token OMPBeginTok;
4537fe6060f1SDimitry Andric     OMPBeginTok.startToken();
4538fe6060f1SDimitry Andric     OMPBeginTok.setKind(tok::annot_attr_openmp);
4539fe6060f1SDimitry Andric     OMPBeginTok.setLocation(Tok.getLocation());
4540fe6060f1SDimitry Andric     OpenMPTokens.push_back(OMPBeginTok);
4541fe6060f1SDimitry Andric 
4542fe6060f1SDimitry Andric     ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens, /*StopAtSemi=*/false,
4543fe6060f1SDimitry Andric                          /*ConsumeFinalToken*/ false);
4544fe6060f1SDimitry Andric     Token OMPEndTok;
4545fe6060f1SDimitry Andric     OMPEndTok.startToken();
4546fe6060f1SDimitry Andric     OMPEndTok.setKind(tok::annot_pragma_openmp_end);
4547fe6060f1SDimitry Andric     OMPEndTok.setLocation(Tok.getLocation());
4548fe6060f1SDimitry Andric     OpenMPTokens.push_back(OMPEndTok);
4549fe6060f1SDimitry Andric   } else {
4550fe6060f1SDimitry Andric     assert(AttrName->isStr("sequence") &&
4551fe6060f1SDimitry Andric            "Expected either 'directive' or 'sequence'");
4552fe6060f1SDimitry Andric     // If the attribute is named 'sequence', its argument is a list of one or
4553fe6060f1SDimitry Andric     // more OpenMP attributes (either 'omp::directive' or 'omp::sequence',
4554fe6060f1SDimitry Andric     // where the 'omp::' is optional).
4555fe6060f1SDimitry Andric     do {
4556fe6060f1SDimitry Andric       // We expect to see one of the following:
4557fe6060f1SDimitry Andric       //  * An identifier (omp) for the attribute namespace followed by ::
4558fe6060f1SDimitry Andric       //  * An identifier (directive) or an identifier (sequence).
4559fe6060f1SDimitry Andric       SourceLocation IdentLoc;
45605f757f3fSDimitry Andric       const IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4561fe6060f1SDimitry Andric 
4562fe6060f1SDimitry Andric       // If there is an identifier and it is 'omp', a double colon is required
4563fe6060f1SDimitry Andric       // followed by the actual identifier we're after.
4564fe6060f1SDimitry Andric       if (Ident && Ident->isStr("omp") && !ExpectAndConsume(tok::coloncolon))
4565fe6060f1SDimitry Andric         Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4566fe6060f1SDimitry Andric 
4567fe6060f1SDimitry Andric       // If we failed to find an identifier (scoped or otherwise), or we found
4568fe6060f1SDimitry Andric       // an unexpected identifier, diagnose.
4569fe6060f1SDimitry Andric       if (!Ident || (!Ident->isStr("directive") && !Ident->isStr("sequence"))) {
4570fe6060f1SDimitry Andric         Diag(Tok.getLocation(), diag::err_expected_sequence_or_directive);
4571fe6060f1SDimitry Andric         SkipUntil(tok::r_paren, StopBeforeMatch);
4572fe6060f1SDimitry Andric         continue;
4573fe6060f1SDimitry Andric       }
4574fe6060f1SDimitry Andric       // We read an identifier. If the identifier is one of the ones we
4575fe6060f1SDimitry Andric       // expected, we can recurse to parse the args.
4576fe6060f1SDimitry Andric       ParseOpenMPAttributeArgs(Ident, OpenMPTokens);
4577fe6060f1SDimitry Andric 
4578fe6060f1SDimitry Andric       // There may be a comma to signal that we expect another directive in the
4579fe6060f1SDimitry Andric       // sequence.
4580fe6060f1SDimitry Andric     } while (TryConsumeToken(tok::comma));
4581fe6060f1SDimitry Andric   }
4582fe6060f1SDimitry Andric   // Parse the closing paren for the argument list.
4583fe6060f1SDimitry Andric   T.consumeClose();
4584fe6060f1SDimitry Andric }
4585fe6060f1SDimitry Andric 
45860b57cec5SDimitry Andric static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
45870b57cec5SDimitry Andric                                               IdentifierInfo *ScopeName) {
4588a7dea167SDimitry Andric   switch (
4589a7dea167SDimitry Andric       ParsedAttr::getParsedKind(AttrName, ScopeName, ParsedAttr::AS_CXX11)) {
45900b57cec5SDimitry Andric   case ParsedAttr::AT_CarriesDependency:
45910b57cec5SDimitry Andric   case ParsedAttr::AT_Deprecated:
45920b57cec5SDimitry Andric   case ParsedAttr::AT_FallThrough:
45930b57cec5SDimitry Andric   case ParsedAttr::AT_CXX11NoReturn:
45940b57cec5SDimitry Andric   case ParsedAttr::AT_NoUniqueAddress:
4595e8d8bef9SDimitry Andric   case ParsedAttr::AT_Likely:
4596e8d8bef9SDimitry Andric   case ParsedAttr::AT_Unlikely:
45970b57cec5SDimitry Andric     return true;
45980b57cec5SDimitry Andric   case ParsedAttr::AT_WarnUnusedResult:
4599*0fca6ea1SDimitry Andric     return !ScopeName && AttrName->getName() == "nodiscard";
46000b57cec5SDimitry Andric   case ParsedAttr::AT_Unused:
4601*0fca6ea1SDimitry Andric     return !ScopeName && AttrName->getName() == "maybe_unused";
46020b57cec5SDimitry Andric   default:
46030b57cec5SDimitry Andric     return false;
46040b57cec5SDimitry Andric   }
46050b57cec5SDimitry Andric }
46060b57cec5SDimitry Andric 
4607*0fca6ea1SDimitry Andric /// Parse the argument to C++23's [[assume()]] attribute.
4608*0fca6ea1SDimitry Andric bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
4609*0fca6ea1SDimitry Andric                                         IdentifierInfo *AttrName,
4610*0fca6ea1SDimitry Andric                                         SourceLocation AttrNameLoc,
4611*0fca6ea1SDimitry Andric                                         SourceLocation *EndLoc,
4612*0fca6ea1SDimitry Andric                                         ParsedAttr::Form Form) {
4613*0fca6ea1SDimitry Andric   assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
4614*0fca6ea1SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_paren);
4615*0fca6ea1SDimitry Andric   T.consumeOpen();
4616*0fca6ea1SDimitry Andric 
4617*0fca6ea1SDimitry Andric   // [dcl.attr.assume]: The expression is potentially evaluated.
4618*0fca6ea1SDimitry Andric   EnterExpressionEvaluationContext Unevaluated(
4619*0fca6ea1SDimitry Andric       Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
4620*0fca6ea1SDimitry Andric 
4621*0fca6ea1SDimitry Andric   TentativeParsingAction TPA(*this);
4622*0fca6ea1SDimitry Andric   ExprResult Res(
4623*0fca6ea1SDimitry Andric       Actions.CorrectDelayedTyposInExpr(ParseConditionalExpression()));
4624*0fca6ea1SDimitry Andric   if (Res.isInvalid()) {
4625*0fca6ea1SDimitry Andric     TPA.Commit();
4626*0fca6ea1SDimitry Andric     SkipUntil(tok::r_paren, tok::r_square, StopAtSemi | StopBeforeMatch);
4627*0fca6ea1SDimitry Andric     if (Tok.is(tok::r_paren))
4628*0fca6ea1SDimitry Andric       T.consumeClose();
4629*0fca6ea1SDimitry Andric     return true;
4630*0fca6ea1SDimitry Andric   }
4631*0fca6ea1SDimitry Andric 
4632*0fca6ea1SDimitry Andric   if (!Tok.isOneOf(tok::r_paren, tok::r_square)) {
4633*0fca6ea1SDimitry Andric     // Emit a better diagnostic if this is an otherwise valid expression that
4634*0fca6ea1SDimitry Andric     // is not allowed here.
4635*0fca6ea1SDimitry Andric     TPA.Revert();
4636*0fca6ea1SDimitry Andric     Res = ParseExpression();
4637*0fca6ea1SDimitry Andric     if (!Res.isInvalid()) {
4638*0fca6ea1SDimitry Andric       auto *E = Res.get();
4639*0fca6ea1SDimitry Andric       Diag(E->getExprLoc(), diag::err_assume_attr_expects_cond_expr)
4640*0fca6ea1SDimitry Andric           << AttrName << FixItHint::CreateInsertion(E->getBeginLoc(), "(")
4641*0fca6ea1SDimitry Andric           << FixItHint::CreateInsertion(PP.getLocForEndOfToken(E->getEndLoc()),
4642*0fca6ea1SDimitry Andric                                         ")")
4643*0fca6ea1SDimitry Andric           << E->getSourceRange();
4644*0fca6ea1SDimitry Andric     }
4645*0fca6ea1SDimitry Andric 
4646*0fca6ea1SDimitry Andric     T.consumeClose();
4647*0fca6ea1SDimitry Andric     return true;
4648*0fca6ea1SDimitry Andric   }
4649*0fca6ea1SDimitry Andric 
4650*0fca6ea1SDimitry Andric   TPA.Commit();
4651*0fca6ea1SDimitry Andric   ArgsUnion Assumption = Res.get();
4652*0fca6ea1SDimitry Andric   auto RParen = Tok.getLocation();
4653*0fca6ea1SDimitry Andric   T.consumeClose();
4654*0fca6ea1SDimitry Andric   Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), nullptr,
4655*0fca6ea1SDimitry Andric                SourceLocation(), &Assumption, 1, Form);
4656*0fca6ea1SDimitry Andric 
4657*0fca6ea1SDimitry Andric   if (EndLoc)
4658*0fca6ea1SDimitry Andric     *EndLoc = RParen;
4659*0fca6ea1SDimitry Andric 
4660*0fca6ea1SDimitry Andric   return false;
4661*0fca6ea1SDimitry Andric }
4662*0fca6ea1SDimitry Andric 
46630b57cec5SDimitry Andric /// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause.
46640b57cec5SDimitry Andric ///
46650b57cec5SDimitry Andric /// [C++11] attribute-argument-clause:
46660b57cec5SDimitry Andric ///         '(' balanced-token-seq ')'
46670b57cec5SDimitry Andric ///
46680b57cec5SDimitry Andric /// [C++11] balanced-token-seq:
46690b57cec5SDimitry Andric ///         balanced-token
46700b57cec5SDimitry Andric ///         balanced-token-seq balanced-token
46710b57cec5SDimitry Andric ///
46720b57cec5SDimitry Andric /// [C++11] balanced-token:
46730b57cec5SDimitry Andric ///         '(' balanced-token-seq ')'
46740b57cec5SDimitry Andric ///         '[' balanced-token-seq ']'
46750b57cec5SDimitry Andric ///         '{' balanced-token-seq '}'
46760b57cec5SDimitry Andric ///         any token but '(', ')', '[', ']', '{', or '}'
4677972a253aSDimitry Andric bool Parser::ParseCXX11AttributeArgs(
4678972a253aSDimitry Andric     IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
4679972a253aSDimitry Andric     ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
4680972a253aSDimitry Andric     SourceLocation ScopeLoc, CachedTokens &OpenMPTokens) {
46810b57cec5SDimitry Andric   assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
46820b57cec5SDimitry Andric   SourceLocation LParenLoc = Tok.getLocation();
46830b57cec5SDimitry Andric   const LangOptions &LO = getLangOpts();
468406c3fb27SDimitry Andric   ParsedAttr::Form Form =
46855f757f3fSDimitry Andric       LO.CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C23();
46860b57cec5SDimitry Andric 
468781ad6265SDimitry Andric   // Try parsing microsoft attributes
468881ad6265SDimitry Andric   if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) {
468981ad6265SDimitry Andric     if (hasAttribute(AttributeCommonInfo::Syntax::AS_Microsoft, ScopeName,
469081ad6265SDimitry Andric                      AttrName, getTargetInfo(), getLangOpts()))
469106c3fb27SDimitry Andric       Form = ParsedAttr::Form::Microsoft();
469281ad6265SDimitry Andric   }
469381ad6265SDimitry Andric 
46940b57cec5SDimitry Andric   // If the attribute isn't known, we will not attempt to parse any
46950b57cec5SDimitry Andric   // arguments.
469606c3fb27SDimitry Andric   if (Form.getSyntax() != ParsedAttr::AS_Microsoft &&
469781ad6265SDimitry Andric       !hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX11
46985f757f3fSDimitry Andric                                  : AttributeCommonInfo::Syntax::AS_C23,
469981ad6265SDimitry Andric                     ScopeName, AttrName, getTargetInfo(), getLangOpts())) {
47000b57cec5SDimitry Andric     // Eat the left paren, then skip to the ending right paren.
47010b57cec5SDimitry Andric     ConsumeParen();
47020b57cec5SDimitry Andric     SkipUntil(tok::r_paren);
47030b57cec5SDimitry Andric     return false;
47040b57cec5SDimitry Andric   }
47050b57cec5SDimitry Andric 
47060b57cec5SDimitry Andric   if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) {
47070b57cec5SDimitry Andric     // GNU-scoped attributes have some special cases to handle GNU-specific
47080b57cec5SDimitry Andric     // behaviors.
47090b57cec5SDimitry Andric     ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
471006c3fb27SDimitry Andric                           ScopeLoc, Form, nullptr);
47110b57cec5SDimitry Andric     return true;
47120b57cec5SDimitry Andric   }
47130b57cec5SDimitry Andric 
4714*0fca6ea1SDimitry Andric   // [[omp::directive]] and [[omp::sequence]] need special handling.
4715*0fca6ea1SDimitry Andric   if (ScopeName && ScopeName->isStr("omp") &&
4716*0fca6ea1SDimitry Andric       (AttrName->isStr("directive") || AttrName->isStr("sequence"))) {
4717fe6060f1SDimitry Andric     Diag(AttrNameLoc, getLangOpts().OpenMP >= 51
4718fe6060f1SDimitry Andric                           ? diag::warn_omp51_compat_attributes
4719fe6060f1SDimitry Andric                           : diag::ext_omp_attributes);
4720fe6060f1SDimitry Andric 
4721fe6060f1SDimitry Andric     ParseOpenMPAttributeArgs(AttrName, OpenMPTokens);
4722fe6060f1SDimitry Andric 
4723fe6060f1SDimitry Andric     // We claim that an attribute was parsed and added so that one is not
4724fe6060f1SDimitry Andric     // created for us by the caller.
4725fe6060f1SDimitry Andric     return true;
4726fe6060f1SDimitry Andric   }
4727fe6060f1SDimitry Andric 
47280b57cec5SDimitry Andric   unsigned NumArgs;
47290b57cec5SDimitry Andric   // Some Clang-scoped attributes have some special parsing behavior.
47300b57cec5SDimitry Andric   if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang")))
47310b57cec5SDimitry Andric     NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,
473206c3fb27SDimitry Andric                                       ScopeName, ScopeLoc, Form);
4733*0fca6ea1SDimitry Andric   // So does C++23's assume() attribute.
4734*0fca6ea1SDimitry Andric   else if (!ScopeName && AttrName->isStr("assume")) {
4735*0fca6ea1SDimitry Andric     if (ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form))
4736*0fca6ea1SDimitry Andric       return true;
4737*0fca6ea1SDimitry Andric     NumArgs = 1;
4738*0fca6ea1SDimitry Andric   } else
4739972a253aSDimitry Andric     NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
474006c3fb27SDimitry Andric                                        ScopeName, ScopeLoc, Form);
47410b57cec5SDimitry Andric 
47420b57cec5SDimitry Andric   if (!Attrs.empty() &&
47430b57cec5SDimitry Andric       IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
47440b57cec5SDimitry Andric     ParsedAttr &Attr = Attrs.back();
47455f757f3fSDimitry Andric 
47465f757f3fSDimitry Andric     // Ignore attributes that don't exist for the target.
47475f757f3fSDimitry Andric     if (!Attr.existsInTarget(getTargetInfo())) {
47485f757f3fSDimitry Andric       Diag(LParenLoc, diag::warn_unknown_attribute_ignored) << AttrName;
47495f757f3fSDimitry Andric       Attr.setInvalid(true);
47505f757f3fSDimitry Andric       return true;
47515f757f3fSDimitry Andric     }
47525f757f3fSDimitry Andric 
47530b57cec5SDimitry Andric     // If the attribute is a standard or built-in attribute and we are
47540b57cec5SDimitry Andric     // parsing an argument list, we need to determine whether this attribute
47550b57cec5SDimitry Andric     // was allowed to have an argument list (such as [[deprecated]]), and how
47560b57cec5SDimitry Andric     // many arguments were parsed (so we can diagnose on [[deprecated()]]).
47570b57cec5SDimitry Andric     if (Attr.getMaxArgs() && !NumArgs) {
47580b57cec5SDimitry Andric       // The attribute was allowed to have arguments, but none were provided
47590b57cec5SDimitry Andric       // even though the attribute parsed successfully. This is an error.
47600b57cec5SDimitry Andric       Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
47610b57cec5SDimitry Andric       Attr.setInvalid(true);
47620b57cec5SDimitry Andric     } else if (!Attr.getMaxArgs()) {
47630b57cec5SDimitry Andric       // The attribute parsed successfully, but was not allowed to have any
47640b57cec5SDimitry Andric       // arguments. It doesn't matter whether any were provided -- the
47650b57cec5SDimitry Andric       // presence of the argument list (even if empty) is diagnosed.
47660b57cec5SDimitry Andric       Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
47670b57cec5SDimitry Andric           << AttrName
47680b57cec5SDimitry Andric           << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
47690b57cec5SDimitry Andric       Attr.setInvalid(true);
47700b57cec5SDimitry Andric     }
47710b57cec5SDimitry Andric   }
47720b57cec5SDimitry Andric   return true;
47730b57cec5SDimitry Andric }
47740b57cec5SDimitry Andric 
47755f757f3fSDimitry Andric /// Parse a C++11 or C23 attribute-specifier.
47760b57cec5SDimitry Andric ///
47770b57cec5SDimitry Andric /// [C++11] attribute-specifier:
47780b57cec5SDimitry Andric ///         '[' '[' attribute-list ']' ']'
47790b57cec5SDimitry Andric ///         alignment-specifier
47800b57cec5SDimitry Andric ///
47810b57cec5SDimitry Andric /// [C++11] attribute-list:
47820b57cec5SDimitry Andric ///         attribute[opt]
47830b57cec5SDimitry Andric ///         attribute-list ',' attribute[opt]
47840b57cec5SDimitry Andric ///         attribute '...'
47850b57cec5SDimitry Andric ///         attribute-list ',' attribute '...'
47860b57cec5SDimitry Andric ///
47870b57cec5SDimitry Andric /// [C++11] attribute:
47880b57cec5SDimitry Andric ///         attribute-token attribute-argument-clause[opt]
47890b57cec5SDimitry Andric ///
47900b57cec5SDimitry Andric /// [C++11] attribute-token:
47910b57cec5SDimitry Andric ///         identifier
47920b57cec5SDimitry Andric ///         attribute-scoped-token
47930b57cec5SDimitry Andric ///
47940b57cec5SDimitry Andric /// [C++11] attribute-scoped-token:
47950b57cec5SDimitry Andric ///         attribute-namespace '::' identifier
47960b57cec5SDimitry Andric ///
47970b57cec5SDimitry Andric /// [C++11] attribute-namespace:
47980b57cec5SDimitry Andric ///         identifier
4799fe6060f1SDimitry Andric void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
4800fe6060f1SDimitry Andric                                                   CachedTokens &OpenMPTokens,
4801fe6060f1SDimitry Andric                                                   SourceLocation *EndLoc) {
48020b57cec5SDimitry Andric   if (Tok.is(tok::kw_alignas)) {
4803*0fca6ea1SDimitry Andric     // alignas is a valid token in C23 but it is not an attribute, it's a type-
4804*0fca6ea1SDimitry Andric     // specifier-qualifier, which means it has different parsing behavior. We
4805*0fca6ea1SDimitry Andric     // handle this in ParseDeclarationSpecifiers() instead of here in C. We
4806*0fca6ea1SDimitry Andric     // should not get here for C any longer.
4807*0fca6ea1SDimitry Andric     assert(getLangOpts().CPlusPlus && "'alignas' is not an attribute in C");
48080b57cec5SDimitry Andric     Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);
4809fe6060f1SDimitry Andric     ParseAlignmentSpecifier(Attrs, EndLoc);
48100b57cec5SDimitry Andric     return;
48110b57cec5SDimitry Andric   }
48120b57cec5SDimitry Andric 
481306c3fb27SDimitry Andric   if (Tok.isRegularKeywordAttribute()) {
481406c3fb27SDimitry Andric     SourceLocation Loc = Tok.getLocation();
481506c3fb27SDimitry Andric     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
48167a6dacacSDimitry Andric     ParsedAttr::Form Form = ParsedAttr::Form(Tok.getKind());
48177a6dacacSDimitry Andric     bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());
481806c3fb27SDimitry Andric     ConsumeToken();
48197a6dacacSDimitry Andric     if (TakesArgs) {
48207a6dacacSDimitry Andric       if (!Tok.is(tok::l_paren))
48217a6dacacSDimitry Andric         Diag(Tok.getLocation(), diag::err_expected_lparen_after) << AttrName;
48227a6dacacSDimitry Andric       else
48237a6dacacSDimitry Andric         ParseAttributeArgsCommon(AttrName, Loc, Attrs, EndLoc,
48247a6dacacSDimitry Andric                                  /*ScopeName*/ nullptr,
48257a6dacacSDimitry Andric                                  /*ScopeLoc*/ Loc, Form);
48267a6dacacSDimitry Andric     } else
48277a6dacacSDimitry Andric       Attrs.addNew(AttrName, Loc, nullptr, Loc, nullptr, 0, Form);
482806c3fb27SDimitry Andric     return;
482906c3fb27SDimitry Andric   }
483006c3fb27SDimitry Andric 
48310b57cec5SDimitry Andric   assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) &&
48320b57cec5SDimitry Andric          "Not a double square bracket attribute list");
48330b57cec5SDimitry Andric 
4834e8d8bef9SDimitry Andric   SourceLocation OpenLoc = Tok.getLocation();
483506c3fb27SDimitry Andric   if (getLangOpts().CPlusPlus) {
483606c3fb27SDimitry Andric     Diag(OpenLoc, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_attribute
483706c3fb27SDimitry Andric                                             : diag::warn_ext_cxx11_attributes);
483806c3fb27SDimitry Andric   } else {
48395f757f3fSDimitry Andric     Diag(OpenLoc, getLangOpts().C23 ? diag::warn_pre_c23_compat_attributes
48405f757f3fSDimitry Andric                                     : diag::warn_ext_c23_attributes);
484106c3fb27SDimitry Andric   }
48420b57cec5SDimitry Andric 
48430b57cec5SDimitry Andric   ConsumeBracket();
4844e8d8bef9SDimitry Andric   checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
48450b57cec5SDimitry Andric   ConsumeBracket();
48460b57cec5SDimitry Andric 
48470b57cec5SDimitry Andric   SourceLocation CommonScopeLoc;
48480b57cec5SDimitry Andric   IdentifierInfo *CommonScopeName = nullptr;
48490b57cec5SDimitry Andric   if (Tok.is(tok::kw_using)) {
48500b57cec5SDimitry Andric     Diag(Tok.getLocation(), getLangOpts().CPlusPlus17
48510b57cec5SDimitry Andric                                 ? diag::warn_cxx14_compat_using_attribute_ns
48520b57cec5SDimitry Andric                                 : diag::ext_using_attribute_ns);
48530b57cec5SDimitry Andric     ConsumeToken();
48540b57cec5SDimitry Andric 
4855349cc55cSDimitry Andric     CommonScopeName = TryParseCXX11AttributeIdentifier(
4856*0fca6ea1SDimitry Andric         CommonScopeLoc, SemaCodeCompletion::AttributeCompletion::Scope);
48570b57cec5SDimitry Andric     if (!CommonScopeName) {
48580b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
48590b57cec5SDimitry Andric       SkipUntil(tok::r_square, tok::colon, StopBeforeMatch);
48600b57cec5SDimitry Andric     }
48610b57cec5SDimitry Andric     if (!TryConsumeToken(tok::colon) && CommonScopeName)
48620b57cec5SDimitry Andric       Diag(Tok.getLocation(), diag::err_expected) << tok::colon;
48630b57cec5SDimitry Andric   }
48640b57cec5SDimitry Andric 
4865fe6060f1SDimitry Andric   bool AttrParsed = false;
4866349cc55cSDimitry Andric   while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) {
4867fe6060f1SDimitry Andric     if (AttrParsed) {
4868fe6060f1SDimitry Andric       // If we parsed an attribute, a comma is required before parsing any
4869fe6060f1SDimitry Andric       // additional attributes.
4870fe6060f1SDimitry Andric       if (ExpectAndConsume(tok::comma)) {
4871fe6060f1SDimitry Andric         SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch);
48720b57cec5SDimitry Andric         continue;
4873fe6060f1SDimitry Andric       }
4874fe6060f1SDimitry Andric       AttrParsed = false;
4875fe6060f1SDimitry Andric     }
4876fe6060f1SDimitry Andric 
4877fe6060f1SDimitry Andric     // Eat all remaining superfluous commas before parsing the next attribute.
4878fe6060f1SDimitry Andric     while (TryConsumeToken(tok::comma))
4879fe6060f1SDimitry Andric       ;
48800b57cec5SDimitry Andric 
48810b57cec5SDimitry Andric     SourceLocation ScopeLoc, AttrLoc;
48820b57cec5SDimitry Andric     IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr;
48830b57cec5SDimitry Andric 
4884349cc55cSDimitry Andric     AttrName = TryParseCXX11AttributeIdentifier(
4885*0fca6ea1SDimitry Andric         AttrLoc, SemaCodeCompletion::AttributeCompletion::Attribute,
4886*0fca6ea1SDimitry Andric         CommonScopeName);
48870b57cec5SDimitry Andric     if (!AttrName)
48880b57cec5SDimitry Andric       // Break out to the "expected ']'" diagnostic.
48890b57cec5SDimitry Andric       break;
48900b57cec5SDimitry Andric 
48910b57cec5SDimitry Andric     // scoped attribute
48920b57cec5SDimitry Andric     if (TryConsumeToken(tok::coloncolon)) {
48930b57cec5SDimitry Andric       ScopeName = AttrName;
48940b57cec5SDimitry Andric       ScopeLoc = AttrLoc;
48950b57cec5SDimitry Andric 
4896349cc55cSDimitry Andric       AttrName = TryParseCXX11AttributeIdentifier(
4897*0fca6ea1SDimitry Andric           AttrLoc, SemaCodeCompletion::AttributeCompletion::Attribute,
4898*0fca6ea1SDimitry Andric           ScopeName);
48990b57cec5SDimitry Andric       if (!AttrName) {
49000b57cec5SDimitry Andric         Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
49010b57cec5SDimitry Andric         SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch);
49020b57cec5SDimitry Andric         continue;
49030b57cec5SDimitry Andric       }
49040b57cec5SDimitry Andric     }
49050b57cec5SDimitry Andric 
49060b57cec5SDimitry Andric     if (CommonScopeName) {
49070b57cec5SDimitry Andric       if (ScopeName) {
49080b57cec5SDimitry Andric         Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)
49090b57cec5SDimitry Andric             << SourceRange(CommonScopeLoc);
49100b57cec5SDimitry Andric       } else {
49110b57cec5SDimitry Andric         ScopeName = CommonScopeName;
49120b57cec5SDimitry Andric         ScopeLoc = CommonScopeLoc;
49130b57cec5SDimitry Andric       }
49140b57cec5SDimitry Andric     }
49150b57cec5SDimitry Andric 
49160b57cec5SDimitry Andric     // Parse attribute arguments
49170b57cec5SDimitry Andric     if (Tok.is(tok::l_paren))
4918fe6060f1SDimitry Andric       AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc,
4919fe6060f1SDimitry Andric                                            ScopeName, ScopeLoc, OpenMPTokens);
49200b57cec5SDimitry Andric 
4921fe6060f1SDimitry Andric     if (!AttrParsed) {
4922fe6060f1SDimitry Andric       Attrs.addNew(
49230b57cec5SDimitry Andric           AttrName,
49240b57cec5SDimitry Andric           SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc),
49250b57cec5SDimitry Andric           ScopeName, ScopeLoc, nullptr, 0,
492606c3fb27SDimitry Andric           getLangOpts().CPlusPlus ? ParsedAttr::Form::CXX11()
49275f757f3fSDimitry Andric                                   : ParsedAttr::Form::C23());
4928fe6060f1SDimitry Andric       AttrParsed = true;
4929fe6060f1SDimitry Andric     }
49300b57cec5SDimitry Andric 
49310b57cec5SDimitry Andric     if (TryConsumeToken(tok::ellipsis))
4932972a253aSDimitry Andric       Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName;
49330b57cec5SDimitry Andric   }
49340b57cec5SDimitry Andric 
4935fe6060f1SDimitry Andric   // If we hit an error and recovered by parsing up to a semicolon, eat the
4936fe6060f1SDimitry Andric   // semicolon and don't issue further diagnostics about missing brackets.
4937fe6060f1SDimitry Andric   if (Tok.is(tok::semi)) {
4938fe6060f1SDimitry Andric     ConsumeToken();
4939fe6060f1SDimitry Andric     return;
4940fe6060f1SDimitry Andric   }
4941fe6060f1SDimitry Andric 
4942e8d8bef9SDimitry Andric   SourceLocation CloseLoc = Tok.getLocation();
49430b57cec5SDimitry Andric   if (ExpectAndConsume(tok::r_square))
49440b57cec5SDimitry Andric     SkipUntil(tok::r_square);
4945e8d8bef9SDimitry Andric   else if (Tok.is(tok::r_square))
4946e8d8bef9SDimitry Andric     checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd);
4947fe6060f1SDimitry Andric   if (EndLoc)
4948fe6060f1SDimitry Andric     *EndLoc = Tok.getLocation();
49490b57cec5SDimitry Andric   if (ExpectAndConsume(tok::r_square))
49500b57cec5SDimitry Andric     SkipUntil(tok::r_square);
49510b57cec5SDimitry Andric }
49520b57cec5SDimitry Andric 
49535f757f3fSDimitry Andric /// ParseCXX11Attributes - Parse a C++11 or C23 attribute-specifier-seq.
49540b57cec5SDimitry Andric ///
49550b57cec5SDimitry Andric /// attribute-specifier-seq:
49560b57cec5SDimitry Andric ///       attribute-specifier-seq[opt] attribute-specifier
495781ad6265SDimitry Andric void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) {
495881ad6265SDimitry Andric   SourceLocation StartLoc = Tok.getLocation();
495981ad6265SDimitry Andric   SourceLocation EndLoc = StartLoc;
49600b57cec5SDimitry Andric 
49610b57cec5SDimitry Andric   do {
496281ad6265SDimitry Andric     ParseCXX11AttributeSpecifier(Attrs, &EndLoc);
496306c3fb27SDimitry Andric   } while (isAllowedCXX11AttributeSpecifier());
49640b57cec5SDimitry Andric 
496581ad6265SDimitry Andric   Attrs.Range = SourceRange(StartLoc, EndLoc);
49660b57cec5SDimitry Andric }
49670b57cec5SDimitry Andric 
49680b57cec5SDimitry Andric void Parser::DiagnoseAndSkipCXX11Attributes() {
496906c3fb27SDimitry Andric   auto Keyword =
497006c3fb27SDimitry Andric       Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() : nullptr;
49710b57cec5SDimitry Andric   // Start and end location of an attribute or an attribute list.
49720b57cec5SDimitry Andric   SourceLocation StartLoc = Tok.getLocation();
49730b57cec5SDimitry Andric   SourceLocation EndLoc = SkipCXX11Attributes();
49740b57cec5SDimitry Andric 
49750b57cec5SDimitry Andric   if (EndLoc.isValid()) {
49760b57cec5SDimitry Andric     SourceRange Range(StartLoc, EndLoc);
497706c3fb27SDimitry Andric     (Keyword ? Diag(StartLoc, diag::err_keyword_not_allowed) << Keyword
497806c3fb27SDimitry Andric              : Diag(StartLoc, diag::err_attributes_not_allowed))
497906c3fb27SDimitry Andric         << Range;
49800b57cec5SDimitry Andric   }
49810b57cec5SDimitry Andric }
49820b57cec5SDimitry Andric 
49830b57cec5SDimitry Andric SourceLocation Parser::SkipCXX11Attributes() {
49840b57cec5SDimitry Andric   SourceLocation EndLoc;
49850b57cec5SDimitry Andric 
49860b57cec5SDimitry Andric   if (!isCXX11AttributeSpecifier())
49870b57cec5SDimitry Andric     return EndLoc;
49880b57cec5SDimitry Andric 
49890b57cec5SDimitry Andric   do {
49900b57cec5SDimitry Andric     if (Tok.is(tok::l_square)) {
49910b57cec5SDimitry Andric       BalancedDelimiterTracker T(*this, tok::l_square);
49920b57cec5SDimitry Andric       T.consumeOpen();
49930b57cec5SDimitry Andric       T.skipToEnd();
49940b57cec5SDimitry Andric       EndLoc = T.getCloseLocation();
49957a6dacacSDimitry Andric     } else if (Tok.isRegularKeywordAttribute() &&
49967a6dacacSDimitry Andric                !doesKeywordAttributeTakeArgs(Tok.getKind())) {
499706c3fb27SDimitry Andric       EndLoc = Tok.getLocation();
499806c3fb27SDimitry Andric       ConsumeToken();
49990b57cec5SDimitry Andric     } else {
50007a6dacacSDimitry Andric       assert((Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute()) &&
50017a6dacacSDimitry Andric              "not an attribute specifier");
50020b57cec5SDimitry Andric       ConsumeToken();
50030b57cec5SDimitry Andric       BalancedDelimiterTracker T(*this, tok::l_paren);
50040b57cec5SDimitry Andric       if (!T.consumeOpen())
50050b57cec5SDimitry Andric         T.skipToEnd();
50060b57cec5SDimitry Andric       EndLoc = T.getCloseLocation();
50070b57cec5SDimitry Andric     }
50080b57cec5SDimitry Andric   } while (isCXX11AttributeSpecifier());
50090b57cec5SDimitry Andric 
50100b57cec5SDimitry Andric   return EndLoc;
50110b57cec5SDimitry Andric }
50120b57cec5SDimitry Andric 
50130b57cec5SDimitry Andric /// Parse uuid() attribute when it appears in a [] Microsoft attribute.
50140b57cec5SDimitry Andric void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
50150b57cec5SDimitry Andric   assert(Tok.is(tok::identifier) && "Not a Microsoft attribute list");
50160b57cec5SDimitry Andric   IdentifierInfo *UuidIdent = Tok.getIdentifierInfo();
50170b57cec5SDimitry Andric   assert(UuidIdent->getName() == "uuid" && "Not a Microsoft attribute list");
50180b57cec5SDimitry Andric 
50190b57cec5SDimitry Andric   SourceLocation UuidLoc = Tok.getLocation();
50200b57cec5SDimitry Andric   ConsumeToken();
50210b57cec5SDimitry Andric 
50220b57cec5SDimitry Andric   // Ignore the left paren location for now.
50230b57cec5SDimitry Andric   BalancedDelimiterTracker T(*this, tok::l_paren);
50240b57cec5SDimitry Andric   if (T.consumeOpen()) {
50250b57cec5SDimitry Andric     Diag(Tok, diag::err_expected) << tok::l_paren;
50260b57cec5SDimitry Andric     return;
50270b57cec5SDimitry Andric   }
50280b57cec5SDimitry Andric 
50290b57cec5SDimitry Andric   ArgsVector ArgExprs;
50305f757f3fSDimitry Andric   if (isTokenStringLiteral()) {
50310b57cec5SDimitry Andric     // Easy case: uuid("...") -- quoted string.
50325f757f3fSDimitry Andric     ExprResult StringResult = ParseUnevaluatedStringLiteralExpression();
50330b57cec5SDimitry Andric     if (StringResult.isInvalid())
50340b57cec5SDimitry Andric       return;
50350b57cec5SDimitry Andric     ArgExprs.push_back(StringResult.get());
50360b57cec5SDimitry Andric   } else {
50370b57cec5SDimitry Andric     // something like uuid({000000A0-0000-0000-C000-000000000049}) -- no
50380b57cec5SDimitry Andric     // quotes in the parens. Just append the spelling of all tokens encountered
50390b57cec5SDimitry Andric     // until the closing paren.
50400b57cec5SDimitry Andric 
50410b57cec5SDimitry Andric     SmallString<42> StrBuffer; // 2 "", 36 bytes UUID, 2 optional {}, 1 nul
50420b57cec5SDimitry Andric     StrBuffer += "\"";
50430b57cec5SDimitry Andric 
50440b57cec5SDimitry Andric     // Since none of C++'s keywords match [a-f]+, accepting just tok::l_brace,
50450b57cec5SDimitry Andric     // tok::r_brace, tok::minus, tok::identifier (think C000) and
50460b57cec5SDimitry Andric     // tok::numeric_constant (0000) should be enough. But the spelling of the
50470b57cec5SDimitry Andric     // uuid argument is checked later anyways, so there's no harm in accepting
50480b57cec5SDimitry Andric     // almost anything here.
50490b57cec5SDimitry Andric     // cl is very strict about whitespace in this form and errors out if any
50500b57cec5SDimitry Andric     // is present, so check the space flags on the tokens.
50510b57cec5SDimitry Andric     SourceLocation StartLoc = Tok.getLocation();
50520b57cec5SDimitry Andric     while (Tok.isNot(tok::r_paren)) {
50530b57cec5SDimitry Andric       if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) {
50540b57cec5SDimitry Andric         Diag(Tok, diag::err_attribute_uuid_malformed_guid);
50550b57cec5SDimitry Andric         SkipUntil(tok::r_paren, StopAtSemi);
50560b57cec5SDimitry Andric         return;
50570b57cec5SDimitry Andric       }
50580b57cec5SDimitry Andric       SmallString<16> SpellingBuffer;
50590b57cec5SDimitry Andric       SpellingBuffer.resize(Tok.getLength() + 1);
50600b57cec5SDimitry Andric       bool Invalid = false;
50610b57cec5SDimitry Andric       StringRef TokSpelling = PP.getSpelling(Tok, SpellingBuffer, &Invalid);
50620b57cec5SDimitry Andric       if (Invalid) {
50630b57cec5SDimitry Andric         SkipUntil(tok::r_paren, StopAtSemi);
50640b57cec5SDimitry Andric         return;
50650b57cec5SDimitry Andric       }
50660b57cec5SDimitry Andric       StrBuffer += TokSpelling;
50670b57cec5SDimitry Andric       ConsumeAnyToken();
50680b57cec5SDimitry Andric     }
50690b57cec5SDimitry Andric     StrBuffer += "\"";
50700b57cec5SDimitry Andric 
50710b57cec5SDimitry Andric     if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) {
50720b57cec5SDimitry Andric       Diag(Tok, diag::err_attribute_uuid_malformed_guid);
50730b57cec5SDimitry Andric       ConsumeParen();
50740b57cec5SDimitry Andric       return;
50750b57cec5SDimitry Andric     }
50760b57cec5SDimitry Andric 
50770b57cec5SDimitry Andric     // Pretend the user wrote the appropriate string literal here.
50780b57cec5SDimitry Andric     // ActOnStringLiteral() copies the string data into the literal, so it's
50790b57cec5SDimitry Andric     // ok that the Token points to StrBuffer.
50800b57cec5SDimitry Andric     Token Toks[1];
50810b57cec5SDimitry Andric     Toks[0].startToken();
50820b57cec5SDimitry Andric     Toks[0].setKind(tok::string_literal);
50830b57cec5SDimitry Andric     Toks[0].setLocation(StartLoc);
50840b57cec5SDimitry Andric     Toks[0].setLiteralData(StrBuffer.data());
50850b57cec5SDimitry Andric     Toks[0].setLength(StrBuffer.size());
50860b57cec5SDimitry Andric     StringLiteral *UuidString =
50875f757f3fSDimitry Andric         cast<StringLiteral>(Actions.ActOnUnevaluatedStringLiteral(Toks).get());
50880b57cec5SDimitry Andric     ArgExprs.push_back(UuidString);
50890b57cec5SDimitry Andric   }
50900b57cec5SDimitry Andric 
50910b57cec5SDimitry Andric   if (!T.consumeClose()) {
50920b57cec5SDimitry Andric     Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,
50930b57cec5SDimitry Andric                  SourceLocation(), ArgExprs.data(), ArgExprs.size(),
509406c3fb27SDimitry Andric                  ParsedAttr::Form::Microsoft());
50950b57cec5SDimitry Andric   }
50960b57cec5SDimitry Andric }
50970b57cec5SDimitry Andric 
50980b57cec5SDimitry Andric /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr]
50990b57cec5SDimitry Andric ///
51000b57cec5SDimitry Andric /// [MS] ms-attribute:
51010b57cec5SDimitry Andric ///             '[' token-seq ']'
51020b57cec5SDimitry Andric ///
51030b57cec5SDimitry Andric /// [MS] ms-attribute-seq:
51040b57cec5SDimitry Andric ///             ms-attribute[opt]
51050b57cec5SDimitry Andric ///             ms-attribute ms-attribute-seq
510681ad6265SDimitry Andric void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) {
51070b57cec5SDimitry Andric   assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
51080b57cec5SDimitry Andric 
510981ad6265SDimitry Andric   SourceLocation StartLoc = Tok.getLocation();
511081ad6265SDimitry Andric   SourceLocation EndLoc = StartLoc;
51110b57cec5SDimitry Andric   do {
51120b57cec5SDimitry Andric     // FIXME: If this is actually a C++11 attribute, parse it as one.
51130b57cec5SDimitry Andric     BalancedDelimiterTracker T(*this, tok::l_square);
51140b57cec5SDimitry Andric     T.consumeOpen();
51150b57cec5SDimitry Andric 
51165ffd83dbSDimitry Andric     // Skip most ms attributes except for a specific list.
51170b57cec5SDimitry Andric     while (true) {
5118349cc55cSDimitry Andric       SkipUntil(tok::r_square, tok::identifier,
5119349cc55cSDimitry Andric                 StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);
5120349cc55cSDimitry Andric       if (Tok.is(tok::code_completion)) {
5121349cc55cSDimitry Andric         cutOffParsing();
5122*0fca6ea1SDimitry Andric         Actions.CodeCompletion().CodeCompleteAttribute(
5123*0fca6ea1SDimitry Andric             AttributeCommonInfo::AS_Microsoft,
5124*0fca6ea1SDimitry Andric             SemaCodeCompletion::AttributeCompletion::Attribute,
5125349cc55cSDimitry Andric             /*Scope=*/nullptr);
5126349cc55cSDimitry Andric         break;
5127349cc55cSDimitry Andric       }
51280b57cec5SDimitry Andric       if (Tok.isNot(tok::identifier)) // ']', but also eof
51290b57cec5SDimitry Andric         break;
51300b57cec5SDimitry Andric       if (Tok.getIdentifierInfo()->getName() == "uuid")
513181ad6265SDimitry Andric         ParseMicrosoftUuidAttributeArgs(Attrs);
513281ad6265SDimitry Andric       else {
513381ad6265SDimitry Andric         IdentifierInfo *II = Tok.getIdentifierInfo();
513481ad6265SDimitry Andric         SourceLocation NameLoc = Tok.getLocation();
51350b57cec5SDimitry Andric         ConsumeToken();
513681ad6265SDimitry Andric         ParsedAttr::Kind AttrKind =
513781ad6265SDimitry Andric             ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft);
513881ad6265SDimitry Andric         // For HLSL we want to handle all attributes, but for MSVC compat, we
513981ad6265SDimitry Andric         // silently ignore unknown Microsoft attributes.
514081ad6265SDimitry Andric         if (getLangOpts().HLSL || AttrKind != ParsedAttr::UnknownAttribute) {
514181ad6265SDimitry Andric           bool AttrParsed = false;
514281ad6265SDimitry Andric           if (Tok.is(tok::l_paren)) {
514381ad6265SDimitry Andric             CachedTokens OpenMPTokens;
514481ad6265SDimitry Andric             AttrParsed =
514581ad6265SDimitry Andric                 ParseCXX11AttributeArgs(II, NameLoc, Attrs, &EndLoc, nullptr,
514681ad6265SDimitry Andric                                         SourceLocation(), OpenMPTokens);
514781ad6265SDimitry Andric             ReplayOpenMPAttributeTokens(OpenMPTokens);
514881ad6265SDimitry Andric           }
514981ad6265SDimitry Andric           if (!AttrParsed) {
515081ad6265SDimitry Andric             Attrs.addNew(II, NameLoc, nullptr, SourceLocation(), nullptr, 0,
515106c3fb27SDimitry Andric                          ParsedAttr::Form::Microsoft());
515281ad6265SDimitry Andric           }
515381ad6265SDimitry Andric         }
515481ad6265SDimitry Andric       }
51550b57cec5SDimitry Andric     }
51560b57cec5SDimitry Andric 
51570b57cec5SDimitry Andric     T.consumeClose();
515881ad6265SDimitry Andric     EndLoc = T.getCloseLocation();
51590b57cec5SDimitry Andric   } while (Tok.is(tok::l_square));
516081ad6265SDimitry Andric 
516181ad6265SDimitry Andric   Attrs.Range = SourceRange(StartLoc, EndLoc);
51620b57cec5SDimitry Andric }
51630b57cec5SDimitry Andric 
51640b57cec5SDimitry Andric void Parser::ParseMicrosoftIfExistsClassDeclaration(
51650b57cec5SDimitry Andric     DeclSpec::TST TagType, ParsedAttributes &AccessAttrs,
51660b57cec5SDimitry Andric     AccessSpecifier &CurAS) {
51670b57cec5SDimitry Andric   IfExistsCondition Result;
51680b57cec5SDimitry Andric   if (ParseMicrosoftIfExistsCondition(Result))
51690b57cec5SDimitry Andric     return;
51700b57cec5SDimitry Andric 
51710b57cec5SDimitry Andric   BalancedDelimiterTracker Braces(*this, tok::l_brace);
51720b57cec5SDimitry Andric   if (Braces.consumeOpen()) {
51730b57cec5SDimitry Andric     Diag(Tok, diag::err_expected) << tok::l_brace;
51740b57cec5SDimitry Andric     return;
51750b57cec5SDimitry Andric   }
51760b57cec5SDimitry Andric 
51770b57cec5SDimitry Andric   switch (Result.Behavior) {
51780b57cec5SDimitry Andric   case IEB_Parse:
51790b57cec5SDimitry Andric     // Parse the declarations below.
51800b57cec5SDimitry Andric     break;
51810b57cec5SDimitry Andric 
51820b57cec5SDimitry Andric   case IEB_Dependent:
51830b57cec5SDimitry Andric     Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
51840b57cec5SDimitry Andric         << Result.IsIfExists;
51850b57cec5SDimitry Andric     // Fall through to skip.
5186bdd1243dSDimitry Andric     [[fallthrough]];
51870b57cec5SDimitry Andric 
51880b57cec5SDimitry Andric   case IEB_Skip:
51890b57cec5SDimitry Andric     Braces.skipToEnd();
51900b57cec5SDimitry Andric     return;
51910b57cec5SDimitry Andric   }
51920b57cec5SDimitry Andric 
51930b57cec5SDimitry Andric   while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
51940b57cec5SDimitry Andric     // __if_exists, __if_not_exists can nest.
51950b57cec5SDimitry Andric     if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
5196972a253aSDimitry Andric       ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, CurAS);
51970b57cec5SDimitry Andric       continue;
51980b57cec5SDimitry Andric     }
51990b57cec5SDimitry Andric 
52000b57cec5SDimitry Andric     // Check for extraneous top-level semicolon.
52010b57cec5SDimitry Andric     if (Tok.is(tok::semi)) {
52020b57cec5SDimitry Andric       ConsumeExtraSemi(InsideStruct, TagType);
52030b57cec5SDimitry Andric       continue;
52040b57cec5SDimitry Andric     }
52050b57cec5SDimitry Andric 
52060b57cec5SDimitry Andric     AccessSpecifier AS = getAccessSpecifierIfPresent();
52070b57cec5SDimitry Andric     if (AS != AS_none) {
52080b57cec5SDimitry Andric       // Current token is a C++ access specifier.
52090b57cec5SDimitry Andric       CurAS = AS;
52100b57cec5SDimitry Andric       SourceLocation ASLoc = Tok.getLocation();
52110b57cec5SDimitry Andric       ConsumeToken();
52120b57cec5SDimitry Andric       if (Tok.is(tok::colon))
52130b57cec5SDimitry Andric         Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation(),
52140b57cec5SDimitry Andric                                      ParsedAttributesView{});
52150b57cec5SDimitry Andric       else
52160b57cec5SDimitry Andric         Diag(Tok, diag::err_expected) << tok::colon;
52170b57cec5SDimitry Andric       ConsumeToken();
52180b57cec5SDimitry Andric       continue;
52190b57cec5SDimitry Andric     }
52200b57cec5SDimitry Andric 
5221*0fca6ea1SDimitry Andric     ParsedTemplateInfo TemplateInfo;
52220b57cec5SDimitry Andric     // Parse all the comma separated declarators.
5223*0fca6ea1SDimitry Andric     ParseCXXClassMemberDeclaration(CurAS, AccessAttrs, TemplateInfo);
52240b57cec5SDimitry Andric   }
52250b57cec5SDimitry Andric 
52260b57cec5SDimitry Andric   Braces.consumeClose();
52270b57cec5SDimitry Andric }
5228