llvm/clang/lib/Parse/ParseDeclCXX.cpp

//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements the C++ Declaration portions of the Parser interfaces.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/Attributes.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/TimeProfiler.h"
#include <optional>

usingnamespaceclang;

/// ParseNamespace - We know that the current token is a namespace keyword. This
/// may either be a top level namespace or a block-level namespace alias. If
/// there was an inline keyword, it has already been parsed.
///
///       namespace-definition: [C++: namespace.def]
///         named-namespace-definition
///         unnamed-namespace-definition
///         nested-namespace-definition
///
///       named-namespace-definition:
///         'inline'[opt] 'namespace' attributes[opt] identifier '{'
///         namespace-body '}'
///
///       unnamed-namespace-definition:
///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
///
///       nested-namespace-definition:
///         'namespace' enclosing-namespace-specifier '::' 'inline'[opt]
///         identifier '{' namespace-body '}'
///
///       enclosing-namespace-specifier:
///         identifier
///         enclosing-namespace-specifier '::' 'inline'[opt] identifier
///
///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
///         'namespace' identifier '=' qualified-namespace-specifier ';'
///
Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
                                              SourceLocation &DeclEnd,
                                              SourceLocation InlineLoc) {}

/// ParseInnerNamespace - Parse the contents of a namespace.
void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
                                 unsigned int index, SourceLocation &InlineLoc,
                                 ParsedAttributes &attrs,
                                 BalancedDelimiterTracker &Tracker) {}

/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
/// alias definition.
///
Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
                                  SourceLocation AliasLoc,
                                  IdentifierInfo *Alias,
                                  SourceLocation &DeclEnd) {}

/// ParseLinkage - We know that the current token is a string_literal
/// and just before that, that extern was seen.
///
///       linkage-specification: [C++ 7.5p2: dcl.link]
///         'extern' string-literal '{' declaration-seq[opt] '}'
///         'extern' string-literal declaration
///
Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {}

/// Parse a standard C++ Modules export-declaration.
///
///       export-declaration:
///         'export' declaration
///         'export' '{' declaration-seq[opt] '}'
///
/// HLSL: Parse export function declaration.
///
///      export-function-declaration:
///         'export' function-declaration
///
///      export-declaration-group:
///         'export' '{' function-declaration-seq[opt] '}'
///
Decl *Parser::ParseExportDeclaration() {}

/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
/// using-directive. Assumes that current token is 'using'.
Parser::DeclGroupPtrTy Parser::ParseUsingDirectiveOrDeclaration(
    DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
    SourceLocation &DeclEnd, ParsedAttributes &Attrs) {}

/// ParseUsingDirective - Parse C++ using-directive, assumes
/// that current token is 'namespace' and 'using' was already parsed.
///
///       using-directive: [C++ 7.3.p4: namespace.udir]
///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
///                 namespace-name ;
/// [GNU] using-directive:
///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
///                 namespace-name attributes[opt] ;
///
Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
                                  SourceLocation UsingLoc,
                                  SourceLocation &DeclEnd,
                                  ParsedAttributes &attrs) {}

/// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
///
///     using-declarator:
///       'typename'[opt] nested-name-specifier unqualified-id
///
bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
                                  UsingDeclarator &D) {}

/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
/// Assumes that 'using' was already seen.
///
///     using-declaration: [C++ 7.3.p3: namespace.udecl]
///       'using' using-declarator-list[opt] ;
///
///     using-declarator-list: [C++1z]
///       using-declarator '...'[opt]
///       using-declarator-list ',' using-declarator '...'[opt]
///
///     using-declarator-list: [C++98-14]
///       using-declarator
///
///     alias-declaration: C++11 [dcl.dcl]p1
///       'using' identifier attribute-specifier-seq[opt] = type-id ;
///
///     using-enum-declaration: [C++20, dcl.enum]
///       'using' elaborated-enum-specifier ;
///       The terminal name of the elaborated-enum-specifier undergoes
///       type-only lookup
///
///     elaborated-enum-specifier:
///       'enum' nested-name-specifier[opt] identifier
Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(
    DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
    SourceLocation UsingLoc, SourceLocation &DeclEnd,
    ParsedAttributes &PrefixAttrs, AccessSpecifier AS) {}

Decl *Parser::ParseAliasDeclarationAfterDeclarator(
    const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
    UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
    ParsedAttributes &Attrs, Decl **OwnedType) {}

static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr,
                                               SourceLocation EndExprLoc) {}

/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
///
/// [C++0x] static_assert-declaration:
///           static_assert ( constant-expression  ,  string-literal  ) ;
///
/// [C11]   static_assert-declaration:
///           _Static_assert ( constant-expression  ,  string-literal  ) ;
///
Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {}

/// ParseDecltypeSpecifier - Parse a C++11 decltype specifier.
///
/// 'decltype' ( expression )
/// 'decltype' ( 'auto' )      [C++1y]
///
SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {}

void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
                                               SourceLocation StartLoc,
                                               SourceLocation EndLoc) {}

SourceLocation Parser::ParsePackIndexingType(DeclSpec &DS) {}

void Parser::AnnotateExistingIndexedTypeNamePack(ParsedType T,
                                                 SourceLocation StartLoc,
                                                 SourceLocation EndLoc) {}

DeclSpec::TST Parser::TypeTransformTokToDeclSpec() {}

bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {}

/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a
/// class name or decltype-specifier. Note that we only check that the result
/// names a type; semantic analysis will need to verify that the type names a
/// class. The result is either a type or null, depending on whether a type
/// name was found.
///
///       base-type-specifier: [C++11 class.derived]
///         class-or-decltype
///       class-or-decltype: [C++11 class.derived]
///         nested-name-specifier[opt] class-name
///         decltype-specifier
///       class-name: [C++ class.name]
///         identifier
///         simple-template-id
///
/// In C++98, instead of base-type-specifier, we have:
///
///         ::[opt] nested-name-specifier[opt] class-name
TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
                                          SourceLocation &EndLocation) {}

void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {}

void Parser::ParseNullabilityClassAttributes(ParsedAttributes &attrs) {}

/// Determine whether the following tokens are valid after a type-specifier
/// which could be a standalone declaration. This will conservatively return
/// true if there's any doubt, and is appropriate for insert-';' fixits.
bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {}

/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
/// until we reach the start of a definition or see a token that
/// cannot start a definition.
///
///       class-specifier: [C++ class]
///         class-head '{' member-specification[opt] '}'
///         class-head '{' member-specification[opt] '}' attributes[opt]
///       class-head:
///         class-key identifier[opt] base-clause[opt]
///         class-key nested-name-specifier identifier base-clause[opt]
///         class-key nested-name-specifier[opt] simple-template-id
///                          base-clause[opt]
/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
/// [GNU]   class-key attributes[opt] nested-name-specifier
///                          identifier base-clause[opt]
/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
///                          simple-template-id base-clause[opt]
///       class-key:
///         'class'
///         'struct'
///         'union'
///
///       elaborated-type-specifier: [C++ dcl.type.elab]
///         class-key ::[opt] nested-name-specifier[opt] identifier
///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
///                          simple-template-id
///
///  Note that the C++ class-specifier and elaborated-type-specifier,
///  together, subsume the C99 struct-or-union-specifier:
///
///       struct-or-union-specifier: [C99 6.7.2.1]
///         struct-or-union identifier[opt] '{' struct-contents '}'
///         struct-or-union identifier
/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
///                                                         '}' attributes[opt]
/// [GNU]   struct-or-union attributes[opt] identifier
///       struct-or-union:
///         'struct'
///         'union'
void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
                                 SourceLocation StartLoc, DeclSpec &DS,
                                 ParsedTemplateInfo &TemplateInfo,
                                 AccessSpecifier AS, bool EnteringContext,
                                 DeclSpecContext DSC,
                                 ParsedAttributes &Attributes) {}

/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
///
///       base-clause : [C++ class.derived]
///         ':' base-specifier-list
///       base-specifier-list:
///         base-specifier '...'[opt]
///         base-specifier-list ',' base-specifier '...'[opt]
void Parser::ParseBaseClause(Decl *ClassDecl) {}

/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
/// one entry in the base class list of a class specifier, for example:
///    class foo : public bar, virtual private baz {
/// 'public bar' and 'virtual private baz' are each base-specifiers.
///
///       base-specifier: [C++ class.derived]
///         attribute-specifier-seq[opt] base-type-specifier
///         attribute-specifier-seq[opt] 'virtual' access-specifier[opt]
///                 base-type-specifier
///         attribute-specifier-seq[opt] access-specifier 'virtual'[opt]
///                 base-type-specifier
BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {}

/// getAccessSpecifierIfPresent - Determine whether the next token is
/// a C++ access-specifier.
///
///       access-specifier: [C++ class.derived]
///         'private'
///         'protected'
///         'public'
AccessSpecifier Parser::getAccessSpecifierIfPresent() const {}

/// If the given declarator has any parts for which parsing has to be
/// delayed, e.g., default arguments or an exception-specification, create a
/// late-parsed method declaration record to handle the parsing at the end of
/// the class definition.
void Parser::HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo,
                                            Decl *ThisDecl) {}

/// isCXX11VirtSpecifier - Determine whether the given token is a C++11
/// virt-specifier.
///
///       virt-specifier:
///         override
///         final
///         __final
VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {}

/// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq.
///
///       virt-specifier-seq:
///         virt-specifier
///         virt-specifier-seq virt-specifier
void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
                                                bool IsInterface,
                                                SourceLocation FriendLoc) {}

/// isCXX11FinalKeyword - Determine whether the next token is a C++11
/// 'final' or Microsoft 'sealed' contextual keyword.
bool Parser::isCXX11FinalKeyword() const {}

/// isClassCompatibleKeyword - Determine whether the next token is a C++11
/// 'final' or Microsoft 'sealed' or 'abstract' contextual keywords.
bool Parser::isClassCompatibleKeyword() const {}

/// Parse a C++ member-declarator up to, but not including, the optional
/// brace-or-equal-initializer or pure-specifier.
bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
    Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,
    LateParsedAttrList &LateParsedAttrs) {}

/// Look for declaration specifiers possibly occurring after C++11
/// virt-specifier-seq and diagnose them.
void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
    Declarator &D, VirtSpecifiers &VS) {}

/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
///
///       member-declaration:
///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
///         function-definition ';'[opt]
/// [C++26] friend-type-declaration
///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
///         using-declaration                                            [TODO]
/// [C++0x] static_assert-declaration
///         template-declaration
/// [GNU]   '__extension__' member-declaration
///
///       member-declarator-list:
///         member-declarator
///         member-declarator-list ',' member-declarator
///
///       member-declarator:
///         declarator virt-specifier-seq[opt] pure-specifier[opt]
/// [C++2a] declarator requires-clause
///         declarator constant-initializer[opt]
/// [C++11] declarator brace-or-equal-initializer[opt]
///         identifier[opt] ':' constant-expression
///
///       virt-specifier-seq:
///         virt-specifier
///         virt-specifier-seq virt-specifier
///
///       virt-specifier:
///         override
///         final
/// [MS]    sealed
///
///       pure-specifier:
///         '= 0'
///
///       constant-initializer:
///         '=' constant-expression
///
///       friend-type-declaration:
///         'friend' friend-type-specifier-list ;
///
///       friend-type-specifier-list:
///         friend-type-specifier ...[opt]
///         friend-type-specifier-list , friend-type-specifier ...[opt]
///
///       friend-type-specifier:
///         simple-type-specifier
///         elaborated-type-specifier
///         typename-specifier
///
Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
    AccessSpecifier AS, ParsedAttributes &AccessAttrs,
    ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject *TemplateDiags) {}

/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer.
/// Also detect and reject any attempted defaulted/deleted function definition.
/// The location of the '=', if any, will be placed in EqualLoc.
///
/// This does not check for a pure-specifier; that's handled elsewhere.
///
///   brace-or-equal-initializer:
///     '=' initializer-expression
///     braced-init-list
///
///   initializer-clause:
///     assignment-expression
///     braced-init-list
///
///   defaulted/deleted function-definition:
///     '=' 'default'
///     '=' 'delete'
///
/// Prior to C++0x, the assignment-expression in an initializer-clause must
/// be a constant-expression.
ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
                                             SourceLocation &EqualLoc) {}

void Parser::SkipCXXMemberSpecification(SourceLocation RecordLoc,
                                        SourceLocation AttrFixitLoc,
                                        unsigned TagType, Decl *TagDecl) {}

Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
    AccessSpecifier &AS, ParsedAttributes &AccessAttrs, DeclSpec::TST TagType,
    Decl *TagDecl) {}

/// ParseCXXMemberSpecification - Parse the class definition.
///
///       member-specification:
///         member-declaration member-specification[opt]
///         access-specifier ':' member-specification[opt]
///
void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
                                         SourceLocation AttrFixitLoc,
                                         ParsedAttributes &Attrs,
                                         unsigned TagType, Decl *TagDecl) {}

void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {}

/// ParseConstructorInitializer - Parse a C++ constructor initializer,
/// which explicitly initializes the members or base classes of a
/// class (C++ [class.base.init]). For example, the three initializers
/// after the ':' in the Derived constructor below:
///
/// @code
/// class Base { };
/// class Derived : Base {
///   int x;
///   float f;
/// public:
///   Derived(float f) : Base(), x(17), f(f) { }
/// };
/// @endcode
///
/// [C++]  ctor-initializer:
///          ':' mem-initializer-list
///
/// [C++]  mem-initializer-list:
///          mem-initializer ...[opt]
///          mem-initializer ...[opt] , mem-initializer-list
void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {}

/// ParseMemInitializer - Parse a C++ member initializer, which is
/// part of a constructor initializer that explicitly initializes one
/// member or base class (C++ [class.base.init]). See
/// ParseConstructorInitializer for an example.
///
/// [C++] mem-initializer:
///         mem-initializer-id '(' expression-list[opt] ')'
/// [C++0x] mem-initializer-id braced-init-list
///
/// [C++] mem-initializer-id:
///         '::'[opt] nested-name-specifier[opt] class-name
///         identifier
MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {}

/// Parse a C++ exception-specification if present (C++0x [except.spec]).
///
///       exception-specification:
///         dynamic-exception-specification
///         noexcept-specification
///
///       noexcept-specification:
///         'noexcept'
///         'noexcept' '(' constant-expression ')'
ExceptionSpecificationType Parser::tryParseExceptionSpecification(
    bool Delayed, SourceRange &SpecificationRange,
    SmallVectorImpl<ParsedType> &DynamicExceptions,
    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
    ExprResult &NoexceptExpr, CachedTokens *&ExceptionSpecTokens) {}

static void diagnoseDynamicExceptionSpecification(Parser &P, SourceRange Range,
                                                  bool IsNoexcept) {}

/// ParseDynamicExceptionSpecification - Parse a C++
/// dynamic-exception-specification (C++ [except.spec]).
///
///       dynamic-exception-specification:
///         'throw' '(' type-id-list [opt] ')'
/// [MS]    'throw' '(' '...' ')'
///
///       type-id-list:
///         type-id ... [opt]
///         type-id-list ',' type-id ... [opt]
///
ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
    SourceRange &SpecificationRange, SmallVectorImpl<ParsedType> &Exceptions,
    SmallVectorImpl<SourceRange> &Ranges) {}

/// ParseTrailingReturnType - Parse a trailing return type on a new-style
/// function declaration.
TypeResult Parser::ParseTrailingReturnType(SourceRange &Range,
                                           bool MayBeFollowedByDirectInit) {}

/// Parse a requires-clause as part of a function declaration.
void Parser::ParseTrailingRequiresClause(Declarator &D) {}

/// We have just started parsing the definition of a new class,
/// so push that class onto our stack of classes that is currently
/// being parsed.
Sema::ParsingClassState Parser::PushParsingClass(Decl *ClassDecl,
                                                 bool NonNestedClass,
                                                 bool IsInterface) {}

/// Deallocate the given parsed class and all of its nested
/// classes.
void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {}

/// Pop the top class of the stack of classes that are
/// currently being parsed.
///
/// This routine should be called when we have finished parsing the
/// definition of a class, but have not yet popped the Scope
/// associated with the class's definition.
void Parser::PopParsingClass(Sema::ParsingClassState state) {}

/// Try to parse an 'identifier' which appears within an attribute-token.
///
/// \return the parsed identifier on success, and 0 if the next token is not an
/// attribute-token.
///
/// C++11 [dcl.attr.grammar]p3:
///   If a keyword or an alternative token that satisfies the syntactic
///   requirements of an identifier is contained in an attribute-token,
///   it is considered an identifier.
IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(
    SourceLocation &Loc, SemaCodeCompletion::AttributeCompletion Completion,
    const IdentifierInfo *Scope) {}

void Parser::ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,
                                      CachedTokens &OpenMPTokens) {}

static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
                                              IdentifierInfo *ScopeName) {}

/// Parse the argument to C++23's [[assume()]] attribute.
bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
                                        IdentifierInfo *AttrName,
                                        SourceLocation AttrNameLoc,
                                        SourceLocation *EndLoc,
                                        ParsedAttr::Form Form) {}

/// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause.
///
/// [C++11] attribute-argument-clause:
///         '(' balanced-token-seq ')'
///
/// [C++11] balanced-token-seq:
///         balanced-token
///         balanced-token-seq balanced-token
///
/// [C++11] balanced-token:
///         '(' balanced-token-seq ')'
///         '[' balanced-token-seq ']'
///         '{' balanced-token-seq '}'
///         any token but '(', ')', '[', ']', '{', or '}'
bool Parser::ParseCXX11AttributeArgs(
    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
    SourceLocation ScopeLoc, CachedTokens &OpenMPTokens) {}

/// Parse a C++11 or C23 attribute-specifier.
///
/// [C++11] attribute-specifier:
///         '[' '[' attribute-list ']' ']'
///         alignment-specifier
///
/// [C++11] attribute-list:
///         attribute[opt]
///         attribute-list ',' attribute[opt]
///         attribute '...'
///         attribute-list ',' attribute '...'
///
/// [C++11] attribute:
///         attribute-token attribute-argument-clause[opt]
///
/// [C++11] attribute-token:
///         identifier
///         attribute-scoped-token
///
/// [C++11] attribute-scoped-token:
///         attribute-namespace '::' identifier
///
/// [C++11] attribute-namespace:
///         identifier
void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
                                                  CachedTokens &OpenMPTokens,
                                                  SourceLocation *EndLoc) {}

/// ParseCXX11Attributes - Parse a C++11 or C23 attribute-specifier-seq.
///
/// attribute-specifier-seq:
///       attribute-specifier-seq[opt] attribute-specifier
void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) {}

void Parser::DiagnoseAndSkipCXX11Attributes() {}

SourceLocation Parser::SkipCXX11Attributes() {}

/// Parse uuid() attribute when it appears in a [] Microsoft attribute.
void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {}

/// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr]
///
/// [MS] ms-attribute:
///             '[' token-seq ']'
///
/// [MS] ms-attribute-seq:
///             ms-attribute[opt]
///             ms-attribute ms-attribute-seq
void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) {}

void Parser::ParseMicrosoftIfExistsClassDeclaration(
    DeclSpec::TST TagType, ParsedAttributes &AccessAttrs,
    AccessSpecifier &CurAS) {}