[clang] [clang][NFC] Regroup declarations in `Parser` (PR #138511)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Mon May 5 04:51:15 PDT 2025


https://github.com/Endilll created https://github.com/llvm/llvm-project/pull/138511

Following the steps of #82217, this patch reorganizes declarations in `Parse.h`. Highlights are:
1) Declarations are grouped in the same fashion as in `Sema.h`. Table of contents is provided at the beginning of `Parser` class. `public` declaration go first, then `private` ones, but unlike `Sema`, most of the stuff in `Parser` is private.
2) Documentation has been moved from `.cpp` files to the header. Grammar was consistently put in `\verbatim` blocks to render nicely in Doxygen.
3) File has been formatted with clang-format, except for the grammar, because clang-format butchers it.


>From 0839ee43872cd0a5e0ab82763caef50953dbe5e2 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 3 May 2025 10:13:48 +0300
Subject: [PATCH 1/5] [clang][NFC] Regroup declarations in `Parser`

---
 clang/include/clang/Parse/Parser.h        | 11023 ++++++++++++++------
 clang/lib/Parse/ParseCXXInlineMethods.cpp |    52 -
 clang/lib/Parse/ParseDecl.cpp             |   566 -
 clang/lib/Parse/ParseDeclCXX.cpp          |   419 -
 clang/lib/Parse/ParseExpr.cpp             |   543 -
 clang/lib/Parse/ParseExprCXX.cpp          |   526 -
 clang/lib/Parse/ParseInit.cpp             |    61 -
 clang/lib/Parse/ParseObjc.cpp             |   376 -
 clang/lib/Parse/ParseOpenACC.cpp          |    57 -
 clang/lib/Parse/ParseOpenMP.cpp           |   348 -
 clang/lib/Parse/ParsePragma.cpp           |    10 -
 clang/lib/Parse/ParseStmt.cpp             |   240 -
 clang/lib/Parse/ParseStmtAsm.cpp          |    58 -
 clang/lib/Parse/ParseTemplate.cpp         |   233 -
 clang/lib/Parse/ParseTentative.cpp        |   396 +-
 clang/lib/Parse/Parser.cpp                |   205 +-
 16 files changed, 7797 insertions(+), 7316 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 00e4b980bf44a..59836bcfb6136 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -153,17 +153,366 @@ enum class CXX11AttributeKind {
 /// parsing units of the grammar, productions are invoked to handle whatever has
 /// been read.
 ///
+/// \nosubgrouping
 class Parser : public CodeCompletionHandler {
+  // Table of Contents
+  // -----------------
+  // 1. Parsing (Parser.cpp)
+  // 2. Parser Entry Point (ParseAST.cpp)
+  // 3. C++ Class Inline Methods (ParseCXXInlineMethods.cpp)
+  // 4. Declarations (ParseDecl.cpp)
+  // 5. C++ Declarations (ParseDeclCXX.cpp)
+  // 6. Expressions (ParseExpr.cpp)
+  // 7. C++ Expressions (ParseExprCXX.cpp)
+  // 8. HLSL Constructs (ParseHLSL.cpp)
+  // 9. HLSL Root Signature (ParseHLSLRootSignature.cpp)
+  // 10. Initializers (ParseInit.cpp)
+  // 11. Objective-C Constructs (ParseObjc.cpp)
+  // 12. OpenACC Constructs (ParseOpenACC.cpp)
+  // 13. OpenMP Constructs (ParseOpenMP.cpp)
+  // 14. Pragmas (ParsePragma.cpp)
+  // 15. Statements (ParseStmt.cpp)
+  // 16. `inline asm` Statement (ParseStmtAsm.cpp)
+  // 17. C++ Templates (ParseTemplate.cpp)
+  // 18. Tentative Parsing (ParseTentative.cpp)
+
+  /// \name Parsing
+  /// Implementations are in Parser.cpp
+  ///@{
+
+  public:
+
   friend class ColonProtectionRAIIObject;
-  friend class ParsingOpenMPDirectiveRAII;
-  friend class ParsingOpenACCDirectiveRAII;
-  friend class InMessageExpressionRAIIObject;
-  friend class OffsetOfStateRAIIObject;
   friend class PoisonSEHIdentifiersRAIIObject;
-  friend class ObjCDeclContextSwitch;
   friend class ParenBraceBracketBalancer;
   friend class BalancedDelimiterTracker;
 
+  Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
+  ~Parser() override;
+
+  const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
+  const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
+  Preprocessor &getPreprocessor() const { return PP; }
+  Sema &getActions() const { return Actions; }
+  AttributeFactory &getAttrFactory() { return AttrFactory; }
+
+  const Token &getCurToken() const { return Tok; }
+  Scope *getCurScope() const { return Actions.getCurScope(); }
+
+  void incrementMSManglingNumber() const {
+    return Actions.incrementMSManglingNumber();
+  }
+
+  // Type forwarding.  All of these are statically 'void*', but they may all be
+  // different actual classes based on the actions in place.
+  typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
+  typedef OpaquePtr<TemplateName> TemplateTy;
+
+  /// Initialize - Warm up the parser.
+  ///
+  void Initialize();
+
+  /// Parse the first top-level declaration in a translation unit.
+  ///
+  ///   translation-unit:
+  /// [C]     external-declaration
+  /// [C]     translation-unit external-declaration
+  /// [C++]   top-level-declaration-seq[opt]
+  /// [C++20] global-module-fragment[opt] module-declaration
+  ///                 top-level-declaration-seq[opt] private-module-fragment[opt]
+  ///
+  /// Note that in C, it is an error if there is no first declaration.
+  bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
+    Sema::ModuleImportState &ImportState);
+
+  /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
+  /// action tells us to.  This returns true if the EOF was encountered.
+  ///
+  ///   top-level-declaration:
+  ///           declaration
+  /// [C++20]   module-import-declaration
+  bool ParseTopLevelDecl(DeclGroupPtrTy &Result,
+  Sema::ModuleImportState &ImportState);
+  bool ParseTopLevelDecl() {
+  DeclGroupPtrTy Result;
+  Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
+  return ParseTopLevelDecl(Result, IS);
+  }
+
+  /// ConsumeToken - Consume the current 'peek token' and lex the next one.
+  /// This does not work with special tokens: string literals, code completion,
+  /// annotation tokens and balanced tokens must be handled using the specific
+  /// consume methods.
+  /// Returns the location of the consumed token.
+  SourceLocation ConsumeToken() {
+  assert(!isTokenSpecial() &&
+  "Should consume special tokens with Consume*Token");
+  PrevTokLocation = Tok.getLocation();
+  PP.Lex(Tok);
+  return PrevTokLocation;
+  }
+
+  bool TryConsumeToken(tok::TokenKind Expected) {
+  if (Tok.isNot(Expected))
+  return false;
+  assert(!isTokenSpecial() &&
+  "Should consume special tokens with Consume*Token");
+  PrevTokLocation = Tok.getLocation();
+  PP.Lex(Tok);
+  return true;
+  }
+
+  bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
+  if (!TryConsumeToken(Expected))
+  return false;
+  Loc = PrevTokLocation;
+  return true;
+  }
+
+  /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
+  /// current token type.  This should only be used in cases where the type of
+  /// the token really isn't known, e.g. in error recovery.
+  SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
+  if (isTokenParen())
+  return ConsumeParen();
+  if (isTokenBracket())
+  return ConsumeBracket();
+  if (isTokenBrace())
+  return ConsumeBrace();
+  if (isTokenStringLiteral())
+  return ConsumeStringToken();
+  if (Tok.is(tok::code_completion))
+  return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
+                : handleUnexpectedCodeCompletionToken();
+  if (Tok.isAnnotation())
+  return ConsumeAnnotationToken();
+  return ConsumeToken();
+  }
+
+
+  SourceLocation getEndOfPreviousToken() {
+  return PP.getLocForEndOfToken(PrevTokLocation);
+  }
+
+  /// GetLookAheadToken - This peeks ahead N tokens and returns that token
+  /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
+  /// returns the token after Tok, etc.
+  ///
+  /// Note that this differs from the Preprocessor's LookAhead method, because
+  /// the Parser always has one token lexed that the preprocessor doesn't.
+  ///
+  const Token &GetLookAheadToken(unsigned N) {
+    if (N == 0 || Tok.is(tok::eof)) return Tok;
+    return PP.LookAhead(N-1);
+  }
+
+  /// NextToken - This peeks ahead one token and returns it without
+  /// consuming it.
+  const Token &NextToken() {
+    return PP.LookAhead(0);
+  }
+
+  /// getTypeAnnotation - Read a parsed type out of an annotation token.
+  static TypeResult getTypeAnnotation(const Token &Tok) {
+    if (!Tok.getAnnotationValue())
+      return TypeError();
+    return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
+  }
+
+  /// TryAnnotateTypeOrScopeToken - If the current token position is on a
+  /// typename (possibly qualified in C++) or a C++ scope specifier not followed
+  /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
+  /// with a single annotation token representing the typename or C++ scope
+  /// respectively.
+  /// This simplifies handling of C++ scope specifiers and allows efficient
+  /// backtracking without the need to re-parse and resolve nested-names and
+  /// typenames.
+  /// It will mainly be called when we expect to treat identifiers as typenames
+  /// (if they are typenames). For example, in C we do not expect identifiers
+  /// inside expressions to be treated as typenames so it will not be called
+  /// for expressions in C.
+  /// The benefit for C/ObjC is that a typename will be annotated and
+  /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
+  /// will not be called twice, once to check whether we have a declaration
+  /// specifier, and another one to get the actual type inside
+  /// ParseDeclarationSpecifiers).
+  ///
+  /// This returns true if an error occurred.
+  ///
+  /// Note that this routine emits an error if you call it with ::new or ::delete
+  /// as the current tokens, so only call it in contexts where these are invalid.
+  bool
+  TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename =
+                                  ImplicitTypenameContext::No);
+  
+  /// Try to annotate a type or scope token, having already parsed an
+  /// optional scope specifier. \p IsNewScope should be \c true unless the scope
+  /// specifier was extracted from an existing tok::annot_cxxscope annotation.
+  bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(
+      CXXScopeSpec &SS, bool IsNewScope,
+      ImplicitTypenameContext AllowImplicitTypename);
+
+  /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
+  /// annotates C++ scope specifiers and template-ids.  This returns
+  /// true if there was an error that could not be recovered from.
+  ///
+  /// Note that this routine emits an error if you call it with ::new or ::delete
+  /// as the current tokens, so only call it in contexts where these are invalid.
+  bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+
+  bool MightBeCXXScopeToken() {
+    return getLangOpts().CPlusPlus &&
+           (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+            (Tok.is(tok::annot_template_id) &&
+             NextToken().is(tok::coloncolon)) ||
+            Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super));
+  }
+  bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
+    return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Scope manipulation
+
+  /// ParseScope - Introduces a new scope for parsing. The kind of
+  /// scope is determined by ScopeFlags. Objects of this type should
+  /// be created on the stack to coincide with the position where the
+  /// parser enters the new scope, and this object's constructor will
+  /// create that new scope. Similarly, once the object is destroyed
+  /// the parser will exit the scope.
+  class ParseScope {
+    Parser *Self;
+    ParseScope(const ParseScope &) = delete;
+    void operator=(const ParseScope &) = delete;
+
+  public:
+    // ParseScope - Construct a new object to manage a scope in the
+    // parser Self where the new Scope is created with the flags
+    // ScopeFlags, but only when we aren't about to enter a compound statement.
+    ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
+               bool BeforeCompoundStmt = false)
+      : Self(Self) {
+      if (EnteredScope && !BeforeCompoundStmt)
+        Self->EnterScope(ScopeFlags);
+      else {
+        if (BeforeCompoundStmt)
+          Self->incrementMSManglingNumber();
+
+        this->Self = nullptr;
+      }
+    }
+
+    // Exit - Exit the scope associated with this object now, rather
+    // than waiting until the object is destroyed.
+    void Exit() {
+      if (Self) {
+        Self->ExitScope();
+        Self = nullptr;
+      }
+    }
+
+    ~ParseScope() {
+      Exit();
+    }
+  };
+
+  /// Introduces zero or more scopes for parsing. The scopes will all be exited
+  /// when the object is destroyed.
+  class MultiParseScope {
+    Parser &Self;
+    unsigned NumScopes = 0;
+
+    MultiParseScope(const MultiParseScope&) = delete;
+
+  public:
+    MultiParseScope(Parser &Self) : Self(Self) {}
+    void Enter(unsigned ScopeFlags) {
+      Self.EnterScope(ScopeFlags);
+      ++NumScopes;
+    }
+    void Exit() {
+      while (NumScopes) {
+        Self.ExitScope();
+        --NumScopes;
+      }
+    }
+    ~MultiParseScope() {
+      Exit();
+    }
+  };
+
+  /// EnterScope - Start a new scope.
+  void EnterScope(unsigned ScopeFlags);
+
+  /// ExitScope - Pop a scope off the scope stack.
+  void ExitScope();
+
+  //===--------------------------------------------------------------------===//
+  // Diagnostic Emission and Error recovery.
+
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
+  DiagnosticBuilder Diag(unsigned DiagID) {
+    return Diag(Tok, DiagID);
+  }
+
+  DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId);
+  DiagnosticBuilder DiagCompat(const Token &Tok, unsigned CompatDiagId);
+  DiagnosticBuilder DiagCompat(unsigned CompatDiagId) {
+    return DiagCompat(Tok, CompatDiagId);
+  }
+
+  /// Control flags for SkipUntil functions.
+  enum SkipUntilFlags {
+    StopAtSemi = 1 << 0,  ///< Stop skipping at semicolon
+    /// Stop skipping at specified token, but don't skip the token itself
+    StopBeforeMatch = 1 << 1,
+    StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
+  };
+
+  friend constexpr SkipUntilFlags operator|(SkipUntilFlags L,
+                                            SkipUntilFlags R) {
+    return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) |
+                                       static_cast<unsigned>(R));
+  }
+
+  /// SkipUntil - Read tokens until we get to the specified token, then consume
+  /// it (unless StopBeforeMatch is specified).  Because we cannot guarantee
+  /// that the token will ever occur, this skips to the next token, or to some
+  /// likely good stopping point.  If Flags has StopAtSemi flag, skipping will
+  /// stop at a ';' character. Balances (), [], and {} delimiter tokens while
+  /// skipping.
+  ///
+  /// If SkipUntil finds the specified token, it returns true, otherwise it
+  /// returns false.
+  bool SkipUntil(tok::TokenKind T,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
+    return SkipUntil(llvm::ArrayRef(T), Flags);
+  }
+  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
+    tok::TokenKind TokArray[] = {T1, T2};
+    return SkipUntil(TokArray, Flags);
+  }
+  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
+    tok::TokenKind TokArray[] = {T1, T2, T3};
+    return SkipUntil(TokArray, Flags);
+  }
+
+  /// SkipUntil - Read tokens until we get to the specified token, then consume
+  /// it (unless no flag StopBeforeMatch).  Because we cannot guarantee that the
+  /// token will ever occur, this skips to the next token, or to some likely
+  /// good stopping point.  If StopAtSemi is true, skipping will stop at a ';'
+  /// character.
+  ///
+  /// If SkipUntil finds the specified token, it returns true, otherwise it
+  /// returns false.
+  bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
+
+  private:
+
   Preprocessor &PP;
 
   /// Tok - The current token we are peeking ahead.  All parsing methods assume
@@ -213,838 +562,888 @@ class Parser : public CodeCompletionHandler {
 
   /// Contextual keywords for Microsoft extensions.
   IdentifierInfo *Ident__except;
-  mutable IdentifierInfo *Ident_sealed;
-  mutable IdentifierInfo *Ident_abstract;
-
-  /// Ident_super - IdentifierInfo for "super", to support fast
-  /// comparison.
-  IdentifierInfo *Ident_super;
-  /// Ident_vector, Ident_bool, Ident_Bool - cached IdentifierInfos for "vector"
-  /// and "bool" fast comparison.  Only present if AltiVec or ZVector are
-  /// enabled.
-  IdentifierInfo *Ident_vector;
-  IdentifierInfo *Ident_bool;
-  IdentifierInfo *Ident_Bool;
-  /// Ident_pixel - cached IdentifierInfos for "pixel" fast comparison.
-  /// Only present if AltiVec enabled.
-  IdentifierInfo *Ident_pixel;
-
-  /// Objective-C contextual keywords.
-  IdentifierInfo *Ident_instancetype;
-
-  /// Identifier for "introduced".
-  IdentifierInfo *Ident_introduced;
-
-  /// Identifier for "deprecated".
-  IdentifierInfo *Ident_deprecated;
-
-  /// Identifier for "obsoleted".
-  IdentifierInfo *Ident_obsoleted;
-
-  /// Identifier for "unavailable".
-  IdentifierInfo *Ident_unavailable;
-
-  /// Identifier for "message".
-  IdentifierInfo *Ident_message;
-
-  /// Identifier for "strict".
-  IdentifierInfo *Ident_strict;
-
-  /// Identifier for "replacement".
-  IdentifierInfo *Ident_replacement;
-
-  /// Identifier for "environment".
-  IdentifierInfo *Ident_environment;
-
-  /// Identifiers used by the 'external_source_symbol' attribute.
-  IdentifierInfo *Ident_language, *Ident_defined_in,
-      *Ident_generated_declaration, *Ident_USR;
-
-  /// C++11 contextual keywords.
-  mutable IdentifierInfo *Ident_final;
-  mutable IdentifierInfo *Ident_GNU_final;
-  mutable IdentifierInfo *Ident_override;
 
   // C++2a contextual keywords.
   mutable IdentifierInfo *Ident_import;
   mutable IdentifierInfo *Ident_module;
 
-  // C++ type trait keywords that can be reverted to identifiers and still be
-  // used as type traits.
-  llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
+  std::unique_ptr<CommentHandler> CommentSemaHandler;
 
-  std::unique_ptr<PragmaHandler> AlignHandler;
-  std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
-  std::unique_ptr<PragmaHandler> OptionsHandler;
-  std::unique_ptr<PragmaHandler> PackHandler;
-  std::unique_ptr<PragmaHandler> MSStructHandler;
-  std::unique_ptr<PragmaHandler> UnusedHandler;
-  std::unique_ptr<PragmaHandler> WeakHandler;
-  std::unique_ptr<PragmaHandler> RedefineExtnameHandler;
-  std::unique_ptr<PragmaHandler> FPContractHandler;
-  std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
-  std::unique_ptr<PragmaHandler> OpenMPHandler;
-  std::unique_ptr<PragmaHandler> OpenACCHandler;
-  std::unique_ptr<PragmaHandler> PCSectionHandler;
-  std::unique_ptr<PragmaHandler> MSCommentHandler;
-  std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
-  std::unique_ptr<PragmaHandler> FPEvalMethodHandler;
-  std::unique_ptr<PragmaHandler> FloatControlHandler;
-  std::unique_ptr<PragmaHandler> MSPointersToMembers;
-  std::unique_ptr<PragmaHandler> MSVtorDisp;
-  std::unique_ptr<PragmaHandler> MSInitSeg;
-  std::unique_ptr<PragmaHandler> MSDataSeg;
-  std::unique_ptr<PragmaHandler> MSBSSSeg;
-  std::unique_ptr<PragmaHandler> MSConstSeg;
-  std::unique_ptr<PragmaHandler> MSCodeSeg;
-  std::unique_ptr<PragmaHandler> MSSection;
-  std::unique_ptr<PragmaHandler> MSStrictGuardStackCheck;
-  std::unique_ptr<PragmaHandler> MSRuntimeChecks;
-  std::unique_ptr<PragmaHandler> MSIntrinsic;
-  std::unique_ptr<PragmaHandler> MSFunction;
-  std::unique_ptr<PragmaHandler> MSOptimize;
-  std::unique_ptr<PragmaHandler> MSFenvAccess;
-  std::unique_ptr<PragmaHandler> MSAllocText;
-  std::unique_ptr<PragmaHandler> CUDAForceHostDeviceHandler;
-  std::unique_ptr<PragmaHandler> OptimizeHandler;
-  std::unique_ptr<PragmaHandler> LoopHintHandler;
-  std::unique_ptr<PragmaHandler> UnrollHintHandler;
-  std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
-  std::unique_ptr<PragmaHandler> UnrollAndJamHintHandler;
-  std::unique_ptr<PragmaHandler> NoUnrollAndJamHintHandler;
-  std::unique_ptr<PragmaHandler> FPHandler;
-  std::unique_ptr<PragmaHandler> STDCFenvAccessHandler;
-  std::unique_ptr<PragmaHandler> STDCFenvRoundHandler;
-  std::unique_ptr<PragmaHandler> STDCCXLIMITHandler;
-  std::unique_ptr<PragmaHandler> STDCUnknownHandler;
-  std::unique_ptr<PragmaHandler> AttributePragmaHandler;
-  std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
-  std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
-  std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
+  /// Gets set to true after calling ProduceSignatureHelp, it is for a
+  /// workaround to make sure ProduceSignatureHelp is only called at the deepest
+  /// function call.
+  bool CalledSignatureHelp = false;
 
-  std::unique_ptr<CommentHandler> CommentSemaHandler;
+  IdentifierInfo *getSEHExceptKeyword();
 
-  /// Whether the '>' token acts as an operator or not. This will be
-  /// true except when we are parsing an expression within a C++
-  /// template argument list, where the '>' closes the template
-  /// argument list.
-  bool GreaterThanIsOperator;
+  /// Whether to skip parsing of function bodies.
+  ///
+  /// This option can be used, for example, to speed up searches for
+  /// declarations/definitions when indexing.
+  bool SkipFunctionBodies;
 
-  /// ColonIsSacred - When this is false, we aggressively try to recover from
-  /// code like "foo : bar" as if it were a typo for "foo :: bar".  This is not
-  /// safe in case statements and a few other things.  This is managed by the
-  /// ColonProtectionRAIIObject RAII object.
-  bool ColonIsSacred;
+  //===--------------------------------------------------------------------===//
+  // Low-Level token peeking and consumption methods.
+  //
 
-  /// Parsing OpenMP directive mode.
-  bool OpenMPDirectiveParsing = false;
+  /// isTokenParen - Return true if the cur token is '(' or ')'.
+  bool isTokenParen() const {
+    return Tok.isOneOf(tok::l_paren, tok::r_paren);
+  }
+  /// isTokenBracket - Return true if the cur token is '[' or ']'.
+  bool isTokenBracket() const {
+    return Tok.isOneOf(tok::l_square, tok::r_square);
+  }
+  /// isTokenBrace - Return true if the cur token is '{' or '}'.
+  bool isTokenBrace() const {
+    return Tok.isOneOf(tok::l_brace, tok::r_brace);
+  }
+  /// isTokenStringLiteral - True if this token is a string-literal.
+  bool isTokenStringLiteral() const {
+    return tok::isStringLiteral(Tok.getKind());
+  }
+  /// isTokenSpecial - True if this token requires special consumption methods.
+  bool isTokenSpecial() const {
+    return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
+           isTokenBrace() || Tok.is(tok::code_completion) || Tok.isAnnotation();
+  }
 
-  /// Parsing OpenACC directive mode.
-  bool OpenACCDirectiveParsing = false;
+  /// Returns true if the current token is '=' or is a type of '='.
+  /// For typos, give a fixit to '='
+  bool isTokenEqualOrEqualTypo();
 
-  /// Currently parsing a situation where an OpenACC array section could be
-  /// legal, such as a 'var-list'.
-  bool AllowOpenACCArraySections = false;
+  /// Return the current token to the token stream and make the given
+  /// token the current token.
+  void UnconsumeToken(Token &Consumed) {
+      Token Next = Tok;
+      PP.EnterToken(Consumed, /*IsReinject*/true);
+      PP.Lex(Tok);
+      PP.EnterToken(Next, /*IsReinject*/true);
+  }
 
-  /// RAII object to set reset OpenACC parsing a context where Array Sections
-  /// are allowed.
-  class OpenACCArraySectionRAII {
-    Parser &P;
+  SourceLocation ConsumeAnnotationToken() {
+    assert(Tok.isAnnotation() && "wrong consume method");
+    SourceLocation Loc = Tok.getLocation();
+    PrevTokLocation = Tok.getAnnotationEndLoc();
+    PP.Lex(Tok);
+    return Loc;
+  }
 
-  public:
-    OpenACCArraySectionRAII(Parser &P) : P(P) {
-      assert(!P.AllowOpenACCArraySections);
-      P.AllowOpenACCArraySections = true;
-    }
-    ~OpenACCArraySectionRAII() {
-      assert(P.AllowOpenACCArraySections);
-      P.AllowOpenACCArraySections = false;
+  /// ConsumeParen - This consume method keeps the paren count up-to-date.
+  ///
+  SourceLocation ConsumeParen() {
+    assert(isTokenParen() && "wrong consume method");
+    if (Tok.getKind() == tok::l_paren)
+      ++ParenCount;
+    else if (ParenCount) {
+      AngleBrackets.clear(*this);
+      --ParenCount;       // Don't let unbalanced )'s drive the count negative.
     }
-  };
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
 
-  /// When true, we are directly inside an Objective-C message
-  /// send expression.
+  /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
   ///
-  /// This is managed by the \c InMessageExpressionRAIIObject class, and
-  /// should not be set directly.
-  bool InMessageExpression;
-
-  /// Gets set to true after calling ProduceSignatureHelp, it is for a
-  /// workaround to make sure ProduceSignatureHelp is only called at the deepest
-  /// function call.
-  bool CalledSignatureHelp = false;
+  SourceLocation ConsumeBracket() {
+    assert(isTokenBracket() && "wrong consume method");
+    if (Tok.getKind() == tok::l_square)
+      ++BracketCount;
+    else if (BracketCount) {
+      AngleBrackets.clear(*this);
+      --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
+    }
 
-  OffsetOfKind OffsetOfState = OffsetOfKind::Outside;
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
 
-  /// The "depth" of the template parameters currently being parsed.
-  unsigned TemplateParameterDepth;
+  /// ConsumeBrace - This consume method keeps the brace count up-to-date.
+  ///
+  SourceLocation ConsumeBrace() {
+    assert(isTokenBrace() && "wrong consume method");
+    if (Tok.getKind() == tok::l_brace)
+      ++BraceCount;
+    else if (BraceCount) {
+      AngleBrackets.clear(*this);
+      --BraceCount;     // Don't let unbalanced }'s drive the count negative.
+    }
 
-  /// Current kind of OpenMP clause
-  OpenMPClauseKind OMPClauseKind = llvm::omp::OMPC_unknown;
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
 
-  /// RAII class that manages the template parameter depth.
-  class TemplateParameterDepthRAII {
-    unsigned &Depth;
-    unsigned AddedLevels;
-  public:
-    explicit TemplateParameterDepthRAII(unsigned &Depth)
-      : Depth(Depth), AddedLevels(0) {}
+  /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
+  /// and returning the token kind.  This method is specific to strings, as it
+  /// handles string literal concatenation, as per C99 5.1.1.2, translation
+  /// phase #6.
+  SourceLocation ConsumeStringToken() {
+    assert(isTokenStringLiteral() &&
+           "Should only consume string literals with this method");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
 
-    ~TemplateParameterDepthRAII() {
-      Depth -= AddedLevels;
-    }
+  /// Consume the current code-completion token.
+  ///
+  /// This routine can be called to consume the code-completion token and
+  /// continue processing in special cases where \c cutOffParsing() isn't
+  /// desired, such as token caching or completion with lookahead.
+  SourceLocation ConsumeCodeCompletionToken() {
+    assert(Tok.is(tok::code_completion));
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
 
-    void operator++() {
-      ++Depth;
-      ++AddedLevels;
-    }
-    void addDepth(unsigned D) {
-      Depth += D;
-      AddedLevels += D;
-    }
-    void setAddedDepth(unsigned D) {
-      Depth = Depth - AddedLevels + D;
-      AddedLevels = D;
-    }
+  /// When we are consuming a code-completion token without having matched
+  /// specific position in the grammar, provide code-completion results based
+  /// on context.
+  ///
+  /// \returns the source location of the code-completion token.
+  SourceLocation handleUnexpectedCodeCompletionToken();
 
-    unsigned getDepth() const { return Depth; }
-    unsigned getOriginalDepth() const { return Depth - AddedLevels; }
-  };
+  /// Abruptly cut off parsing; mainly used when we have reached the
+  /// code-completion point.
+  void cutOffParsing() {
+    if (PP.isCodeCompletionEnabled())
+      PP.setCodeCompletionReached();
+    // Cut off parsing by acting as if we reached the end-of-file.
+    Tok.setKind(tok::eof);
+  }
 
-  /// Factory object for creating ParsedAttr objects.
-  AttributeFactory AttrFactory;
+  /// Determine if we're at the end of the file or at a transition
+  /// between modules.
+  bool isEofOrEom() {
+    tok::TokenKind Kind = Tok.getKind();
+    return Kind == tok::eof || Kind == tok::annot_module_begin ||
+           Kind == tok::annot_module_end || Kind == tok::annot_module_include ||
+           Kind == tok::annot_repl_input_end;
+  }
 
-  /// Gathers and cleans up TemplateIdAnnotations when parsing of a
-  /// top-level declaration is finished.
-  SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
+  static void setTypeAnnotation(Token &Tok, TypeResult T) {
+    assert((T.isInvalid() || T.get()) &&
+           "produced a valid-but-null type annotation?");
+    Tok.setAnnotationValue(T.isInvalid() ? nullptr : T.get().getAsOpaquePtr());
+  }
 
-  /// Don't destroy template annotations in MaybeDestroyTemplateIds even if
-  /// we're at the end of a declaration. Instead, we defer the destruction until
-  /// after a top-level declaration.
-  /// Use DelayTemplateIdDestructionRAII rather than setting it directly.
-  bool DelayTemplateIdDestruction = false;
+  static NamedDecl *getNonTypeAnnotation(const Token &Tok) {
+    return static_cast<NamedDecl*>(Tok.getAnnotationValue());
+  }
 
-  void MaybeDestroyTemplateIds() {
-    if (DelayTemplateIdDestruction)
-      return;
-    if (!TemplateIds.empty() &&
-        (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens()))
-      DestroyTemplateIds();
+  static void setNonTypeAnnotation(Token &Tok, NamedDecl *ND) {
+    Tok.setAnnotationValue(ND);
   }
-  void DestroyTemplateIds();
 
-  /// RAII object to destroy TemplateIdAnnotations where possible, from a
-  /// likely-good position during parsing.
-  struct DestroyTemplateIdAnnotationsRAIIObj {
-    Parser &Self;
+  static IdentifierInfo *getIdentifierAnnotation(const Token &Tok) {
+    return static_cast<IdentifierInfo*>(Tok.getAnnotationValue());
+  }
 
-    DestroyTemplateIdAnnotationsRAIIObj(Parser &Self) : Self(Self) {}
-    ~DestroyTemplateIdAnnotationsRAIIObj() { Self.MaybeDestroyTemplateIds(); }
-  };
+  static void setIdentifierAnnotation(Token &Tok, IdentifierInfo *ND) {
+    Tok.setAnnotationValue(ND);
+  }
 
-  struct DelayTemplateIdDestructionRAII {
-    Parser &Self;
-    bool PrevDelayTemplateIdDestruction;
+  /// Read an already-translated primary expression out of an annotation
+  /// token.
+  static ExprResult getExprAnnotation(const Token &Tok) {
+    return ExprResult::getFromOpaquePointer(Tok.getAnnotationValue());
+  }
 
-    DelayTemplateIdDestructionRAII(Parser &Self,
-                                   bool DelayTemplateIdDestruction) noexcept
-        : Self(Self),
-          PrevDelayTemplateIdDestruction(Self.DelayTemplateIdDestruction) {
-      Self.DelayTemplateIdDestruction = DelayTemplateIdDestruction;
-    }
+  /// Set the primary expression corresponding to the given annotation
+  /// token.
+  static void setExprAnnotation(Token &Tok, ExprResult ER) {
+    Tok.setAnnotationValue(ER.getAsOpaquePointer());
+  }
 
-    ~DelayTemplateIdDestructionRAII() noexcept {
-      Self.DelayTemplateIdDestruction = PrevDelayTemplateIdDestruction;
-    }
-  };
+  /// Attempt to classify the name at the current token position. This may
+  /// form a type, scope or primary expression annotation, or replace the token
+  /// with a typo-corrected keyword. This is only appropriate when the current
+  /// name must refer to an entity which has already been declared.
+  ///
+  /// \param CCC Indicates how to perform typo-correction for this name. If NULL,
+  ///        no typo correction will be performed.
+  /// \param AllowImplicitTypename Whether we are in a context where a dependent
+  ///        nested-name-specifier without typename is treated as a type (e.g.
+  ///        T::type).
+  AnnotatedNameKind
+  TryAnnotateName(CorrectionCandidateCallback *CCC = nullptr,
+                  ImplicitTypenameContext AllowImplicitTypename =
+                      ImplicitTypenameContext::No);
 
-  /// Identifiers which have been declared within a tentative parse.
-  SmallVector<const IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
+  /// Push a tok::annot_cxxscope token onto the token stream.
+  void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
 
-  /// Tracker for '<' tokens that might have been intended to be treated as an
-  /// angle bracket instead of a less-than comparison.
+  /// TryKeywordIdentFallback - For compatibility with system headers using
+  /// keywords as identifiers, attempt to convert the current token to an
+  /// identifier and optionally disable the keyword for the remainder of the
+  /// translation unit. This returns false if the token was not replaced,
+  /// otherwise emits a diagnostic and returns true.
+  bool TryKeywordIdentFallback(bool DisableKeyword);
+
+  /// Get the TemplateIdAnnotation from the token and put it in the
+  /// cleanup pool so that it gets destroyed when parsing the current top level
+  /// declaration is finished.
+  TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
+
+  /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
+  /// input.  If so, it is consumed and false is returned.
   ///
-  /// This happens when the user intends to form a template-id, but typoes the
-  /// template-name or forgets a 'template' keyword for a dependent template
-  /// name.
+  /// If a trivial punctuator misspelling is encountered, a FixIt error
+  /// diagnostic is issued and false is returned after recovery.
   ///
-  /// We track these locations from the point where we see a '<' with a
-  /// name-like expression on its left until we see a '>' or '>>' that might
-  /// match it.
-  struct AngleBracketTracker {
-    /// Flags used to rank candidate template names when there is more than one
-    /// '<' in a scope.
-    enum Priority : unsigned short {
-      /// A non-dependent name that is a potential typo for a template name.
-      PotentialTypo = 0x0,
-      /// A dependent name that might instantiate to a template-name.
-      DependentName = 0x2,
-
-      /// A space appears before the '<' token.
-      SpaceBeforeLess = 0x0,
-      /// No space before the '<' token
-      NoSpaceBeforeLess = 0x1,
+  /// If the input is malformed, this emits the specified diagnostic and true is
+  /// returned.
+  bool ExpectAndConsume(tok::TokenKind ExpectedTok,
+                        unsigned Diag = diag::err_expected,
+                        StringRef DiagMsg = "");
 
-      LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ DependentName)
-    };
+  /// The parser expects a semicolon and, if present, will consume it.
+  ///
+  /// If the next token is not a semicolon, this emits the specified diagnostic,
+  /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
+  /// to the semicolon, consumes that extra token.
+  bool ExpectAndConsumeSemi(unsigned DiagID , StringRef TokenUsed = "");
 
-    struct Loc {
-      Expr *TemplateName;
-      SourceLocation LessLoc;
-      AngleBracketTracker::Priority Priority;
-      unsigned short ParenCount, BracketCount, BraceCount;
+  /// Consume any extra semi-colons until the end of the line.
+  void ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST T = TST_unspecified);
 
-      bool isActive(Parser &P) const {
-        return P.ParenCount == ParenCount && P.BracketCount == BracketCount &&
-               P.BraceCount == BraceCount;
-      }
+  /// Return false if the next token is an identifier. An 'expected identifier'
+  /// error is emitted otherwise.
+  ///
+  /// The parser tries to recover from the error by checking if the next token
+  /// is a C++ keyword when parsing Objective-C++. Return false if the recovery
+  /// was successful.
+  bool expectIdentifier();
 
-      bool isActiveOrNested(Parser &P) const {
-        return isActive(P) || P.ParenCount > ParenCount ||
-               P.BracketCount > BracketCount || P.BraceCount > BraceCount;
-      }
-    };
+  /// Kinds of compound pseudo-tokens formed by a sequence of two real tokens.
+  enum class CompoundToken {
+    /// A '(' '{' beginning a statement-expression.
+    StmtExprBegin,
+    /// A '}' ')' ending a statement-expression.
+    StmtExprEnd,
+    /// A '[' '[' beginning a C++11 or C23 attribute.
+    AttrBegin,
+    /// A ']' ']' ending a C++11 or C23 attribute.
+    AttrEnd,
+    /// A '::' '*' forming a C++ pointer-to-member declaration.
+    MemberPtr,
+  };
 
-    SmallVector<Loc, 8> Locs;
+  /// Check that a compound operator was written in a "sensible" way, and warn
+  /// if not.
+  void checkCompoundToken(SourceLocation FirstTokLoc,
+                          tok::TokenKind FirstTokKind, CompoundToken Op);
 
-    /// Add an expression that might have been intended to be a template name.
-    /// In the case of ambiguity, we arbitrarily select the innermost such
-    /// expression, for example in 'foo < bar < baz', 'bar' is the current
-    /// candidate. No attempt is made to track that 'foo' is also a candidate
-    /// for the case where we see a second suspicious '>' token.
-    void add(Parser &P, Expr *TemplateName, SourceLocation LessLoc,
-             Priority Prio) {
-      if (!Locs.empty() && Locs.back().isActive(P)) {
-        if (Locs.back().Priority <= Prio) {
-          Locs.back().TemplateName = TemplateName;
-          Locs.back().LessLoc = LessLoc;
-          Locs.back().Priority = Prio;
-        }
-      } else {
-        Locs.push_back({TemplateName, LessLoc, Prio,
-                        P.ParenCount, P.BracketCount, P.BraceCount});
-      }
-    }
+  void diagnoseUseOfC11Keyword(const Token &Tok);
 
-    /// Mark the current potential missing template location as having been
-    /// handled (this happens if we pass a "corresponding" '>' or '>>' token
-    /// or leave a bracket scope).
-    void clear(Parser &P) {
-      while (!Locs.empty() && Locs.back().isActiveOrNested(P))
-        Locs.pop_back();
-    }
+  /// RAII object used to modify the scope flags for the current scope.
+  class ParseScopeFlags {
+    Scope *CurScope;
+    unsigned OldFlags = 0;
+    ParseScopeFlags(const ParseScopeFlags &) = delete;
+    void operator=(const ParseScopeFlags &) = delete;
 
-    /// Get the current enclosing expression that might hve been intended to be
-    /// a template name.
-    Loc *getCurrent(Parser &P) {
-      if (!Locs.empty() && Locs.back().isActive(P))
-        return &Locs.back();
-      return nullptr;
-    }
+  public:
+    /// Set the flags for the current scope to ScopeFlags. If ManageFlags is false,
+    /// this object does nothing.
+    ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true);
+    
+    /// Restore the flags for the current scope to what they were before this
+    /// object overrode them.
+    ~ParseScopeFlags();
   };
 
-  AngleBracketTracker AngleBrackets;
+  /// Emits a diagnostic suggesting parentheses surrounding a
+  /// given range.
+  ///
+  /// \param Loc The location where we'll emit the diagnostic.
+  /// \param DK The kind of diagnostic to emit.
+  /// \param ParenRange Source range enclosing code that should be parenthesized.
+  void SuggestParentheses(SourceLocation Loc, unsigned DK,
+    SourceRange ParenRange);
 
-  IdentifierInfo *getSEHExceptKeyword();
-
-  /// True if we are within an Objective-C container while parsing C-like decls.
+  //===--------------------------------------------------------------------===//
+  // C99 6.9: External Definitions.
+  
+  /// ParseExternalDeclaration:
   ///
-  /// This is necessary because Sema thinks we have left the container
-  /// to parse the C-like decls, meaning Actions.ObjC().getObjCDeclContext()
-  /// will be NULL.
-  bool ParsingInObjCContainer;
+  /// The `Attrs` that are passed in are C++11 attributes and appertain to the
+  /// declaration.
+  ///
+  ///       external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
+  ///         function-definition
+  ///         declaration
+  /// [GNU]   asm-definition
+  /// [GNU]   __extension__ external-declaration
+  /// [OBJC]  objc-class-definition
+  /// [OBJC]  objc-class-declaration
+  /// [OBJC]  objc-alias-declaration
+  /// [OBJC]  objc-protocol-definition
+  /// [OBJC]  objc-method-definition
+  /// [OBJC]  @end
+  /// [C++]   linkage-specification
+  /// [GNU] asm-definition:
+  ///         simple-asm-expr ';'
+  /// [C++11] empty-declaration
+  /// [C++11] attribute-declaration
+  ///
+  /// [C++11] empty-declaration:
+  ///           ';'
+  ///
+  /// [C++0x/GNU] 'extern' 'template' declaration
+  ///
+  /// [C++20] module-import-declaration
+  ///
+  DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &DeclAttrs,
+                                          ParsedAttributes &DeclSpecAttrs,
+                                          ParsingDeclSpec *DS = nullptr);
+  
+  /// Determine whether the current token, if it occurs after a
+  /// declarator, continues a declaration or declaration list.
+  bool isDeclarationAfterDeclarator();
+  
+  /// Determine whether the current token, if it occurs after a
+  /// declarator, indicates the start of a function definition.
+  bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
 
-  /// Whether to skip parsing of function bodies.
+  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
+      ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,
+      ParsingDeclSpec *DS = nullptr, AccessSpecifier AS = AS_none);
+  
+  /// Parse either a function-definition or a declaration.  We can't tell which
+  /// we have until we read up to the compound-statement in function-definition.
+  /// TemplateParams, if non-NULL, provides the template parameters when we're
+  /// parsing a C++ template-declaration.
   ///
-  /// This option can be used, for example, to speed up searches for
-  /// declarations/definitions when indexing.
-  bool SkipFunctionBodies;
+  ///       function-definition: [C99 6.9.1]
+  ///         decl-specs      declarator declaration-list[opt] compound-statement
+  /// [C90] function-definition: [C99 6.7.1] - implicit int result
+  /// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
+  ///
+  ///       declaration: [C99 6.7]
+  ///         declaration-specifiers init-declarator-list[opt] ';'
+  /// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode]
+  /// [OMP]   threadprivate-directive
+  /// [OMP]   allocate-directive                         [TODO]
+  ///
+  DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributes &Attrs,
+                                                ParsedAttributes &DeclSpecAttrs,
+                                                ParsingDeclSpec &DS,
+                                                AccessSpecifier AS);
 
-  /// The location of the expression statement that is being parsed right now.
-  /// Used to determine if an expression that is being parsed is a statement or
-  /// just a regular sub-expression.
-  SourceLocation ExprStatementTokLoc;
+  void SkipFunctionBody();
 
-  /// Flags describing a context in which we're parsing a statement.
-  enum class ParsedStmtContext {
-    /// This context permits declarations in language modes where declarations
-    /// are not statements.
-    AllowDeclarationsInC = 0x1,
-    /// This context permits standalone OpenMP directives.
-    AllowStandaloneOpenMPDirectives = 0x2,
-    /// This context is at the top level of a GNU statement expression.
-    InStmtExpr = 0x4,
+  struct ParsedTemplateInfo;
+  class LateParsedAttrList;
 
-    /// The context of a regular substatement.
-    SubStmt = 0,
-    /// The context of a compound-statement.
-    Compound = AllowDeclarationsInC | AllowStandaloneOpenMPDirectives,
+  /// ParseFunctionDefinition - We parsed and verified that the specified
+  /// Declarator is well formed.  If this is a K&R-style function, read the
+  /// parameters declaration-list, then start the compound-statement.
+  ///
+  ///       function-definition: [C99 6.9.1]
+  ///         decl-specs      declarator declaration-list[opt] compound-statement
+  /// [C90] function-definition: [C99 6.7.1] - implicit int result
+  /// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
+  /// [C++] function-definition: [C++ 8.4]
+  ///         decl-specifier-seq[opt] declarator ctor-initializer[opt]
+  ///         function-body
+  /// [C++] function-definition: [C++ 8.4]
+  ///         decl-specifier-seq[opt] declarator function-try-block
+  ///
+  Decl *ParseFunctionDefinition(ParsingDeclarator &D,
+                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                 LateParsedAttrList *LateParsedAttrs = nullptr);
 
-    LLVM_MARK_AS_BITMASK_ENUM(InStmtExpr)
-  };
+  /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
+  /// types for a function with a K&R-style identifier list for arguments.
+  void ParseKNRParamDeclarations(Declarator &D);
 
-  /// Act on an expression statement that might be the last statement in a
-  /// GNU statement expression. Checks whether we are actually at the end of
-  /// a statement expression and builds a suitable expression statement.
-  StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx);
+  /// ParseSimpleAsm
+  ///
+  /// [GNU] simple-asm-expr:
+  ///         'asm' '(' asm-string-literal ')'
+  ///
+  /// EndLoc is filled with the location of the last token of the simple-asm.
+  ExprResult ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc);
+  
+  /// ParseAsmStringLiteral - This is just a normal string-literal, but is not
+  /// allowed to be a wide string, and is not subject to character translation.
+  /// Unlike GCC, we also diagnose an empty string literal when parsing for an
+  /// asm label as opposed to an asm statement, because such a construct does not
+  /// behave well.
+  ///
+  /// [GNU] asm-string-literal:
+  ///         string-literal
+  ///
+  ExprResult ParseAsmStringLiteral(bool ForAsmLabel);
 
-public:
-  Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
-  ~Parser() override;
+  /// Describes the condition of a Microsoft __if_exists or
+  /// __if_not_exists block.
+  struct IfExistsCondition {
+    /// The location of the initial keyword.
+    SourceLocation KeywordLoc;
+    /// Whether this is an __if_exists block (rather than an
+    /// __if_not_exists block).
+    bool IsIfExists;
 
-  const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
-  const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
-  Preprocessor &getPreprocessor() const { return PP; }
-  Sema &getActions() const { return Actions; }
-  AttributeFactory &getAttrFactory() { return AttrFactory; }
+    /// Nested-name-specifier preceding the name.
+    CXXScopeSpec SS;
 
-  const Token &getCurToken() const { return Tok; }
-  Scope *getCurScope() const { return Actions.getCurScope(); }
-  void incrementMSManglingNumber() const {
-    return Actions.incrementMSManglingNumber();
-  }
+    /// The name we're looking for.
+    UnqualifiedId Name;
 
-  ObjCContainerDecl *getObjCDeclContext() const {
-    return Actions.ObjC().getObjCDeclContext();
-  }
+    /// The behavior of this __if_exists or __if_not_exists block
+    /// should.
+    IfExistsBehavior Behavior;
+  };
 
-  // Type forwarding.  All of these are statically 'void*', but they may all be
-  // different actual classes based on the actions in place.
-  typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
-  typedef OpaquePtr<TemplateName> TemplateTy;
+  bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result);
+  void ParseMicrosoftIfExistsExternalDeclaration();
 
-  typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
+  //===--------------------------------------------------------------------===//
+  // Modules
+  
+  /// Parse a declaration beginning with the 'module' keyword or C++20
+  /// context-sensitive keyword (optionally preceded by 'export').
+  ///
+  ///   module-declaration:   [C++20]
+  ///     'export'[opt] 'module' module-name attribute-specifier-seq[opt] ';'
+  ///
+  ///   global-module-fragment:  [C++2a]
+  ///     'module' ';' top-level-declaration-seq[opt]
+  ///   module-declaration:      [C++2a]
+  ///     'export'[opt] 'module' module-name module-partition[opt]
+  ///            attribute-specifier-seq[opt] ';'
+  ///   private-module-fragment: [C++2a]
+  ///     'module' ':' 'private' ';' top-level-declaration-seq[opt]
+  DeclGroupPtrTy ParseModuleDecl(Sema::ModuleImportState &ImportState);
 
-  typedef Sema::FullExprArg FullExprArg;
+  /// Parse a module import declaration. This is essentially the same for
+  /// Objective-C and C++20 except for the leading '@' (in ObjC) and the
+  /// trailing optional attributes (in C++).
+  ///
+  /// [ObjC]  @import declaration:
+  ///           '@' 'import' module-name ';'
+  /// [ModTS] module-import-declaration:
+  ///           'import' module-name attribute-specifier-seq[opt] ';'
+  /// [C++20] module-import-declaration:
+  ///           'export'[opt] 'import' module-name
+  ///                   attribute-specifier-seq[opt] ';'
+  ///           'export'[opt] 'import' module-partition
+  ///                   attribute-specifier-seq[opt] ';'
+  ///           'export'[opt] 'import' header-name
+  ///                   attribute-specifier-seq[opt] ';'
+  Decl *ParseModuleImport(SourceLocation AtLoc,
+                          Sema::ModuleImportState &ImportState);
 
-  /// A SmallVector of statements.
-  typedef SmallVector<Stmt *, 24> StmtVector;
+  /// Try recover parser when module annotation appears where it must not
+  /// be found.
+  /// \returns false if the recover was successful and parsing may be continued, or
+  /// true if parser must bail out to top level and handle the token there.
+  bool parseMisplacedModuleImport();
 
-  // Parsing methods.
+  bool tryParseMisplacedModuleImport() {
+    tok::TokenKind Kind = Tok.getKind();
+    if (Kind == tok::annot_module_begin || Kind == tok::annot_module_end ||
+        Kind == tok::annot_module_include)
+      return parseMisplacedModuleImport();
+    return false;
+  }
 
-  /// Initialize - Warm up the parser.
+  /// Parse a C++ / Objective-C module name (both forms use the same
+  /// grammar).
   ///
-  void Initialize();
+  ///         module-name:
+  ///           module-name-qualifier[opt] identifier
+  ///         module-name-qualifier:
+  ///           module-name-qualifier[opt] identifier '.'
+  bool ParseModuleName(SourceLocation UseLoc,
+                       SmallVectorImpl<IdentifierLoc> &Path, bool IsImport);
 
-  /// Parse the first top-level declaration in a translation unit.
-  bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
-                              Sema::ModuleImportState &ImportState);
+  //===--------------------------------------------------------------------===//
+  // Preprocessor code-completion pass-through
+  void CodeCompleteDirective(bool InConditional) override;
+  void CodeCompleteInConditionalExclusion() override;
+  void CodeCompleteMacroName(bool IsDefinition) override;
+  void CodeCompletePreprocessorExpression() override;
+  void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
+                                 unsigned ArgumentIndex) override;
+  void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) override;
+  void CodeCompleteNaturalLanguage() override;
 
-  /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
-  /// the EOF was encountered.
-  bool ParseTopLevelDecl(DeclGroupPtrTy &Result,
-                         Sema::ModuleImportState &ImportState);
-  bool ParseTopLevelDecl() {
-    DeclGroupPtrTy Result;
-    Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
-    return ParseTopLevelDecl(Result, IS);
-  }
+  ///@}
 
-  /// ConsumeToken - Consume the current 'peek token' and lex the next one.
-  /// This does not work with special tokens: string literals, code completion,
-  /// annotation tokens and balanced tokens must be handled using the specific
-  /// consume methods.
-  /// Returns the location of the consumed token.
-  SourceLocation ConsumeToken() {
-    assert(!isTokenSpecial() &&
-           "Should consume special tokens with Consume*Token");
-    PrevTokLocation = Tok.getLocation();
-    PP.Lex(Tok);
-    return PrevTokLocation;
-  }
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-  bool TryConsumeToken(tok::TokenKind Expected) {
-    if (Tok.isNot(Expected))
-      return false;
-    assert(!isTokenSpecial() &&
-           "Should consume special tokens with Consume*Token");
-    PrevTokLocation = Tok.getLocation();
-    PP.Lex(Tok);
-    return true;
-  }
+  /// \name Parser Entry Point
+  /// Implementations are in ParseAST.cpp
+  ///@{
 
-  bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
-    if (!TryConsumeToken(Expected))
-      return false;
-    Loc = PrevTokLocation;
-    return true;
-  }
+  public:
 
-  /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
-  /// current token type.  This should only be used in cases where the type of
-  /// the token really isn't known, e.g. in error recovery.
-  SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
-    if (isTokenParen())
-      return ConsumeParen();
-    if (isTokenBracket())
-      return ConsumeBracket();
-    if (isTokenBrace())
-      return ConsumeBrace();
-    if (isTokenStringLiteral())
-      return ConsumeStringToken();
-    if (Tok.is(tok::code_completion))
-      return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
-                                      : handleUnexpectedCodeCompletionToken();
-    if (Tok.isAnnotation())
-      return ConsumeAnnotationToken();
-    return ConsumeToken();
-  }
+  private:
 
+  ///@}
 
-  SourceLocation getEndOfPreviousToken() {
-    return PP.getLocForEndOfToken(PrevTokLocation);
-  }
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-  /// Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds
-  /// to the given nullability kind.
-  IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability) {
-    return Actions.getNullabilityKeyword(nullability);
-  }
+  /// \name C++ Class Inline Methods
+  /// Implementations are in ParseCXXInlineMethods.cpp
+  ///@{
+
+  public:
+
+  private:
 
-private:
   //===--------------------------------------------------------------------===//
-  // Low-Level token peeking and consumption methods.
-  //
+  // Lexing and parsing of C++ inline methods.
 
-  /// isTokenParen - Return true if the cur token is '(' or ')'.
-  bool isTokenParen() const {
-    return Tok.isOneOf(tok::l_paren, tok::r_paren);
-  }
-  /// isTokenBracket - Return true if the cur token is '[' or ']'.
-  bool isTokenBracket() const {
-    return Tok.isOneOf(tok::l_square, tok::r_square);
-  }
-  /// isTokenBrace - Return true if the cur token is '{' or '}'.
-  bool isTokenBrace() const {
-    return Tok.isOneOf(tok::l_brace, tok::r_brace);
-  }
-  /// isTokenStringLiteral - True if this token is a string-literal.
-  bool isTokenStringLiteral() const {
-    return tok::isStringLiteral(Tok.getKind());
-  }
-  /// isTokenSpecial - True if this token requires special consumption methods.
-  bool isTokenSpecial() const {
-    return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
-           isTokenBrace() || Tok.is(tok::code_completion) || Tok.isAnnotation();
-  }
+  struct ParsingClass;
 
-  /// Returns true if the current token is '=' or is a type of '='.
-  /// For typos, give a fixit to '='
-  bool isTokenEqualOrEqualTypo();
+  /// [class.mem]p1: "... the class is regarded as complete within
+  /// - function bodies
+  /// - default arguments
+  /// - exception-specifications (TODO: C++0x)
+  /// - and brace-or-equal-initializers for non-static data members
+  /// (including such things in nested classes)."
+  /// LateParsedDeclarations build the tree of those elements so they can
+  /// be parsed after parsing the top-level class.
+  class LateParsedDeclaration {
+  public:
+    virtual ~LateParsedDeclaration();
 
-  /// Return the current token to the token stream and make the given
-  /// token the current token.
-  void UnconsumeToken(Token &Consumed) {
-      Token Next = Tok;
-      PP.EnterToken(Consumed, /*IsReinject*/true);
-      PP.Lex(Tok);
-      PP.EnterToken(Next, /*IsReinject*/true);
-  }
+    virtual void ParseLexedMethodDeclarations();
+    virtual void ParseLexedMemberInitializers();
+    virtual void ParseLexedMethodDefs();
+    virtual void ParseLexedAttributes();
+    virtual void ParseLexedPragmas();
+  };
 
-  SourceLocation ConsumeAnnotationToken() {
-    assert(Tok.isAnnotation() && "wrong consume method");
-    SourceLocation Loc = Tok.getLocation();
-    PrevTokLocation = Tok.getAnnotationEndLoc();
-    PP.Lex(Tok);
-    return Loc;
-  }
+  /// Inner node of the LateParsedDeclaration tree that parses
+  /// all its members recursively.
+  class LateParsedClass : public LateParsedDeclaration {
+  public:
+    LateParsedClass(Parser *P, ParsingClass *C);
+    ~LateParsedClass() override;
 
-  /// ConsumeParen - This consume method keeps the paren count up-to-date.
-  ///
-  SourceLocation ConsumeParen() {
-    assert(isTokenParen() && "wrong consume method");
-    if (Tok.getKind() == tok::l_paren)
-      ++ParenCount;
-    else if (ParenCount) {
-      AngleBrackets.clear(*this);
-      --ParenCount;       // Don't let unbalanced )'s drive the count negative.
-    }
-    PrevTokLocation = Tok.getLocation();
-    PP.Lex(Tok);
-    return PrevTokLocation;
-  }
+    void ParseLexedMethodDeclarations() override;
+    void ParseLexedMemberInitializers() override;
+    void ParseLexedMethodDefs() override;
+    void ParseLexedAttributes() override;
+    void ParseLexedPragmas() override;
 
-  /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
-  ///
-  SourceLocation ConsumeBracket() {
-    assert(isTokenBracket() && "wrong consume method");
-    if (Tok.getKind() == tok::l_square)
-      ++BracketCount;
-    else if (BracketCount) {
-      AngleBrackets.clear(*this);
-      --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
-    }
+    // Delete copy constructor and copy assignment operator.
+    LateParsedClass(const LateParsedClass &) = delete;
+    LateParsedClass &operator=(const LateParsedClass &) = delete;
 
-    PrevTokLocation = Tok.getLocation();
-    PP.Lex(Tok);
-    return PrevTokLocation;
-  }
+  private:
+    Parser *Self;
+    ParsingClass *Class;
+  };
 
-  /// ConsumeBrace - This consume method keeps the brace count up-to-date.
-  ///
-  SourceLocation ConsumeBrace() {
-    assert(isTokenBrace() && "wrong consume method");
-    if (Tok.getKind() == tok::l_brace)
-      ++BraceCount;
-    else if (BraceCount) {
-      AngleBrackets.clear(*this);
-      --BraceCount;     // Don't let unbalanced }'s drive the count negative.
-    }
+  /// Contains the lexed tokens of an attribute with arguments that
+  /// may reference member variables and so need to be parsed at the
+  /// end of the class declaration after parsing all other member
+  /// member declarations.
+  /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
+  /// LateParsedTokens.
+  struct LateParsedAttribute : public LateParsedDeclaration {
+    Parser *Self;
+    CachedTokens Toks;
+    IdentifierInfo &AttrName;
+    IdentifierInfo *MacroII = nullptr;
+    SourceLocation AttrNameLoc;
+    SmallVector<Decl*, 2> Decls;
 
-    PrevTokLocation = Tok.getLocation();
-    PP.Lex(Tok);
-    return PrevTokLocation;
-  }
+    explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
+                                 SourceLocation Loc)
+      : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
 
-  /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
-  /// and returning the token kind.  This method is specific to strings, as it
-  /// handles string literal concatenation, as per C99 5.1.1.2, translation
-  /// phase #6.
-  SourceLocation ConsumeStringToken() {
-    assert(isTokenStringLiteral() &&
-           "Should only consume string literals with this method");
-    PrevTokLocation = Tok.getLocation();
-    PP.Lex(Tok);
-    return PrevTokLocation;
-  }
+    void ParseLexedAttributes() override;
 
-  /// Consume the current code-completion token.
-  ///
-  /// This routine can be called to consume the code-completion token and
-  /// continue processing in special cases where \c cutOffParsing() isn't
-  /// desired, such as token caching or completion with lookahead.
-  SourceLocation ConsumeCodeCompletionToken() {
-    assert(Tok.is(tok::code_completion));
-    PrevTokLocation = Tok.getLocation();
-    PP.Lex(Tok);
-    return PrevTokLocation;
-  }
+    void addDecl(Decl *D) { Decls.push_back(D); }
+  };
 
-  /// When we are consuming a code-completion token without having matched
-  /// specific position in the grammar, provide code-completion results based
-  /// on context.
-  ///
-  /// \returns the source location of the code-completion token.
-  SourceLocation handleUnexpectedCodeCompletionToken();
+  /// Contains the lexed tokens of a pragma with arguments that
+  /// may reference member variables and so need to be parsed at the
+  /// end of the class declaration after parsing all other member
+  /// member declarations.
+  class LateParsedPragma : public LateParsedDeclaration {
+    Parser *Self = nullptr;
+    AccessSpecifier AS = AS_none;
+    CachedTokens Toks;
 
-  /// Abruptly cut off parsing; mainly used when we have reached the
-  /// code-completion point.
-  void cutOffParsing() {
-    if (PP.isCodeCompletionEnabled())
-      PP.setCodeCompletionReached();
-    // Cut off parsing by acting as if we reached the end-of-file.
-    Tok.setKind(tok::eof);
-  }
+  public:
+    explicit LateParsedPragma(Parser *P, AccessSpecifier AS)
+        : Self(P), AS(AS) {}
 
-  /// Determine if we're at the end of the file or at a transition
-  /// between modules.
-  bool isEofOrEom() {
-    tok::TokenKind Kind = Tok.getKind();
-    return Kind == tok::eof || Kind == tok::annot_module_begin ||
-           Kind == tok::annot_module_end || Kind == tok::annot_module_include ||
-           Kind == tok::annot_repl_input_end;
-  }
+    void takeToks(CachedTokens &Cached) { Toks.swap(Cached); }
+    const CachedTokens &toks() const { return Toks; }
+    AccessSpecifier getAccessSpecifier() const { return AS; }
 
-  /// Checks if the \p Level is valid for use in a fold expression.
-  bool isFoldOperator(prec::Level Level) const;
+    void ParseLexedPragmas() override;
+  };
 
-  /// Checks if the \p Kind is a valid operator for fold expressions.
-  bool isFoldOperator(tok::TokenKind Kind) const;
+  // A list of late-parsed attributes.  Used by ParseGNUAttributes.
+  class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
+  public:
+    LateParsedAttrList(bool PSoon = false,
+                       bool LateAttrParseExperimentalExtOnly = false)
+        : ParseSoon(PSoon),
+          LateAttrParseExperimentalExtOnly(LateAttrParseExperimentalExtOnly) {}
 
-  /// Initialize all pragma handlers.
-  void initializePragmaHandlers();
+    bool parseSoon() { return ParseSoon; }
+    /// returns true iff the attribute to be parsed should only be late parsed
+    /// if it is annotated with `LateAttrParseExperimentalExt`
+    bool lateAttrParseExperimentalExtOnly() {
+      return LateAttrParseExperimentalExtOnly;
+    }
 
-  /// Destroy and reset all pragma handlers.
-  void resetPragmaHandlers();
+  private:
+    bool ParseSoon; // Are we planning to parse these shortly after creation?
+    bool LateAttrParseExperimentalExtOnly;
+  };
 
-  /// Handle the annotation token produced for #pragma unused(...)
-  void HandlePragmaUnused();
+  /// Contains the lexed tokens of a member function definition
+  /// which needs to be parsed at the end of the class declaration
+  /// after parsing all other member declarations.
+  struct LexedMethod : public LateParsedDeclaration {
+    Parser *Self;
+    Decl *D;
+    CachedTokens Toks;
 
-  /// Handle the annotation token produced for
-  /// #pragma GCC visibility...
-  void HandlePragmaVisibility();
+    explicit LexedMethod(Parser *P, Decl *MD) : Self(P), D(MD) {}
 
-  /// Handle the annotation token produced for
-  /// #pragma pack...
-  void HandlePragmaPack();
+    void ParseLexedMethodDefs() override;
+  };
 
-  /// Handle the annotation token produced for
-  /// #pragma ms_struct...
-  void HandlePragmaMSStruct();
+  /// LateParsedDefaultArgument - Keeps track of a parameter that may
+  /// have a default argument that cannot be parsed yet because it
+  /// occurs within a member function declaration inside the class
+  /// (C++ [class.mem]p2).
+  struct LateParsedDefaultArgument {
+    explicit LateParsedDefaultArgument(Decl *P,
+                                       std::unique_ptr<CachedTokens> Toks = nullptr)
+      : Param(P), Toks(std::move(Toks)) { }
 
-  void HandlePragmaMSPointersToMembers();
+    /// Param - The parameter declaration for this parameter.
+    Decl *Param;
 
-  void HandlePragmaMSVtorDisp();
+    /// Toks - The sequence of tokens that comprises the default
+    /// argument expression, not including the '=' or the terminating
+    /// ')' or ','. This will be NULL for parameters that have no
+    /// default argument.
+    std::unique_ptr<CachedTokens> Toks;
+  };
 
-  void HandlePragmaMSPragma();
-  bool HandlePragmaMSSection(StringRef PragmaName,
-                             SourceLocation PragmaLocation);
-  bool HandlePragmaMSSegment(StringRef PragmaName,
-                             SourceLocation PragmaLocation);
-  bool HandlePragmaMSInitSeg(StringRef PragmaName,
-                             SourceLocation PragmaLocation);
-  bool HandlePragmaMSStrictGuardStackCheck(StringRef PragmaName,
-                                           SourceLocation PragmaLocation);
-  bool HandlePragmaMSFunction(StringRef PragmaName,
-                              SourceLocation PragmaLocation);
-  bool HandlePragmaMSAllocText(StringRef PragmaName,
-                               SourceLocation PragmaLocation);
-  bool HandlePragmaMSOptimize(StringRef PragmaName,
-                              SourceLocation PragmaLocation);
+  /// LateParsedMethodDeclaration - A method declaration inside a class that
+  /// contains at least one entity whose parsing needs to be delayed
+  /// until the class itself is completely-defined, such as a default
+  /// argument (C++ [class.mem]p2).
+  struct LateParsedMethodDeclaration : public LateParsedDeclaration {
+    explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
+        : Self(P), Method(M), ExceptionSpecTokens(nullptr) {}
 
-  /// Handle the annotation token produced for
-  /// #pragma align...
-  void HandlePragmaAlign();
+    void ParseLexedMethodDeclarations() override;
 
-  /// Handle the annotation token produced for
-  /// #pragma clang __debug dump...
-  void HandlePragmaDump();
+    Parser *Self;
 
-  /// Handle the annotation token produced for
-  /// #pragma weak id...
-  void HandlePragmaWeak();
+    /// Method - The method declaration.
+    Decl *Method;
 
-  /// Handle the annotation token produced for
-  /// #pragma weak id = id...
-  void HandlePragmaWeakAlias();
+    /// DefaultArgs - Contains the parameters of the function and
+    /// their default arguments. At least one of the parameters will
+    /// have a default argument, but all of the parameters of the
+    /// method will be stored so that they can be reintroduced into
+    /// scope at the appropriate times.
+    SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
 
-  /// Handle the annotation token produced for
-  /// #pragma redefine_extname...
-  void HandlePragmaRedefineExtname();
+    /// The set of tokens that make up an exception-specification that
+    /// has not yet been parsed.
+    CachedTokens *ExceptionSpecTokens;
+  };
 
-  /// Handle the annotation token produced for
-  /// #pragma STDC FP_CONTRACT...
-  void HandlePragmaFPContract();
+  /// LateParsedMemberInitializer - An initializer for a non-static class data
+  /// member whose parsing must to be delayed until the class is completely
+  /// defined (C++11 [class.mem]p2).
+  struct LateParsedMemberInitializer : public LateParsedDeclaration {
+    LateParsedMemberInitializer(Parser *P, Decl *FD)
+      : Self(P), Field(FD) { }
 
-  /// Handle the annotation token produced for
-  /// #pragma STDC FENV_ACCESS...
-  void HandlePragmaFEnvAccess();
+    void ParseLexedMemberInitializers() override;
 
-  /// Handle the annotation token produced for
-  /// #pragma STDC FENV_ROUND...
-  void HandlePragmaFEnvRound();
+    Parser *Self;
 
-  /// Handle the annotation token produced for
-  /// #pragma STDC CX_LIMITED_RANGE...
-  void HandlePragmaCXLimitedRange();
+    /// Field - The field declaration.
+    Decl *Field;
 
-  /// Handle the annotation token produced for
-  /// #pragma float_control
-  void HandlePragmaFloatControl();
+    /// CachedTokens - The sequence of tokens that comprises the initializer,
+    /// including any leading '='.
+    CachedTokens Toks;
+  };
 
-  /// \brief Handle the annotation token produced for
-  /// #pragma clang fp ...
-  void HandlePragmaFP();
+  /// LateParsedDeclarationsContainer - During parsing of a top (non-nested)
+  /// C++ class, its method declarations that contain parts that won't be
+  /// parsed until after the definition is completed (C++ [class.mem]p2),
+  /// the method declarations and possibly attached inline definitions
+  /// will be stored here with the tokens that will be parsed to create those
+  /// entities.
+  typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
 
-  /// Handle the annotation token produced for
-  /// #pragma OPENCL EXTENSION...
-  void HandlePragmaOpenCLExtension();
+  /// Utility to re-enter a possibly-templated scope while parsing its
+  /// late-parsed components.
+  struct ReenterTemplateScopeRAII;
+  
+  /// Utility to re-enter a class scope while parsing its late-parsed components.
+  struct ReenterClassScopeRAII;
 
-  /// Handle the annotation token produced for
-  /// #pragma clang __debug captured
-  StmtResult HandlePragmaCaptured();
+  /// ParseCXXInlineMethodDef - We parsed and verified that the specified
+  /// Declarator is a well formed C++ inline method definition. Now lex its body
+  /// and store its tokens for parsing after the C++ class is complete.
+  NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
+                                     const ParsedAttributesView &AccessAttrs,
+                                     ParsingDeclarator &D,
+                                     const ParsedTemplateInfo &TemplateInfo,
+                                     const VirtSpecifiers &VS,
+                                     SourceLocation PureSpecLoc);
 
-  /// Handle the annotation token produced for
-  /// #pragma clang loop and #pragma unroll.
-  bool HandlePragmaLoopHint(LoopHint &Hint);
+  /// Parse the optional ("message") part of a deleted-function-body.
+  StringLiteral *ParseCXXDeletedFunctionMessage();
+  
+  /// If we've encountered '= delete' in a context where it is ill-formed, such
+  /// as in the declaration of a non-function, also skip the ("message") part if
+  /// it is present to avoid issuing further diagnostics.
+  void SkipDeletedFunctionBody();
 
-  bool ParsePragmaAttributeSubjectMatchRuleSet(
-      attr::ParsedSubjectMatchRuleSet &SubjectMatchRules,
-      SourceLocation &AnyLoc, SourceLocation &LastMatchRuleEndLoc);
+  /// ParseCXXNonStaticMemberInitializer - We parsed and verified that the
+  /// specified Declarator is a well formed C++ non-static data member
+  /// declaration. Now lex its initializer and store its tokens for parsing
+  /// after the class is complete.
+  void ParseCXXNonStaticMemberInitializer(Decl *VarD);
 
-  void HandlePragmaAttribute();
+  /// Wrapper class which calls ParseLexedAttribute, after setting up the
+  /// scope appropriately.
+  void ParseLexedAttributes(ParsingClass &Class);
+  
+  /// Parse all attributes in LAs, and attach them to Decl D.
+  void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
+                               bool EnterScope, bool OnDefinition);
 
-  /// GetLookAheadToken - This peeks ahead N tokens and returns that token
-  /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
-  /// returns the token after Tok, etc.
+  /// Finish parsing an attribute for which parsing was delayed.
+  /// This will be called at the end of parsing a class declaration
+  /// for each LateParsedAttribute. We consume the saved tokens and
+  /// create an attribute with the arguments filled in. We add this
+  /// to the Attribute list for the decl.
+  void ParseLexedAttribute(LateParsedAttribute &LA,
+                           bool EnterScope, bool OnDefinition);
+
+  /// ParseLexedMethodDeclarations - We finished parsing the member
+  /// specification of a top (non-nested) C++ class. Now go over the
+  /// stack of method declarations with some parts for which parsing was
+  /// delayed (such as default arguments) and parse them.
+  void ParseLexedMethodDeclarations(ParsingClass &Class);
+  void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
+  
+  /// ParseLexedMethodDefs - We finished parsing the member specification of a top
+  /// (non-nested) C++ class. Now go over the stack of lexed methods that were
+  /// collected during its parsing and parse them all.
+  void ParseLexedMethodDefs(ParsingClass &Class);
+  void ParseLexedMethodDef(LexedMethod &LM);
+  
+  /// ParseLexedMemberInitializers - We finished parsing the member specification
+  /// of a top (non-nested) C++ class. Now go over the stack of lexed data member
+  /// initializers that were collected during its parsing and parse them all.
+  void ParseLexedMemberInitializers(ParsingClass &Class);
+  void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name Declarations
+  /// Implementations are in ParseDecl.cpp
+  ///@{
+
+  public:
+
+  /// SkipMalformedDecl - Read tokens until we get to some likely good stopping
+  /// point for skipping past a simple-declaration.
   ///
-  /// Note that this differs from the Preprocessor's LookAhead method, because
-  /// the Parser always has one token lexed that the preprocessor doesn't.
+  /// Skip until we reach something which seems like a sensible place to pick
+  /// up parsing after a malformed declaration. This will sometimes stop sooner
+  /// than SkipUntil(tok::r_brace) would, but will never stop later.
+  void SkipMalformedDecl();
+
+  /// ParseTypeName
+  ///       type-name: [C99 6.7.6]
+  ///         specifier-qualifier-list abstract-declarator[opt]
   ///
-  const Token &GetLookAheadToken(unsigned N) {
-    if (N == 0 || Tok.is(tok::eof)) return Tok;
-    return PP.LookAhead(N-1);
-  }
+  /// Called type-id in C++.
+  TypeResult
+  ParseTypeName(SourceRange *Range = nullptr,
+                DeclaratorContext Context = DeclaratorContext::TypeName,
+                AccessSpecifier AS = AS_none, Decl **OwnedType = nullptr,
+                ParsedAttributes *Attrs = nullptr);
 
-public:
-  /// NextToken - This peeks ahead one token and returns it without
-  /// consuming it.
-  const Token &NextToken() {
-    return PP.LookAhead(0);
-  }
+  private:
 
-  /// getTypeAnnotation - Read a parsed type out of an annotation token.
-  static TypeResult getTypeAnnotation(const Token &Tok) {
-    if (!Tok.getAnnotationValue())
-      return TypeError();
-    return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
-  }
+  /// Ident_vector, Ident_bool, Ident_Bool - cached IdentifierInfos for "vector"
+  /// and "bool" fast comparison.  Only present if AltiVec or ZVector are
+  /// enabled.
+  IdentifierInfo *Ident_vector;
+  IdentifierInfo *Ident_bool;
+  IdentifierInfo *Ident_Bool;
 
-private:
-  static void setTypeAnnotation(Token &Tok, TypeResult T) {
-    assert((T.isInvalid() || T.get()) &&
-           "produced a valid-but-null type annotation?");
-    Tok.setAnnotationValue(T.isInvalid() ? nullptr : T.get().getAsOpaquePtr());
-  }
+  /// Ident_pixel - cached IdentifierInfos for "pixel" fast comparison.
+  /// Only present if AltiVec enabled.
+  IdentifierInfo *Ident_pixel;
 
-  static NamedDecl *getNonTypeAnnotation(const Token &Tok) {
-    return static_cast<NamedDecl*>(Tok.getAnnotationValue());
-  }
+  /// Identifier for "introduced".
+  IdentifierInfo *Ident_introduced;
 
-  static void setNonTypeAnnotation(Token &Tok, NamedDecl *ND) {
-    Tok.setAnnotationValue(ND);
-  }
+  /// Identifier for "deprecated".
+  IdentifierInfo *Ident_deprecated;
 
-  static IdentifierInfo *getIdentifierAnnotation(const Token &Tok) {
-    return static_cast<IdentifierInfo*>(Tok.getAnnotationValue());
-  }
+  /// Identifier for "obsoleted".
+  IdentifierInfo *Ident_obsoleted;
 
-  static void setIdentifierAnnotation(Token &Tok, IdentifierInfo *ND) {
-    Tok.setAnnotationValue(ND);
-  }
+  /// Identifier for "unavailable".
+  IdentifierInfo *Ident_unavailable;
 
-  /// Read an already-translated primary expression out of an annotation
-  /// token.
-  static ExprResult getExprAnnotation(const Token &Tok) {
-    return ExprResult::getFromOpaquePointer(Tok.getAnnotationValue());
-  }
+  /// Identifier for "message".
+  IdentifierInfo *Ident_message;
 
-  /// Set the primary expression corresponding to the given annotation
-  /// token.
-  static void setExprAnnotation(Token &Tok, ExprResult ER) {
-    Tok.setAnnotationValue(ER.getAsOpaquePointer());
-  }
+  /// Identifier for "strict".
+  IdentifierInfo *Ident_strict;
 
-public:
-  // If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to
-  // find a type name by attempting typo correction.
-  bool
-  TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename =
-                                  ImplicitTypenameContext::No);
-  bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(
-      CXXScopeSpec &SS, bool IsNewScope,
-      ImplicitTypenameContext AllowImplicitTypename);
-  bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+  /// Identifier for "replacement".
+  IdentifierInfo *Ident_replacement;
 
-  bool MightBeCXXScopeToken() {
-    return getLangOpts().CPlusPlus &&
-           (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
-            (Tok.is(tok::annot_template_id) &&
-             NextToken().is(tok::coloncolon)) ||
-            Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super));
-  }
-  bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
-    return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
-  }
+  /// Identifier for "environment".
+  IdentifierInfo *Ident_environment;
 
-private:
-  AnnotatedNameKind
-  TryAnnotateName(CorrectionCandidateCallback *CCC = nullptr,
-                  ImplicitTypenameContext AllowImplicitTypename =
-                      ImplicitTypenameContext::No);
+  /// Identifiers used by the 'external_source_symbol' attribute.
+  IdentifierInfo *Ident_language, *Ident_defined_in,
+  *Ident_generated_declaration, *Ident_USR;
 
-  /// Push a tok::annot_cxxscope token onto the token stream.
-  void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
+  /// Factory object for creating ParsedAttr objects.
+  AttributeFactory AttrFactory;
 
   /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
   /// replacing them with the non-context-sensitive keywords.  This returns
@@ -1073,2935 +1472,7101 @@ class Parser : public CodeCompletionHandler {
     return TryAltiVecVectorTokenOutOfLine();
   }
 
+  /// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
+  /// from TryAltiVecVectorToken.
   bool TryAltiVecVectorTokenOutOfLine();
   bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
                                 const char *&PrevSpec, unsigned &DiagID,
                                 bool &isInvalid);
 
-  /// Returns true if the current token is the identifier 'instancetype'.
-  ///
-  /// Should only be used in Objective-C language modes.
-  bool isObjCInstancetype() {
-    assert(getLangOpts().ObjC);
-    if (Tok.isAnnotation())
-      return false;
-    if (!Ident_instancetype)
-      Ident_instancetype = PP.getIdentifierInfo("instancetype");
-    return Tok.getIdentifierInfo() == Ident_instancetype;
-  }
-
-  /// TryKeywordIdentFallback - For compatibility with system headers using
-  /// keywords as identifiers, attempt to convert the current token to an
-  /// identifier and optionally disable the keyword for the remainder of the
-  /// translation unit. This returns false if the token was not replaced,
-  /// otherwise emits a diagnostic and returns true.
-  bool TryKeywordIdentFallback(bool DisableKeyword);
+  void ParseLexedCAttributeList(LateParsedAttrList &LA, bool EnterScope,
+                                ParsedAttributes *OutAttrs = nullptr);
 
-  /// Get the TemplateIdAnnotation from the token.
-  TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
+  /// Finish parsing an attribute for which parsing was delayed.
+  /// This will be called at the end of parsing a class declaration
+  /// for each LateParsedAttribute. We consume the saved tokens and
+  /// create an attribute with the arguments filled in. We add this
+  /// to the Attribute list for the decl.
+  void ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
+                            ParsedAttributes *OutAttrs = nullptr);
+ 
+  void ParseLexedPragmas(ParsingClass &Class);
+  void ParseLexedPragma(LateParsedPragma &LP);
 
-  /// TentativeParsingAction - An object that is used as a kind of "tentative
-  /// parsing transaction". It gets instantiated to mark the token position and
-  /// after the token consumption is done, Commit() or Revert() is called to
-  /// either "commit the consumed tokens" or revert to the previously marked
-  /// token position. Example:
+  /// Consume tokens and store them in the passed token container until
+  /// we've passed the try keyword and constructor initializers and have consumed
+  /// the opening brace of the function body. The opening brace will be consumed
+  /// if and only if there was no error.
   ///
-  ///   TentativeParsingAction TPA(*this);
-  ///   ConsumeToken();
-  ///   ....
-  ///   TPA.Revert();
+  /// \return True on error.
+  bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
+  
+  /// ConsumeAndStoreInitializer - Consume and store the token at the passed token
+  /// container until the end of the current initializer expression (either a
+  /// default argument or an in-class initializer for a non-static data member).
   ///
-  /// If the Unannotated parameter is true, any token annotations created
-  /// during the tentative parse are reverted.
-  class TentativeParsingAction {
-    Parser &P;
-    PreferredTypeBuilder PrevPreferredType;
-    Token PrevTok;
-    size_t PrevTentativelyDeclaredIdentifierCount;
-    unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
-    bool isActive;
+  /// Returns \c true if we reached the end of something initializer-shaped,
+  /// \c false if we bailed out.
+  bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK);
+  
+  /// Consume and store tokens from the '?' to the ':' in a conditional
+  /// expression.
+  bool ConsumeAndStoreConditional(CachedTokens &Toks);
+  bool ConsumeAndStoreUntil(tok::TokenKind T1,
+                            CachedTokens &Toks,
+                            bool StopAtSemi = true,
+                            bool ConsumeFinalToken = true) {
+    return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
+  }
 
-  public:
-    explicit TentativeParsingAction(Parser &p, bool Unannotated = false)
-        : P(p), PrevPreferredType(P.PreferredType) {
-      PrevTok = P.Tok;
-      PrevTentativelyDeclaredIdentifierCount =
-          P.TentativelyDeclaredIdentifiers.size();
-      PrevParenCount = P.ParenCount;
-      PrevBracketCount = P.BracketCount;
-      PrevBraceCount = P.BraceCount;
-      P.PP.EnableBacktrackAtThisPos(Unannotated);
-      isActive = true;
-    }
-    void Commit() {
-      assert(isActive && "Parsing action was finished!");
-      P.TentativelyDeclaredIdentifiers.resize(
-          PrevTentativelyDeclaredIdentifierCount);
-      P.PP.CommitBacktrackedTokens();
-      isActive = false;
-    }
-    void Revert() {
-      assert(isActive && "Parsing action was finished!");
-      P.PP.Backtrack();
-      P.PreferredType = PrevPreferredType;
-      P.Tok = PrevTok;
-      P.TentativelyDeclaredIdentifiers.resize(
-          PrevTentativelyDeclaredIdentifierCount);
-      P.ParenCount = PrevParenCount;
-      P.BracketCount = PrevBracketCount;
-      P.BraceCount = PrevBraceCount;
-      isActive = false;
-    }
-    ~TentativeParsingAction() {
-      assert(!isActive && "Forgot to call Commit or Revert!");
-    }
-  };
-  /// A TentativeParsingAction that automatically reverts in its destructor.
-  /// Useful for disambiguation parses that will always be reverted.
-  class RevertingTentativeParsingAction
-      : private Parser::TentativeParsingAction {
-  public:
-    using TentativeParsingAction::TentativeParsingAction;
-
-    ~RevertingTentativeParsingAction() { Revert(); }
-  };
+  /// ConsumeAndStoreUntil - Consume and store the token at the passed token
+  /// container until the token 'T' is reached (which gets
+  /// consumed/stored too, if ConsumeFinalToken).
+  /// If StopAtSemi is true, then we will stop early at a ';' character.
+  /// Returns true if token 'T1' or 'T2' was found.
+  /// NOTE: This is a specialized version of Parser::SkipUntil.
+  bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
+                            CachedTokens &Toks,
+                            bool StopAtSemi = true,
+                            bool ConsumeFinalToken = true);
+ 
+  //===--------------------------------------------------------------------===//
+  // C99 6.7: Declarations.
 
-  /// ObjCDeclContextSwitch - An object used to switch context from
-  /// an objective-c decl context to its enclosing decl context and
-  /// back.
-  class ObjCDeclContextSwitch {
-    Parser &P;
-    ObjCContainerDecl *DC;
-    SaveAndRestore<bool> WithinObjCContainer;
-  public:
-    explicit ObjCDeclContextSwitch(Parser &p)
-      : P(p), DC(p.getObjCDeclContext()),
-        WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
-      if (DC)
-        P.Actions.ObjC().ActOnObjCTemporaryExitContainerContext(DC);
-    }
-    ~ObjCDeclContextSwitch() {
-      if (DC)
-        P.Actions.ObjC().ActOnObjCReenterContainerContext(DC);
-    }
+  /// A context for parsing declaration specifiers.  TODO: flesh this
+  /// out, there are other significant restrictions on specifiers than
+  /// would be best implemented in the parser.
+  enum class DeclSpecContext {
+    DSC_normal,         // normal context
+    DSC_class,          // class context, enables 'friend'
+    DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
+    DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
+    DSC_alias_declaration,  // C++11 type-specifier-seq in an alias-declaration
+    DSC_conv_operator,      // C++ type-specifier-seq in an conversion operator
+    DSC_top_level,          // top-level/namespace declaration context
+    DSC_template_param,     // template parameter context
+    DSC_template_arg,       // template argument context
+    DSC_template_type_arg,  // template type argument context
+    DSC_objc_method_result, // ObjC method result context, enables
+                            // 'instancetype'
+    DSC_condition,          // condition declaration context
+    DSC_association, // A _Generic selection expression's type association
+    DSC_new,         // C++ new expression
   };
 
-  /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
-  /// input.  If so, it is consumed and false is returned.
-  ///
-  /// If a trivial punctuator misspelling is encountered, a FixIt error
-  /// diagnostic is issued and false is returned after recovery.
-  ///
-  /// If the input is malformed, this emits the specified diagnostic and true is
-  /// returned.
-  bool ExpectAndConsume(tok::TokenKind ExpectedTok,
-                        unsigned Diag = diag::err_expected,
-                        StringRef DiagMsg = "");
-
-  /// The parser expects a semicolon and, if present, will consume it.
-  ///
-  /// If the next token is not a semicolon, this emits the specified diagnostic,
-  /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
-  /// to the semicolon, consumes that extra token.
-  bool ExpectAndConsumeSemi(unsigned DiagID , StringRef TokenUsed = "");
-
-  /// Consume any extra semi-colons until the end of the line.
-  void ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST T = TST_unspecified);
+  /// Is this a context in which we are parsing just a type-specifier (or
+  /// trailing-type-specifier)?
+  static bool isTypeSpecifier(DeclSpecContext DSC) {
+    switch (DSC) {
+    case DeclSpecContext::DSC_normal:
+    case DeclSpecContext::DSC_template_param:
+    case DeclSpecContext::DSC_template_arg:
+    case DeclSpecContext::DSC_class:
+    case DeclSpecContext::DSC_top_level:
+    case DeclSpecContext::DSC_objc_method_result:
+    case DeclSpecContext::DSC_condition:
+      return false;
 
-  /// Return false if the next token is an identifier. An 'expected identifier'
-  /// error is emitted otherwise.
-  ///
-  /// The parser tries to recover from the error by checking if the next token
-  /// is a C++ keyword when parsing Objective-C++. Return false if the recovery
-  /// was successful.
-  bool expectIdentifier();
+    case DeclSpecContext::DSC_template_type_arg:
+    case DeclSpecContext::DSC_type_specifier:
+    case DeclSpecContext::DSC_conv_operator:
+    case DeclSpecContext::DSC_trailing:
+    case DeclSpecContext::DSC_alias_declaration:
+    case DeclSpecContext::DSC_association:
+    case DeclSpecContext::DSC_new:
+      return true;
+    }
+    llvm_unreachable("Missing DeclSpecContext case");
+  }
 
-  /// Kinds of compound pseudo-tokens formed by a sequence of two real tokens.
-  enum class CompoundToken {
-    /// A '(' '{' beginning a statement-expression.
-    StmtExprBegin,
-    /// A '}' ')' ending a statement-expression.
-    StmtExprEnd,
-    /// A '[' '[' beginning a C++11 or C23 attribute.
-    AttrBegin,
-    /// A ']' ']' ending a C++11 or C23 attribute.
-    AttrEnd,
-    /// A '::' '*' forming a C++ pointer-to-member declaration.
-    MemberPtr,
+  /// Whether a defining-type-specifier is permitted in a given context.
+  enum class AllowDefiningTypeSpec {
+    /// The grammar doesn't allow a defining-type-specifier here, and we must
+    /// not parse one (eg, because a '{' could mean something else).
+    No,
+    /// The grammar doesn't allow a defining-type-specifier here, but we permit
+    /// one for error recovery purposes. Sema will reject.
+    NoButErrorRecovery,
+    /// The grammar allows a defining-type-specifier here, even though it's
+    /// always invalid. Sema will reject.
+    YesButInvalid,
+    /// The grammar allows a defining-type-specifier here, and one can be valid.
+    Yes
   };
 
-  /// Check that a compound operator was written in a "sensible" way, and warn
-  /// if not.
-  void checkCompoundToken(SourceLocation FirstTokLoc,
-                          tok::TokenKind FirstTokKind, CompoundToken Op);
-
-  void diagnoseUseOfC11Keyword(const Token &Tok);
+  /// Is this a context in which we are parsing defining-type-specifiers (and
+  /// so permit class and enum definitions in addition to non-defining class and
+  /// enum elaborated-type-specifiers)?
+  static AllowDefiningTypeSpec
+  isDefiningTypeSpecifierContext(DeclSpecContext DSC, bool IsCPlusPlus) {
+    switch (DSC) {
+    case DeclSpecContext::DSC_normal:
+    case DeclSpecContext::DSC_class:
+    case DeclSpecContext::DSC_top_level:
+    case DeclSpecContext::DSC_alias_declaration:
+    case DeclSpecContext::DSC_objc_method_result:
+      return AllowDefiningTypeSpec::Yes;
 
-public:
-  //===--------------------------------------------------------------------===//
-  // Scope manipulation
+    case DeclSpecContext::DSC_condition:
+    case DeclSpecContext::DSC_template_param:
+      return AllowDefiningTypeSpec::YesButInvalid;
 
-  /// ParseScope - Introduces a new scope for parsing. The kind of
-  /// scope is determined by ScopeFlags. Objects of this type should
-  /// be created on the stack to coincide with the position where the
-  /// parser enters the new scope, and this object's constructor will
-  /// create that new scope. Similarly, once the object is destroyed
-  /// the parser will exit the scope.
-  class ParseScope {
-    Parser *Self;
-    ParseScope(const ParseScope &) = delete;
-    void operator=(const ParseScope &) = delete;
+    case DeclSpecContext::DSC_template_type_arg:
+    case DeclSpecContext::DSC_type_specifier:
+      return AllowDefiningTypeSpec::NoButErrorRecovery;
 
-  public:
-    // ParseScope - Construct a new object to manage a scope in the
-    // parser Self where the new Scope is created with the flags
-    // ScopeFlags, but only when we aren't about to enter a compound statement.
-    ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
-               bool BeforeCompoundStmt = false)
-      : Self(Self) {
-      if (EnteredScope && !BeforeCompoundStmt)
-        Self->EnterScope(ScopeFlags);
-      else {
-        if (BeforeCompoundStmt)
-          Self->incrementMSManglingNumber();
+    case DeclSpecContext::DSC_association:
+      return IsCPlusPlus ? AllowDefiningTypeSpec::NoButErrorRecovery
+                         : AllowDefiningTypeSpec::Yes;
 
-        this->Self = nullptr;
-      }
+    case DeclSpecContext::DSC_trailing:
+    case DeclSpecContext::DSC_conv_operator:
+    case DeclSpecContext::DSC_template_arg:
+    case DeclSpecContext::DSC_new:
+      return AllowDefiningTypeSpec::No;
     }
+    llvm_unreachable("Missing DeclSpecContext case");
+  }
 
-    // Exit - Exit the scope associated with this object now, rather
-    // than waiting until the object is destroyed.
-    void Exit() {
-      if (Self) {
-        Self->ExitScope();
-        Self = nullptr;
-      }
-    }
+  /// Is this a context in which an opaque-enum-declaration can appear?
+  static bool isOpaqueEnumDeclarationContext(DeclSpecContext DSC) {
+    switch (DSC) {
+    case DeclSpecContext::DSC_normal:
+    case DeclSpecContext::DSC_class:
+    case DeclSpecContext::DSC_top_level:
+      return true;
 
-    ~ParseScope() {
-      Exit();
+    case DeclSpecContext::DSC_alias_declaration:
+    case DeclSpecContext::DSC_objc_method_result:
+    case DeclSpecContext::DSC_condition:
+    case DeclSpecContext::DSC_template_param:
+    case DeclSpecContext::DSC_template_type_arg:
+    case DeclSpecContext::DSC_type_specifier:
+    case DeclSpecContext::DSC_trailing:
+    case DeclSpecContext::DSC_association:
+    case DeclSpecContext::DSC_conv_operator:
+    case DeclSpecContext::DSC_template_arg:
+    case DeclSpecContext::DSC_new:
+
+      return false;
     }
-  };
+    llvm_unreachable("Missing DeclSpecContext case");
+  }
 
-  /// Introduces zero or more scopes for parsing. The scopes will all be exited
-  /// when the object is destroyed.
-  class MultiParseScope {
-    Parser &Self;
-    unsigned NumScopes = 0;
+  /// Is this a context in which we can perform class template argument
+  /// deduction?
+  static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
+    switch (DSC) {
+    case DeclSpecContext::DSC_normal:
+    case DeclSpecContext::DSC_template_param:
+    case DeclSpecContext::DSC_template_arg:
+    case DeclSpecContext::DSC_class:
+    case DeclSpecContext::DSC_top_level:
+    case DeclSpecContext::DSC_condition:
+    case DeclSpecContext::DSC_type_specifier:
+    case DeclSpecContext::DSC_association:
+    case DeclSpecContext::DSC_conv_operator:
+    case DeclSpecContext::DSC_new:
+      return true;
 
-    MultiParseScope(const MultiParseScope&) = delete;
-
-  public:
-    MultiParseScope(Parser &Self) : Self(Self) {}
-    void Enter(unsigned ScopeFlags) {
-      Self.EnterScope(ScopeFlags);
-      ++NumScopes;
-    }
-    void Exit() {
-      while (NumScopes) {
-        Self.ExitScope();
-        --NumScopes;
-      }
-    }
-    ~MultiParseScope() {
-      Exit();
+    case DeclSpecContext::DSC_objc_method_result:
+    case DeclSpecContext::DSC_template_type_arg:
+    case DeclSpecContext::DSC_trailing:
+    case DeclSpecContext::DSC_alias_declaration:
+      return false;
     }
-  };
-
-  /// EnterScope - Start a new scope.
-  void EnterScope(unsigned ScopeFlags);
-
-  /// ExitScope - Pop a scope off the scope stack.
-  void ExitScope();
+    llvm_unreachable("Missing DeclSpecContext case");
+  }
 
-  /// Re-enter the template scopes for a declaration that might be a template.
-  unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D);
+  // Is this a context in which an implicit 'typename' is allowed?
+  static ImplicitTypenameContext
+  getImplicitTypenameContext(DeclSpecContext DSC) {
+    switch (DSC) {
+    case DeclSpecContext::DSC_class:
+    case DeclSpecContext::DSC_top_level:
+    case DeclSpecContext::DSC_type_specifier:
+    case DeclSpecContext::DSC_template_type_arg:
+    case DeclSpecContext::DSC_trailing:
+    case DeclSpecContext::DSC_alias_declaration:
+    case DeclSpecContext::DSC_template_param:
+    case DeclSpecContext::DSC_new:
+      return ImplicitTypenameContext::Yes;
 
-private:
-  /// RAII object used to modify the scope flags for the current scope.
-  class ParseScopeFlags {
-    Scope *CurScope;
-    unsigned OldFlags = 0;
-    ParseScopeFlags(const ParseScopeFlags &) = delete;
-    void operator=(const ParseScopeFlags &) = delete;
+    case DeclSpecContext::DSC_normal:
+    case DeclSpecContext::DSC_objc_method_result:
+    case DeclSpecContext::DSC_condition:
+    case DeclSpecContext::DSC_template_arg:
+    case DeclSpecContext::DSC_conv_operator:
+    case DeclSpecContext::DSC_association:
+      return ImplicitTypenameContext::No;
+    }
+    llvm_unreachable("Missing DeclSpecContext case");
+  }
 
-  public:
-    ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true);
-    ~ParseScopeFlags();
+  /// Information on a C++0x for-range-initializer found while parsing a
+  /// declaration which turns out to be a for-range-declaration.
+  struct ForRangeInit {
+    SourceLocation ColonLoc;
+    ExprResult RangeExpr;
+    SmallVector<MaterializeTemporaryExpr *, 8> LifetimeExtendTemps;
+    bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
+  };
+  struct ForRangeInfo : ForRangeInit {
+    StmtResult LoopVar;
   };
 
-  //===--------------------------------------------------------------------===//
-  // Diagnostic Emission and Error recovery.
+  /// ParseDeclaration - Parse a full 'declaration', which consists of
+  /// declaration-specifiers, some number of declarators, and a semicolon.
+  /// 'Context' should be a DeclaratorContext value.  This returns the
+  /// location of the semicolon in DeclEnd.
+  ///
+  ///       declaration: [C99 6.7]
+  ///         block-declaration ->
+  ///           simple-declaration
+  ///           others                   [FIXME]
+  /// [C++]   template-declaration
+  /// [C++]   namespace-definition
+  /// [C++]   using-directive
+  /// [C++]   using-declaration
+  /// [C++11/C11] static_assert-declaration
+  ///         others... [FIXME]
+  ///
+  DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
+                                  SourceLocation &DeclEnd,
+                                  ParsedAttributes &DeclAttrs,
+                                  ParsedAttributes &DeclSpecAttrs,
+                                  SourceLocation *DeclSpecStart = nullptr);
+  
+  ///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
+  ///         declaration-specifiers init-declarator-list[opt] ';'
+  /// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
+  ///             init-declarator-list ';'
+  ///[C90/C++]init-declarator-list ';'                             [TODO]
+  /// [OMP]   threadprivate-directive
+  /// [OMP]   allocate-directive                                   [TODO]
+  ///
+  ///       for-range-declaration: [C++11 6.5p1: stmt.ranged]
+  ///         attribute-specifier-seq[opt] type-specifier-seq declarator
+  ///
+  /// If RequireSemi is false, this does not check for a ';' at the end of the
+  /// declaration.  If it is true, it checks for and eats it.
+  ///
+  /// If FRI is non-null, we might be parsing a for-range-declaration instead
+  /// of a simple-declaration. If we find that we are, we also parse the
+  /// for-range-initializer, and place it here.
+  ///
+  /// DeclSpecStart is used when decl-specifiers are parsed before parsing
+  /// the Declaration. The SourceLocation for this Decl is set to
+  /// DeclSpecStart if DeclSpecStart is non-null.
+  DeclGroupPtrTy
+  ParseSimpleDeclaration(DeclaratorContext Context, SourceLocation &DeclEnd,
+                         ParsedAttributes &DeclAttrs,
+                         ParsedAttributes &DeclSpecAttrs, bool RequireSemi,
+                         ForRangeInit *FRI = nullptr,
+                         SourceLocation *DeclSpecStart = nullptr);
+  
+  /// ParseDeclGroup - Having concluded that this is either a function
+  /// definition or a group of object declarations, actually parse the
+  /// result.
+  ///
+  /// Returns true if this might be the start of a declarator, or a common typo
+  /// for a declarator.
+  bool MightBeDeclarator(DeclaratorContext Context);
+  DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, DeclaratorContext Context,
+                                ParsedAttributes &Attrs,
+                                ParsedTemplateInfo &TemplateInfo,
+                                SourceLocation *DeclEnd = nullptr,
+                                ForRangeInit *FRI = nullptr);
+  
+  /// Parse 'declaration' after parsing 'declaration-specifiers
+  /// declarator'. This method parses the remainder of the declaration
+  /// (including any attributes or initializer, among other things) and
+  /// finalizes the declaration.
+  ///
+  ///       init-declarator: [C99 6.7]
+  ///         declarator
+  ///         declarator '=' initializer
+  /// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
+  /// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
+  /// [C++]   declarator initializer[opt]
+  ///
+  /// [C++] initializer:
+  /// [C++]   '=' initializer-clause
+  /// [C++]   '(' expression-list ')'
+  /// [C++0x] '=' 'default'                                                [TODO]
+  /// [C++0x] '=' 'delete'
+  /// [C++0x] braced-init-list
+  ///
+  /// According to the standard grammar, =default and =delete are function
+  /// definitions, but that definitely doesn't fit with the parser here.
+  ///
+  Decl *ParseDeclarationAfterDeclarator(Declarator &D,
+               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+  
+  /// Parse an optional simple-asm-expr and attributes, and attach them to a
+  /// declarator. Returns true on an error.
+  bool ParseAsmAttributesAfterDeclarator(Declarator &D);
+  Decl *ParseDeclarationAfterDeclaratorAndAttributes(
+      Declarator &D,
+      const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+      ForRangeInit *FRI = nullptr);
 
-public:
-  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
-  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
-  DiagnosticBuilder Diag(unsigned DiagID) {
-    return Diag(Tok, DiagID);
+  /// ParseImplicitInt - This method is called when we have an non-typename
+  /// identifier in a declspec (which normally terminates the decl spec) when
+  /// the declspec has no type specifier.  In this case, the declspec is either
+  /// malformed or is "implicit int" (in K&R and C89).
+  ///
+  /// This method handles diagnosing this prettily and returns false if the
+  /// declspec is done being processed.  If it recovers and thinks there may be
+  /// other pieces of declspec after it, it returns true.
+  ///
+  bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
+                        ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,
+                        DeclSpecContext DSC, ParsedAttributes &Attrs);
+  
+  /// Determine the declaration specifier context from the declarator
+  /// context.
+  ///
+  /// \param Context the declarator context, which is one of the
+  /// DeclaratorContext enumerator values.
+  DeclSpecContext
+  getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
+  void
+  ParseDeclarationSpecifiers(DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
+                             AccessSpecifier AS = AS_none,
+                             DeclSpecContext DSC = DeclSpecContext::DSC_normal,
+                             LateParsedAttrList *LateAttrs = nullptr) {
+    return ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC, LateAttrs,
+                                      getImplicitTypenameContext(DSC));
   }
 
-  DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId);
-  DiagnosticBuilder DiagCompat(const Token &Tok, unsigned CompatDiagId);
-  DiagnosticBuilder DiagCompat(unsigned CompatDiagId) {
-    return DiagCompat(Tok, CompatDiagId);
-  }
+  /// ParseDeclarationSpecifiers
+  ///       declaration-specifiers: [C99 6.7]
+  ///         storage-class-specifier declaration-specifiers[opt]
+  ///         type-specifier declaration-specifiers[opt]
+  /// [C99]   function-specifier declaration-specifiers[opt]
+  /// [C11]   alignment-specifier declaration-specifiers[opt]
+  /// [GNU]   attributes declaration-specifiers[opt]
+  /// [Clang] '__module_private__' declaration-specifiers[opt]
+  /// [ObjC1] '__kindof' declaration-specifiers[opt]
+  ///
+  ///       storage-class-specifier: [C99 6.7.1]
+  ///         'typedef'
+  ///         'extern'
+  ///         'static'
+  ///         'auto'
+  ///         'register'
+  /// [C++]   'mutable'
+  /// [C++11] 'thread_local'
+  /// [C11]   '_Thread_local'
+  /// [GNU]   '__thread'
+  ///       function-specifier: [C99 6.7.4]
+  /// [C99]   'inline'
+  /// [C++]   'virtual'
+  /// [C++]   'explicit'
+  /// [OpenCL] '__kernel'
+  ///       'friend': [C++ dcl.friend]
+  ///       'constexpr': [C++0x dcl.constexpr]
+  void
+  ParseDeclarationSpecifiers(DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
+                             AccessSpecifier AS, DeclSpecContext DSC,
+                             LateParsedAttrList *LateAttrs,
+                             ImplicitTypenameContext AllowImplicitTypename);
 
-private:
-  void SuggestParentheses(SourceLocation Loc, unsigned DK,
-                          SourceRange ParenRange);
-  void CheckNestedObjCContexts(SourceLocation AtLoc);
+  /// Determine whether we're looking at something that might be a declarator
+  /// in a simple-declaration. If it can't possibly be a declarator, maybe
+  /// diagnose a missing semicolon after a prior tag definition in the decl
+  /// specifier.
+  ///
+  /// \return \c true if an error occurred and this can't be any kind of
+  /// declaration.
+  bool DiagnoseMissingSemiAfterTagDefinition(
+      DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext,
+      LateParsedAttrList *LateAttrs = nullptr);
 
-public:
+  void ParseSpecifierQualifierList(
+      DeclSpec &DS, AccessSpecifier AS = AS_none,
+      DeclSpecContext DSC = DeclSpecContext::DSC_normal) {
+    ParseSpecifierQualifierList(DS, getImplicitTypenameContext(DSC), AS, DSC);
+  }
 
-  /// Control flags for SkipUntil functions.
-  enum SkipUntilFlags {
-    StopAtSemi = 1 << 0,  ///< Stop skipping at semicolon
-    /// Stop skipping at specified token, but don't skip the token itself
-    StopBeforeMatch = 1 << 1,
-    StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
-  };
+  /// ParseSpecifierQualifierList
+  ///        specifier-qualifier-list:
+  ///          type-specifier specifier-qualifier-list[opt]
+  ///          type-qualifier specifier-qualifier-list[opt]
+  /// [GNU]    attributes     specifier-qualifier-list[opt]
+  ///
+  void ParseSpecifierQualifierList(
+      DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,
+      AccessSpecifier AS = AS_none,
+      DeclSpecContext DSC = DeclSpecContext::DSC_normal);
 
-  friend constexpr SkipUntilFlags operator|(SkipUntilFlags L,
-                                            SkipUntilFlags R) {
-    return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) |
-                                       static_cast<unsigned>(R));
-  }
+  /// ParseEnumSpecifier
+  ///       enum-specifier: [C99 6.7.2.2]
+  ///         'enum' identifier[opt] '{' enumerator-list '}'
+  ///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
+  /// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
+  ///                                                 '}' attributes[opt]
+  /// [MS]    'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
+  ///                                                 '}'
+  ///         'enum' identifier
+  /// [GNU]   'enum' attributes[opt] identifier
+  ///
+  /// [C++11] enum-head '{' enumerator-list[opt] '}'
+  /// [C++11] enum-head '{' enumerator-list ','  '}'
+  ///
+  ///       enum-head: [C++11]
+  ///         enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
+  ///         enum-key attribute-specifier-seq[opt] nested-name-specifier
+  ///             identifier enum-base[opt]
+  ///
+  ///       enum-key: [C++11]
+  ///         'enum'
+  ///         'enum' 'class'
+  ///         'enum' 'struct'
+  ///
+  ///       enum-base: [C++11]
+  ///         ':' type-specifier-seq
+  ///
+  /// [C++] elaborated-type-specifier:
+  /// [C++]   'enum' nested-name-specifier[opt] identifier
+  ///
+  void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
+                          const ParsedTemplateInfo &TemplateInfo,
+                          AccessSpecifier AS, DeclSpecContext DSC);
+  
+  /// ParseEnumBody - Parse a {} enclosed enumerator-list.
+  ///       enumerator-list:
+  ///         enumerator
+  ///         enumerator-list ',' enumerator
+  ///       enumerator:
+  ///         enumeration-constant attributes[opt]
+  ///         enumeration-constant attributes[opt] '=' constant-expression
+  ///       enumeration-constant:
+  ///         identifier
+  ///
+  void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl,
+                     SkipBodyInfo *SkipBody = nullptr);
+  
+  /// ParseStructUnionBody
+  ///       struct-contents:
+  ///         struct-declaration-list
+  /// [EXT]   empty
+  /// [GNU]   "struct-declaration-list" without terminating ';'
+  ///       struct-declaration-list:
+  ///         struct-declaration
+  ///         struct-declaration-list struct-declaration
+  /// [OBC]   '@' 'defs' '(' class-name ')'
+  ///
+  void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
+                            RecordDecl *TagDecl);
 
-  /// SkipUntil - Read tokens until we get to the specified token, then consume
-  /// it (unless StopBeforeMatch is specified).  Because we cannot guarantee
-  /// that the token will ever occur, this skips to the next token, or to some
-  /// likely good stopping point.  If Flags has StopAtSemi flag, skipping will
-  /// stop at a ';' character. Balances (), [], and {} delimiter tokens while
-  /// skipping.
+  /// ParseStructDeclaration - Parse a struct declaration without the terminating
+  /// semicolon.
   ///
-  /// If SkipUntil finds the specified token, it returns true, otherwise it
-  /// returns false.
-  bool SkipUntil(tok::TokenKind T,
-                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
-    return SkipUntil(llvm::ArrayRef(T), Flags);
-  }
-  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
-                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
-    tok::TokenKind TokArray[] = {T1, T2};
-    return SkipUntil(TokArray, Flags);
-  }
-  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3,
-                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
-    tok::TokenKind TokArray[] = {T1, T2, T3};
-    return SkipUntil(TokArray, Flags);
-  }
-  bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
-                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
+  /// Note that a struct declaration refers to a declaration in a struct,
+  /// not to the declaration of a struct.
+  ///
+  ///       struct-declaration:
+  /// [C23]   attributes-specifier-seq[opt]
+  ///           specifier-qualifier-list struct-declarator-list
+  /// [GNU]   __extension__ struct-declaration
+  /// [GNU]   specifier-qualifier-list
+  ///       struct-declarator-list:
+  ///         struct-declarator
+  ///         struct-declarator-list ',' struct-declarator
+  /// [GNU]   struct-declarator-list ',' attributes[opt] struct-declarator
+  ///       struct-declarator:
+  ///         declarator
+  /// [GNU]   declarator attributes[opt]
+  ///         declarator[opt] ':' constant-expression
+  /// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
+  ///
+  void ParseStructDeclaration(
+      ParsingDeclSpec &DS,
+      llvm::function_ref<Decl *(ParsingFieldDeclarator &)> FieldsCallback,
+      LateParsedAttrList *LateFieldAttrs = nullptr);
 
-  /// SkipMalformedDecl - Read tokens until we get to some likely good stopping
-  /// point for skipping past a simple-declaration.
-  void SkipMalformedDecl();
+  DeclGroupPtrTy ParseTopLevelStmtDecl();
 
-  /// The location of the first statement inside an else that might
-  /// have a missleading indentation. If there is no
-  /// MisleadingIndentationChecker on an else active, this location is invalid.
-  SourceLocation MisleadingIndentationElseLoc;
+  /// isDeclarationSpecifier() - Return true if the current token is part of a
+  /// declaration specifier.
+  ///
+  /// \param AllowImplicitTypename whether this is a context where T::type [T
+  /// dependent] can appear.
+  /// \param DisambiguatingWithExpression True to indicate that the purpose of
+  /// this check is to disambiguate between an expression and a declaration.
+  bool isDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
+                              bool DisambiguatingWithExpression = false);
+  
+  /// isTypeSpecifierQualifier - Return true if the current token could be the
+  /// start of a specifier-qualifier-list.
+  bool isTypeSpecifierQualifier();
 
-private:
-  //===--------------------------------------------------------------------===//
-  // Lexing and parsing of C++ inline methods.
+  /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
+  /// is definitely a type-specifier.  Return false if it isn't part of a type
+  /// specifier or if we're not sure.
+  bool isKnownToBeTypeSpecifier(const Token &Tok) const;
 
-  struct ParsingClass;
+  /// Starting with a scope specifier, identifier, or
+  /// template-id that refers to the current class, determine whether
+  /// this is a constructor declarator.
+  bool isConstructorDeclarator(
+      bool Unqualified, bool DeductionGuide = false,
+      DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
+      const ParsedTemplateInfo *TemplateInfo = nullptr);
 
-  /// [class.mem]p1: "... the class is regarded as complete within
-  /// - function bodies
-  /// - default arguments
-  /// - exception-specifications (TODO: C++0x)
-  /// - and brace-or-equal-initializers for non-static data members
-  /// (including such things in nested classes)."
-  /// LateParsedDeclarations build the tree of those elements so they can
-  /// be parsed after parsing the top-level class.
-  class LateParsedDeclaration {
-  public:
-    virtual ~LateParsedDeclaration();
+  /// Diagnoses use of _ExtInt as being deprecated, and diagnoses use of
+  /// _BitInt as an extension when appropriate.
+  void DiagnoseBitIntUse(const Token &Tok);
 
-    virtual void ParseLexedMethodDeclarations();
-    virtual void ParseLexedMemberInitializers();
-    virtual void ParseLexedMethodDefs();
-    virtual void ParseLexedAttributes();
-    virtual void ParseLexedPragmas();
-  };
+  // Check for the start of an attribute-specifier-seq in a context where an
+  // attribute is not allowed.
+  bool CheckProhibitedCXX11Attribute() {
+    assert(Tok.is(tok::l_square));
+    if (NextToken().isNot(tok::l_square))
+      return false;
+    return DiagnoseProhibitedCXX11Attribute();
+  }
 
-  /// Inner node of the LateParsedDeclaration tree that parses
-  /// all its members recursively.
-  class LateParsedClass : public LateParsedDeclaration {
-  public:
-    LateParsedClass(Parser *P, ParsingClass *C);
-    ~LateParsedClass() override;
+  /// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
+  /// of a C++11 attribute-specifier in a location where an attribute is not
+  /// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
+  /// situation.
+  ///
+  /// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
+  /// this doesn't appear to actually be an attribute-specifier, and the caller
+  /// should try to parse it.
+  bool DiagnoseProhibitedCXX11Attribute();
 
-    void ParseLexedMethodDeclarations() override;
-    void ParseLexedMemberInitializers() override;
-    void ParseLexedMethodDefs() override;
-    void ParseLexedAttributes() override;
-    void ParseLexedPragmas() override;
+  void CheckMisplacedCXX11Attribute(ParsedAttributes &Attrs,
+                                    SourceLocation CorrectLocation) {
+    if (!Tok.isRegularKeywordAttribute() &&
+        (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
+        Tok.isNot(tok::kw_alignas))
+      return;
+    DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
+  }
 
-    // Delete copy constructor and copy assignment operator.
-    LateParsedClass(const LateParsedClass &) = delete;
-    LateParsedClass &operator=(const LateParsedClass &) = delete;
+  /// We have found the opening square brackets of a C++11
+  /// attribute-specifier in a location where an attribute is not permitted, but
+  /// we know where the attributes ought to be written. Parse them anyway, and
+  /// provide a fixit moving them to the right place.
+  void DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs,
+                                       SourceLocation CorrectLocation);
 
-  private:
-    Parser *Self;
-    ParsingClass *Class;
-  };
+  // Usually, `__attribute__((attrib)) class Foo {} var` means that attribute
+  // applies to var, not the type Foo.
+  // As an exception to the rule, __declspec(align(...)) before the
+  // class-key affects the type instead of the variable.
+  // Also, Microsoft-style [attributes] seem to affect the type instead of the
+  // variable.
+  // This function moves attributes that should apply to the type off DS to Attrs.
+  void stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, DeclSpec &DS,
+                                      TagUseKind TUK);
 
-  /// Contains the lexed tokens of an attribute with arguments that
-  /// may reference member variables and so need to be parsed at the
-  /// end of the class declaration after parsing all other member
-  /// member declarations.
-  /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
-  /// LateParsedTokens.
-  struct LateParsedAttribute : public LateParsedDeclaration {
-    Parser *Self;
-    CachedTokens Toks;
-    IdentifierInfo &AttrName;
-    IdentifierInfo *MacroII = nullptr;
-    SourceLocation AttrNameLoc;
-    SmallVector<Decl*, 2> Decls;
+  // FixItLoc = possible correct location for the attributes
+  void ProhibitAttributes(ParsedAttributes &Attrs,
+                          SourceLocation FixItLoc = SourceLocation()) {
+    if (Attrs.Range.isInvalid())
+      return;
+    DiagnoseProhibitedAttributes(Attrs, FixItLoc);
+    Attrs.clear();
+  }
 
-    explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
-                                 SourceLocation Loc)
-      : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
+  void ProhibitAttributes(ParsedAttributesView &Attrs,
+                          SourceLocation FixItLoc = SourceLocation()) {
+    if (Attrs.Range.isInvalid())
+      return;
+    DiagnoseProhibitedAttributes(Attrs, FixItLoc);
+    Attrs.clearListOnly();
+  }
+  void DiagnoseProhibitedAttributes(const ParsedAttributesView &Attrs,
+                                    SourceLocation FixItLoc);
 
-    void ParseLexedAttributes() override;
+  // Forbid C++11 and C23 attributes that appear on certain syntactic locations
+  // which standard permits but we don't supported yet, for example, attributes
+  // appertain to decl specifiers.
+  // For the most cases we don't want to warn on unknown type attributes, but
+  // left them to later diagnoses. However, for a few cases like module
+  // declarations and module import declarations, we should do it.
+  void ProhibitCXX11Attributes(ParsedAttributes &Attrs, unsigned AttrDiagID,
+                               unsigned KeywordDiagId,
+                               bool DiagnoseEmptyAttrs = false,
+                               bool WarnOnUnknownAttrs = false);
 
-    void addDecl(Decl *D) { Decls.push_back(D); }
-  };
+  /// Emit warnings for C++11 and C23 attributes that are in a position that
+  /// clang accepts as an extension.
+  void DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs);
 
-  /// Contains the lexed tokens of a pragma with arguments that
-  /// may reference member variables and so need to be parsed at the
-  /// end of the class declaration after parsing all other member
-  /// member declarations.
-  class LateParsedPragma : public LateParsedDeclaration {
-    Parser *Self = nullptr;
-    AccessSpecifier AS = AS_none;
-    CachedTokens Toks;
+  ExprResult ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName);
 
-  public:
-    explicit LateParsedPragma(Parser *P, AccessSpecifier AS)
-        : Self(P), AS(AS) {}
+  bool
+  ParseAttributeArgumentList(const clang::IdentifierInfo &AttrName,
+                             SmallVectorImpl<Expr *> &Exprs,
+                             ParsedAttributeArgumentsProperties ArgsProperties);
 
-    void takeToks(CachedTokens &Cached) { Toks.swap(Cached); }
-    const CachedTokens &toks() const { return Toks; }
-    AccessSpecifier getAccessSpecifier() const { return AS; }
+  /// Parses syntax-generic attribute arguments for attributes which are
+  /// known to the implementation, and adds them to the given ParsedAttributes
+  /// list with the given attribute syntax. Returns the number of arguments
+  /// parsed for the attribute.
+  unsigned
+  ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+                           ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                           IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                           ParsedAttr::Form Form);
 
-    void ParseLexedPragmas() override;
+  enum ParseAttrKindMask {
+    PAKM_GNU = 1 << 0,
+    PAKM_Declspec = 1 << 1,
+    PAKM_CXX11 = 1 << 2,
   };
 
-  // A list of late-parsed attributes.  Used by ParseGNUAttributes.
-  class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
-  public:
-    LateParsedAttrList(bool PSoon = false,
-                       bool LateAttrParseExperimentalExtOnly = false)
-        : ParseSoon(PSoon),
-          LateAttrParseExperimentalExtOnly(LateAttrParseExperimentalExtOnly) {}
+  /// \brief Parse attributes based on what syntaxes are desired, allowing for
+  /// the order to vary. e.g. with PAKM_GNU | PAKM_Declspec:
+  /// __attribute__((...)) __declspec(...) __attribute__((...)))
+  /// Note that Microsoft attributes (spelled with single square brackets) are
+  /// not supported by this because of parsing ambiguities with other
+  /// constructs.
+  ///
+  /// There are some attribute parse orderings that should not be allowed in
+  /// arbitrary order. e.g.,
+  ///
+  ///   [[]] __attribute__(()) int i; // OK
+  ///   __attribute__(()) [[]] int i; // Not OK
+  ///
+  /// Such situations should use the specific attribute parsing functionality.
+  void ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
+                       LateParsedAttrList *LateAttrs = nullptr);
+  /// \brief Possibly parse attributes based on what syntaxes are desired,
+  /// allowing for the order to vary.
+  bool MaybeParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
+                            LateParsedAttrList *LateAttrs = nullptr) {
+    if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec) ||
+        isAllowedCXX11AttributeSpecifier()) {
+      ParseAttributes(WhichAttrKinds, Attrs, LateAttrs);
+      return true;
+    }
+    return false;
+  }
 
-    bool parseSoon() { return ParseSoon; }
-    /// returns true iff the attribute to be parsed should only be late parsed
-    /// if it is annotated with `LateAttrParseExperimentalExt`
-    bool lateAttrParseExperimentalExtOnly() {
-      return LateAttrParseExperimentalExtOnly;
+  void MaybeParseGNUAttributes(Declarator &D,
+                               LateParsedAttrList *LateAttrs = nullptr) {
+    if (Tok.is(tok::kw___attribute)) {
+      ParsedAttributes Attrs(AttrFactory);
+      ParseGNUAttributes(Attrs, LateAttrs, &D);
+      D.takeAttributes(Attrs);
     }
+  }
 
-  private:
-    bool ParseSoon; // Are we planning to parse these shortly after creation?
-    bool LateAttrParseExperimentalExtOnly;
-  };
+  bool MaybeParseGNUAttributes(ParsedAttributes &Attrs,
+                               LateParsedAttrList *LateAttrs = nullptr) {
+    if (Tok.is(tok::kw___attribute)) {
+      ParseGNUAttributes(Attrs, LateAttrs);
+      return true;
+    }
+    return false;
+  }
 
-  /// Contains the lexed tokens of a member function definition
-  /// which needs to be parsed at the end of the class declaration
-  /// after parsing all other member declarations.
-  struct LexedMethod : public LateParsedDeclaration {
-    Parser *Self;
-    Decl *D;
-    CachedTokens Toks;
+  /// ParseSingleGNUAttribute - Parse a single GNU attribute.
+  ///
+  /// [GNU]  attrib:
+  ///          empty
+  ///          attrib-name
+  ///          attrib-name '(' identifier ')'
+  ///          attrib-name '(' identifier ',' nonempty-expr-list ')'
+  ///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
+  ///
+  /// [GNU]  attrib-name:
+  ///          identifier
+  ///          typespec
+  ///          typequal
+  ///          storageclass
+  bool ParseSingleGNUAttribute(ParsedAttributes &Attrs, SourceLocation &EndLoc,
+                               LateParsedAttrList *LateAttrs = nullptr,
+                               Declarator *D = nullptr);
+  
+  /// ParseGNUAttributes - Parse a non-empty attributes list.
+  ///
+  /// [GNU] attributes:
+  ///         attribute
+  ///         attributes attribute
+  ///
+  /// [GNU]  attribute:
+  ///          '__attribute__' '(' '(' attribute-list ')' ')'
+  ///
+  /// [GNU]  attribute-list:
+  ///          attrib
+  ///          attribute_list ',' attrib
+  ///
+  /// [GNU]  attrib:
+  ///          empty
+  ///          attrib-name
+  ///          attrib-name '(' identifier ')'
+  ///          attrib-name '(' identifier ',' nonempty-expr-list ')'
+  ///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
+  ///
+  /// [GNU]  attrib-name:
+  ///          identifier
+  ///          typespec
+  ///          typequal
+  ///          storageclass
+  ///
+  /// Whether an attribute takes an 'identifier' is determined by the
+  /// attrib-name. GCC's behavior here is not worth imitating:
+  ///
+  ///  * In C mode, if the attribute argument list starts with an identifier
+  ///    followed by a ',' or an ')', and the identifier doesn't resolve to
+  ///    a type, it is parsed as an identifier. If the attribute actually
+  ///    wanted an expression, it's out of luck (but it turns out that no
+  ///    attributes work that way, because C constant expressions are very
+  ///    limited).
+  ///  * In C++ mode, if the attribute argument list starts with an identifier,
+  ///    and the attribute *wants* an identifier, it is parsed as an identifier.
+  ///    At block scope, any additional tokens between the identifier and the
+  ///    ',' or ')' are ignored, otherwise they produce a parse error.
+  ///
+  /// We follow the C++ model, but don't allow junk after the identifier.
+  void ParseGNUAttributes(ParsedAttributes &Attrs,
+                          LateParsedAttrList *LateAttrs = nullptr,
+                          Declarator *D = nullptr);
+  
+  /// Parse the arguments to a parameterized GNU attribute or
+  /// a C++11 attribute in "gnu" namespace.
+  void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
+                             SourceLocation AttrNameLoc,
+                             ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                             IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                             ParsedAttr::Form Form, Declarator *D);
+  IdentifierLoc *ParseIdentifierLoc();
 
-    explicit LexedMethod(Parser *P, Decl *MD) : Self(P), D(MD) {}
+  unsigned
+  ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+                          ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                          IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                          ParsedAttr::Form Form);
 
-    void ParseLexedMethodDefs() override;
-  };
+  void MaybeParseCXX11Attributes(Declarator &D) {
+    if (isAllowedCXX11AttributeSpecifier()) {
+      ParsedAttributes Attrs(AttrFactory);
+      ParseCXX11Attributes(Attrs);
+      D.takeAttributes(Attrs);
+    }
+  }
 
-  /// LateParsedDefaultArgument - Keeps track of a parameter that may
-  /// have a default argument that cannot be parsed yet because it
-  /// occurs within a member function declaration inside the class
-  /// (C++ [class.mem]p2).
-  struct LateParsedDefaultArgument {
-    explicit LateParsedDefaultArgument(Decl *P,
-                                       std::unique_ptr<CachedTokens> Toks = nullptr)
-      : Param(P), Toks(std::move(Toks)) { }
+  bool MaybeParseCXX11Attributes(ParsedAttributes &Attrs,
+                                 bool OuterMightBeMessageSend = false) {
+    if (isAllowedCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) {
+      ParseCXX11Attributes(Attrs);
+      return true;
+    }
+    return false;
+  }
 
-    /// Param - The parameter declaration for this parameter.
-    Decl *Param;
+  void MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) {
+    if ((getLangOpts().MicrosoftExt || getLangOpts().HLSL) &&
+        Tok.is(tok::l_square)) {
+      ParsedAttributes AttrsWithRange(AttrFactory);
+      ParseMicrosoftAttributes(AttrsWithRange);
+      Attrs.takeAllFrom(AttrsWithRange);
+    }
+  }
 
-    /// Toks - The sequence of tokens that comprises the default
-    /// argument expression, not including the '=' or the terminating
-    /// ')' or ','. This will be NULL for parameters that have no
-    /// default argument.
-    std::unique_ptr<CachedTokens> Toks;
-  };
-
-  /// LateParsedMethodDeclaration - A method declaration inside a class that
-  /// contains at least one entity whose parsing needs to be delayed
-  /// until the class itself is completely-defined, such as a default
-  /// argument (C++ [class.mem]p2).
-  struct LateParsedMethodDeclaration : public LateParsedDeclaration {
-    explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
-        : Self(P), Method(M), ExceptionSpecTokens(nullptr) {}
-
-    void ParseLexedMethodDeclarations() override;
-
-    Parser *Self;
-
-    /// Method - The method declaration.
-    Decl *Method;
+  bool MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {
+    if (getLangOpts().DeclSpecKeyword && Tok.is(tok::kw___declspec)) {
+      ParseMicrosoftDeclSpecs(Attrs);
+      return true;
+    }
+    return false;
+  }
 
-    /// DefaultArgs - Contains the parameters of the function and
-    /// their default arguments. At least one of the parameters will
-    /// have a default argument, but all of the parameters of the
-    /// method will be stored so that they can be reintroduced into
-    /// scope at the appropriate times.
-    SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
+  /// [MS] decl-specifier:
+  ///             __declspec ( extended-decl-modifier-seq )
+  ///
+  /// [MS] extended-decl-modifier-seq:
+  ///             extended-decl-modifier[opt]
+  ///             extended-decl-modifier extended-decl-modifier-seq
+  void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs);
+  bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
+                                  SourceLocation AttrNameLoc,
+                                  ParsedAttributes &Attrs);
+  void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
+  void ParseWebAssemblyFuncrefTypeAttribute(ParsedAttributes &Attrs);
+  void DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
+  SourceLocation SkipExtendedMicrosoftTypeAttributes();
 
-    /// The set of tokens that make up an exception-specification that
-    /// has not yet been parsed.
-    CachedTokens *ExceptionSpecTokens;
-  };
+  void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
+  void ParseOpenCLKernelAttributes(ParsedAttributes &attrs);
+  void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
+  void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs);
+  void ParseCUDAFunctionAttributes(ParsedAttributes &attrs);
+  bool isHLSLQualifier(const Token &Tok) const;
+  void ParseHLSLQualifiers(ParsedAttributes &Attrs);
 
-  /// LateParsedMemberInitializer - An initializer for a non-static class data
-  /// member whose parsing must to be delayed until the class is completely
-  /// defined (C++11 [class.mem]p2).
-  struct LateParsedMemberInitializer : public LateParsedDeclaration {
-    LateParsedMemberInitializer(Parser *P, Decl *FD)
-      : Self(P), Field(FD) { }
+  /// Parse a version number.
+  ///
+  /// version:
+  ///   simple-integer
+  ///   simple-integer '.' simple-integer
+  ///   simple-integer '_' simple-integer
+  ///   simple-integer '.' simple-integer '.' simple-integer
+  ///   simple-integer '_' simple-integer '_' simple-integer
+  VersionTuple ParseVersionTuple(SourceRange &Range);
 
-    void ParseLexedMemberInitializers() override;
+  /// Parse the contents of the "availability" attribute.
+  ///
+  /// availability-attribute:
+  ///   'availability' '(' platform ',' opt-strict version-arg-list,
+  ///                      opt-replacement, opt-message')'
+  ///
+  /// platform:
+  ///   identifier
+  ///
+  /// opt-strict:
+  ///   'strict' ','
+  ///
+  /// version-arg-list:
+  ///   version-arg
+  ///   version-arg ',' version-arg-list
+  ///
+  /// version-arg:
+  ///   'introduced' '=' version
+  ///   'deprecated' '=' version
+  ///   'obsoleted' = version
+  ///   'unavailable'
+  /// opt-replacement:
+  ///   'replacement' '=' <string>
+  /// opt-message:
+  ///   'message' '=' <string>
+  void ParseAvailabilityAttribute(IdentifierInfo &Availability,
+                                  SourceLocation AvailabilityLoc,
+                                  ParsedAttributes &attrs,
+                                  SourceLocation *endLoc,
+                                  IdentifierInfo *ScopeName,
+                                  SourceLocation ScopeLoc,
+                                  ParsedAttr::Form Form);
 
-    Parser *Self;
+  /// Parse the contents of the "external_source_symbol" attribute.
+  ///
+  /// external-source-symbol-attribute:
+  ///   'external_source_symbol' '(' keyword-arg-list ')'
+  ///
+  /// keyword-arg-list:
+  ///   keyword-arg
+  ///   keyword-arg ',' keyword-arg-list
+  ///
+  /// keyword-arg:
+  ///   'language' '=' <string>
+  ///   'defined_in' '=' <string>
+  ///   'USR' '=' <string>
+  ///   'generated_declaration'
+  void ParseExternalSourceSymbolAttribute(IdentifierInfo &ExternalSourceSymbol,
+                                          SourceLocation Loc,
+                                          ParsedAttributes &Attrs,
+                                          SourceLocation *EndLoc,
+                                          IdentifierInfo *ScopeName,
+                                          SourceLocation ScopeLoc,
+                                          ParsedAttr::Form Form);
 
-    /// Field - The field declaration.
-    Decl *Field;
+  /// Parse the contents of the "objc_bridge_related" attribute.
+  /// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
+  /// related_class:
+  ///     Identifier
+  ///
+  /// opt-class_method:
+  ///     Identifier: | <empty>
+  ///
+  /// opt-instance_method:
+  ///     Identifier | <empty>
+  ///
+  void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
+                                       SourceLocation ObjCBridgeRelatedLoc,
+                                       ParsedAttributes &Attrs,
+                                       SourceLocation *EndLoc,
+                                       IdentifierInfo *ScopeName,
+                                       SourceLocation ScopeLoc,
+                                       ParsedAttr::Form Form);
 
-    /// CachedTokens - The sequence of tokens that comprises the initializer,
-    /// including any leading '='.
-    CachedTokens Toks;
-  };
+  void ParseSwiftNewTypeAttribute(IdentifierInfo &AttrName,
+                                  SourceLocation AttrNameLoc,
+                                  ParsedAttributes &Attrs,
+                                  SourceLocation *EndLoc,
+                                  IdentifierInfo *ScopeName,
+                                  SourceLocation ScopeLoc,
+                                  ParsedAttr::Form Form);
 
-  /// LateParsedDeclarationsContainer - During parsing of a top (non-nested)
-  /// C++ class, its method declarations that contain parts that won't be
-  /// parsed until after the definition is completed (C++ [class.mem]p2),
-  /// the method declarations and possibly attached inline definitions
-  /// will be stored here with the tokens that will be parsed to create those
-  /// entities.
-  typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
+  void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
+                                        SourceLocation AttrNameLoc,
+                                        ParsedAttributes &Attrs,
+                                        SourceLocation *EndLoc,
+                                        IdentifierInfo *ScopeName,
+                                        SourceLocation ScopeLoc,
+                                        ParsedAttr::Form Form);
 
-  /// Representation of a class that has been parsed, including
-  /// any member function declarations or definitions that need to be
-  /// parsed after the corresponding top-level class is complete.
-  struct ParsingClass {
-    ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface)
-        : TopLevelClass(TopLevelClass), IsInterface(IsInterface),
-          TagOrTemplate(TagOrTemplate) {}
+  void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
+                                 SourceLocation AttrNameLoc,
+                                 ParsedAttributes &Attrs,
+                                 IdentifierInfo *ScopeName,
+                                 SourceLocation ScopeLoc,
+                                 ParsedAttr::Form Form);
 
-    /// Whether this is a "top-level" class, meaning that it is
-    /// not nested within another class.
-    bool TopLevelClass : 1;
+  void DistributeCLateParsedAttrs(Decl *Dcl, LateParsedAttrList *LateAttrs);
 
-    /// Whether this class is an __interface.
-    bool IsInterface : 1;
+  /// Bounds attributes (e.g., counted_by):
+  ///   AttrName '(' expression ')'
+  void ParseBoundsAttribute(IdentifierInfo &AttrName,
+                            SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
+                            IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                            ParsedAttr::Form Form);
 
-    /// The class or class template whose definition we are parsing.
-    Decl *TagOrTemplate;
+  /// [GNU]   typeof-specifier:
+  ///           typeof ( expressions )
+  ///           typeof ( type-name )
+  /// [GNU/C++] typeof unary-expression
+  /// [C23]   typeof-specifier:
+  ///           typeof '(' typeof-specifier-argument ')'
+  ///           typeof_unqual '(' typeof-specifier-argument ')'
+  ///
+  ///         typeof-specifier-argument:
+  ///           expression
+  ///           type-name
+  ///
+  void ParseTypeofSpecifier(DeclSpec &DS);
 
-    /// LateParsedDeclarations - Method declarations, inline definitions and
-    /// nested classes that contain pieces whose parsing will be delayed until
-    /// the top-level class is fully defined.
-    LateParsedDeclarationsContainer LateParsedDeclarations;
-  };
+  /// [C11]   atomic-specifier:
+  ///           _Atomic ( type-name )
+  ///
+  void ParseAtomicSpecifier(DeclSpec &DS);
 
-  /// The stack of classes that is currently being
-  /// parsed. Nested and local classes will be pushed onto this stack
-  /// when they are parsed, and removed afterward.
-  std::stack<ParsingClass *> ClassStack;
+  /// ParseAlignArgument - Parse the argument to an alignment-specifier.
+  ///
+  /// [C11]   type-id
+  /// [C11]   constant-expression
+  /// [C++0x] type-id ...[opt]
+  /// [C++0x] assignment-expression ...[opt]
+  ExprResult ParseAlignArgument(StringRef KWName, SourceLocation Start,
+                                SourceLocation &EllipsisLoc, bool &IsType,
+                                ParsedType &Ty);
+  
+  /// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
+  /// attribute to Attrs.
+  ///
+  /// alignment-specifier:
+  /// [C11]   '_Alignas' '(' type-id ')'
+  /// [C11]   '_Alignas' '(' constant-expression ')'
+  /// [C++11] 'alignas' '(' type-id ...[opt] ')'
+  /// [C++11] 'alignas' '(' assignment-expression ...[opt] ')'
+  void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
+                               SourceLocation *endLoc = nullptr);
+  ExprResult ParseExtIntegerArgument();
 
-  ParsingClass &getCurrentClass() {
-    assert(!ClassStack.empty() && "No lexed method stacks!");
-    return *ClassStack.top();
-  }
+  /// type-qualifier:
+  ///    ('__ptrauth') '(' constant-expression
+  ///                   (',' constant-expression)[opt]
+  ///                   (',' constant-expression)[opt] ')'
+  void ParsePtrauthQualifier(ParsedAttributes &Attrs);
 
-  /// RAII object used to manage the parsing of a class definition.
-  class ParsingClassDefinition {
+  /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
+  /// enter a new C++ declarator scope and exit it when the function is
+  /// finished.
+  class DeclaratorScopeObj {
     Parser &P;
-    bool Popped;
-    Sema::ParsingClassState State;
-
+    CXXScopeSpec &SS;
+    bool EnteredScope;
+    bool CreatedScope;
   public:
-    ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass,
-                           bool IsInterface)
-      : P(P), Popped(false),
-        State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
-    }
+    DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
+      : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
 
-    /// Pop this class of the stack.
-    void Pop() {
-      assert(!Popped && "Nested class has already been popped");
-      Popped = true;
-      P.PopParsingClass(State);
+    void EnterDeclaratorScope() {
+      assert(!EnteredScope && "Already entered the scope!");
+      assert(SS.isSet() && "C++ scope was not set!");
+
+      CreatedScope = true;
+      P.EnterScope(0); // Not a decl scope.
+
+      if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
+        EnteredScope = true;
     }
 
-    ~ParsingClassDefinition() {
-      if (!Popped)
-        P.PopParsingClass(State);
+    ~DeclaratorScopeObj() {
+      if (EnteredScope) {
+        assert(SS.isSet() && "C++ scope was cleared ?");
+        P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
+      }
+      if (CreatedScope)
+        P.ExitScope();
     }
   };
 
-  /// Contains information about any template-specific
-  /// information that has been parsed prior to parsing declaration
-  /// specifiers.
-  struct ParsedTemplateInfo {
-    ParsedTemplateInfo() : Kind(ParsedTemplateKind::NonTemplate), TemplateParams(nullptr) {}
+  /// ParseDeclarator - Parse and verify a newly-initialized declarator.
+  void ParseDeclarator(Declarator &D);
+  /// A function that parses a variant of direct-declarator.
+  typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
+  
+  /// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
+  /// is parsed by the function passed to it. Pass null, and the direct-declarator
+  /// isn't parsed at all, making this function effectively parse the C++
+  /// ptr-operator production.
+  ///
+  /// If the grammar of this construct is extended, matching changes must also be
+  /// made to TryParseDeclarator and MightBeDeclarator, and possibly to
+  /// isConstructorDeclarator.
+  ///
+  ///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
+  /// [C]     pointer[opt] direct-declarator
+  /// [C++]   direct-declarator
+  /// [C++]   ptr-operator declarator
+  ///
+  ///       pointer: [C99 6.7.5]
+  ///         '*' type-qualifier-list[opt]
+  ///         '*' type-qualifier-list[opt] pointer
+  ///
+  ///       ptr-operator:
+  ///         '*' cv-qualifier-seq[opt]
+  ///         '&'
+  /// [C++0x] '&&'
+  /// [GNU]   '&' restrict[opt] attributes[opt]
+  /// [GNU?]  '&&' restrict[opt] attributes[opt]
+  ///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
+  void ParseDeclaratorInternal(Declarator &D,
+                               DirectDeclParseFunction DirectDeclParser);
 
-    ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
-                       bool isSpecialization,
-                       bool lastParameterListWasEmpty = false)
-      : Kind(isSpecialization? ParsedTemplateKind::ExplicitSpecialization : ParsedTemplateKind::Template),
-        TemplateParams(TemplateParams),
-        LastParameterListWasEmpty(lastParameterListWasEmpty) { }
+  enum AttrRequirements {
+    AR_NoAttributesParsed = 0, ///< No attributes are diagnosed.
+    AR_GNUAttributesParsedAndRejected = 1 << 0, ///< Diagnose GNU attributes.
+    AR_GNUAttributesParsed = 1 << 1,
+    AR_CXX11AttributesParsed = 1 << 2,
+    AR_DeclspecAttributesParsed = 1 << 3,
+    AR_AllAttributesParsed = AR_GNUAttributesParsed |
+                             AR_CXX11AttributesParsed |
+                             AR_DeclspecAttributesParsed,
+    AR_VendorAttributesParsed = AR_GNUAttributesParsed |
+                                AR_DeclspecAttributesParsed
+  };
 
-    explicit ParsedTemplateInfo(SourceLocation ExternLoc,
-                                SourceLocation TemplateLoc)
-      : Kind(ParsedTemplateKind::ExplicitInstantiation), TemplateParams(nullptr),
-        ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
-        LastParameterListWasEmpty(false){ }
+  /// ParseTypeQualifierListOpt
+  ///          type-qualifier-list: [C99 6.7.5]
+  ///            type-qualifier
+  /// [vendor]   attributes
+  ///              [ only if AttrReqs & AR_VendorAttributesParsed ]
+  ///            type-qualifier-list type-qualifier
+  /// [vendor]   type-qualifier-list attributes
+  ///              [ only if AttrReqs & AR_VendorAttributesParsed ]
+  /// [C++0x]    attribute-specifier[opt] is allowed before cv-qualifier-seq
+  ///              [ only if AttReqs & AR_CXX11AttributesParsed ]
+  /// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
+  /// AttrRequirements bitmask values.
+  void ParseTypeQualifierListOpt(
+      DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
+      bool AtomicAllowed = true, bool IdentifierRequired = false,
+      std::optional<llvm::function_ref<void()>> CodeCompletionHandler =
+          std::nullopt);
+  
+  /// ParseDirectDeclarator
+  ///       direct-declarator: [C99 6.7.5]
+  /// [C99]   identifier
+  ///         '(' declarator ')'
+  /// [GNU]   '(' attributes declarator ')'
+  /// [C90]   direct-declarator '[' constant-expression[opt] ']'
+  /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
+  /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
+  /// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
+  /// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
+  /// [C++11] direct-declarator '[' constant-expression[opt] ']'
+  ///                    attribute-specifier-seq[opt]
+  ///         direct-declarator '(' parameter-type-list ')'
+  ///         direct-declarator '(' identifier-list[opt] ')'
+  /// [GNU]   direct-declarator '(' parameter-forward-declarations
+  ///                    parameter-type-list[opt] ')'
+  /// [C++]   direct-declarator '(' parameter-declaration-clause ')'
+  ///                    cv-qualifier-seq[opt] exception-specification[opt]
+  /// [C++11] direct-declarator '(' parameter-declaration-clause ')'
+  ///                    attribute-specifier-seq[opt] cv-qualifier-seq[opt]
+  ///                    ref-qualifier[opt] exception-specification[opt]
+  /// [C++]   declarator-id
+  /// [C++11] declarator-id attribute-specifier-seq[opt]
+  ///
+  ///       declarator-id: [C++ 8]
+  ///         '...'[opt] id-expression
+  ///         '::'[opt] nested-name-specifier[opt] type-name
+  ///
+  ///       id-expression: [C++ 5.1]
+  ///         unqualified-id
+  ///         qualified-id
+  ///
+  ///       unqualified-id: [C++ 5.1]
+  ///         identifier
+  ///         operator-function-id
+  ///         conversion-function-id
+  ///          '~' class-name
+  ///         template-id
+  ///
+  /// C++17 adds the following, which we also handle here:
+  ///
+  ///       simple-declaration:
+  ///         <decl-spec> '[' identifier-list ']' brace-or-equal-initializer ';'
+  ///
+  /// Note, any additional constructs added here may need corresponding changes
+  /// in isConstructorDeclarator.
+  void ParseDirectDeclarator(Declarator &D);
+  void ParseDecompositionDeclarator(Declarator &D);
+  
+  /// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
+  /// only called before the identifier, so these are most likely just grouping
+  /// parens for precedence.  If we find that these are actually function
+  /// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
+  ///
+  ///       direct-declarator:
+  ///         '(' declarator ')'
+  /// [GNU]   '(' attributes declarator ')'
+  ///         direct-declarator '(' parameter-type-list ')'
+  ///         direct-declarator '(' identifier-list[opt] ')'
+  /// [GNU]   direct-declarator '(' parameter-forward-declarations
+  ///                    parameter-type-list[opt] ')'
+  ///
+  void ParseParenDeclarator(Declarator &D);
+  
+  /// ParseFunctionDeclarator - We are after the identifier and have parsed the
+  /// declarator D up to a paren, which indicates that we are parsing function
+  /// arguments.
+  ///
+  /// If FirstArgAttrs is non-null, then the caller parsed those attributes
+  /// immediately after the open paren - they will be applied to the DeclSpec
+  /// of the first parameter.
+  ///
+  /// If RequiresArg is true, then the first argument of the function is required
+  /// to be present and required to not be an identifier list.
+  ///
+  /// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
+  /// (C++11) ref-qualifier[opt], exception-specification[opt],
+  /// (C++11) attribute-specifier-seq[opt], (C++11) trailing-return-type[opt] and
+  /// (C++2a) the trailing requires-clause.
+  ///
+  /// [C++11] exception-specification:
+  ///           dynamic-exception-specification
+  ///           noexcept-specification
+  ///
+  void ParseFunctionDeclarator(Declarator &D, ParsedAttributes &FirstArgAttrs,
+                               BalancedDelimiterTracker &Tracker,
+                               bool IsAmbiguous, bool RequiresArg = false);
+  void InitCXXThisScopeForDeclaratorIfRelevant(
+      const Declarator &D, const DeclSpec &DS,
+      std::optional<Sema::CXXThisScopeRAII> &ThisScope);
+  
+  /// ParseRefQualifier - Parses a member function ref-qualifier. Returns
+  /// true if a ref-qualifier is found.
+  bool ParseRefQualifier(bool &RefQualifierIsLValueRef,
+                         SourceLocation &RefQualifierLoc);
+  
+  /// isFunctionDeclaratorIdentifierList - This parameter list may have an
+  /// identifier list form for a K&R-style function:  void foo(a,b,c)
+  ///
+  /// Note that identifier-lists are only allowed for normal declarators, not for
+  /// abstract-declarators.
+  bool isFunctionDeclaratorIdentifierList();
+  
+  /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
+  /// we found a K&R-style identifier list instead of a typed parameter list.
+  ///
+  /// After returning, ParamInfo will hold the parsed parameters.
+  ///
+  ///       identifier-list: [C99 6.7.5]
+  ///         identifier
+  ///         identifier-list ',' identifier
+  ///
+  void ParseFunctionDeclaratorIdentifierList(
+         Declarator &D,
+         SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
+  void ParseParameterDeclarationClause(
+      Declarator &D, ParsedAttributes &attrs,
+      SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
+      SourceLocation &EllipsisLoc) {
+    return ParseParameterDeclarationClause(
+        D.getContext(), attrs, ParamInfo, EllipsisLoc,
+        D.getCXXScopeSpec().isSet() &&
+            D.isFunctionDeclaratorAFunctionDeclaration());
+  }
 
-    ParsedTemplateKind Kind;
+  /// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
+  /// after the opening parenthesis. This function will not parse a K&R-style
+  /// identifier list.
+  ///
+  /// DeclContext is the context of the declarator being parsed.  If FirstArgAttrs
+  /// is non-null, then the caller parsed those attributes immediately after the
+  /// open paren - they will be applied to the DeclSpec of the first parameter.
+  ///
+  /// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
+  /// be the location of the ellipsis, if any was parsed.
+  ///
+  ///       parameter-type-list: [C99 6.7.5]
+  ///         parameter-list
+  ///         parameter-list ',' '...'
+  /// [C++]   parameter-list '...'
+  ///
+  ///       parameter-list: [C99 6.7.5]
+  ///         parameter-declaration
+  ///         parameter-list ',' parameter-declaration
+  ///
+  ///       parameter-declaration: [C99 6.7.5]
+  ///         declaration-specifiers declarator
+  /// [C++]   declaration-specifiers declarator '=' assignment-expression
+  /// [C++11]                                       initializer-clause
+  /// [GNU]   declaration-specifiers declarator attributes
+  ///         declaration-specifiers abstract-declarator[opt]
+  /// [C++]   declaration-specifiers abstract-declarator[opt]
+  ///           '=' assignment-expression
+  /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
+  /// [C++11] attribute-specifier-seq parameter-declaration
+  /// [C++2b] attribute-specifier-seq 'this' parameter-declaration
+  ///
+  void ParseParameterDeclarationClause(
+      DeclaratorContext DeclaratorContext, ParsedAttributes &attrs,
+      SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
+      SourceLocation &EllipsisLoc, bool IsACXXFunctionDeclaration = false);
 
-    /// The template parameter lists, for template declarations
-    /// and explicit specializations.
-    TemplateParameterLists *TemplateParams;
+  /// [C90]   direct-declarator '[' constant-expression[opt] ']'
+  /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
+  /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
+  /// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
+  /// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
+  /// [C++11] direct-declarator '[' constant-expression[opt] ']'
+  ///                           attribute-specifier-seq[opt]
+  void ParseBracketDeclarator(Declarator &D);
+  
+  /// Diagnose brackets before an identifier.
+  void ParseMisplacedBracketDeclarator(Declarator &D);
 
-    /// The location of the 'extern' keyword, if any, for an explicit
-    /// instantiation
-    SourceLocation ExternLoc;
+  /// Parse the given string as a type.
+  ///
+  /// This is a dangerous utility function currently employed only by API notes.
+  /// It is not a general entry-point for safely parsing types from strings.
+  ///
+  /// \param TypeStr The string to be parsed as a type.
+  /// \param Context The name of the context in which this string is being
+  /// parsed, which will be used in diagnostics.
+  /// \param IncludeLoc The location at which this parse was triggered.
+  TypeResult ParseTypeFromString(StringRef TypeStr, StringRef Context,
+                                 SourceLocation IncludeLoc);
 
-    /// The location of the 'template' keyword, for an explicit
-    /// instantiation.
-    SourceLocation TemplateLoc;
+  ///@}
 
-    /// Whether the last template parameter list was empty.
-    bool LastParameterListWasEmpty;
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-    SourceRange getSourceRange() const LLVM_READONLY;
-  };
+  /// \name C++ Declarations
+  /// Implementations are in ParseDeclCXX.cpp
+  ///@{
 
-  // In ParseCXXInlineMethods.cpp.
-  struct ReenterTemplateScopeRAII;
-  struct ReenterClassScopeRAII;
+  public:
 
-  void LexTemplateFunctionForLateParsing(CachedTokens &Toks);
-  void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT);
+  private:
 
-  static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
+  /// Contextual keywords for Microsoft extensions.
+  mutable IdentifierInfo *Ident_sealed;
+  mutable IdentifierInfo *Ident_abstract;
 
-  Sema::ParsingClassState
-  PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
-  void DeallocateParsedClasses(ParsingClass *Class);
-  void PopParsingClass(Sema::ParsingClassState);
+  /// C++11 contextual keywords.
+  mutable IdentifierInfo *Ident_final;
+  mutable IdentifierInfo *Ident_GNU_final;
+  mutable IdentifierInfo *Ident_override;
 
-  NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
-                                     const ParsedAttributesView &AccessAttrs,
-                                     ParsingDeclarator &D,
-                                     const ParsedTemplateInfo &TemplateInfo,
-                                     const VirtSpecifiers &VS,
-                                     SourceLocation PureSpecLoc);
-  StringLiteral *ParseCXXDeletedFunctionMessage();
-  void SkipDeletedFunctionBody();
-  void ParseCXXNonStaticMemberInitializer(Decl *VarD);
-  void ParseLexedAttributes(ParsingClass &Class);
-  void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
-                               bool EnterScope, bool OnDefinition);
-  void ParseLexedCAttributeList(LateParsedAttrList &LA, bool EnterScope,
-                                ParsedAttributes *OutAttrs = nullptr);
-  void ParseLexedAttribute(LateParsedAttribute &LA,
-                           bool EnterScope, bool OnDefinition);
-  void ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
-                            ParsedAttributes *OutAttrs = nullptr);
-  void ParseLexedMethodDeclarations(ParsingClass &Class);
-  void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
-  void ParseLexedMethodDefs(ParsingClass &Class);
-  void ParseLexedMethodDef(LexedMethod &LM);
-  void ParseLexedMemberInitializers(ParsingClass &Class);
-  void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
-  void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
-  void ParseLexedPragmas(ParsingClass &Class);
-  void ParseLexedPragma(LateParsedPragma &LP);
-  bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
-  bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK);
-  bool ConsumeAndStoreConditional(CachedTokens &Toks);
-  bool ConsumeAndStoreUntil(tok::TokenKind T1,
-                            CachedTokens &Toks,
-                            bool StopAtSemi = true,
-                            bool ConsumeFinalToken = true) {
-    return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
-  }
-  bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
-                            CachedTokens &Toks,
-                            bool StopAtSemi = true,
-                            bool ConsumeFinalToken = true);
+  /// Representation of a class that has been parsed, including
+  /// any member function declarations or definitions that need to be
+  /// parsed after the corresponding top-level class is complete.
+  struct ParsingClass {
+    ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface)
+        : TopLevelClass(TopLevelClass), IsInterface(IsInterface),
+          TagOrTemplate(TagOrTemplate) {}
 
-  //===--------------------------------------------------------------------===//
-  // C99 6.9: External Definitions.
-  DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &DeclAttrs,
-                                          ParsedAttributes &DeclSpecAttrs,
-                                          ParsingDeclSpec *DS = nullptr);
-  bool isDeclarationAfterDeclarator();
-  bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
-  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
-      ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,
-      ParsingDeclSpec *DS = nullptr, AccessSpecifier AS = AS_none);
-  DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributes &Attrs,
-                                                ParsedAttributes &DeclSpecAttrs,
-                                                ParsingDeclSpec &DS,
-                                                AccessSpecifier AS);
+    /// Whether this is a "top-level" class, meaning that it is
+    /// not nested within another class.
+    bool TopLevelClass : 1;
 
-  void SkipFunctionBody();
-  Decl *ParseFunctionDefinition(ParsingDeclarator &D,
-                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
-                 LateParsedAttrList *LateParsedAttrs = nullptr);
-  void ParseKNRParamDeclarations(Declarator &D);
-  // EndLoc is filled with the location of the last token of the simple-asm.
-  ExprResult ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc);
-  ExprResult ParseAsmStringLiteral(bool ForAsmLabel);
+    /// Whether this class is an __interface.
+    bool IsInterface : 1;
 
-  // Objective-C External Declarations
-  void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
-  DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
-                                       ParsedAttributes &DeclSpecAttrs);
-  DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
-  Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
-                                        ParsedAttributes &prefixAttrs);
-  class ObjCTypeParamListScope;
-  ObjCTypeParamList *parseObjCTypeParamList();
-  ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
-      ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
-      SmallVectorImpl<IdentifierLoc> &protocolIdents, SourceLocation &rAngleLoc,
-      bool mayBeProtocolList = true);
+    /// The class or class template whose definition we are parsing.
+    Decl *TagOrTemplate;
 
-  void HelperActionsForIvarDeclarations(ObjCContainerDecl *interfaceDecl,
-                                        SourceLocation atLoc,
-                                        BalancedDelimiterTracker &T,
-                                        SmallVectorImpl<Decl *> &AllIvarDecls,
-                                        bool RBraceMissing);
-  void ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
-                                       tok::ObjCKeywordKind visibility,
-                                       SourceLocation atLoc);
-  bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P,
-                                   SmallVectorImpl<SourceLocation> &PLocs,
-                                   bool WarnOnDeclarations,
-                                   bool ForObjCContainer,
-                                   SourceLocation &LAngleLoc,
-                                   SourceLocation &EndProtoLoc,
-                                   bool consumeLastToken);
+    /// LateParsedDeclarations - Method declarations, inline definitions and
+    /// nested classes that contain pieces whose parsing will be delayed until
+    /// the top-level class is fully defined.
+    LateParsedDeclarationsContainer LateParsedDeclarations;
+  };
 
-  /// Parse the first angle-bracket-delimited clause for an
-  /// Objective-C object or object pointer type, which may be either
-  /// type arguments or protocol qualifiers.
-  void parseObjCTypeArgsOrProtocolQualifiers(
-         ParsedType baseType,
-         SourceLocation &typeArgsLAngleLoc,
-         SmallVectorImpl<ParsedType> &typeArgs,
-         SourceLocation &typeArgsRAngleLoc,
-         SourceLocation &protocolLAngleLoc,
-         SmallVectorImpl<Decl *> &protocols,
-         SmallVectorImpl<SourceLocation> &protocolLocs,
-         SourceLocation &protocolRAngleLoc,
-         bool consumeLastToken,
-         bool warnOnIncompleteProtocols);
+  /// The stack of classes that is currently being
+  /// parsed. Nested and local classes will be pushed onto this stack
+  /// when they are parsed, and removed afterward.
+  std::stack<ParsingClass *> ClassStack;
 
-  /// Parse either Objective-C type arguments or protocol qualifiers; if the
-  /// former, also parse protocol qualifiers afterward.
-  void parseObjCTypeArgsAndProtocolQualifiers(
-         ParsedType baseType,
-         SourceLocation &typeArgsLAngleLoc,
-         SmallVectorImpl<ParsedType> &typeArgs,
-         SourceLocation &typeArgsRAngleLoc,
-         SourceLocation &protocolLAngleLoc,
-         SmallVectorImpl<Decl *> &protocols,
-         SmallVectorImpl<SourceLocation> &protocolLocs,
-         SourceLocation &protocolRAngleLoc,
-         bool consumeLastToken);
+  ParsingClass &getCurrentClass() {
+    assert(!ClassStack.empty() && "No lexed method stacks!");
+    return *ClassStack.top();
+  }
 
-  /// Parse a protocol qualifier type such as '<NSCopying>', which is
-  /// an anachronistic way of writing 'id<NSCopying>'.
-  TypeResult parseObjCProtocolQualifierType(SourceLocation &rAngleLoc);
+  /// RAII object used to manage the parsing of a class definition.
+  class ParsingClassDefinition {
+    Parser &P;
+    bool Popped;
+    Sema::ParsingClassState State;
 
-  /// Parse Objective-C type arguments and protocol qualifiers, extending the
-  /// current type with the parsed result.
-  TypeResult parseObjCTypeArgsAndProtocolQualifiers(SourceLocation loc,
-                                                    ParsedType type,
-                                                    bool consumeLastToken,
-                                                    SourceLocation &endLoc);
-
-  void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
-                                  Decl *CDecl);
-  DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
-                                                ParsedAttributes &prefixAttrs);
-
-  struct ObjCImplParsingDataRAII {
-    Parser &P;
-    Decl *Dcl;
-    bool HasCFunction;
-    typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
-    LateParsedObjCMethodContainer LateParsedObjCMethods;
-
-    ObjCImplParsingDataRAII(Parser &parser, Decl *D)
-      : P(parser), Dcl(D), HasCFunction(false) {
-      P.CurParsedObjCImpl = this;
-      Finished = false;
+  public:
+    ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass,
+                           bool IsInterface)
+      : P(P), Popped(false),
+        State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
     }
-    ~ObjCImplParsingDataRAII();
 
-    void finish(SourceRange AtEnd);
-    bool isFinished() const { return Finished; }
+    /// Pop this class of the stack.
+    void Pop() {
+      assert(!Popped && "Nested class has already been popped");
+      Popped = true;
+      P.PopParsingClass(State);
+    }
 
-  private:
-    bool Finished;
+    ~ParsingClassDefinition() {
+      if (!Popped)
+        P.PopParsingClass(State);
+    }
   };
-  ObjCImplParsingDataRAII *CurParsedObjCImpl;
-  void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
-
-  DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
-                                                      ParsedAttributes &Attrs);
-  DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
-  Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
-  Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
-  Decl *ParseObjCPropertyDynamic(SourceLocation atLoc);
 
-  IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
+  /// 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 tryParseExceptionSpecification(
+                    bool Delayed,
+                    SourceRange &SpecificationRange,
+                    SmallVectorImpl<ParsedType> &DynamicExceptions,
+                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
+                    ExprResult &NoexceptExpr,
+                    CachedTokens *&ExceptionSpecTokens);
 
-  IdentifierInfo *ObjCTypeQuals[llvm::to_underlying(ObjCTypeQual::NumQuals)];
+  /// ParseDynamicExceptionSpecification - Parse a C++
+  /// dynamic-exception-specification (C++ [except.spec]).
+  /// EndLoc is filled with the location of the last token of the specification.
+  ///
+  ///       dynamic-exception-specification:
+  ///         'throw' '(' type-id-list [opt] ')'
+  /// [MS]    'throw' '(' '...' ')'
+  ///
+  ///       type-id-list:
+  ///         type-id ... [opt]
+  ///         type-id-list ',' type-id ... [opt]
+  ///
+  ExceptionSpecificationType ParseDynamicExceptionSpecification(
+                                  SourceRange &SpecificationRange,
+                                  SmallVectorImpl<ParsedType> &Exceptions,
+                                  SmallVectorImpl<SourceRange> &Ranges);
 
-  bool isTokIdentifier_in() const;
+  //===--------------------------------------------------------------------===//
+  // C++0x 8: Function declaration trailing-return-type
 
-  ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx,
-                               ParsedAttributes *ParamAttrs);
-  Decl *ParseObjCMethodPrototype(
-            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
-            bool MethodDefinition = true);
-  Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
-            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
-            bool MethodDefinition=true);
-  void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
+  /// ParseTrailingReturnType - Parse a trailing return type on a new-style
+  /// function declaration.
+  TypeResult ParseTrailingReturnType(SourceRange &Range,
+                                     bool MayBeFollowedByDirectInit);
 
-  Decl *ParseObjCMethodDefinition();
+  /// Parse a requires-clause as part of a function declaration.
+  void ParseTrailingRequiresClause(Declarator &D);
 
-public:
-  //===--------------------------------------------------------------------===//
-  // C99 6.5: Expressions.
+  void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
+                                              ParsedAttributes &AccessAttrs,
+                                              AccessSpecifier &CurAS);
 
-  ExprResult
-  ParseExpression(TypeCastState isTypeCast = TypeCastState::NotTypeCast);
-  ExprResult ParseConstantExpressionInExprEvalContext(
-      TypeCastState isTypeCast = TypeCastState::NotTypeCast);
-  ExprResult ParseConstantExpression();
-  ExprResult ParseArrayBoundExpression();
-  ExprResult ParseCaseExpression(SourceLocation CaseLoc);
-  ExprResult ParseConstraintExpression();
-  ExprResult
-  ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause);
-  ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause);
-  // Expr that doesn't include commas.
-  ExprResult ParseAssignmentExpression(
-      TypeCastState isTypeCast = TypeCastState::NotTypeCast);
-  ExprResult ParseConditionalExpression();
+  SourceLocation ParsePackIndexingType(DeclSpec &DS);
+  void AnnotateExistingIndexedTypeNamePack(ParsedType T,
+                                           SourceLocation StartLoc,
+                                           SourceLocation EndLoc);
 
-  ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
-                                  unsigned &NumLineToksConsumed,
-                                  bool IsUnevaluated);
+  /// Return true if the next token should be treated as a [[]] attribute,
+  /// or as a keyword that behaves like one.  The former is only true if
+  /// [[]] attributes are enabled, whereas the latter is true whenever
+  /// such a keyword appears.  The arguments are as for
+  /// isCXX11AttributeSpecifier.
+  bool isAllowedCXX11AttributeSpecifier(bool Disambiguate = false,
+                                        bool OuterMightBeMessageSend = false) {
+    return (Tok.isRegularKeywordAttribute() ||
+            isCXX11AttributeSpecifier(Disambiguate, OuterMightBeMessageSend) !=
+                CXX11AttributeKind::NotAttributeSpecifier);
+  }
 
-  ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
-  ExprResult ParseUnevaluatedStringLiteralExpression();
+  /// Skip C++11 and C23 attributes and return the end location of the
+  /// last one.
+  /// \returns SourceLocation() if there are no attributes.
+  SourceLocation SkipCXX11Attributes();
 
-private:
-  ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
-                                          bool Unevaluated);
+  /// Diagnose and skip C++11 and C23 attributes that appear in syntactic
+  /// locations where attributes are not allowed.
+  void DiagnoseAndSkipCXX11Attributes();
 
-  ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
+  void ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,
+                                CachedTokens &OpenMPTokens);
 
-  ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
+  /// 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 ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
+                                            CachedTokens &OpenMPTokens,
+                                            SourceLocation *EndLoc = nullptr);
+  void ParseCXX11AttributeSpecifier(ParsedAttributes &Attrs,
+                                    SourceLocation *EndLoc = nullptr) {
+    CachedTokens OpenMPTokens;
+    ParseCXX11AttributeSpecifierInternal(Attrs, OpenMPTokens, EndLoc);
+    ReplayOpenMPAttributeTokens(OpenMPTokens);
+  }
+  
+  /// ParseCXX11Attributes - Parse a C++11 or C23 attribute-specifier-seq.
+  ///
+  /// attribute-specifier-seq:
+  ///       attribute-specifier-seq[opt] attribute-specifier
+  void ParseCXX11Attributes(ParsedAttributes &attrs);
+  
+  /// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause.
+  /// Parses a C++11 (or C23)-style attribute argument list. Returns true
+  /// if this results in adding an attribute to the ParsedAttributes list.
+  ///
+  /// [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 ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
+                               SourceLocation AttrNameLoc,
+                               ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                               IdentifierInfo *ScopeName,
+                               SourceLocation ScopeLoc,
+                               CachedTokens &OpenMPTokens);
 
-  ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec);
+  /// Parse the argument to C++23's [[assume()]] attribute. Returns true on error.
+  bool ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
+                                  IdentifierInfo *AttrName,
+                                  SourceLocation AttrNameLoc,
+                                  SourceLocation *EndLoc,
+                                  ParsedAttr::Form Form);
 
-  bool isRevertibleTypeTrait(const IdentifierInfo *Id,
-                             clang::tok::TokenKind *Kind = nullptr);
+  /// 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 *TryParseCXX11AttributeIdentifier(
+      SourceLocation &Loc,
+      SemaCodeCompletion::AttributeCompletion Completion =
+          SemaCodeCompletion::AttributeCompletion::None,
+      const IdentifierInfo *EnclosingScope = nullptr);
 
-  ExprResult ParseCastExpression(CastParseKind ParseKind,
-                                 bool isAddressOfOperand,
-                                 bool &NotCastExpr,
-                                 TypeCastState isTypeCast,
-                                 bool isVectorLiteral = false,
-                                 bool *NotPrimaryExpression = nullptr);
-  ExprResult
-  ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand = false,
-                      TypeCastState isTypeCast = TypeCastState::NotTypeCast,
-                      bool isVectorLiteral = false,
-                      bool *NotPrimaryExpression = nullptr);
+  /// Parse uuid() attribute when it appears in a [] Microsoft attribute.
+  void 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 ParseMicrosoftAttributes(ParsedAttributes &Attrs);
 
-  /// Returns true if the next token cannot start an expression.
-  bool isNotExpressionStart();
+  void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
+  void ParseNullabilityClassAttributes(ParsedAttributes &attrs);
 
-  /// Returns true if the next token would start a postfix-expression
-  /// suffix.
-  bool isPostfixExpressionSuffixStart() {
-    tok::TokenKind K = Tok.getKind();
-    return (K == tok::l_square || K == tok::l_paren ||
-            K == tok::period || K == tok::arrow ||
-            K == tok::plusplus || K == tok::minusminus);
-  }
+  /// ParseDecltypeSpecifier - Parse a C++11 decltype specifier.
+  ///
+  /// 'decltype' ( expression )
+  /// 'decltype' ( 'auto' )      [C++1y]
+  ///
+  SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
+  void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
+                                         SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
 
-  bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
-  void checkPotentialAngleBracket(ExprResult &PotentialTemplateName);
-  bool checkPotentialAngleBracketDelimiter(const AngleBracketTracker::Loc &,
-                                           const Token &OpToken);
-  bool checkPotentialAngleBracketDelimiter(const Token &OpToken) {
-    if (auto *Info = AngleBrackets.getCurrent(*this))
-      return checkPotentialAngleBracketDelimiter(*Info, OpToken);
-    return false;
+  /// isCXX11VirtSpecifier - Determine whether the given token is a C++11
+  /// virt-specifier.
+  ///
+  ///       virt-specifier:
+  ///         override
+  ///         final
+  ///         __final
+  VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
+  VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
+    return isCXX11VirtSpecifier(Tok);
   }
 
-  ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
-  ExprResult ParseUnaryExprOrTypeTraitExpression();
-  ExprResult ParseBuiltinPrimaryExpression();
-  ExprResult ParseSYCLUniqueStableNameExpression();
+  /// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq.
+  ///
+  ///       virt-specifier-seq:
+  ///         virt-specifier
+  ///         virt-specifier-seq virt-specifier
+  void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface,
+                                          SourceLocation FriendLoc);
 
-  ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
-                                                     bool &isCastExpr,
-                                                     ParsedType &CastTy,
-                                                     SourceRange &CastRange);
+  /// isCXX11FinalKeyword - Determine whether the next token is a C++11
+  /// 'final' or Microsoft 'sealed' contextual keyword.
+  bool isCXX11FinalKeyword() const;
+  
+  /// isClassCompatibleKeyword - Determine whether the next token is a C++11
+  /// 'final' or Microsoft 'sealed' or 'abstract' contextual keywords.
+  bool isClassCompatibleKeyword() const;
 
-  /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
-  bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
-                           llvm::function_ref<void()> ExpressionStarts =
-                               llvm::function_ref<void()>(),
-                           bool FailImmediatelyOnInvalidExpr = false,
-                           bool EarlyTypoCorrection = false);
+  bool MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS);
+  DeclSpec::TST TypeTransformTokToDeclSpec();
 
-  /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
-  /// used for misc language extensions.
-  bool ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs);
+  void DiagnoseUnexpectedNamespace(NamedDecl *Context);
 
-  ExprResult ParseParenExpression(ParenParseOption &ExprType,
-                                        bool stopIfCastExpr,
-                                        bool isTypeCast,
-                                        ParsedType &CastTy,
-                                        SourceLocation &RParenLoc);
-
-  ExprResult ParseCXXAmbiguousParenExpression(
-      ParenParseOption &ExprType, ParsedType &CastTy,
-      BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
-  ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
-                                                  SourceLocation LParenLoc,
-                                                  SourceLocation RParenLoc);
-
-  ExprResult ParseGenericSelectionExpression();
-
-  ExprResult ParseObjCBoolLiteral();
-
-  ExprResult ParseFoldExpression(ExprResult LHS, BalancedDelimiterTracker &T);
-
-  //===--------------------------------------------------------------------===//
-  // C++ Expressions
-  ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOperand,
-                                     Token &Replacement);
-
-  ExprResult tryParseCXXPackIndexingExpression(ExprResult PackIdExpression);
-  ExprResult ParseCXXPackIndexingExpression(ExprResult PackIdExpression);
-
-  ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
+  /// 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 ';'
+  ///
+  DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
+                                SourceLocation &DeclEnd,
+                                SourceLocation InlineLoc = SourceLocation());
 
-  bool areTokensAdjacent(const Token &A, const Token &B);
+  struct InnerNamespaceInfo {
+    SourceLocation NamespaceLoc;
+    SourceLocation InlineLoc;
+    SourceLocation IdentLoc;
+    IdentifierInfo *Ident;
+  };
+  using InnerNamespaceInfoList = llvm::SmallVector<InnerNamespaceInfo, 4>;
 
-  void CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectTypePtr,
-                                  bool EnteringContext, IdentifierInfo &II,
-                                  CXXScopeSpec &SS);
+  /// ParseInnerNamespace - Parse the contents of a namespace.
+  void ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
+                           unsigned int index, SourceLocation &InlineLoc,
+                           ParsedAttributes &attrs,
+                           BalancedDelimiterTracker &Tracker);
+  
+  /// 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 *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 *ParseExportDeclaration();
 
-  bool ParseOptionalCXXScopeSpecifier(
-      CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHasErrors,
-      bool EnteringContext, bool *MayBePseudoDestructor = nullptr,
-      bool IsTypename = false, const IdentifierInfo **LastII = nullptr,
-      bool OnlyNamespace = false, bool InUsingDeclaration = false,
-      bool Disambiguation = false);
+  /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
+  /// using-directive. Assumes that current token is 'using'.
+  DeclGroupPtrTy 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 *ParseUsingDirective(DeclaratorContext Context,
+                            SourceLocation UsingLoc,
+                            SourceLocation &DeclEnd,
+                            ParsedAttributes &attrs);
 
-  //===--------------------------------------------------------------------===//
-  // C++11 5.1.2: Lambda expressions
+  struct UsingDeclarator {
+    SourceLocation TypenameLoc;
+    CXXScopeSpec SS;
+    UnqualifiedId Name;
+    SourceLocation EllipsisLoc;
 
-  /// Result of tentatively parsing a lambda-introducer.
-  enum class LambdaIntroducerTentativeParse {
-    /// This appears to be a lambda-introducer, which has been fully parsed.
-    Success,
-    /// This is a lambda-introducer, but has not been fully parsed, and this
-    /// function needs to be called again to parse it.
-    Incomplete,
-    /// This is definitely an Objective-C message send expression, rather than
-    /// a lambda-introducer, attribute-specifier, or array designator.
-    MessageSend,
-    /// This is not a lambda-introducer.
-    Invalid,
+    void clear() {
+      TypenameLoc = EllipsisLoc = SourceLocation();
+      SS.clear();
+      Name.clear();
+    }
   };
 
-  // [...] () -> type {...}
-  ExprResult ParseLambdaExpression();
-  ExprResult TryParseLambdaExpression();
-  bool
-  ParseLambdaIntroducer(LambdaIntroducer &Intro,
-                        LambdaIntroducerTentativeParse *Tentative = nullptr);
-  ExprResult ParseLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro);
-
-  //===--------------------------------------------------------------------===//
-  // C++ 5.2p1: C++ Casts
-  ExprResult ParseCXXCasts();
-
-  /// Parse a __builtin_bit_cast(T, E), used to implement C++2a std::bit_cast.
-  ExprResult ParseBuiltinBitCast();
+  /// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
+  ///
+  ///     using-declarator:
+  ///       'typename'[opt] nested-name-specifier unqualified-id
+  ///
+  bool 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
+  DeclGroupPtrTy ParseUsingDeclaration(DeclaratorContext Context,
+                                       const ParsedTemplateInfo &TemplateInfo,
+                                       SourceLocation UsingLoc,
+                                       SourceLocation &DeclEnd,
+                                       ParsedAttributes &Attrs,
+                                       AccessSpecifier AS = AS_none);
+  Decl *ParseAliasDeclarationAfterDeclarator(
+      const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
+      UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
+      ParsedAttributes &Attrs, Decl **OwnedType = nullptr);
 
-  //===--------------------------------------------------------------------===//
-  // C++ 5.2p1: C++ Type Identification
-  ExprResult ParseCXXTypeid();
+  /// 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 *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
+  
+  /// ParseNamespaceAlias - Parse the part after the '=' in a namespace
+  /// alias definition.
+  ///
+  Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
+                            SourceLocation AliasLoc, IdentifierInfo *Alias,
+                            SourceLocation &DeclEnd);
 
   //===--------------------------------------------------------------------===//
-  //  C++ : Microsoft __uuidof Expression
-  ExprResult ParseCXXUuidof();
+  // C++ 9: classes [class] and C structs/unions.
+  
+  /// 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 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 ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
+                           DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
+                           AccessSpecifier AS, bool EnteringContext,
+                           DeclSpecContext DSC, ParsedAttributes &Attributes);
+  void SkipCXXMemberSpecification(SourceLocation StartLoc,
+                                  SourceLocation AttrFixitLoc,
+                                  unsigned TagType,
+                                  Decl *TagDecl);
+  
+  /// ParseCXXMemberSpecification - Parse the class definition.
+  ///
+  ///       member-specification:
+  ///         member-declaration member-specification[opt]
+  ///         access-specifier ':' member-specification[opt]
+  ///
+  void ParseCXXMemberSpecification(SourceLocation StartLoc,
+                                   SourceLocation AttrFixitLoc,
+                                   ParsedAttributes &Attrs, unsigned TagType,
+                                   Decl *TagDecl);
+  
+  /// 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 ParseCXXMemberInitializer(Decl *D, bool IsFunction,
+                                       SourceLocation &EqualLoc);
+  
+  /// Parse a C++ member-declarator up to, but not including, the optional
+  /// brace-or-equal-initializer or pure-specifier.
+  bool
+  ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
+                                            VirtSpecifiers &VS,
+                                            ExprResult &BitfieldSize,
+                                            LateParsedAttrList &LateAttrs);
+  
+  /// Look for declaration specifiers possibly occurring after C++11
+  /// virt-specifier-seq and diagnose them.
+  void 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
+  ///
+  DeclGroupPtrTy ParseCXXClassMemberDeclaration(
+      AccessSpecifier AS, ParsedAttributes &Attr,
+      ParsedTemplateInfo &TemplateInfo,
+      ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
+  DeclGroupPtrTy
+  ParseCXXClassMemberDeclarationWithPragmas(AccessSpecifier &AS,
+                                            ParsedAttributes &AccessAttrs,
+                                            DeclSpec::TST TagType, Decl *Tag);
+  
+  /// 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 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 ParseMemInitializer(Decl *ConstructorDecl);
+  
+  /// 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 HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
+                                      Decl *ThisDecl);
 
   //===--------------------------------------------------------------------===//
-  // C++ 5.2.4: C++ Pseudo-Destructor Expressions
-  ExprResult ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
-                                            tok::TokenKind OpKind,
-                                            CXXScopeSpec &SS,
-                                            ParsedType ObjectType);
+  // C++ 10: Derived classes [class.derived]
+  
+  /// 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 ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
+                                    SourceLocation &EndLocation);
+  
+  /// 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 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 ParseBaseSpecifier(Decl *ClassDecl);
+  
+  /// getAccessSpecifierIfPresent - Determine whether the next token is
+  /// a C++ access-specifier.
+  ///
+  ///       access-specifier: [C++ class.derived]
+  ///         'private'
+  ///         'protected'
+  ///         'public'
+  AccessSpecifier getAccessSpecifierIfPresent() const;
 
-  //===--------------------------------------------------------------------===//
-  // C++ 9.3.2: C++ 'this' pointer
-  ExprResult ParseCXXThis();
+  ///@}
 
-  //===--------------------------------------------------------------------===//
-  // C++ 15: C++ Throw Expression
-  ExprResult ParseThrowExpression();
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-  ExceptionSpecificationType tryParseExceptionSpecification(
-                    bool Delayed,
-                    SourceRange &SpecificationRange,
-                    SmallVectorImpl<ParsedType> &DynamicExceptions,
-                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
-                    ExprResult &NoexceptExpr,
-                    CachedTokens *&ExceptionSpecTokens);
+  /// \name Expressions
+  /// Implementations are in ParseExpr.cpp
+  ///@{
 
-  // EndLoc is filled with the location of the last token of the specification.
-  ExceptionSpecificationType ParseDynamicExceptionSpecification(
-                                  SourceRange &SpecificationRange,
-                                  SmallVectorImpl<ParsedType> &Exceptions,
-                                  SmallVectorImpl<SourceRange> &Ranges);
+  public:
 
-  //===--------------------------------------------------------------------===//
-  // C++0x 8: Function declaration trailing-return-type
-  TypeResult ParseTrailingReturnType(SourceRange &Range,
-                                     bool MayBeFollowedByDirectInit);
+  friend class OffsetOfStateRAIIObject;
 
-  //===--------------------------------------------------------------------===//
-  // C++ 2.13.5: C++ Boolean Literals
-  ExprResult ParseCXXBoolLiteral();
+  typedef Sema::FullExprArg FullExprArg;
 
   //===--------------------------------------------------------------------===//
-  // C++ 5.2.3: Explicit type conversion (functional notation)
-  ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
+  // C99 6.5: Expressions.
 
-  /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
-  /// This should only be called when the current token is known to be part of
-  /// simple-type-specifier.
-  void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
+  /// Simple precedence-based parser for binary/ternary operators.
+  ///
+  /// Note: we diverge from the C99 grammar when parsing the assignment-expression
+  /// production.  C99 specifies that the LHS of an assignment operator should be
+  /// parsed as a unary-expression, but consistency dictates that it be a
+  /// conditional-expession.  In practice, the important thing here is that the
+  /// LHS of an assignment has to be an l-value, which productions between
+  /// unary-expression and conditional-expression don't produce.  Because we want
+  /// consistency, we parse the LHS as a conditional-expression, then check for
+  /// l-value-ness in semantic analysis stages.
+  ///
+  /// \verbatim
+  ///       pm-expression: [C++ 5.5]
+  ///         cast-expression
+  ///         pm-expression '.*' cast-expression
+  ///         pm-expression '->*' cast-expression
+  ///
+  ///       multiplicative-expression: [C99 6.5.5]
+  ///     Note: in C++, apply pm-expression instead of cast-expression
+  ///         cast-expression
+  ///         multiplicative-expression '*' cast-expression
+  ///         multiplicative-expression '/' cast-expression
+  ///         multiplicative-expression '%' cast-expression
+  ///
+  ///       additive-expression: [C99 6.5.6]
+  ///         multiplicative-expression
+  ///         additive-expression '+' multiplicative-expression
+  ///         additive-expression '-' multiplicative-expression
+  ///
+  ///       shift-expression: [C99 6.5.7]
+  ///         additive-expression
+  ///         shift-expression '<<' additive-expression
+  ///         shift-expression '>>' additive-expression
+  ///
+  ///       compare-expression: [C++20 expr.spaceship]
+  ///         shift-expression
+  ///         compare-expression '<=>' shift-expression
+  ///
+  ///       relational-expression: [C99 6.5.8]
+  ///         compare-expression
+  ///         relational-expression '<' compare-expression
+  ///         relational-expression '>' compare-expression
+  ///         relational-expression '<=' compare-expression
+  ///         relational-expression '>=' compare-expression
+  ///
+  ///       equality-expression: [C99 6.5.9]
+  ///         relational-expression
+  ///         equality-expression '==' relational-expression
+  ///         equality-expression '!=' relational-expression
+  ///
+  ///       AND-expression: [C99 6.5.10]
+  ///         equality-expression
+  ///         AND-expression '&' equality-expression
+  ///
+  ///       exclusive-OR-expression: [C99 6.5.11]
+  ///         AND-expression
+  ///         exclusive-OR-expression '^' AND-expression
+  ///
+  ///       inclusive-OR-expression: [C99 6.5.12]
+  ///         exclusive-OR-expression
+  ///         inclusive-OR-expression '|' exclusive-OR-expression
+  ///
+  ///       logical-AND-expression: [C99 6.5.13]
+  ///         inclusive-OR-expression
+  ///         logical-AND-expression '&&' inclusive-OR-expression
+  ///
+  ///       logical-OR-expression: [C99 6.5.14]
+  ///         logical-AND-expression
+  ///         logical-OR-expression '||' logical-AND-expression
+  ///
+  ///       conditional-expression: [C99 6.5.15]
+  ///         logical-OR-expression
+  ///         logical-OR-expression '?' expression ':' conditional-expression
+  /// [GNU]   logical-OR-expression '?' ':' conditional-expression
+  /// [C++] the third operand is an assignment-expression
+  ///
+  ///       assignment-expression: [C99 6.5.16]
+  ///         conditional-expression
+  ///         unary-expression assignment-operator assignment-expression
+  /// [C++]   throw-expression [C++ 15]
+  ///
+  ///       assignment-operator: one of
+  ///         = *= /= %= += -= <<= >>= &= ^= |=
+  ///
+  ///       expression: [C99 6.5.17]
+  ///         assignment-expression ...[opt]
+  ///         expression ',' assignment-expression ...[opt]
+  /// \endverbatim
+  ExprResult
+  ParseExpression(TypeCastState isTypeCast = TypeCastState::NotTypeCast);
+  
+  ExprResult ParseConstantExpressionInExprEvalContext(
+      TypeCastState isTypeCast = TypeCastState::NotTypeCast);
+  ExprResult ParseConstantExpression();
+  ExprResult ParseArrayBoundExpression();
+  ExprResult ParseCaseExpression(SourceLocation CaseLoc);
+  
+  /// Parse a constraint-expression.
+  ///
+  /// \verbatim
+  ///       constraint-expression: C++2a[temp.constr.decl]p1
+  ///         logical-or-expression
+  /// \endverbatim
+  ExprResult ParseConstraintExpression();
+  
+  /// \brief Parse a constraint-logical-and-expression.
+  ///
+  /// \verbatim
+  ///       C++2a[temp.constr.decl]p1
+  ///       constraint-logical-and-expression:
+  ///         primary-expression
+  ///         constraint-logical-and-expression '&&' primary-expression
+  ///
+  /// \endverbatim
+  ExprResult
+  ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause);
+  
+  /// \brief Parse a constraint-logical-or-expression.
+  ///
+  /// \verbatim
+  ///       C++2a[temp.constr.decl]p1
+  ///       constraint-logical-or-expression:
+  ///         constraint-logical-and-expression
+  ///         constraint-logical-or-expression '||'
+  ///             constraint-logical-and-expression
+  ///
+  /// \endverbatim
+  ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause);
+  
+  /// Parse an expr that doesn't include (top-level) commas.
+  ExprResult ParseAssignmentExpression(
+      TypeCastState isTypeCast = TypeCastState::NotTypeCast);
+  
+  ExprResult ParseConditionalExpression();
 
-  bool ParseCXXTypeSpecifierSeq(
-      DeclSpec &DS, DeclaratorContext Context = DeclaratorContext::TypeName);
+  /// ParseStringLiteralExpression - This handles the various token types that
+  /// form string literals, and also handles string concatenation [C99 5.1.1.2,
+  /// translation phase #6].
+  ///
+  /// \verbatim
+  ///       primary-expression: [C99 6.5.1]
+  ///         string-literal
+  /// \verbatim
+  ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
+  ExprResult ParseUnevaluatedStringLiteralExpression();
 
-  //===--------------------------------------------------------------------===//
-  // C++ 5.3.4 and 5.3.5: C++ new and delete
-  bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr*> &Exprs,
-                                   Declarator &D);
-  void ParseDirectNewDeclarator(Declarator &D);
-  ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
-  ExprResult ParseCXXDeleteExpression(bool UseGlobal,
-                                            SourceLocation Start);
+  private:
 
-  //===--------------------------------------------------------------------===//
-  // C++ if/switch/while/for condition expression.
-  struct ForRangeInfo;
-  Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt,
-                                          SourceLocation Loc,
-                                          Sema::ConditionKind CK,
-                                          bool MissingOK,
-                                          ForRangeInfo *FRI = nullptr,
-                                          bool EnterForConditionScope = false);
-  DeclGroupPtrTy ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
-                                                      ParsedAttributes &Attrs);
+  /// Whether the '>' token acts as an operator or not. This will be
+  /// true except when we are parsing an expression within a C++
+  /// template argument list, where the '>' closes the template
+  /// argument list.
+  bool GreaterThanIsOperator;
 
-  //===--------------------------------------------------------------------===//
-  // C++ Coroutines
+  // C++ type trait keywords that can be reverted to identifiers and still be
+  // used as type traits.
+  llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
 
-  ExprResult ParseCoyieldExpression();
+  OffsetOfKind OffsetOfState = OffsetOfKind::Outside;
 
-  //===--------------------------------------------------------------------===//
-  // C++ Concepts
+  /// The location of the expression statement that is being parsed right now.
+  /// Used to determine if an expression that is being parsed is a statement or
+  /// just a regular sub-expression.
+  SourceLocation ExprStatementTokLoc;
 
-  ExprResult ParseRequiresExpression();
-  void ParseTrailingRequiresClause(Declarator &D);
+  /// Checks if the \p Level is valid for use in a fold expression.
+  bool isFoldOperator(prec::Level Level) const;
 
-  //===--------------------------------------------------------------------===//
-  // C99 6.7.8: Initialization.
+  /// Checks if the \p Kind is a valid operator for fold expressions.
+  bool isFoldOperator(tok::TokenKind Kind) const;
 
-  /// ParseInitializer
-  ///       initializer: [C99 6.7.8]
-  ///         assignment-expression
-  ///         '{' ...
-  ExprResult ParseInitializer() {
-    if (Tok.isNot(tok::l_brace))
-      return ParseAssignmentExpression();
-    return ParseBraceInitializer();
+  /// 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
+  PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
+  
+  /// Deallocate the given parsed class and all of its nested
+  /// classes.
+  void DeallocateParsedClasses(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 PopParsingClass(Sema::ParsingClassState);
+
+  ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
+                                          bool Unevaluated);
+
+  /// This routine is called when the '@' is seen and consumed.
+  /// Current token is an Identifier and is not a 'try'. This
+  /// routine is necessary to disambiguate \@try-statement from,
+  /// for example, \@encode-expression.
+  ///
+  ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
+
+  /// This routine is called when a leading '__extension__' is seen and
+  /// consumed.  This is necessary because the token gets consumed in the
+  /// process of disambiguating between an expression and a declaration.
+  ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
+
+  /// Parse a binary expression that starts with \p LHS and has a
+  /// precedence of at least \p MinPrec.
+  ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec);
+
+  bool isRevertibleTypeTrait(const IdentifierInfo *Id,
+                             clang::tok::TokenKind *Kind = nullptr);
+
+  /// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
+  /// a unary-expression.
+  ///
+  /// \p isAddressOfOperand exists because an id-expression that is the operand
+  /// of address-of gets special treatment due to member pointers. NotCastExpr
+  /// is set to true if the token is not the start of a cast-expression, and no
+  /// diagnostic is emitted in this case and no tokens are consumed.
+  ///
+  /// \verbatim
+  ///       cast-expression: [C99 6.5.4]
+  ///         unary-expression
+  ///         '(' type-name ')' cast-expression
+  ///
+  ///       unary-expression:  [C99 6.5.3]
+  ///         postfix-expression
+  ///         '++' unary-expression
+  ///         '--' unary-expression
+  /// [Coro]  'co_await' cast-expression
+  ///         unary-operator cast-expression
+  ///         'sizeof' unary-expression
+  ///         'sizeof' '(' type-name ')'
+  /// [C++11] 'sizeof' '...' '(' identifier ')'
+  /// [GNU]   '__alignof' unary-expression
+  /// [GNU]   '__alignof' '(' type-name ')'
+  /// [C11]   '_Alignof' '(' type-name ')'
+  /// [C++11] 'alignof' '(' type-id ')'
+  /// [C2y]   '_Countof' unary-expression
+  /// [C2y]   '_Countof' '(' type-name ')'
+  /// [GNU]   '&&' identifier
+  /// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7]
+  /// [C++]   new-expression
+  /// [C++]   delete-expression
+  ///
+  ///       unary-operator: one of
+  ///         '&'  '*'  '+'  '-'  '~'  '!'
+  /// [GNU]   '__extension__'  '__real'  '__imag'
+  ///
+  ///       primary-expression: [C99 6.5.1]
+  /// [C99]   identifier
+  /// [C++]   id-expression
+  ///         constant
+  ///         string-literal
+  /// [C++]   boolean-literal  [C++ 2.13.5]
+  /// [C++11] 'nullptr'        [C++11 2.14.7]
+  /// [C++11] user-defined-literal
+  ///         '(' expression ')'
+  /// [C11]   generic-selection
+  /// [C++2a] requires-expression
+  ///         '__func__'        [C99 6.4.2.2]
+  /// [GNU]   '__FUNCTION__'
+  /// [MS]    '__FUNCDNAME__'
+  /// [MS]    'L__FUNCTION__'
+  /// [MS]    '__FUNCSIG__'
+  /// [MS]    'L__FUNCSIG__'
+  /// [GNU]   '__PRETTY_FUNCTION__'
+  /// [GNU]   '(' compound-statement ')'
+  /// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
+  /// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
+  /// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
+  ///                                     assign-expr ')'
+  /// [GNU]   '__builtin_FILE' '(' ')'
+  /// [CLANG] '__builtin_FILE_NAME' '(' ')'
+  /// [GNU]   '__builtin_FUNCTION' '(' ')'
+  /// [MS]    '__builtin_FUNCSIG' '(' ')'
+  /// [GNU]   '__builtin_LINE' '(' ')'
+  /// [CLANG] '__builtin_COLUMN' '(' ')'
+  /// [GNU]   '__builtin_source_location' '(' ')'
+  /// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+  /// [GNU]   '__null'
+  /// [OBJC]  '[' objc-message-expr ']'
+  /// [OBJC]  '\@selector' '(' objc-selector-arg ')'
+  /// [OBJC]  '\@protocol' '(' identifier ')'
+  /// [OBJC]  '\@encode' '(' type-name ')'
+  /// [OBJC]  objc-string-literal
+  /// [C++]   simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
+  /// [C++11] simple-type-specifier braced-init-list                  [C++11 5.2.3]
+  /// [C++]   typename-specifier '(' expression-list[opt] ')'         [C++ 5.2.3]
+  /// [C++11] typename-specifier braced-init-list                     [C++11 5.2.3]
+  /// [C++]   'const_cast' '<' type-name '>' '(' expression ')'       [C++ 5.2p1]
+  /// [C++]   'dynamic_cast' '<' type-name '>' '(' expression ')'     [C++ 5.2p1]
+  /// [C++]   'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
+  /// [C++]   'static_cast' '<' type-name '>' '(' expression ')'      [C++ 5.2p1]
+  /// [C++]   'typeid' '(' expression ')'                             [C++ 5.2p1]
+  /// [C++]   'typeid' '(' type-id ')'                                [C++ 5.2p1]
+  /// [C++]   'this'          [C++ 9.3.2]
+  /// [G++]   unary-type-trait '(' type-id ')'
+  /// [G++]   binary-type-trait '(' type-id ',' type-id ')'           [TODO]
+  /// [EMBT]  array-type-trait '(' type-id ',' integer ')'
+  /// [clang] '^' block-literal
+  ///
+  ///       constant: [C99 6.4.4]
+  ///         integer-constant
+  ///         floating-constant
+  ///         enumeration-constant -> identifier
+  ///         character-constant
+  ///
+  ///       id-expression: [C++ 5.1]
+  ///                   unqualified-id
+  ///                   qualified-id
+  ///
+  ///       unqualified-id: [C++ 5.1]
+  ///                   identifier
+  ///                   operator-function-id
+  ///                   conversion-function-id
+  ///                   '~' class-name
+  ///                   template-id
+  ///
+  ///       new-expression: [C++ 5.3.4]
+  ///                   '::'[opt] 'new' new-placement[opt] new-type-id
+  ///                                     new-initializer[opt]
+  ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
+  ///                                     new-initializer[opt]
+  ///
+  ///       delete-expression: [C++ 5.3.5]
+  ///                   '::'[opt] 'delete' cast-expression
+  ///                   '::'[opt] 'delete' '[' ']' cast-expression
+  ///
+  /// [GNU/Embarcadero] unary-type-trait:
+  ///                   '__is_arithmetic'
+  ///                   '__is_floating_point'
+  ///                   '__is_integral'
+  ///                   '__is_lvalue_expr'
+  ///                   '__is_rvalue_expr'
+  ///                   '__is_complete_type'
+  ///                   '__is_void'
+  ///                   '__is_array'
+  ///                   '__is_function'
+  ///                   '__is_reference'
+  ///                   '__is_lvalue_reference'
+  ///                   '__is_rvalue_reference'
+  ///                   '__is_fundamental'
+  ///                   '__is_object'
+  ///                   '__is_scalar'
+  ///                   '__is_compound'
+  ///                   '__is_pointer'
+  ///                   '__is_member_object_pointer'
+  ///                   '__is_member_function_pointer'
+  ///                   '__is_member_pointer'
+  ///                   '__is_const'
+  ///                   '__is_volatile'
+  ///                   '__is_trivial'
+  ///                   '__is_standard_layout'
+  ///                   '__is_signed'
+  ///                   '__is_unsigned'
+  ///
+  /// [GNU] unary-type-trait:
+  ///                   '__has_nothrow_assign'
+  ///                   '__has_nothrow_copy'
+  ///                   '__has_nothrow_constructor'
+  ///                   '__has_trivial_assign'                  [TODO]
+  ///                   '__has_trivial_copy'                    [TODO]
+  ///                   '__has_trivial_constructor'
+  ///                   '__has_trivial_destructor'
+  ///                   '__has_virtual_destructor'
+  ///                   '__is_abstract'                         [TODO]
+  ///                   '__is_class'
+  ///                   '__is_empty'                            [TODO]
+  ///                   '__is_enum'
+  ///                   '__is_final'
+  ///                   '__is_pod'
+  ///                   '__is_polymorphic'
+  ///                   '__is_sealed'                           [MS]
+  ///                   '__is_trivial'
+  ///                   '__is_union'
+  ///                   '__has_unique_object_representations'
+  ///
+  /// [Clang] unary-type-trait:
+  ///                   '__is_aggregate'
+  ///                   '__trivially_copyable'
+  ///
+  ///       binary-type-trait:
+  /// [GNU]             '__is_base_of'
+  /// [MS]              '__is_convertible_to'
+  ///                   '__is_convertible'
+  ///                   '__is_same'
+  ///
+  /// [Embarcadero] array-type-trait:
+  ///                   '__array_rank'
+  ///                   '__array_extent'
+  ///
+  /// [Embarcadero] expression-trait:
+  ///                   '__is_lvalue_expr'
+  ///                   '__is_rvalue_expr'
+  /// \endverbatim
+  ///
+  ExprResult ParseCastExpression(CastParseKind ParseKind,
+                                 bool isAddressOfOperand,
+                                 bool &NotCastExpr,
+                                 TypeCastState isTypeCast,
+                                 bool isVectorLiteral = false,
+                                 bool *NotPrimaryExpression = nullptr);
+  ExprResult
+  ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand = false,
+                      TypeCastState isTypeCast = TypeCastState::NotTypeCast,
+                      bool isVectorLiteral = false,
+                      bool *NotPrimaryExpression = nullptr);
+
+  /// Returns true if the next token cannot start an expression.
+  bool isNotExpressionStart();
+
+  /// Returns true if the next token would start a postfix-expression
+  /// suffix.
+  bool isPostfixExpressionSuffixStart() {
+    tok::TokenKind K = Tok.getKind();
+    return (K == tok::l_square || K == tok::l_paren ||
+            K == tok::period || K == tok::arrow ||
+            K == tok::plusplus || K == tok::minusminus);
   }
-  bool MayBeDesignationStart();
-  ExprResult ParseBraceInitializer();
-  struct DesignatorCompletionInfo {
-    SmallVectorImpl<Expr *> &InitExprs;
-    QualType PreferredBaseType;
-  };
-  ExprResult ParseInitializerWithPotentialDesignator(DesignatorCompletionInfo);
-  ExprResult createEmbedExpr();
+
+  /// Once the leading part of a postfix-expression is parsed, this
+  /// method parses any suffixes that apply.
+  ///
+  /// \verbatim
+  ///       postfix-expression: [C99 6.5.2]
+  ///         primary-expression
+  ///         postfix-expression '[' expression ']'
+  ///         postfix-expression '[' braced-init-list ']'
+  ///         postfix-expression '[' expression-list [opt] ']'  [C++23 12.4.5]
+  ///         postfix-expression '(' argument-expression-list[opt] ')'
+  ///         postfix-expression '.' identifier
+  ///         postfix-expression '->' identifier
+  ///         postfix-expression '++'
+  ///         postfix-expression '--'
+  ///         '(' type-name ')' '{' initializer-list '}'
+  ///         '(' type-name ')' '{' initializer-list ',' '}'
+  ///
+  ///       argument-expression-list: [C99 6.5.2]
+  ///         argument-expression ...[opt]
+  ///         argument-expression-list ',' assignment-expression ...[opt]
+  /// \endverbatim
+  ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
+  
+  /// Parse a sizeof or alignof expression.
+  ///
+  /// \verbatim
+  ///       unary-expression:  [C99 6.5.3]
+  ///         'sizeof' unary-expression
+  ///         'sizeof' '(' type-name ')'
+  /// [C++11] 'sizeof' '...' '(' identifier ')'
+  /// [Clang] '__datasizeof' unary-expression
+  /// [Clang] '__datasizeof' '(' type-name ')'
+  /// [GNU]   '__alignof' unary-expression
+  /// [GNU]   '__alignof' '(' type-name ')'
+  /// [C11]   '_Alignof' '(' type-name ')'
+  /// [C++11] 'alignof' '(' type-id ')'
+  /// [C2y]   '_Countof' unary-expression
+  /// [C2y]   '_Countof' '(' type-name ')'
+  /// \endverbatim
+  ExprResult ParseUnaryExprOrTypeTraitExpression();
+  
+  /// ParseBuiltinPrimaryExpression
+  ///
+  /// \verbatim
+  ///       primary-expression: [C99 6.5.1]
+  /// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
+  /// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
+  /// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
+  ///                                     assign-expr ')'
+  /// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+  /// [GNU]   '__builtin_FILE' '(' ')'
+  /// [CLANG] '__builtin_FILE_NAME' '(' ')'
+  /// [GNU]   '__builtin_FUNCTION' '(' ')'
+  /// [MS]    '__builtin_FUNCSIG' '(' ')'
+  /// [GNU]   '__builtin_LINE' '(' ')'
+  /// [CLANG] '__builtin_COLUMN' '(' ')'
+  /// [GNU]   '__builtin_source_location' '(' ')'
+  /// [OCL]   '__builtin_astype' '(' assignment-expression ',' type-name ')'
+  ///
+  /// [GNU] offsetof-member-designator:
+  /// [GNU]   identifier
+  /// [GNU]   offsetof-member-designator '.' identifier
+  /// [GNU]   offsetof-member-designator '[' expression ']'
+  /// \endverbatim
+  ExprResult ParseBuiltinPrimaryExpression();
+  
+  /// Parse a __builtin_sycl_unique_stable_name expression.  Accepts a type-id as
+  /// a parameter.
+  ExprResult ParseSYCLUniqueStableNameExpression();
+
+  /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/
+  /// vec_step and we are at the start of an expression or a parenthesized
+  /// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the
+  /// expression (isCastExpr == false) or the type (isCastExpr == true).
+  ///
+  /// \verbatim
+  ///       unary-expression:  [C99 6.5.3]
+  ///         'sizeof' unary-expression
+  ///         'sizeof' '(' type-name ')'
+  /// [Clang] '__datasizeof' unary-expression
+  /// [Clang] '__datasizeof' '(' type-name ')'
+  /// [GNU]   '__alignof' unary-expression
+  /// [GNU]   '__alignof' '(' type-name ')'
+  /// [C11]   '_Alignof' '(' type-name ')'
+  /// [C++0x] 'alignof' '(' type-id ')'
+  ///
+  /// [GNU]   typeof-specifier:
+  ///           typeof ( expressions )
+  ///           typeof ( type-name )
+  /// [GNU/C++] typeof unary-expression
+  /// [C23]   typeof-specifier:
+  ///           typeof '(' typeof-specifier-argument ')'
+  ///           typeof_unqual '(' typeof-specifier-argument ')'
+  ///
+  ///         typeof-specifier-argument:
+  ///           expression
+  ///           type-name
+  ///
+  /// [OpenCL 1.1 6.11.12] vec_step built-in function:
+  ///           vec_step ( expressions )
+  ///           vec_step ( type-name )
+  /// \endverbatim
+  ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
+                                                     bool &isCastExpr,
+                                                     ParsedType &CastTy,
+                                                     SourceRange &CastRange);
+
+  /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
+  ///
+  /// \verbatim
+  ///       argument-expression-list:
+  ///         assignment-expression
+  ///         argument-expression-list , assignment-expression
+  ///
+  /// [C++] expression-list:
+  /// [C++]   assignment-expression
+  /// [C++]   expression-list , assignment-expression
+  ///
+  /// [C++0x] expression-list:
+  /// [C++0x]   initializer-list
+  ///
+  /// [C++0x] initializer-list
+  /// [C++0x]   initializer-clause ...[opt]
+  /// [C++0x]   initializer-list , initializer-clause ...[opt]
+  ///
+  /// [C++0x] initializer-clause:
+  /// [C++0x]   assignment-expression
+  /// [C++0x]   braced-init-list
+  /// \endverbatim
+  bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
+                           llvm::function_ref<void()> ExpressionStarts =
+                               llvm::function_ref<void()>(),
+                           bool FailImmediatelyOnInvalidExpr = false,
+                           bool EarlyTypoCorrection = false);
+
+  /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
+  /// used for misc language extensions.
+  ///
+  /// \verbatim
+  ///       simple-expression-list:
+  ///         assignment-expression
+  ///         simple-expression-list , assignment-expression
+  /// \endverbatim
+  bool ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs);
+
+  /// ParseParenExpression - This parses the unit that starts with a '(' token,
+  /// based on what is allowed by ExprType.  The actual thing parsed is returned
+  /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
+  /// not the parsed cast-expression.
+  ///
+  /// \verbatim
+  ///       primary-expression: [C99 6.5.1]
+  ///         '(' expression ')'
+  /// [GNU]   '(' compound-statement ')'      (if !ParenExprOnly)
+  ///       postfix-expression: [C99 6.5.2]
+  ///         '(' type-name ')' '{' initializer-list '}'
+  ///         '(' type-name ')' '{' initializer-list ',' '}'
+  ///       cast-expression: [C99 6.5.4]
+  ///         '(' type-name ')' cast-expression
+  /// [ARC]   bridged-cast-expression
+  /// [ARC] bridged-cast-expression:
+  ///         (__bridge type-name) cast-expression
+  ///         (__bridge_transfer type-name) cast-expression
+  ///         (__bridge_retained type-name) cast-expression
+  ///       fold-expression: [C++1z]
+  ///         '(' cast-expression fold-operator '...' ')'
+  ///         '(' '...' fold-operator cast-expression ')'
+  ///         '(' cast-expression fold-operator '...'
+  ///                 fold-operator cast-expression ')'
+  /// [OPENMP] Array shaping operation
+  ///       '(' '[' expression ']' { '[' expression ']' } cast-expression
+  /// \endverbatim
+  ExprResult ParseParenExpression(ParenParseOption &ExprType,
+                                        bool stopIfCastExpr,
+                                        bool isTypeCast,
+                                        ParsedType &CastTy,
+                                        SourceLocation &RParenLoc);
+
+  /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
+  /// and we are at the left brace.
+  ///
+  /// \verbatim
+  ///       postfix-expression: [C99 6.5.2]
+  ///         '(' type-name ')' '{' initializer-list '}'
+  ///         '(' type-name ')' '{' initializer-list ',' '}'
+  /// \endverbatim
+  ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
+                                                  SourceLocation LParenLoc,
+                                                  SourceLocation RParenLoc);
+
+  /// ParseGenericSelectionExpression - Parse a C11 generic-selection
+  /// [C11 6.5.1.1].
+  ///
+  /// \verbatim
+  ///    generic-selection:
+  ///           _Generic ( assignment-expression , generic-assoc-list )
+  ///    generic-assoc-list:
+  ///           generic-association
+  ///           generic-assoc-list , generic-association
+  ///    generic-association:
+  ///           type-name : assignment-expression
+  ///           default : assignment-expression
+  /// \endverbatim
+  ///
+  /// As an extension, Clang also accepts:
+  /// \verbatim
+  ///   generic-selection:
+  ///          _Generic ( type-name, generic-assoc-list )
+  /// \endverbatim
+  ExprResult ParseGenericSelectionExpression();
+
+  /// ParseObjCBoolLiteral - This handles the objective-c Boolean literals.
+  ///
+  ///         '__objc_yes'
+  ///         '__objc_no'
+  ExprResult ParseObjCBoolLiteral();
+
+  /// Parse A C++1z fold-expression after the opening paren and optional
+  /// left-hand-side expression.
+  ///
+  /// \verbatim
+  ///   fold-expression:
+  ///       ( cast-expression fold-operator ... )
+  ///       ( ... fold-operator cast-expression )
+  ///       ( cast-expression fold-operator ... fold-operator cast-expression )
+  /// \endverbatim
+  ExprResult ParseFoldExpression(ExprResult LHS, BalancedDelimiterTracker &T);
+
   void injectEmbedTokens();
 
   //===--------------------------------------------------------------------===//
   // clang Expressions
 
+  /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
+  /// like ^(int x){ return x+1; }
+  ///
+  /// \verbatim
+  ///         block-literal:
+  /// [clang]   '^' block-args[opt] compound-statement
+  /// [clang]   '^' block-id compound-statement
+  /// [clang] block-args:
+  /// [clang]   '(' parameter-list ')'
+  /// \endverbatim
   ExprResult ParseBlockLiteralExpression();  // ^{...}
 
-  //===--------------------------------------------------------------------===//
-  // Objective-C Expressions
-  ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
-  ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
-  ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
-  ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
-  ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
-  ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
-  ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
-  ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
-  ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
-  ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
-  ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
-  bool isSimpleObjCMessageExpression();
-  ExprResult ParseObjCMessageExpression();
-  ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
-                                            SourceLocation SuperLoc,
-                                            ParsedType ReceiverType,
-                                            Expr *ReceiverExpr);
+  /// Parse an assignment expression where part of an Objective-C message
+  /// send has already been parsed.
+  ///
+  /// In this case \p LBracLoc indicates the location of the '[' of the message
+  /// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating
+  /// the receiver of the message.
+  ///
+  /// Since this handles full assignment-expression's, it handles postfix
+  /// expressions and other binary operators for these expressions as well.
   ExprResult ParseAssignmentExprWithObjCMessageExprStart(
       SourceLocation LBracloc, SourceLocation SuperLoc,
       ParsedType ReceiverType, Expr *ReceiverExpr);
-  bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
-
-  //===--------------------------------------------------------------------===//
-  // C99 6.8: Statements and Blocks.
-
-  /// A SmallVector of expressions.
-  typedef SmallVector<Expr*, 12> ExprVector;
 
-  StmtResult
-  ParseStatement(SourceLocation *TrailingElseLoc = nullptr,
-                 ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt);
-  StmtResult ParseStatementOrDeclaration(
-      StmtVector &Stmts, ParsedStmtContext StmtCtx,
-      SourceLocation *TrailingElseLoc = nullptr);
-  StmtResult ParseStatementOrDeclarationAfterAttributes(
-      StmtVector &Stmts, ParsedStmtContext StmtCtx,
-      SourceLocation *TrailingElseLoc, ParsedAttributes &DeclAttrs,
-      ParsedAttributes &DeclSpecAttrs);
-  StmtResult ParseExprStatement(ParsedStmtContext StmtCtx);
-  StmtResult ParseLabeledStatement(ParsedAttributes &Attrs,
-                                   ParsedStmtContext StmtCtx);
-  StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx,
-                                bool MissingCase = false,
-                                ExprResult Expr = ExprResult());
-  StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx);
-  StmtResult ParseCompoundStatement(bool isStmtExpr = false);
-  StmtResult ParseCompoundStatement(bool isStmtExpr,
-                                    unsigned ScopeFlags);
-  void ParseCompoundStatementLeadingPragmas();
-  void DiagnoseLabelAtEndOfCompoundStatement();
-  bool ConsumeNullStmt(StmtVector &Stmts);
-  StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
-  bool ParseParenExprOrCondition(StmtResult *InitStmt,
-                                 Sema::ConditionResult &CondResult,
-                                 SourceLocation Loc, Sema::ConditionKind CK,
-                                 SourceLocation &LParenLoc,
-                                 SourceLocation &RParenLoc);
-  StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
-  StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
-  StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
-  StmtResult ParseDoStatement();
-  StmtResult ParseForStatement(SourceLocation *TrailingElseLoc);
-  StmtResult ParseGotoStatement();
-  StmtResult ParseContinueStatement();
-  StmtResult ParseBreakStatement();
-  StmtResult ParseReturnStatement();
-  StmtResult ParseAsmStatement(bool &msAsm);
-  StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
-  StmtResult ParsePragmaLoopHint(StmtVector &Stmts, ParsedStmtContext StmtCtx,
-                                 SourceLocation *TrailingElseLoc,
-                                 ParsedAttributes &Attrs);
+  /// Return true if we know that we are definitely looking at a
+  /// decl-specifier, and isn't part of an expression such as a function-style
+  /// cast. Return false if it's no a decl-specifier, or we're not sure.
+  bool isKnownToBeDeclarationSpecifier() {
+    if (getLangOpts().CPlusPlus)
+      return isCXXDeclarationSpecifier(ImplicitTypenameContext::No) ==
+             TPResult::True;
+    return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
+  }
 
-  /// Describes the condition of a Microsoft __if_exists or
-  /// __if_not_exists block.
-  struct IfExistsCondition {
-    /// The location of the initial keyword.
-    SourceLocation KeywordLoc;
-    /// Whether this is an __if_exists block (rather than an
-    /// __if_not_exists block).
-    bool IsIfExists;
+  /// Checks whether the current tokens form a type-id or an expression for the
+  /// purposes of use as the initial operand to a generic selection expression.
+  /// This requires special handling in C++ because it accepts either a type or
+  /// an expression, and we need to disambiguate which is which. However, we
+  /// cannot use the same logic as we've used for sizeof expressions, because
+  /// that logic relies on the operator only accepting a single argument,
+  /// whereas _Generic accepts a list of arguments.
+  bool isTypeIdForGenericSelection() {
+    if (getLangOpts().CPlusPlus) {
+      bool isAmbiguous;
+      return isCXXTypeId(TentativeCXXTypeIdContext::AsGenericSelectionArgument,
+                         isAmbiguous);
+    }
+    return isTypeSpecifierQualifier();
+  }
 
-    /// Nested-name-specifier preceding the name.
-    CXXScopeSpec SS;
+  /// Checks if the current tokens form type-id or expression.
+  /// It is similar to isTypeIdInParens but does not suppose that type-id
+  /// is in parenthesis.
+  bool isTypeIdUnambiguously() {
+    if (getLangOpts().CPlusPlus) {
+      bool isAmbiguous;
+      return isCXXTypeId(TentativeCXXTypeIdContext::Unambiguous, isAmbiguous);
+    }
+    return isTypeSpecifierQualifier();
+  }
 
-    /// The name we're looking for.
-    UnqualifiedId Name;
+  /// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
+  ///
+  /// \verbatim
+  /// [clang] block-id:
+  /// [clang]   specifier-qualifier-list block-declarator
+  /// \endverbatim
+  void ParseBlockId(SourceLocation CaretLoc); 
 
-    /// The behavior of this __if_exists or __if_not_exists block
-    /// should.
-    IfExistsBehavior Behavior;
+  /// Parse availability query specification.
+  ///
+  ///  availability-spec:
+  ///     '*'
+  ///     identifier version-tuple
+  std::optional<AvailabilitySpec> ParseAvailabilitySpec();
+  ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
+
+  /// Tries to parse cast part of OpenMP array shaping operation:
+  /// '[' expression ']' { '[' expression ']' } ')'.
+  bool tryParseOpenMPArrayShapingCastPart();
+
+  ExprResult ParseBuiltinPtrauthTypeDiscriminator();
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name C++ Expressions
+  /// Implementations are in ParseExprCXX.cpp
+  ///@{
+
+  public:
+
+  /// Parse a C++ unqualified-id (or a C identifier), which describes the
+  /// name of an entity.
+  ///
+  /// \code
+  ///       unqualified-id: [C++ expr.prim.general]
+  ///         identifier
+  ///         operator-function-id
+  ///         conversion-function-id
+  /// [C++0x] literal-operator-id [TODO]
+  ///         ~ class-name
+  ///         template-id
+  ///
+  /// \endcode
+  ///
+  /// \param SS The nested-name-specifier that preceded this unqualified-id. If
+  /// non-empty, then we are parsing the unqualified-id of a qualified-id.
+  ///
+  /// \param ObjectType if this unqualified-id occurs within a member access
+  /// expression, the type of the base object whose member is being accessed.
+  ///
+  /// \param ObjectHadErrors if this unqualified-id occurs within a member access
+  /// expression, indicates whether the original subexpressions had any errors.
+  /// When true, diagnostics for missing 'template' keyword will be supressed.
+  ///
+  /// \param EnteringContext whether we are entering the scope of the
+  /// nested-name-specifier.
+  ///
+  /// \param AllowDestructorName whether we allow parsing of a destructor name.
+  ///
+  /// \param AllowConstructorName whether we allow parsing a constructor name.
+  ///
+  /// \param AllowDeductionGuide whether we allow parsing a deduction guide name.
+  ///
+  /// \param Result on a successful parse, contains the parsed unqualified-id.
+  ///
+  /// \returns true if parsing fails, false otherwise.
+  bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
+                          bool ObjectHadErrors, bool EnteringContext,
+                          bool AllowDestructorName, bool AllowConstructorName,
+                          bool AllowDeductionGuide,
+                          SourceLocation *TemplateKWLoc, UnqualifiedId &Result);
+
+  private:
+
+  /// ColonIsSacred - When this is false, we aggressively try to recover from
+  /// code like "foo : bar" as if it were a typo for "foo :: bar".  This is not
+  /// safe in case statements and a few other things.  This is managed by the
+  /// ColonProtectionRAIIObject RAII object.
+  bool ColonIsSacred;
+
+  /// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
+  /// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
+  /// based on the context past the parens.
+  ExprResult ParseCXXAmbiguousParenExpression(
+      ParenParseOption &ExprType, ParsedType &CastTy,
+      BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Expressions
+  ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOperand,
+                                     Token &Replacement);
+
+  ExprResult tryParseCXXPackIndexingExpression(ExprResult PackIdExpression);
+  ExprResult ParseCXXPackIndexingExpression(ExprResult PackIdExpression);
+
+  /// ParseCXXIdExpression - Handle id-expression.
+  ///
+  ///       id-expression:
+  ///         unqualified-id
+  ///         qualified-id
+  ///
+  ///       qualified-id:
+  ///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
+  ///         '::' identifier
+  ///         '::' operator-function-id
+  ///         '::' template-id
+  ///
+  /// NOTE: The standard specifies that, for qualified-id, the parser does not
+  /// expect:
+  ///
+  ///   '::' conversion-function-id
+  ///   '::' '~' class-name
+  ///
+  /// This may cause a slight inconsistency on diagnostics:
+  ///
+  /// class C {};
+  /// namespace A {}
+  /// void f() {
+  ///   :: A :: ~ C(); // Some Sema error about using destructor with a
+  ///                  // namespace.
+  ///   :: ~ C(); // Some Parser error like 'unexpected ~'.
+  /// }
+  ///
+  /// We simplify the parser a bit and make it work like:
+  ///
+  ///       qualified-id:
+  ///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
+  ///         '::' unqualified-id
+  ///
+  /// That way Sema can handle and report similar errors for namespaces and the
+  /// global scope.
+  ///
+  /// The isAddressOfOperand parameter indicates that this id-expression is a
+  /// direct operand of the address-of operator. This is, besides member contexts,
+  /// the only place where a qualified-id naming a non-static class member may
+  /// appear.
+  ///
+  ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
+
+  // Are the two tokens adjacent in the same source file?
+  bool areTokensAdjacent(const Token &A, const Token &B);
+
+  // Check for '<::' which should be '< ::' instead of '[:' when following
+  // a template name.
+  void CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectTypePtr,
+                                  bool EnteringContext, IdentifierInfo &II,
+                                  CXXScopeSpec &SS);
+
+  /// Parse global scope or nested-name-specifier if present.
+  ///
+  /// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
+  /// may be preceded by '::'). Note that this routine will not parse ::new or
+  /// ::delete; it will just leave them in the token stream.
+  ///
+  ///       '::'[opt] nested-name-specifier
+  ///       '::'
+  ///
+  ///       nested-name-specifier:
+  ///         type-name '::'
+  ///         namespace-name '::'
+  ///         nested-name-specifier identifier '::'
+  ///         nested-name-specifier 'template'[opt] simple-template-id '::'
+  ///
+  ///
+  /// \param SS the scope specifier that will be set to the parsed
+  /// nested-name-specifier (or empty)
+  ///
+  /// \param ObjectType if this nested-name-specifier is being parsed following
+  /// the "." or "->" of a member access expression, this parameter provides the
+  /// type of the object whose members are being accessed.
+  ///
+  /// \param ObjectHadErrors if this unqualified-id occurs within a member access
+  /// expression, indicates whether the original subexpressions had any errors.
+  /// When true, diagnostics for missing 'template' keyword will be supressed.
+  ///
+  /// \param EnteringContext whether we will be entering into the context of
+  /// the nested-name-specifier after parsing it.
+  ///
+  /// \param MayBePseudoDestructor When non-NULL, points to a flag that
+  /// indicates whether this nested-name-specifier may be part of a
+  /// pseudo-destructor name. In this case, the flag will be set false
+  /// if we don't actually end up parsing a destructor name. Moreover,
+  /// if we do end up determining that we are parsing a destructor name,
+  /// the last component of the nested-name-specifier is not parsed as
+  /// part of the scope specifier.
+  ///
+  /// \param IsTypename If \c true, this nested-name-specifier is known to be
+  /// part of a type name. This is used to improve error recovery.
+  ///
+  /// \param LastII When non-NULL, points to an IdentifierInfo* that will be
+  /// filled in with the leading identifier in the last component of the
+  /// nested-name-specifier, if any.
+  ///
+  /// \param OnlyNamespace If true, only considers namespaces in lookup.
+  ///
+  ///
+  /// \returns true if there was an error parsing a scope specifier
+  bool ParseOptionalCXXScopeSpecifier(
+      CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHasErrors,
+      bool EnteringContext, bool *MayBePseudoDestructor = nullptr,
+      bool IsTypename = false, const IdentifierInfo **LastII = nullptr,
+      bool OnlyNamespace = false, bool InUsingDeclaration = false,
+      bool Disambiguation = false);
+
+  //===--------------------------------------------------------------------===//
+  // C++11 5.1.2: Lambda expressions
+
+  /// Result of tentatively parsing a lambda-introducer.
+  enum class LambdaIntroducerTentativeParse {
+    /// This appears to be a lambda-introducer, which has been fully parsed.
+    Success,
+    /// This is a lambda-introducer, but has not been fully parsed, and this
+    /// function needs to be called again to parse it.
+    Incomplete,
+    /// This is definitely an Objective-C message send expression, rather than
+    /// a lambda-introducer, attribute-specifier, or array designator.
+    MessageSend,
+    /// This is not a lambda-introducer.
+    Invalid,
   };
 
-  bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result);
-  void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
-  void ParseMicrosoftIfExistsExternalDeclaration();
-  void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
-                                              ParsedAttributes &AccessAttrs,
-                                              AccessSpecifier &CurAS);
-  bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
-                                              bool &InitExprsOk);
-  bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
-                           SmallVectorImpl<Expr *> &Constraints,
-                           SmallVectorImpl<Expr *> &Exprs);
+  /// ParseLambdaExpression - Parse a C++11 lambda expression.
+  ///
+  ///       lambda-expression:
+  ///         lambda-introducer lambda-declarator compound-statement
+  ///         lambda-introducer '<' template-parameter-list '>'
+  ///             requires-clause[opt] lambda-declarator compound-statement
+  ///
+  ///       lambda-introducer:
+  ///         '[' lambda-capture[opt] ']'
+  ///
+  ///       lambda-capture:
+  ///         capture-default
+  ///         capture-list
+  ///         capture-default ',' capture-list
+  ///
+  ///       capture-default:
+  ///         '&'
+  ///         '='
+  ///
+  ///       capture-list:
+  ///         capture
+  ///         capture-list ',' capture
+  ///
+  ///       capture:
+  ///         simple-capture
+  ///         init-capture     [C++1y]
+  ///
+  ///       simple-capture:
+  ///         identifier
+  ///         '&' identifier
+  ///         'this'
+  ///
+  ///       init-capture:      [C++1y]
+  ///         identifier initializer
+  ///         '&' identifier initializer
+  ///
+  ///       lambda-declarator:
+  ///         lambda-specifiers     [C++23]
+  ///         '(' parameter-declaration-clause ')' lambda-specifiers
+  ///             requires-clause[opt]
+  ///
+  ///       lambda-specifiers:
+  ///         decl-specifier-seq[opt] noexcept-specifier[opt]
+  ///             attribute-specifier-seq[opt] trailing-return-type[opt]
+  ///
+  ExprResult ParseLambdaExpression();
+  
+  /// Use lookahead and potentially tentative parsing to determine if we are
+  /// looking at a C++11 lambda expression, and parse it if we are.
+  ///
+  /// If we are not looking at a lambda expression, returns ExprError().
+  ExprResult TryParseLambdaExpression();
+  
+  /// Parse a lambda introducer.
+  /// \param Intro A LambdaIntroducer filled in with information about the
+  ///        contents of the lambda-introducer.
+  /// \param Tentative If non-null, we are disambiguating between a
+  ///        lambda-introducer and some other construct. In this mode, we do not
+  ///        produce any diagnostics or take any other irreversible action unless
+  ///        we're sure that this is a lambda-expression.
+  /// \return \c true if parsing (or disambiguation) failed with a diagnostic and
+  ///         the caller should bail out / recover.
+  bool
+  ParseLambdaIntroducer(LambdaIntroducer &Intro,
+                        LambdaIntroducerTentativeParse *Tentative = nullptr);
+  
+  /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda
+  /// expression.
+  ExprResult ParseLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2p1: C++ Casts
+  
+  /// ParseCXXCasts - This handles the various ways to cast expressions to another
+  /// type.
+  ///
+  ///       postfix-expression: [C++ 5.2p1]
+  ///         'dynamic_cast' '<' type-name '>' '(' expression ')'
+  ///         'static_cast' '<' type-name '>' '(' expression ')'
+  ///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
+  ///         'const_cast' '<' type-name '>' '(' expression ')'
+  ///
+  /// C++ for OpenCL s2.3.1 adds:
+  ///         'addrspace_cast' '<' type-name '>' '(' expression ')'
+  ExprResult ParseCXXCasts();
+
+  /// Parse a __builtin_bit_cast(T, E), used to implement C++2a std::bit_cast.
+  ExprResult ParseBuiltinBitCast();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2p1: C++ Type Identification
+  
+  /// ParseCXXTypeid - This handles the C++ typeid expression.
+  ///
+  ///       postfix-expression: [C++ 5.2p1]
+  ///         'typeid' '(' expression ')'
+  ///         'typeid' '(' type-id ')'
+  ///
+  ExprResult ParseCXXTypeid();
+
+  //===--------------------------------------------------------------------===//
+  //  C++ : Microsoft __uuidof Expression
+  
+  /// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
+  ///
+  ///         '__uuidof' '(' expression ')'
+  ///         '__uuidof' '(' type-id ')'
+  ///
+  ExprResult ParseCXXUuidof();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2.4: C++ Pseudo-Destructor Expressions
+  
+  /// Parse a C++ pseudo-destructor expression after the base,
+  /// . or -> operator, and nested-name-specifier have already been
+  /// parsed. We're handling this fragment of the grammar:
+  ///
+  ///       postfix-expression: [C++2a expr.post]
+  ///         postfix-expression . template[opt] id-expression
+  ///         postfix-expression -> template[opt] id-expression
+  ///
+  ///       id-expression:
+  ///         qualified-id
+  ///         unqualified-id
+  ///
+  ///       qualified-id:
+  ///         nested-name-specifier template[opt] unqualified-id
+  ///
+  ///       nested-name-specifier:
+  ///         type-name ::
+  ///         decltype-specifier ::    FIXME: not implemented, but probably only
+  ///                                         allowed in C++ grammar by accident
+  ///         nested-name-specifier identifier ::
+  ///         nested-name-specifier template[opt] simple-template-id ::
+  ///         [...]
+  ///
+  ///       unqualified-id:
+  ///         ~ type-name
+  ///         ~ decltype-specifier
+  ///         [...]
+  ///
+  /// ... where the all but the last component of the nested-name-specifier
+  /// has already been parsed, and the base expression is not of a non-dependent
+  /// class type.
+  ExprResult ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
+                                            tok::TokenKind OpKind,
+                                            CXXScopeSpec &SS,
+                                            ParsedType ObjectType);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 9.3.2: C++ 'this' pointer
+  
+  /// ParseCXXThis - This handles the C++ 'this' pointer.
+  ///
+  /// C++ 9.3.2: In the body of a non-static member function, the keyword this is
+  /// a non-lvalue expression whose value is the address of the object for which
+  /// the function is called.
+  ExprResult ParseCXXThis();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 15: C++ Throw Expression
+  
+  /// ParseThrowExpression - This handles the C++ throw expression.
+  ///
+  ///       throw-expression: [C++ 15]
+  ///         'throw' assignment-expression[opt]
+  ExprResult ParseThrowExpression();
+  
+  //===--------------------------------------------------------------------===//
+  // C++ 2.13.5: C++ Boolean Literals
+  
+  /// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
+  ///
+  ///       boolean-literal: [C++ 2.13.5]
+  ///         'true'
+  ///         'false'
+  ExprResult ParseCXXBoolLiteral();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2.3: Explicit type conversion (functional notation)
+  
+  /// ParseCXXTypeConstructExpression - Parse construction of a specified type.
+  /// Can be interpreted either as function-style casting ("int(x)")
+  /// or class type construction ("ClassType(x,y,z)")
+  /// or creation of a value-initialized type ("int()").
+  /// See [C++ 5.2.3].
+  ///
+  ///       postfix-expression: [C++ 5.2p1]
+  ///         simple-type-specifier '(' expression-list[opt] ')'
+  /// [C++0x] simple-type-specifier braced-init-list
+  ///         typename-specifier '(' expression-list[opt] ')'
+  /// [C++0x] typename-specifier braced-init-list
+  ///
+  /// In C++1z onwards, the type specifier can also be a template-name.
+  ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
+
+  /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
+  /// This should only be called when the current token is known to be part of
+  /// simple-type-specifier.
+  ///
+  ///       simple-type-specifier:
+  ///         '::'[opt] nested-name-specifier[opt] type-name
+  ///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
+  ///         char
+  ///         wchar_t
+  ///         bool
+  ///         short
+  ///         int
+  ///         long
+  ///         signed
+  ///         unsigned
+  ///         float
+  ///         double
+  ///         void
+  /// [GNU]   typeof-specifier
+  /// [C++0x] auto               [TODO]
+  ///
+  ///       type-name:
+  ///         class-name
+  ///         enum-name
+  ///         typedef-name
+  ///
+  void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
+
+  /// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
+  /// [dcl.name]), which is a non-empty sequence of type-specifiers,
+  /// e.g., "const short int". Note that the DeclSpec is *not* finished
+  /// by parsing the type-specifier-seq, because these sequences are
+  /// typically followed by some form of declarator. Returns true and
+  /// emits diagnostics if this is not a type-specifier-seq, false
+  /// otherwise.
+  ///
+  ///   type-specifier-seq: [C++ 8.1]
+  ///     type-specifier type-specifier-seq[opt]
+  ///
+  bool ParseCXXTypeSpecifierSeq(
+      DeclSpec &DS, DeclaratorContext Context = DeclaratorContext::TypeName);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.3.4 and 5.3.5: C++ new and delete
+  
+  /// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
+  /// This ambiguity appears in the syntax of the C++ new operator.
+  ///
+  ///        new-expression:
+  ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
+  ///                                     new-initializer[opt]
+  ///
+  ///        new-placement:
+  ///                   '(' expression-list ')'
+  ///
+  bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr*> &Exprs,
+                                   Declarator &D);
+  
+  /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
+  /// passed to ParseDeclaratorInternal.
+  ///
+  ///        direct-new-declarator:
+  ///                   '[' expression[opt] ']'
+  ///                   direct-new-declarator '[' constant-expression ']'
+  ///
+  void ParseDirectNewDeclarator(Declarator &D);
+  
+  /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
+  /// memory in a typesafe manner and call constructors.
+  ///
+  /// This method is called to parse the new expression after the optional :: has
+  /// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
+  /// is its location.  Otherwise, "Start" is the location of the 'new' token.
+  ///
+  ///        new-expression:
+  ///                   '::'[opt] 'new' new-placement[opt] new-type-id
+  ///                                     new-initializer[opt]
+  ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
+  ///                                     new-initializer[opt]
+  ///
+  ///        new-placement:
+  ///                   '(' expression-list ')'
+  ///
+  ///        new-type-id:
+  ///                   type-specifier-seq new-declarator[opt]
+  /// [GNU]             attributes type-specifier-seq new-declarator[opt]
+  ///
+  ///        new-declarator:
+  ///                   ptr-operator new-declarator[opt]
+  ///                   direct-new-declarator
+  ///
+  ///        new-initializer:
+  ///                   '(' expression-list[opt] ')'
+  /// [C++0x]           braced-init-list
+  ///
+  ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
+  
+  /// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
+  /// to free memory allocated by new.
+  ///
+  /// This method is called to parse the 'delete' expression after the optional
+  /// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
+  /// and "Start" is its location.  Otherwise, "Start" is the location of the
+  /// 'delete' token.
+  ///
+  ///        delete-expression:
+  ///                   '::'[opt] 'delete' cast-expression
+  ///                   '::'[opt] 'delete' '[' ']' cast-expression
+  ExprResult ParseCXXDeleteExpression(bool UseGlobal,
+                                            SourceLocation Start);
+
+  //===--------------------------------------------------------------------===//
+  // C++ if/switch/while/for condition expression.
+  
+  /// ParseCXXCondition - if/switch/while condition expression.
+  ///
+  ///       condition:
+  ///         expression
+  ///         type-specifier-seq declarator '=' assignment-expression
+  /// [C++11] type-specifier-seq declarator '=' initializer-clause
+  /// [C++11] type-specifier-seq declarator braced-init-list
+  /// [Clang] type-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
+  ///             brace-or-equal-initializer
+  /// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
+  ///             '=' assignment-expression
+  ///
+  /// In C++1z, a condition may in some contexts be preceded by an
+  /// optional init-statement. This function will parse that too.
+  ///
+  /// \param InitStmt If non-null, an init-statement is permitted, and if present
+  /// will be parsed and stored here.
+  ///
+  /// \param Loc The location of the start of the statement that requires this
+  /// condition, e.g., the "for" in a for loop.
+  ///
+  /// \param MissingOK Whether an empty condition is acceptable here. Otherwise
+  /// it is considered an error to be recovered from.
+  ///
+  /// \param FRI If non-null, a for range declaration is permitted, and if
+  /// present will be parsed and stored here, and a null result will be returned.
+  ///
+  /// \param EnterForConditionScope If true, enter a continue/break scope at the
+  /// appropriate moment for a 'for' loop.
+  ///
+  /// \returns The parsed condition.
+  Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt,
+                                          SourceLocation Loc,
+                                          Sema::ConditionKind CK,
+                                          bool MissingOK,
+                                          ForRangeInfo *FRI = nullptr,
+                                          bool EnterForConditionScope = false);
+  DeclGroupPtrTy ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
+                                                      ParsedAttributes &Attrs);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Coroutines
+
+  /// Parse the C++ Coroutines co_yield expression.
+  ///
+  ///       co_yield-expression:
+  ///         'co_yield' assignment-expression[opt]
+  ExprResult ParseCoyieldExpression();
+
+  //===--------------------------------------------------------------------===//
+  // C++ Concepts
+
+  /// ParseRequiresExpression - Parse a C++2a requires-expression.
+  /// C++2a [expr.prim.req]p1
+  ///     A requires-expression provides a concise way to express requirements on
+  ///     template arguments. A requirement is one that can be checked by name
+  ///     lookup (6.4) or by checking properties of types and expressions.
+  ///
+  ///     requires-expression:
+  ///         'requires' requirement-parameter-list[opt] requirement-body
+  ///
+  ///     requirement-parameter-list:
+  ///         '(' parameter-declaration-clause[opt] ')'
+  ///
+  ///     requirement-body:
+  ///         '{' requirement-seq '}'
+  ///
+  ///     requirement-seq:
+  ///         requirement
+  ///         requirement-seq requirement
+  ///
+  ///     requirement:
+  ///         simple-requirement
+  ///         type-requirement
+  ///         compound-requirement
+  ///         nested-requirement
+  ExprResult ParseRequiresExpression();
+
+  /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
+  /// whether the parens contain an expression or a type-id.
+  /// Returns true for a type-id and false for an expression.
+  bool isTypeIdInParens(bool &isAmbiguous) {
+    if (getLangOpts().CPlusPlus)
+      return isCXXTypeId(TentativeCXXTypeIdContext::InParens, isAmbiguous);
+    isAmbiguous = false;
+    return isTypeSpecifierQualifier();
+  }
+  bool isTypeIdInParens() {
+    bool isAmbiguous;
+    return isTypeIdInParens(isAmbiguous);
+  }
+
+  /// Finish parsing a C++ unqualified-id that is a template-id of
+  /// some form.
+  ///
+  /// This routine is invoked when a '<' is encountered after an identifier or
+  /// operator-function-id is parsed by \c ParseUnqualifiedId() to determine
+  /// whether the unqualified-id is actually a template-id. This routine will
+  /// then parse the template arguments and form the appropriate template-id to
+  /// return to the caller.
+  ///
+  /// \param SS the nested-name-specifier that precedes this template-id, if
+  /// we're actually parsing a qualified-id.
+  ///
+  /// \param ObjectType if this unqualified-id occurs within a member access
+  /// expression, the type of the base object whose member is being accessed.
+  ///
+  /// \param ObjectHadErrors this unqualified-id occurs within a member access
+  /// expression, indicates whether the original subexpressions had any errors.
+  ///
+  /// \param Name for constructor and destructor names, this is the actual
+  /// identifier that may be a template-name.
+  ///
+  /// \param NameLoc the location of the class-name in a constructor or
+  /// destructor.
+  ///
+  /// \param EnteringContext whether we're entering the scope of the
+  /// nested-name-specifier.
+  ///
+  /// \param Id as input, describes the template-name or operator-function-id
+  /// that precedes the '<'. If template arguments were parsed successfully,
+  /// will be updated with the template-id.
+  ///
+  /// \param AssumeTemplateId When true, this routine will assume that the name
+  /// refers to a template without performing name lookup to verify.
+  ///
+  /// \returns true if a parse error occurred, false otherwise.
+  bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
+                                    ParsedType ObjectType,
+                                    bool ObjectHadErrors,
+                                    SourceLocation TemplateKWLoc,
+                                    IdentifierInfo *Name,
+                                    SourceLocation NameLoc,
+                                    bool EnteringContext,
+                                    UnqualifiedId &Id,
+                                    bool AssumeTemplateId);
+  
+  /// Parse an operator-function-id or conversion-function-id as part
+  /// of a C++ unqualified-id.
+  ///
+  /// This routine is responsible only for parsing the operator-function-id or
+  /// conversion-function-id; it does not handle template arguments in any way.
+  ///
+  /// \code
+  ///       operator-function-id: [C++ 13.5]
+  ///         'operator' operator
+  ///
+  ///       operator: one of
+  ///            new   delete  new[]   delete[]
+  ///            +     -    *  /    %  ^    &   |   ~
+  ///            !     =    <  >    += -=   *=  /=  %=
+  ///            ^=    &=   |= <<   >> >>= <<=  ==  !=
+  ///            <=    >=   && ||   ++ --   ,   ->* ->
+  ///            ()    []   <=>
+  ///
+  ///       conversion-function-id: [C++ 12.3.2]
+  ///         operator conversion-type-id
+  ///
+  ///       conversion-type-id:
+  ///         type-specifier-seq conversion-declarator[opt]
+  ///
+  ///       conversion-declarator:
+  ///         ptr-operator conversion-declarator[opt]
+  /// \endcode
+  ///
+  /// \param SS The nested-name-specifier that preceded this unqualified-id. If
+  /// non-empty, then we are parsing the unqualified-id of a qualified-id.
+  ///
+  /// \param EnteringContext whether we are entering the scope of the
+  /// nested-name-specifier.
+  ///
+  /// \param ObjectType if this unqualified-id occurs within a member access
+  /// expression, the type of the base object whose member is being accessed.
+  ///
+  /// \param Result on a successful parse, contains the parsed unqualified-id.
+  ///
+  /// \returns true if parsing fails, false otherwise.
+  bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
+                                  ParsedType ObjectType,
+                                  UnqualifiedId &Result);
+
+  //===--------------------------------------------------------------------===//
+  // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
+  
+  /// Parse the built-in type-trait pseudo-functions that allow
+  /// implementation of the TR1/C++11 type traits templates.
+  ///
+  ///       primary-expression:
+  ///          unary-type-trait '(' type-id ')'
+  ///          binary-type-trait '(' type-id ',' type-id ')'
+  ///          type-trait '(' type-id-seq ')'
+  ///
+  ///       type-id-seq:
+  ///          type-id ...[opt] type-id-seq[opt]
+  ///
+  ExprResult ParseTypeTrait();
+
+  //===--------------------------------------------------------------------===//
+  // Embarcadero: Arary and Expression Traits
+  
+  /// ParseArrayTypeTrait - Parse the built-in array type-trait
+  /// pseudo-functions.
+  ///
+  ///       primary-expression:
+  /// [Embarcadero]     '__array_rank' '(' type-id ')'
+  /// [Embarcadero]     '__array_extent' '(' type-id ',' expression ')'
+  ///
+  ExprResult ParseArrayTypeTrait();
+  
+  /// ParseExpressionTrait - Parse built-in expression-trait
+  /// pseudo-functions like __is_lvalue_expr( xxx ).
+  ///
+  ///       primary-expression:
+  /// [Embarcadero]     expression-trait '(' expression ')'
+  ///
+  ExprResult ParseExpressionTrait();
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name HLSL Constructs
+  /// Implementations are in ParseHLSL.cpp
+  ///@{
+
+  public:
+
+  private:
+
+  bool MaybeParseHLSLAnnotations(Declarator &D,
+                                 SourceLocation *EndLoc = nullptr,
+                                 bool CouldBeBitField = false) {
+    assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only");
+    if (Tok.is(tok::colon)) {
+      ParsedAttributes Attrs(AttrFactory);
+      ParseHLSLAnnotations(Attrs, EndLoc, CouldBeBitField);
+      D.takeAttributes(Attrs);
+      return true;
+    }
+    return false;
+  }
+
+  void MaybeParseHLSLAnnotations(ParsedAttributes &Attrs,
+                                 SourceLocation *EndLoc = nullptr) {
+    assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only");
+    if (Tok.is(tok::colon))
+      ParseHLSLAnnotations(Attrs, EndLoc);
+  }
+
+  void ParseHLSLAnnotations(ParsedAttributes &Attrs,
+                            SourceLocation *EndLoc = nullptr,
+                            bool CouldBeBitField = false);
+  Decl *ParseHLSLBuffer(SourceLocation &DeclEnd);
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name HLSL Root Signature
+  /// Implementations are in ParseHLSLRootSignature.cpp
+  ///@{
+
+  public:
+
+  private:
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name Initializers
+  /// Implementations are in ParseInit.cpp
+  ///@{
+
+  public:
+
+  private:
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.7.8: Initialization.
+
+  /// ParseInitializer
+  ///       initializer: [C99 6.7.8]
+  ///         assignment-expression
+  ///         '{' ...
+  ExprResult ParseInitializer() {
+    if (Tok.isNot(tok::l_brace))
+      return ParseAssignmentExpression();
+    return ParseBraceInitializer();
+  }
+  
+  /// MayBeDesignationStart - Return true if the current token might be the start
+  /// of a designator.  If we can tell it is impossible that it is a designator,
+  /// return false.
+  bool MayBeDesignationStart();
+  
+  /// ParseBraceInitializer - Called when parsing an initializer that has a
+  /// leading open brace.
+  ///
+  ///       initializer: [C99 6.7.8]
+  ///         '{' initializer-list '}'
+  ///         '{' initializer-list ',' '}'
+  /// [C23]   '{' '}'
+  ///
+  ///       initializer-list:
+  ///         designation[opt] initializer ...[opt]
+  ///         initializer-list ',' designation[opt] initializer ...[opt]
+  ///
+  ExprResult ParseBraceInitializer();
+  
+  struct DesignatorCompletionInfo {
+    SmallVectorImpl<Expr *> &InitExprs;
+    QualType PreferredBaseType;
+  };
+  
+  /// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
+  /// checking to see if the token stream starts with a designator.
+  ///
+  /// C99:
+  ///
+  ///       designation:
+  ///         designator-list '='
+  /// [GNU]   array-designator
+  /// [GNU]   identifier ':'
+  ///
+  ///       designator-list:
+  ///         designator
+  ///         designator-list designator
+  ///
+  ///       designator:
+  ///         array-designator
+  ///         '.' identifier
+  ///
+  ///       array-designator:
+  ///         '[' constant-expression ']'
+  /// [GNU]   '[' constant-expression '...' constant-expression ']'
+  ///
+  /// C++20:
+  ///
+  ///       designated-initializer-list:
+  ///         designated-initializer-clause
+  ///         designated-initializer-list ',' designated-initializer-clause
+  ///
+  ///       designated-initializer-clause:
+  ///         designator brace-or-equal-initializer
+  ///
+  ///       designator:
+  ///         '.' identifier
+  ///
+  /// We allow the C99 syntax extensions in C++20, but do not allow the C++20
+  /// extension (a braced-init-list after the designator with no '=') in C99.
+  ///
+  /// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
+  /// initializer (because it is an expression).  We need to consider this case
+  /// when parsing array designators.
+  ///
+  /// \p CodeCompleteCB is called with Designation parsed so far.
+  ExprResult ParseInitializerWithPotentialDesignator(DesignatorCompletionInfo);
+  
+  ExprResult createEmbedExpr();
+
+  /// A SmallVector of expressions.
+  typedef SmallVector<Expr*, 12> ExprVector;
+
+  // Return true if a comma (or closing brace) is necessary after the
+  // __if_exists/if_not_exists statement.
+  bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
+                                              bool &InitExprsOk);
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name Objective-C Constructs
+  /// Implementations are in ParseObjc.cpp
+  ///@{
+
+  public:
+
+  friend class InMessageExpressionRAIIObject;
+  friend class ObjCDeclContextSwitch;
+
+  ObjCContainerDecl *getObjCDeclContext() const {
+    return Actions.ObjC().getObjCDeclContext();
+  }
+
+  /// Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds
+  /// to the given nullability kind.
+  IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability) {
+    return Actions.getNullabilityKeyword(nullability);
+  }
+
+  private:
+
+  /// Objective-C contextual keywords.
+  IdentifierInfo *Ident_instancetype;
+
+  /// Ident_super - IdentifierInfo for "super", to support fast
+  /// comparison.
+  IdentifierInfo *Ident_super;
+
+  /// When true, we are directly inside an Objective-C message
+  /// send expression.
+  ///
+  /// This is managed by the \c InMessageExpressionRAIIObject class, and
+  /// should not be set directly.
+  bool InMessageExpression;
+
+  /// True if we are within an Objective-C container while parsing C-like decls.
+  ///
+  /// This is necessary because Sema thinks we have left the container
+  /// to parse the C-like decls, meaning Actions.ObjC().getObjCDeclContext()
+  /// will be NULL.
+  bool ParsingInObjCContainer;
+
+  /// Returns true if the current token is the identifier 'instancetype'.
+  ///
+  /// Should only be used in Objective-C language modes.
+  bool isObjCInstancetype() {
+    assert(getLangOpts().ObjC);
+    if (Tok.isAnnotation())
+      return false;
+    if (!Ident_instancetype)
+      Ident_instancetype = PP.getIdentifierInfo("instancetype");
+    return Tok.getIdentifierInfo() == Ident_instancetype;
+  }
+
+  /// ObjCDeclContextSwitch - An object used to switch context from
+  /// an objective-c decl context to its enclosing decl context and
+  /// back.
+  class ObjCDeclContextSwitch {
+    Parser &P;
+    ObjCContainerDecl *DC;
+    SaveAndRestore<bool> WithinObjCContainer;
+  public:
+    explicit ObjCDeclContextSwitch(Parser &p)
+      : P(p), DC(p.getObjCDeclContext()),
+        WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
+      if (DC)
+        P.Actions.ObjC().ActOnObjCTemporaryExitContainerContext(DC);
+    }
+    ~ObjCDeclContextSwitch() {
+      if (DC)
+        P.Actions.ObjC().ActOnObjCReenterContainerContext(DC);
+    }
+  };
+
+  void CheckNestedObjCContexts(SourceLocation AtLoc);
+
+  void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
+
+  // Objective-C External Declarations
+  
+  /// Skips attributes after an Objective-C @ directive. Emits a diagnostic.
+  void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
+  
+  /// ParseObjCAtDirectives - Handle parts of the external-declaration production:
+  ///       external-declaration: [C99 6.9]
+  /// [OBJC]  objc-class-definition
+  /// [OBJC]  objc-class-declaration
+  /// [OBJC]  objc-alias-declaration
+  /// [OBJC]  objc-protocol-definition
+  /// [OBJC]  objc-method-definition
+  /// [OBJC]  '@' 'end'
+  DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
+                                       ParsedAttributes &DeclSpecAttrs);
+  
+  ///
+  /// objc-class-declaration:
+  ///    '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
+  ///
+  /// objc-class-forward-decl:
+  ///   identifier objc-type-parameter-list[opt]
+  ///
+  DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
+  
+  ///
+  ///   objc-interface:
+  ///     objc-class-interface-attributes[opt] objc-class-interface
+  ///     objc-category-interface
+  ///
+  ///   objc-class-interface:
+  ///     '@' 'interface' identifier objc-type-parameter-list[opt]
+  ///       objc-superclass[opt] objc-protocol-refs[opt]
+  ///       objc-class-instance-variables[opt]
+  ///       objc-interface-decl-list
+  ///     @end
+  ///
+  ///   objc-category-interface:
+  ///     '@' 'interface' identifier objc-type-parameter-list[opt]
+  ///       '(' identifier[opt] ')' objc-protocol-refs[opt]
+  ///       objc-interface-decl-list
+  ///     @end
+  ///
+  ///   objc-superclass:
+  ///     ':' identifier objc-type-arguments[opt]
+  ///
+  ///   objc-class-interface-attributes:
+  ///     __attribute__((visibility("default")))
+  ///     __attribute__((visibility("hidden")))
+  ///     __attribute__((deprecated))
+  ///     __attribute__((unavailable))
+  ///     __attribute__((objc_exception)) - used by NSException on 64-bit
+  ///     __attribute__((objc_root_class))
+  ///
+  Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
+                                        ParsedAttributes &prefixAttrs);
+  
+  /// Class to handle popping type parameters when leaving the scope.
+  class ObjCTypeParamListScope;
+  
+  /// Parse an objc-type-parameter-list.
+  ObjCTypeParamList *parseObjCTypeParamList();
+  
+  /// Parse an Objective-C type parameter list, if present, or capture
+  /// the locations of the protocol identifiers for a list of protocol
+  /// references.
+  ///
+  ///   objc-type-parameter-list:
+  ///     '<' objc-type-parameter (',' objc-type-parameter)* '>'
+  ///
+  ///   objc-type-parameter:
+  ///     objc-type-parameter-variance? identifier objc-type-parameter-bound[opt]
+  ///
+  ///   objc-type-parameter-bound:
+  ///     ':' type-name
+  ///
+  ///   objc-type-parameter-variance:
+  ///     '__covariant'
+  ///     '__contravariant'
+  ///
+  /// \param lAngleLoc The location of the starting '<'.
+  ///
+  /// \param protocolIdents Will capture the list of identifiers, if the
+  /// angle brackets contain a list of protocol references rather than a
+  /// type parameter list.
+  ///
+  /// \param rAngleLoc The location of the ending '>'.
+  ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
+      ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
+      SmallVectorImpl<IdentifierLoc> &protocolIdents, SourceLocation &rAngleLoc,
+      bool mayBeProtocolList = true);
+
+  void HelperActionsForIvarDeclarations(ObjCContainerDecl *interfaceDecl,
+                                        SourceLocation atLoc,
+                                        BalancedDelimiterTracker &T,
+                                        SmallVectorImpl<Decl *> &AllIvarDecls,
+                                        bool RBraceMissing);
+  
+  ///   objc-class-instance-variables:
+  ///     '{' objc-instance-variable-decl-list[opt] '}'
+  ///
+  ///   objc-instance-variable-decl-list:
+  ///     objc-visibility-spec
+  ///     objc-instance-variable-decl ';'
+  ///     ';'
+  ///     objc-instance-variable-decl-list objc-visibility-spec
+  ///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
+  ///     objc-instance-variable-decl-list static_assert-declaration
+  ///     objc-instance-variable-decl-list ';'
+  ///
+  ///   objc-visibility-spec:
+  ///     @private
+  ///     @protected
+  ///     @public
+  ///     @package [OBJC2]
+  ///
+  ///   objc-instance-variable-decl:
+  ///     struct-declaration
+  ///
+  void ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
+                                       tok::ObjCKeywordKind visibility,
+                                       SourceLocation atLoc);
+  
+  ///   objc-protocol-refs:
+  ///     '<' identifier-list '>'
+  ///
+  bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P,
+                                   SmallVectorImpl<SourceLocation> &PLocs,
+                                   bool WarnOnDeclarations,
+                                   bool ForObjCContainer,
+                                   SourceLocation &LAngleLoc,
+                                   SourceLocation &EndProtoLoc,
+                                   bool consumeLastToken);
+
+  /// Parse the first angle-bracket-delimited clause for an
+  /// Objective-C object or object pointer type, which may be either
+  /// type arguments or protocol qualifiers.
+  ///
+  ///   objc-type-arguments:
+  ///     '<' type-name '...'[opt] (',' type-name '...'[opt])* '>'
+  ///
+  void parseObjCTypeArgsOrProtocolQualifiers(
+         ParsedType baseType,
+         SourceLocation &typeArgsLAngleLoc,
+         SmallVectorImpl<ParsedType> &typeArgs,
+         SourceLocation &typeArgsRAngleLoc,
+         SourceLocation &protocolLAngleLoc,
+         SmallVectorImpl<Decl *> &protocols,
+         SmallVectorImpl<SourceLocation> &protocolLocs,
+         SourceLocation &protocolRAngleLoc,
+         bool consumeLastToken,
+         bool warnOnIncompleteProtocols);
+
+  /// Parse either Objective-C type arguments or protocol qualifiers; if the
+  /// former, also parse protocol qualifiers afterward.
+  void parseObjCTypeArgsAndProtocolQualifiers(
+         ParsedType baseType,
+         SourceLocation &typeArgsLAngleLoc,
+         SmallVectorImpl<ParsedType> &typeArgs,
+         SourceLocation &typeArgsRAngleLoc,
+         SourceLocation &protocolLAngleLoc,
+         SmallVectorImpl<Decl *> &protocols,
+         SmallVectorImpl<SourceLocation> &protocolLocs,
+         SourceLocation &protocolRAngleLoc,
+         bool consumeLastToken);
+
+  /// Parse a protocol qualifier type such as '<NSCopying>', which is
+  /// an anachronistic way of writing 'id<NSCopying>'.
+  TypeResult parseObjCProtocolQualifierType(SourceLocation &rAngleLoc);
+
+  /// Parse Objective-C type arguments and protocol qualifiers, extending the
+  /// current type with the parsed result.
+  TypeResult parseObjCTypeArgsAndProtocolQualifiers(SourceLocation loc,
+                                                    ParsedType type,
+                                                    bool consumeLastToken,
+                                                    SourceLocation &endLoc);
+
+  ///   objc-interface-decl-list:
+  ///     empty
+  ///     objc-interface-decl-list objc-property-decl [OBJC2]
+  ///     objc-interface-decl-list objc-method-requirement [OBJC2]
+  ///     objc-interface-decl-list objc-method-proto ';'
+  ///     objc-interface-decl-list declaration
+  ///     objc-interface-decl-list ';'
+  ///
+  ///   objc-method-requirement: [OBJC2]
+  ///     @required
+  ///     @optional
+  ///
+  void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
+                                  Decl *CDecl);
+
+  ///   objc-protocol-declaration:
+  ///     objc-protocol-definition
+  ///     objc-protocol-forward-reference
+  ///
+  ///   objc-protocol-definition:
+  ///     \@protocol identifier
+  ///       objc-protocol-refs[opt]
+  ///       objc-interface-decl-list
+  ///     \@end
+  ///
+  ///   objc-protocol-forward-reference:
+  ///     \@protocol identifier-list ';'
+  ///
+  ///   "\@protocol identifier ;" should be resolved as "\@protocol
+  ///   identifier-list ;": objc-interface-decl-list may not start with a
+  ///   semicolon in the first alternative if objc-protocol-refs are omitted.
+  DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
+                                                ParsedAttributes &prefixAttrs);
+
+  struct ObjCImplParsingDataRAII {
+    Parser &P;
+    Decl *Dcl;
+    bool HasCFunction;
+    typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
+    LateParsedObjCMethodContainer LateParsedObjCMethods;
+
+    ObjCImplParsingDataRAII(Parser &parser, Decl *D)
+      : P(parser), Dcl(D), HasCFunction(false) {
+      P.CurParsedObjCImpl = this;
+      Finished = false;
+    }
+    ~ObjCImplParsingDataRAII();
+
+    void finish(SourceRange AtEnd);
+    bool isFinished() const { return Finished; }
+
+  private:
+    bool Finished;
+  };
+  ObjCImplParsingDataRAII *CurParsedObjCImpl;
+  
+  /// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them
+  /// for later parsing.
+  void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
+
+  ///   objc-implementation:
+  ///     objc-class-implementation-prologue
+  ///     objc-category-implementation-prologue
+  ///
+  ///   objc-class-implementation-prologue:
+  ///     @implementation identifier objc-superclass[opt]
+  ///       objc-class-instance-variables[opt]
+  ///
+  ///   objc-category-implementation-prologue:
+  ///     @implementation identifier ( identifier )
+  DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
+                                                      ParsedAttributes &Attrs);
+  DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
+  
+  ///   compatibility-alias-decl:
+  ///     @compatibility_alias alias-name  class-name ';'
+  ///
+  Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
+
+  ///   property-synthesis:
+  ///     @synthesize property-ivar-list ';'
+  ///
+  ///   property-ivar-list:
+  ///     property-ivar
+  ///     property-ivar-list ',' property-ivar
+  ///
+  ///   property-ivar:
+  ///     identifier
+  ///     identifier '=' identifier
+  ///
+  Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
+
+  ///   property-dynamic:
+  ///     @dynamic  property-list
+  ///
+  ///   property-list:
+  ///     identifier
+  ///     property-list ',' identifier
+  ///
+  Decl *ParseObjCPropertyDynamic(SourceLocation atLoc);
+
+  ///   objc-selector:
+  ///     identifier
+  ///     one of
+  ///       enum struct union if else while do for switch case default
+  ///       break continue return goto asm sizeof typeof __alignof
+  ///       unsigned long const short volatile signed restrict _Complex
+  ///       in out inout bycopy byref oneway int char float double void _Bool
+  ///
+  IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
+
+  IdentifierInfo *ObjCTypeQuals[llvm::to_underlying(ObjCTypeQual::NumQuals)];
+
+  ///  objc-for-collection-in: 'in'
+  ///
+  bool isTokIdentifier_in() const;
+
+  ///   objc-type-name:
+  ///     '(' objc-type-qualifiers[opt] type-name ')'
+  ///     '(' objc-type-qualifiers[opt] ')'
+  ///
+  ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx,
+                               ParsedAttributes *ParamAttrs);
+  
+  ///   objc-method-proto:
+  ///     objc-instance-method objc-method-decl objc-method-attributes[opt]
+  ///     objc-class-method objc-method-decl objc-method-attributes[opt]
+  ///
+  ///   objc-instance-method: '-'
+  ///   objc-class-method: '+'
+  ///
+  ///   objc-method-attributes:         [OBJC2]
+  ///     __attribute__((deprecated))
+  ///
+  Decl *ParseObjCMethodPrototype(
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+            bool MethodDefinition = true);
+  
+  ///   objc-method-decl:
+  ///     objc-selector
+  ///     objc-keyword-selector objc-parmlist[opt]
+  ///     objc-type-name objc-selector
+  ///     objc-type-name objc-keyword-selector objc-parmlist[opt]
+  ///
+  ///   objc-keyword-selector:
+  ///     objc-keyword-decl
+  ///     objc-keyword-selector objc-keyword-decl
+  ///
+  ///   objc-keyword-decl:
+  ///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
+  ///     objc-selector ':' objc-keyword-attributes[opt] identifier
+  ///     ':' objc-type-name objc-keyword-attributes[opt] identifier
+  ///     ':' objc-keyword-attributes[opt] identifier
+  ///
+  ///   objc-parmlist:
+  ///     objc-parms objc-ellipsis[opt]
+  ///
+  ///   objc-parms:
+  ///     objc-parms , parameter-declaration
+  ///
+  ///   objc-ellipsis:
+  ///     , ...
+  ///
+  ///   objc-keyword-attributes:         [OBJC2]
+  ///     __attribute__((unused))
+  ///
+  Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+            bool MethodDefinition=true);
+  
+  ///   Parse property attribute declarations.
+  ///
+  ///   property-attr-decl: '(' property-attrlist ')'
+  ///   property-attrlist:
+  ///     property-attribute
+  ///     property-attrlist ',' property-attribute
+  ///   property-attribute:
+  ///     getter '=' identifier
+  ///     setter '=' identifier ':'
+  ///     direct
+  ///     readonly
+  ///     readwrite
+  ///     assign
+  ///     retain
+  ///     copy
+  ///     nonatomic
+  ///     atomic
+  ///     strong
+  ///     weak
+  ///     unsafe_unretained
+  ///     nonnull
+  ///     nullable
+  ///     null_unspecified
+  ///     null_resettable
+  ///     class
+  ///
+  void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
+
+  ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
+  ///
+  Decl *ParseObjCMethodDefinition();
+  
+  //===--------------------------------------------------------------------===//
+  // Objective-C Expressions
+  ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
+  ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
+  
+  /// ParseObjCCharacterLiteral -
+  /// objc-scalar-literal : '@' character-literal
+  ///                        ;
+  ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
+  
+  /// ParseObjCNumericLiteral -
+  /// objc-scalar-literal : '@' scalar-literal
+  ///                        ;
+  /// scalar-literal : | numeric-constant			/* any numeric constant. */
+  ///                    ;
+  ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
+  
+  /// ParseObjCBooleanLiteral -
+  /// objc-scalar-literal : '@' boolean-keyword
+  ///                        ;
+  /// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
+  ///                        ;
+  ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
+  
+  ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
+  ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
+  
+  /// ParseObjCBoxedExpr -
+  /// objc-box-expression:
+  ///       @( assignment-expression )
+  ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
+  
+  ///    objc-encode-expression:
+  ///      \@encode ( type-name )
+  ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
+  
+  ///     objc-selector-expression
+  ///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
+  ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
+  
+  ///     objc-protocol-expression
+  ///       \@protocol ( protocol-name )
+  ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+  
+  /// Determine whether the parser is currently referring to a an
+  /// Objective-C message send, using a simplified heuristic to avoid overhead.
+  ///
+  /// This routine will only return true for a subset of valid message-send
+  /// expressions.
+  bool isSimpleObjCMessageExpression();
+  
+  ///   objc-message-expr:
+  ///     '[' objc-receiver objc-message-args ']'
+  ///
+  ///   objc-receiver: [C]
+  ///     'super'
+  ///     expression
+  ///     class-name
+  ///     type-name
+  ///
+  ExprResult ParseObjCMessageExpression();
+
+  /// Parse the remainder of an Objective-C message following the
+  /// '[' objc-receiver.
+  ///
+  /// This routine handles sends to super, class messages (sent to a
+  /// class name), and instance messages (sent to an object), and the
+  /// target is represented by \p SuperLoc, \p ReceiverType, or \p
+  /// ReceiverExpr, respectively. Only one of these parameters may have
+  /// a valid value.
+  ///
+  /// \param LBracLoc The location of the opening '['.
+  ///
+  /// \param SuperLoc If this is a send to 'super', the location of the
+  /// 'super' keyword that indicates a send to the superclass.
+  ///
+  /// \param ReceiverType If this is a class message, the type of the
+  /// class we are sending a message to.
+  ///
+  /// \param ReceiverExpr If this is an instance message, the expression
+  /// used to compute the receiver object.
+  ///
+  ///   objc-message-args:
+  ///     objc-selector
+  ///     objc-keywordarg-list
+  ///
+  ///   objc-keywordarg-list:
+  ///     objc-keywordarg
+  ///     objc-keywordarg-list objc-keywordarg
+  ///
+  ///   objc-keywordarg:
+  ///     selector-name[opt] ':' objc-keywordexpr
+  ///
+  ///   objc-keywordexpr:
+  ///     nonempty-expr-list
+  ///
+  ///   nonempty-expr-list:
+  ///     assignment-expression
+  ///     nonempty-expr-list , assignment-expression
+  ///
+  ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
+                                            SourceLocation SuperLoc,
+                                            ParsedType ReceiverType,
+                                            Expr *ReceiverExpr);
+
+  /// Parse the receiver of an Objective-C++ message send.
+  ///
+  /// This routine parses the receiver of a message send in
+  /// Objective-C++ either as a type or as an expression. Note that this
+  /// routine must not be called to parse a send to 'super', since it
+  /// has no way to return such a result.
+  ///
+  /// \param IsExpr Whether the receiver was parsed as an expression.
+  ///
+  /// \param TypeOrExpr If the receiver was parsed as an expression (\c
+  /// IsExpr is true), the parsed expression. If the receiver was parsed
+  /// as a type (\c IsExpr is false), the parsed type.
+  ///
+  /// \returns True if an error occurred during parsing or semantic
+  /// analysis, in which case the arguments do not have valid
+  /// values. Otherwise, returns false for a successful parse.
+  ///
+  ///   objc-receiver: [C++]
+  ///     'super' [not parsed here]
+  ///     expression
+  ///     simple-type-specifier
+  ///     typename-specifier
+  bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
+
+  //===--------------------------------------------------------------------===//
+  // Objective-C Statements
+
+  enum class ParsedStmtContext;
+
+  StmtResult ParseObjCAtStatement(SourceLocation atLoc,
+                                  ParsedStmtContext StmtCtx);
+  
+  ///  objc-try-catch-statement:
+  ///    @try compound-statement objc-catch-list[opt]
+  ///    @try compound-statement objc-catch-list[opt] @finally compound-statement
+  ///
+  ///  objc-catch-list:
+  ///    @catch ( parameter-declaration ) compound-statement
+  ///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
+  ///  catch-parameter-declaration:
+  ///     parameter-declaration
+  ///     '...' [OBJC2]
+  ///
+  StmtResult ParseObjCTryStmt(SourceLocation atLoc);
+  
+  ///  objc-throw-statement:
+  ///    throw expression[opt];
+  ///
+  StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
+  
+  /// objc-synchronized-statement:
+  ///   @synchronized '(' expression ')' compound-statement
+  ///
+  StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
+  
+  /// objc-autoreleasepool-statement:
+  ///   @autoreleasepool compound-statement
+  ///
+  StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc);
+  
+  /// ParseObjCTypeQualifierList - This routine parses the objective-c's type
+  /// qualifier list and builds their bitmask representation in the input
+  /// argument.
+  ///
+  ///   objc-type-qualifiers:
+  ///     objc-type-qualifier
+  ///     objc-type-qualifiers objc-type-qualifier
+  ///
+  ///   objc-type-qualifier:
+  ///     'in'
+  ///     'out'
+  ///     'inout'
+  ///     'oneway'
+  ///     'bycopy's
+  ///     'byref'
+  ///     'nonnull'
+  ///     'nullable'
+  ///     'null_unspecified'
+  ///
+  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
+                                  DeclaratorContext Context);
+
+  /// Determine whether we are currently at the start of an Objective-C
+  /// class message that appears to be missing the open bracket '['.
+  bool isStartOfObjCClassMessageMissingOpenBracket();
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name OpenACC Constructs
+  /// Implementations are in ParseOpenACC.cpp
+  ///@{
+
+  public:
+
+  friend class ParsingOpenACCDirectiveRAII;
+
+  /// Parse OpenACC directive on a declaration.
+  ///
+  /// Placeholder for now, should just ignore the directives after emitting a
+  /// diagnostic. Eventually will be split into a few functions to parse
+  /// different situations.
+  DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS,
+                                           ParsedAttributes &Attrs,
+                                           DeclSpec::TST TagType,
+                                           Decl *TagDecl);
+  
+  // Parse OpenACC Directive on a Statement.
+  StmtResult ParseOpenACCDirectiveStmt();
+
+  private:
+
+  /// Parsing OpenACC directive mode.
+  bool OpenACCDirectiveParsing = false;
+
+  /// Currently parsing a situation where an OpenACC array section could be
+  /// legal, such as a 'var-list'.
+  bool AllowOpenACCArraySections = false;
+
+  /// RAII object to set reset OpenACC parsing a context where Array Sections
+  /// are allowed.
+  class OpenACCArraySectionRAII {
+    Parser &P;
+
+  public:
+    OpenACCArraySectionRAII(Parser &P) : P(P) {
+      assert(!P.AllowOpenACCArraySections);
+      P.AllowOpenACCArraySections = true;
+    }
+    ~OpenACCArraySectionRAII() {
+      assert(P.AllowOpenACCArraySections);
+      P.AllowOpenACCArraySections = false;
+    }
+  };
+
+  /// A struct to hold the information that got parsed by ParseOpenACCDirective,
+  /// so that the callers of it can use that to construct the appropriate AST
+  /// nodes.
+  struct OpenACCDirectiveParseInfo {
+    OpenACCDirectiveKind DirKind;
+    SourceLocation StartLoc;
+    SourceLocation DirLoc;
+    SourceLocation LParenLoc;
+    SourceLocation RParenLoc;
+    SourceLocation EndLoc;
+    SourceLocation MiscLoc;
+    OpenACCAtomicKind AtomicKind;
+    SmallVector<Expr *> Exprs;
+    SmallVector<OpenACCClause *> Clauses;
+    // TODO OpenACC: As we implement support for the Atomic, Routine, and Cache
+    // constructs, we likely want to put that information in here as well.
+  };
+
+  struct OpenACCWaitParseInfo {
+    bool Failed = false;
+    Expr *DevNumExpr = nullptr;
+    SourceLocation QueuesLoc;
+    SmallVector<Expr *> QueueIdExprs;
+
+    SmallVector<Expr *> getAllExprs() {
+      SmallVector<Expr *> Out;
+      Out.push_back(DevNumExpr);
+      llvm::append_range(Out, QueueIdExprs);
+      return Out;
+    }
+  };
+  struct OpenACCCacheParseInfo {
+    bool Failed = false;
+    SourceLocation ReadOnlyLoc;
+    SmallVector<Expr *> Vars;
+  };
+
+  /// Represents the 'error' state of parsing an OpenACC Clause, and stores
+  /// whether we can continue parsing, or should give up on the directive.
+  enum class OpenACCParseCanContinue { Cannot = 0, Can = 1 };
+
+  /// A type to represent the state of parsing an OpenACC Clause. Situations
+  /// that result in an OpenACCClause pointer are a success and can continue
+  /// parsing, however some other situations can also continue.
+  /// FIXME: This is better represented as a std::expected when we get C++23.
+  using OpenACCClauseParseResult =
+      llvm::PointerIntPair<OpenACCClause *, 1, OpenACCParseCanContinue>;
+
+  OpenACCClauseParseResult OpenACCCanContinue();
+  OpenACCClauseParseResult OpenACCCannotContinue();
+  OpenACCClauseParseResult OpenACCSuccess(OpenACCClause *Clause);
+
+  /// Parses the OpenACC directive (the entire pragma) including the clause
+  /// list, but does not produce the main AST node.
+  OpenACCDirectiveParseInfo ParseOpenACCDirective();
+  /// Helper that parses an ID Expression based on the language options.
+  ExprResult ParseOpenACCIDExpression();
+
+  /// Parses the variable list for the `cache` construct.
+  ///
+  /// OpenACC 3.3, section 2.10:
+  /// In C and C++, the syntax of the cache directive is:
+  ///
+  /// #pragma acc cache ([readonly:]var-list) new-line
+  OpenACCCacheParseInfo ParseOpenACCCacheVarList();
+  
+  /// Tries to parse the 'modifier-list' for a 'copy', 'copyin', 'copyout', or
+  /// 'create' clause.
+  OpenACCModifierKind tryParseModifierList(OpenACCClauseKind CK);
+
+  using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
+  
+  /// Parses a single variable in a variable list for OpenACC.
+  ///
+  /// OpenACC 3.3, section 1.6:
+  /// In this spec, a 'var' (in italics) is one of the following:
+  /// - a variable name (a scalar, array, or composite variable name)
+  /// - a subarray specification with subscript ranges
+  /// - an array element
+  /// - a member of a composite variable
+  /// - a common block name between slashes (fortran only)
+  OpenACCVarParseResult ParseOpenACCVar(OpenACCDirectiveKind DK,
+                                        OpenACCClauseKind CK);
+
+  /// Parses the variable list for the variety of places that take a var-list.
+  llvm::SmallVector<Expr *> ParseOpenACCVarList(OpenACCDirectiveKind DK,
+                                                OpenACCClauseKind CK);
+  
+  /// Parses any parameters for an OpenACC Clause, including required/optional
+  /// parens.
+  ///
+  /// The OpenACC Clause List is a comma or space-delimited list of clauses (see
+  /// the comment on ParseOpenACCClauseList).  The concept of a 'clause' doesn't
+  /// really have its owner grammar and each individual one has its own definition.
+  /// However, they all are named with a single-identifier (or auto/default!)
+  /// token, followed in some cases by either braces or parens.
+  OpenACCClauseParseResult
+  ParseOpenACCClauseParams(ArrayRef<const OpenACCClause *> ExistingClauses,
+                           OpenACCDirectiveKind DirKind, OpenACCClauseKind Kind,
+                           SourceLocation ClauseLoc);
+
+  /// Parses a single clause in a clause-list for OpenACC. Returns nullptr on
+  /// error.
+  OpenACCClauseParseResult
+  ParseOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
+                     OpenACCDirectiveKind DirKind);
+  
+  /// Parses the clause-list for an OpenACC directive.
+  ///
+  /// OpenACC 3.3, section 1.7:
+  /// To simplify the specification and convey appropriate constraint information,
+  /// a pqr-list is a comma-separated list of pdr items. The one exception is a
+  /// clause-list, which is a list of one or more clauses optionally separated by
+  /// commas.
+  SmallVector<OpenACCClause *>
+  ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
+  
+  /// OpenACC 3.3, section 2.16:
+  /// In this section and throughout the specification, the term wait-argument
+  /// means:
+  /// [ devnum : int-expr : ] [ queues : ] async-argument-list
+  OpenACCWaitParseInfo ParseOpenACCWaitArgument(SourceLocation Loc,
+                                                bool IsDirective);
+
+  /// Parses the clause of the 'bind' argument, which can be a string literal or
+  /// an identifier.
+  std::variant<std::monostate, StringLiteral *, IdentifierInfo *>
+  ParseOpenACCBindClauseArgument();
+
+  /// A type to represent the state of parsing after an attempt to parse an
+  /// OpenACC int-expr. This is useful to determine whether an int-expr list can
+  /// continue parsing after a failed int-expr.
+  using OpenACCIntExprParseResult =
+      std::pair<ExprResult, OpenACCParseCanContinue>;
+  /// Parses the clause kind of 'int-expr', which can be any integral
+  /// expression.
+  OpenACCIntExprParseResult ParseOpenACCIntExpr(OpenACCDirectiveKind DK,
+                                                OpenACCClauseKind CK,
+                                                SourceLocation Loc);
+  /// Parses the argument list for 'num_gangs', which allows up to 3
+  /// 'int-expr's.
+  bool ParseOpenACCIntExprList(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
+                               SourceLocation Loc,
+                               llvm::SmallVectorImpl<Expr *> &IntExprs);
+  
+  /// Parses the 'device-type-list', which is a list of identifiers.
+  ///
+  /// OpenACC 3.3 Section 2.4:
+  /// The argument to the device_type clause is a comma-separated list of one or
+  /// more device architecture name identifiers, or an asterisk.
+  ///
+  /// The syntax of the device_type clause is
+  /// device_type( * )
+  /// device_type( device-type-list )
+  ///
+  /// The device_type clause may be abbreviated to dtype.
+  bool ParseOpenACCDeviceTypeList(llvm::SmallVector<IdentifierLoc> &Archs);
+  
+  /// Parses the 'async-argument', which is an integral value with two
+  /// 'special' values that are likely negative (but come from Macros).
+  ///
+  /// OpenACC 3.3 section 2.16:
+  /// In this section and throughout the specification, the term async-argument
+  /// means a nonnegative scalar integer expression (int for C or C++, integer for
+  /// Fortran), or one of the special values acc_async_noval or acc_async_sync, as
+  /// defined in the C header file and the Fortran openacc module. The special
+  /// values are negative values, so as not to conflict with a user-specified
+  /// nonnegative async-argument.
+  OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
+                                                      OpenACCClauseKind CK,
+                                                      SourceLocation Loc);
+
+  /// Parses the 'size-expr', which is an integral value, or an asterisk.
+  /// Asterisk is represented by a OpenACCAsteriskSizeExpr
+  ///
+  /// OpenACC 3.3 Section 2.9:
+  /// size-expr is one of:
+  ///    *
+  ///    int-expr
+  /// Note that this is specified under 'gang-arg-list', but also applies to 'tile'
+  /// via reference.
+  ExprResult ParseOpenACCSizeExpr(OpenACCClauseKind CK);
+  
+  /// Parses a comma delimited list of 'size-expr's.
+  bool ParseOpenACCSizeExprList(OpenACCClauseKind CK,
+                                llvm::SmallVectorImpl<Expr *> &SizeExprs);
+  
+  /// Parses a 'gang-arg-list', used for the 'gang' clause.
+  ///
+  /// OpenACC 3.3 Section 2.9:
+  ///
+  /// where gang-arg is one of:
+  /// [num:]int-expr
+  /// dim:int-expr
+  /// static:size-expr
+  bool ParseOpenACCGangArgList(SourceLocation GangLoc,
+                               llvm::SmallVectorImpl<OpenACCGangKind> &GKs,
+                               llvm::SmallVectorImpl<Expr *> &IntExprs);
+
+  using OpenACCGangArgRes = std::pair<OpenACCGangKind, ExprResult>;
+  /// Parses a 'gang-arg', used for the 'gang' clause. Returns a pair of the
+  /// ExprResult (which contains the validity of the expression), plus the gang
+  /// kind for the current argument.
+  OpenACCGangArgRes ParseOpenACCGangArg(SourceLocation GangLoc);
+  /// Parses a 'condition' expr, ensuring it results in a
+  ExprResult ParseOpenACCConditionExpr();
+  DeclGroupPtrTy
+  ParseOpenACCAfterRoutineDecl(AccessSpecifier &AS, ParsedAttributes &Attrs,
+                               DeclSpec::TST TagType, Decl *TagDecl,
+                               OpenACCDirectiveParseInfo &DirInfo);
+  StmtResult ParseOpenACCAfterRoutineStmt(OpenACCDirectiveParseInfo &DirInfo);
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name OpenMP Constructs
+  /// Implementations are in ParseOpenMP.cpp
+  ///@{
+
+  public:
+
+  friend class ParsingOpenMPDirectiveRAII;
+
+  private:
+
+  /// Parsing OpenMP directive mode.
+  bool OpenMPDirectiveParsing = false;
+
+  /// Current kind of OpenMP clause
+  OpenMPClauseKind OMPClauseKind = llvm::omp::OMPC_unknown;
+
+  void ReplayOpenMPAttributeTokens(CachedTokens &OpenMPTokens) {
+    // If parsing the attributes found an OpenMP directive, emit those tokens
+    // to the parse stream now.
+    if (!OpenMPTokens.empty()) {
+      PP.EnterToken(Tok, /*IsReinject*/ true);
+      PP.EnterTokenStream(OpenMPTokens, /*DisableMacroExpansion*/ true,
+                          /*IsReinject*/ true);
+      ConsumeAnyToken(/*ConsumeCodeCompletionTok*/ true);
+    }
+  }
+
+  //===--------------------------------------------------------------------===//
+  // OpenMP: Directives and clauses.
+  
+  /// Parse clauses for '#pragma omp declare simd'.
+  DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
+                                            CachedTokens &Toks,
+                                            SourceLocation Loc);
+
+  /// Parse a property kind into \p TIProperty for the selector set \p Set and
+  /// selector \p Selector.
+  void parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
+                                 llvm::omp::TraitSet Set,
+                                 llvm::omp::TraitSelector Selector,
+                                 llvm::StringMap<SourceLocation> &Seen);
+
+  /// Parse a selector kind into \p TISelector for the selector set \p Set.
+  void parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
+                                 llvm::omp::TraitSet Set,
+                                 llvm::StringMap<SourceLocation> &Seen);
+
+  /// Parse a selector set kind into \p TISet.
+  void parseOMPTraitSetKind(OMPTraitSet &TISet,
+                            llvm::StringMap<SourceLocation> &Seen);
+
+  /// Parses an OpenMP context property.
+  void parseOMPContextProperty(OMPTraitSelector &TISelector,
+                               llvm::omp::TraitSet Set,
+                               llvm::StringMap<SourceLocation> &Seen);
+
+  /// Parses an OpenMP context selector.
+  ///
+  /// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
+  void parseOMPContextSelector(OMPTraitSelector &TISelector,
+                               llvm::omp::TraitSet Set,
+                               llvm::StringMap<SourceLocation> &SeenSelectors);
+
+  /// Parses an OpenMP context selector set.
+  ///
+  /// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
+  void parseOMPContextSelectorSet(OMPTraitSet &TISet,
+                                  llvm::StringMap<SourceLocation> &SeenSets);
+
+  /// Parse OpenMP context selectors:
+  ///
+  /// <trait-set-selector> [, <trait-set-selector>]*
+  bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI);
+
+  /// Parse an 'append_args' clause for '#pragma omp declare variant'.
+  bool parseOpenMPAppendArgs(SmallVectorImpl<OMPInteropInfo> &InteropInfos);
+
+  /// Parse a `match` clause for an '#pragma omp declare variant'. Return true
+  /// if there was an error.
+  bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI,
+                                         OMPTraitInfo *ParentTI);
+
+  /// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
+  void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
+                                     SourceLocation Loc);
+
+  /// Parse 'omp [begin] assume[s]' directive.
+  ///
+  /// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
+  /// where
+  ///
+  ///   clause:
+  ///     'ext_IMPL_DEFINED'
+  ///     'absent' '(' directive-name [, directive-name]* ')'
+  ///     'contains' '(' directive-name [, directive-name]* ')'
+  ///     'holds' '(' scalar-expression ')'
+  ///     'no_openmp'
+  ///     'no_openmp_routines'
+  ///     'no_openmp_constructs' (OpenMP 6.0)
+  ///     'no_parallelism'
+  ///
+  void ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
+                                   SourceLocation Loc);
+
+  /// Parse 'omp end assumes' directive.
+  void ParseOpenMPEndAssumesDirective(SourceLocation Loc);
+
+  /// Parses clauses for directive.
+  ///
+  /// <clause> [clause[ [,] clause] ... ]
+  ///
+  ///  clauses: for error directive
+  ///     'at' '(' compilation | execution ')'
+  ///     'severity' '(' fatal | warning ')'
+  ///     'message' '(' msg-string ')'
+  /// ....
+  ///
+  /// \param DKind Kind of current directive.
+  /// \param clauses for current directive.
+  /// \param start location for clauses of current directive
+  void ParseOpenMPClauses(OpenMPDirectiveKind DKind,
+                          SmallVectorImpl<clang::OMPClause *> &Clauses,
+                          SourceLocation Loc);
+
+  /// Parse clauses for '#pragma omp [begin] declare target'.
+  void ParseOMPDeclareTargetClauses(SemaOpenMP::DeclareTargetContextInfo &DTCI);
+
+  /// Parse '#pragma omp end declare target'.
+  void ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
+                                         OpenMPDirectiveKind EndDKind,
+                                         SourceLocation Loc);
+
+  /// Skip tokens until a `annot_pragma_openmp_end` was found. Emit a warning if
+  /// it is not the current token.
+  void skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind);
+
+  /// Check the \p FoundKind against the \p ExpectedKind, if not issue an error
+  /// that the "end" matching the "begin" directive of kind \p BeginKind was not
+  /// found. Finally, if the expected kind was found or if \p SkipUntilOpenMPEnd
+  /// is set, skip ahead using the helper `skipUntilPragmaOpenMPEnd`.
+  void parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
+                            OpenMPDirectiveKind ExpectedKind,
+                            OpenMPDirectiveKind FoundKind,
+                            SourceLocation MatchingLoc,
+                            SourceLocation FoundLoc,
+                            bool SkipUntilOpenMPEnd);
+
+  /// Parses declarative OpenMP directives.
+  ///
+  ///       threadprivate-directive:
+  ///         annot_pragma_openmp 'threadprivate' simple-variable-list
+  ///         annot_pragma_openmp_end
+  ///
+  ///       allocate-directive:
+  ///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
+  ///         annot_pragma_openmp_end
+  ///
+  ///       declare-reduction-directive:
+  ///        annot_pragma_openmp 'declare' 'reduction' [...]
+  ///        annot_pragma_openmp_end
+  ///
+  ///       declare-mapper-directive:
+  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
+  ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
+  ///         annot_pragma_openmp_end
+  ///
+  ///       declare-simd-directive:
+  ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
+  ///         annot_pragma_openmp_end
+  ///         <function declaration/definition>
+  ///
+  ///       requires directive:
+  ///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
+  ///         annot_pragma_openmp_end
+  ///
+  ///       assumes directive:
+  ///         annot_pragma_openmp 'assumes' <clause> [[[,] <clause>] ... ]
+  ///         annot_pragma_openmp_end
+  ///       or
+  ///         annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
+  ///         annot_pragma_openmp 'end assumes'
+  ///         annot_pragma_openmp_end
+  ///
+  DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
+      AccessSpecifier &AS, ParsedAttributes &Attrs, bool Delayed = false,
+      DeclSpec::TST TagType = DeclSpec::TST_unspecified,
+      Decl *TagDecl = nullptr);
+  
+  /// Parse 'omp declare reduction' construct.
+  ///
+  ///       declare-reduction-directive:
+  ///        annot_pragma_openmp 'declare' 'reduction'
+  ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
+  ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
+  ///        annot_pragma_openmp_end
+  /// <reduction_id> is either a base language identifier or one of the following
+  /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
+  ///
+  DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
+  
+  /// Parses initializer for provided omp_priv declaration inside the reduction
+  /// initializer.
+  void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);
+
+  /// Parses 'omp declare mapper' directive.
+  ///
+  ///       declare-mapper-directive:
+  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
+  ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
+  ///         annot_pragma_openmp_end
+  /// <mapper-identifier> and <var> are base language identifiers.
+  ///
+  DeclGroupPtrTy ParseOpenMPDeclareMapperDirective(AccessSpecifier AS);
+
+  /// Parses variable declaration in 'omp declare mapper' directive.
+  TypeResult parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
+                                             DeclarationName &Name,
+                                             AccessSpecifier AS = AS_none);
+
+  /// Parses simple list of variables.
+  ///
+  ///   simple-variable-list:
+  ///         '(' id-expression {, id-expression} ')'
+  ///
+  /// \param Kind Kind of the directive.
+  /// \param Callback Callback function to be called for the list elements.
+  /// \param AllowScopeSpecifier true, if the variables can have fully
+  /// qualified names.
+  ///
+  bool ParseOpenMPSimpleVarList(
+      OpenMPDirectiveKind Kind,
+      const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
+          Callback,
+      bool AllowScopeSpecifier);
+  
+  /// Parses declarative or executable directive.
+  ///
+  ///       threadprivate-directive:
+  ///         annot_pragma_openmp 'threadprivate' simple-variable-list
+  ///         annot_pragma_openmp_end
+  ///
+  ///       allocate-directive:
+  ///         annot_pragma_openmp 'allocate' simple-variable-list
+  ///         annot_pragma_openmp_end
+  ///
+  ///       declare-reduction-directive:
+  ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
+  ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
+  ///         ('omp_priv' '=' <expression>|<function_call>) ')']
+  ///         annot_pragma_openmp_end
+  ///
+  ///       declare-mapper-directive:
+  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
+  ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
+  ///         annot_pragma_openmp_end
+  ///
+  ///       executable-directive:
+  ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
+  ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
+  ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
+  ///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'error'
+  ///         | 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
+  ///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
+  ///         'master taskloop' | 'master taskloop simd' | 'parallel master
+  ///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
+  ///         enter data' | 'target exit data' | 'target parallel' | 'target
+  ///         parallel for' | 'target update' | 'distribute parallel for' |
+  ///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
+  ///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
+  ///         simd' | 'teams distribute parallel for simd' | 'teams distribute
+  ///         parallel for' | 'target teams' | 'target teams distribute' | 'target
+  ///         teams distribute parallel for' | 'target teams distribute parallel
+  ///         for simd' | 'target teams distribute simd' | 'masked' |
+  ///         'parallel masked' {clause} annot_pragma_openmp_end
+  ///
+  ///
+  /// \param StmtCtx The context in which we're parsing the directive.
+  /// \param ReadDirectiveWithinMetadirective true if directive is within a
+  /// metadirective and therefore ends on the closing paren.
+  StmtResult ParseOpenMPDeclarativeOrExecutableDirective(
+      ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false);
+
+  /// Parses executable directive.
+  ///
+  /// \param StmtCtx The context in which we're parsing the directive.
+  /// \param DKind The kind of the executable directive.
+  /// \param Loc Source location of the beginning of the directive.
+  /// \param ReadDirectiveWithinMetadirective true if directive is within a
+  /// metadirective and therefore ends on the closing paren.
+  StmtResult
+  ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
+                                 OpenMPDirectiveKind DKind, SourceLocation Loc,
+                                 bool ReadDirectiveWithinMetadirective);
+
+  /// Parses informational directive.
+  ///
+  /// \param StmtCtx The context in which we're parsing the directive.
+  /// \param DKind The kind of the informational directive.
+  /// \param Loc Source location of the beginning of the directive.
+  /// \param ReadDirectiveWithinMetadirective true if directive is within a
+  /// metadirective and therefore ends on the closing paren.
+  StmtResult ParseOpenMPInformationalDirective(
+      ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc,
+      bool ReadDirectiveWithinMetadirective);
+
+  /// Parses clause of kind \a CKind for directive of a kind \a Kind.
+  ///
+  ///    clause:
+  ///       if-clause | final-clause | num_threads-clause | safelen-clause |
+  ///       default-clause | private-clause | firstprivate-clause | shared-clause
+  ///       | linear-clause | aligned-clause | collapse-clause | bind-clause |
+  ///       lastprivate-clause | reduction-clause | proc_bind-clause |
+  ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
+  ///       mergeable-clause | flush-clause | read-clause | write-clause |
+  ///       update-clause | capture-clause | seq_cst-clause | device-clause |
+  ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
+  ///       thread_limit-clause | priority-clause | grainsize-clause |
+  ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
+  ///       from-clause | is_device_ptr-clause | task_reduction-clause |
+  ///       in_reduction-clause | allocator-clause | allocate-clause |
+  ///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
+  ///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
+  ///       exclusive-clause | uses_allocators-clause | use_device_addr-clause |
+  ///       has_device_addr
+  ///
+  /// \param DKind Kind of current directive.
+  /// \param CKind Kind of current clause.
+  /// \param FirstClause true, if this is the first clause of a kind \a CKind
+  /// in current directive.
+  ///
+  OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind,
+                               OpenMPClauseKind CKind, bool FirstClause);
+  
+  /// Parses clause with a single expression of a kind \a Kind.
+  ///
+  /// Parsing of OpenMP clauses with single expressions like 'final',
+  /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
+  /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
+  /// 'detach'.
+  ///
+  ///    final-clause:
+  ///      'final' '(' expression ')'
+  ///
+  ///    num_threads-clause:
+  ///      'num_threads' '(' expression ')'
+  ///
+  ///    safelen-clause:
+  ///      'safelen' '(' expression ')'
+  ///
+  ///    simdlen-clause:
+  ///      'simdlen' '(' expression ')'
+  ///
+  ///    collapse-clause:
+  ///      'collapse' '(' expression ')'
+  ///
+  ///    priority-clause:
+  ///      'priority' '(' expression ')'
+  ///
+  ///    grainsize-clause:
+  ///      'grainsize' '(' expression ')'
+  ///
+  ///    num_tasks-clause:
+  ///      'num_tasks' '(' expression ')'
+  ///
+  ///    hint-clause:
+  ///      'hint' '(' expression ')'
+  ///
+  ///    allocator-clause:
+  ///      'allocator' '(' expression ')'
+  ///
+  ///    detach-clause:
+  ///      'detach' '(' event-handler-expression ')'
+  ///
+  ///    align-clause
+  ///      'align' '(' positive-integer-constant ')'
+  ///
+  ///    holds-clause
+  ///      'holds' '(' expression ')'
+  ///
+  ///
+  /// \param Kind Kind of current clause.
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// nullptr.
+  ///
+  OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
+                                         bool ParseOnly);
+  /// Parses simple clause like 'default' or 'proc_bind' of a kind \a Kind.
+  ///
+  ///    default-clause:
+  ///         'default' '(' 'none' | 'shared' | 'private' | 'firstprivate' ')'
+  ///
+  ///    proc_bind-clause:
+  ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
+  ///
+  ///    bind-clause:
+  ///         'bind' '(' 'teams' | 'parallel' | 'thread' ')'
+  ///
+  ///    update-clause:
+  ///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' |
+  ///         'inoutset' ')'
+  ///
+  /// \param Kind Kind of current clause.
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// nullptr.
+  ///
+  OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind, bool ParseOnly);
+  
+  /// Parse indirect clause for '#pragma omp declare target' directive.
+  ///  'indirect' '[' '(' invoked-by-fptr ')' ']'
+  /// where invoked-by-fptr is a constant boolean expression that evaluates to
+  /// true or false at compile time.
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// false;
+  bool ParseOpenMPIndirectClause(SemaOpenMP::DeclareTargetContextInfo &DTCI,
+                                 bool ParseOnly);
+  /// Parses clause with a single expression and an additional argument
+  /// of a kind \a Kind like 'schedule' or 'dist_schedule'.
+  ///
+  ///    schedule-clause:
+  ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
+  ///      ')'
+  ///
+  ///    if-clause:
+  ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
+  ///
+  ///    defaultmap:
+  ///      'defaultmap' '(' modifier [ ':' kind ] ')'
+  ///
+  ///    device-clause:
+  ///      'device' '(' [ device-modifier ':' ] expression ')'
+  ///
+  /// \param DKind Directive kind.
+  /// \param Kind Kind of current clause.
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// nullptr.
+  ///
+  OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
+                                                OpenMPClauseKind Kind,
+                                                bool ParseOnly);
+
+  /// Parses the 'sizes' clause of a '#pragma omp tile' directive.
+  OMPClause *ParseOpenMPSizesClause();
+
+  /// Parses the 'permutation' clause of a '#pragma omp interchange' directive.
+  OMPClause *ParseOpenMPPermutationClause();
+
+  /// Parses clause without any additional arguments like 'ordered'.
+  ///
+  ///    ordered-clause:
+  ///         'ordered'
+  ///
+  ///    nowait-clause:
+  ///         'nowait'
+  ///
+  ///    untied-clause:
+  ///         'untied'
+  ///
+  ///    mergeable-clause:
+  ///         'mergeable'
+  ///
+  ///    read-clause:
+  ///         'read'
+  ///
+  ///    threads-clause:
+  ///         'threads'
+  ///
+  ///    simd-clause:
+  ///         'simd'
+  ///
+  ///    nogroup-clause:
+  ///         'nogroup'
+  ///
+  /// \param Kind Kind of current clause.
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// nullptr.
+  ///
+  OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly = false);
+  
+  /// Parses clause with the list of variables of a kind \a Kind:
+  /// 'private', 'firstprivate', 'lastprivate',
+  /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
+  /// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
+  ///
+  ///    private-clause:
+  ///       'private' '(' list ')'
+  ///    firstprivate-clause:
+  ///       'firstprivate' '(' list ')'
+  ///    lastprivate-clause:
+  ///       'lastprivate' '(' list ')'
+  ///    shared-clause:
+  ///       'shared' '(' list ')'
+  ///    linear-clause:
+  ///       'linear' '(' linear-list [ ':' linear-step ] ')'
+  ///    aligned-clause:
+  ///       'aligned' '(' list [ ':' alignment ] ')'
+  ///    reduction-clause:
+  ///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
+  ///    task_reduction-clause:
+  ///       'task_reduction' '(' reduction-identifier ':' list ')'
+  ///    in_reduction-clause:
+  ///       'in_reduction' '(' reduction-identifier ':' list ')'
+  ///    copyprivate-clause:
+  ///       'copyprivate' '(' list ')'
+  ///    flush-clause:
+  ///       'flush' '(' list ')'
+  ///    depend-clause:
+  ///       'depend' '(' in | out | inout : list | source ')'
+  ///    map-clause:
+  ///       'map' '(' [ [ always [,] ] [ close [,] ]
+  ///          [ mapper '(' mapper-identifier ')' [,] ]
+  ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
+  ///    to-clause:
+  ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
+  ///    from-clause:
+  ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
+  ///    use_device_ptr-clause:
+  ///       'use_device_ptr' '(' list ')'
+  ///    use_device_addr-clause:
+  ///       'use_device_addr' '(' list ')'
+  ///    is_device_ptr-clause:
+  ///       'is_device_ptr' '(' list ')'
+  ///    has_device_addr-clause:
+  ///       'has_device_addr' '(' list ')'
+  ///    allocate-clause:
+  ///       'allocate' '(' [ allocator ':' ] list ')'
+  ///       As of OpenMP 5.1 there's also
+  ///         'allocate' '(' allocate-modifier: list ')'
+  ///         where allocate-modifier is: 'allocator' '(' allocator ')'
+  ///    nontemporal-clause:
+  ///       'nontemporal' '(' list ')'
+  ///    inclusive-clause:
+  ///       'inclusive' '(' list ')'
+  ///    exclusive-clause:
+  ///       'exclusive' '(' list ')'
+  ///
+  /// For 'linear' clause linear-list may have the following forms:
+  ///  list
+  ///  modifier(list)
+  /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
+  ///
+  /// \param Kind Kind of current clause.
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// nullptr.
+  ///
+  OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
+                                      OpenMPClauseKind Kind, bool ParseOnly);
+
+  /// Parses a clause consisting of a list of expressions.
+  ///
+  /// \param Kind          The clause to parse.
+  /// \param ClauseNameLoc [out] The location of the clause name.
+  /// \param OpenLoc       [out] The location of '('.
+  /// \param CloseLoc      [out] The location of ')'.
+  /// \param Exprs         [out] The parsed expressions.
+  /// \param ReqIntConst   If true, each expression must be an integer constant.
+  ///
+  /// \return Whether the clause was parsed successfully.
+  bool ParseOpenMPExprListClause(OpenMPClauseKind Kind,
+                                 SourceLocation &ClauseNameLoc,
+                                 SourceLocation &OpenLoc,
+                                 SourceLocation &CloseLoc,
+                                 SmallVectorImpl<Expr *> &Exprs,
+                                 bool ReqIntConst = false);
+
+  /// Parses simple expression in parens for single-expression clauses of OpenMP
+  /// constructs.
+  /// <iterators> = 'iterator' '(' { [ <iterator-type> ] identifier =
+  /// <range-specification> }+ ')'
+  ExprResult ParseOpenMPIteratorsExpr();
+
+  /// Parses allocators and traits in the context of the uses_allocator clause.
+  /// Expected format:
+  /// '(' { <allocator> [ '(' <allocator_traits> ')' ] }+ ')'
+  OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind);
+
+  /// Parses the 'interop' parts of the 'append_args' and 'init' clauses.
+  bool ParseOMPInteropInfo(OMPInteropInfo &InteropInfo, OpenMPClauseKind Kind);
+
+  /// Parses clause with an interop variable of kind \a Kind.
+  ///
+  /// init-clause:
+  ///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
+  ///
+  /// destroy-clause:
+  ///   destroy(interop-var)
+  ///
+  /// use-clause:
+  ///   use(interop-var)
+  ///
+  /// interop-modifier:
+  ///   prefer_type(preference-list)
+  ///
+  /// preference-list:
+  ///   foreign-runtime-id [, foreign-runtime-id]...
+  ///
+  /// foreign-runtime-id:
+  ///   <string-literal> | <constant-integral-expression>
+  ///
+  /// interop-type:
+  ///   target | targetsync
+  ///
+  /// \param Kind Kind of current clause.
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// nullptr.
+  //
+  OMPClause *ParseOpenMPInteropClause(OpenMPClauseKind Kind, bool ParseOnly);
+
+  /// Parses a ompx_attribute clause
+  ///
+  /// \param ParseOnly true to skip the clause's semantic actions and return
+  /// nullptr.
+  //
+  OMPClause *ParseOpenMPOMPXAttributesClause(bool ParseOnly);
+
+public:
+  /// Parses simple expression in parens for single-expression clauses of OpenMP
+  /// constructs.
+  /// \param RLoc Returned location of right paren.
+  ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc,
+                                   bool IsAddressOfOperand = false);
+
+  /// Parses a reserved locator like 'omp_all_memory'.
+  bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
+                                  SemaOpenMP::OpenMPVarListDataTy &Data,
+                                  const LangOptions &LangOpts);
+  /// Parses clauses with list.
+  bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind,
+                          SmallVectorImpl<Expr *> &Vars,
+                          SemaOpenMP::OpenMPVarListDataTy &Data);
+
+  /// Parses the mapper modifier in map, to, and from clauses.
+  bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data);
+  
+  /// Parse map-type-modifiers in map clause.
+  /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] [map-type] : ] list)
+  /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
+  /// present
+  /// where, map-type ::= alloc | delete | from | release | to | tofrom
+  bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data);
+
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
+
+  /// \name Pragmas
+  /// Implementations are in ParsePragma.cpp
+  ///@{
+
+  public:
+
+  private:
+
+  std::unique_ptr<PragmaHandler> AlignHandler;
+  std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
+  std::unique_ptr<PragmaHandler> OptionsHandler;
+  std::unique_ptr<PragmaHandler> PackHandler;
+  std::unique_ptr<PragmaHandler> MSStructHandler;
+  std::unique_ptr<PragmaHandler> UnusedHandler;
+  std::unique_ptr<PragmaHandler> WeakHandler;
+  std::unique_ptr<PragmaHandler> RedefineExtnameHandler;
+  std::unique_ptr<PragmaHandler> FPContractHandler;
+  std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
+  std::unique_ptr<PragmaHandler> OpenMPHandler;
+  std::unique_ptr<PragmaHandler> OpenACCHandler;
+  std::unique_ptr<PragmaHandler> PCSectionHandler;
+  std::unique_ptr<PragmaHandler> MSCommentHandler;
+  std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
+  std::unique_ptr<PragmaHandler> FPEvalMethodHandler;
+  std::unique_ptr<PragmaHandler> FloatControlHandler;
+  std::unique_ptr<PragmaHandler> MSPointersToMembers;
+  std::unique_ptr<PragmaHandler> MSVtorDisp;
+  std::unique_ptr<PragmaHandler> MSInitSeg;
+  std::unique_ptr<PragmaHandler> MSDataSeg;
+  std::unique_ptr<PragmaHandler> MSBSSSeg;
+  std::unique_ptr<PragmaHandler> MSConstSeg;
+  std::unique_ptr<PragmaHandler> MSCodeSeg;
+  std::unique_ptr<PragmaHandler> MSSection;
+  std::unique_ptr<PragmaHandler> MSStrictGuardStackCheck;
+  std::unique_ptr<PragmaHandler> MSRuntimeChecks;
+  std::unique_ptr<PragmaHandler> MSIntrinsic;
+  std::unique_ptr<PragmaHandler> MSFunction;
+  std::unique_ptr<PragmaHandler> MSOptimize;
+  std::unique_ptr<PragmaHandler> MSFenvAccess;
+  std::unique_ptr<PragmaHandler> MSAllocText;
+  std::unique_ptr<PragmaHandler> CUDAForceHostDeviceHandler;
+  std::unique_ptr<PragmaHandler> OptimizeHandler;
+  std::unique_ptr<PragmaHandler> LoopHintHandler;
+  std::unique_ptr<PragmaHandler> UnrollHintHandler;
+  std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
+  std::unique_ptr<PragmaHandler> UnrollAndJamHintHandler;
+  std::unique_ptr<PragmaHandler> NoUnrollAndJamHintHandler;
+  std::unique_ptr<PragmaHandler> FPHandler;
+  std::unique_ptr<PragmaHandler> STDCFenvAccessHandler;
+  std::unique_ptr<PragmaHandler> STDCFenvRoundHandler;
+  std::unique_ptr<PragmaHandler> STDCCXLIMITHandler;
+  std::unique_ptr<PragmaHandler> STDCUnknownHandler;
+  std::unique_ptr<PragmaHandler> AttributePragmaHandler;
+  std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
+  std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
+  std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
+
+  /// Initialize all pragma handlers.
+  void initializePragmaHandlers();
 
-  //===--------------------------------------------------------------------===//
-  // C++ 6: Statements and Blocks
+  /// Destroy and reset all pragma handlers.
+  void resetPragmaHandlers();
 
-  StmtResult ParseCXXTryBlock();
-  StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
-  StmtResult ParseCXXCatchBlock(bool FnCatch = false);
+  /// Handle the annotation token produced for #pragma unused(...)
+  ///
+  /// Each annot_pragma_unused is followed by the argument token so e.g.
+  /// "#pragma unused(x,y)" becomes:
+  /// annot_pragma_unused 'x' annot_pragma_unused 'y'
+  void HandlePragmaUnused();
 
-  //===--------------------------------------------------------------------===//
-  // MS: SEH Statements and Blocks
+  /// Handle the annotation token produced for
+  /// #pragma GCC visibility...
+  void HandlePragmaVisibility();
 
-  StmtResult ParseSEHTryBlock();
-  StmtResult ParseSEHExceptBlock(SourceLocation Loc);
-  StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
-  StmtResult ParseSEHLeaveStatement();
+  /// Handle the annotation token produced for
+  /// #pragma pack...
+  void HandlePragmaPack();
 
-  //===--------------------------------------------------------------------===//
-  // Objective-C Statements
+  /// Handle the annotation token produced for
+  /// #pragma ms_struct...
+  void HandlePragmaMSStruct();
 
-  StmtResult ParseObjCAtStatement(SourceLocation atLoc,
-                                  ParsedStmtContext StmtCtx);
-  StmtResult ParseObjCTryStmt(SourceLocation atLoc);
-  StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
-  StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
-  StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc);
+  void HandlePragmaMSPointersToMembers();
 
+  void HandlePragmaMSVtorDisp();
 
-  //===--------------------------------------------------------------------===//
-  // C99 6.7: Declarations.
+  void HandlePragmaMSPragma();
+  bool HandlePragmaMSSection(StringRef PragmaName,
+                              SourceLocation PragmaLocation);
+  bool HandlePragmaMSSegment(StringRef PragmaName,
+                              SourceLocation PragmaLocation);
 
-  /// A context for parsing declaration specifiers.  TODO: flesh this
-  /// out, there are other significant restrictions on specifiers than
-  /// would be best implemented in the parser.
-  enum class DeclSpecContext {
-    DSC_normal,         // normal context
-    DSC_class,          // class context, enables 'friend'
-    DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
-    DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
-    DSC_alias_declaration,  // C++11 type-specifier-seq in an alias-declaration
-    DSC_conv_operator,      // C++ type-specifier-seq in an conversion operator
-    DSC_top_level,          // top-level/namespace declaration context
-    DSC_template_param,     // template parameter context
-    DSC_template_arg,       // template argument context
-    DSC_template_type_arg,  // template type argument context
-    DSC_objc_method_result, // ObjC method result context, enables
-                            // 'instancetype'
-    DSC_condition,          // condition declaration context
-    DSC_association, // A _Generic selection expression's type association
-    DSC_new,         // C++ new expression
-  };
+  // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
+  bool HandlePragmaMSInitSeg(StringRef PragmaName,
+                              SourceLocation PragmaLocation);
 
-  /// Is this a context in which we are parsing just a type-specifier (or
-  /// trailing-type-specifier)?
-  static bool isTypeSpecifier(DeclSpecContext DSC) {
-    switch (DSC) {
-    case DeclSpecContext::DSC_normal:
-    case DeclSpecContext::DSC_template_param:
-    case DeclSpecContext::DSC_template_arg:
-    case DeclSpecContext::DSC_class:
-    case DeclSpecContext::DSC_top_level:
-    case DeclSpecContext::DSC_objc_method_result:
-    case DeclSpecContext::DSC_condition:
-      return false;
+  // #pragma strict_gs_check(pop)
+  // #pragma strict_gs_check(push, "on" | "off")
+  // #pragma strict_gs_check("on" | "off")
+  bool HandlePragmaMSStrictGuardStackCheck(StringRef PragmaName,
+                                            SourceLocation PragmaLocation);
+  bool HandlePragmaMSFunction(StringRef PragmaName,
+                              SourceLocation PragmaLocation);
+  bool HandlePragmaMSAllocText(StringRef PragmaName,
+                                SourceLocation PragmaLocation);
+  
+  // #pragma optimize("gsty", on|off)
+  bool HandlePragmaMSOptimize(StringRef PragmaName,
+                              SourceLocation PragmaLocation);
 
-    case DeclSpecContext::DSC_template_type_arg:
-    case DeclSpecContext::DSC_type_specifier:
-    case DeclSpecContext::DSC_conv_operator:
-    case DeclSpecContext::DSC_trailing:
-    case DeclSpecContext::DSC_alias_declaration:
-    case DeclSpecContext::DSC_association:
-    case DeclSpecContext::DSC_new:
-      return true;
-    }
-    llvm_unreachable("Missing DeclSpecContext case");
-  }
+  /// Handle the annotation token produced for
+  /// #pragma align...
+  void HandlePragmaAlign();
 
-  /// Whether a defining-type-specifier is permitted in a given context.
-  enum class AllowDefiningTypeSpec {
-    /// The grammar doesn't allow a defining-type-specifier here, and we must
-    /// not parse one (eg, because a '{' could mean something else).
-    No,
-    /// The grammar doesn't allow a defining-type-specifier here, but we permit
-    /// one for error recovery purposes. Sema will reject.
-    NoButErrorRecovery,
-    /// The grammar allows a defining-type-specifier here, even though it's
-    /// always invalid. Sema will reject.
-    YesButInvalid,
-    /// The grammar allows a defining-type-specifier here, and one can be valid.
-    Yes
-  };
+  /// Handle the annotation token produced for
+  /// #pragma clang __debug dump...
+  void HandlePragmaDump();
 
-  /// Is this a context in which we are parsing defining-type-specifiers (and
-  /// so permit class and enum definitions in addition to non-defining class and
-  /// enum elaborated-type-specifiers)?
-  static AllowDefiningTypeSpec
-  isDefiningTypeSpecifierContext(DeclSpecContext DSC, bool IsCPlusPlus) {
-    switch (DSC) {
-    case DeclSpecContext::DSC_normal:
-    case DeclSpecContext::DSC_class:
-    case DeclSpecContext::DSC_top_level:
-    case DeclSpecContext::DSC_alias_declaration:
-    case DeclSpecContext::DSC_objc_method_result:
-      return AllowDefiningTypeSpec::Yes;
+  /// Handle the annotation token produced for
+  /// #pragma weak id...
+  void HandlePragmaWeak();
 
-    case DeclSpecContext::DSC_condition:
-    case DeclSpecContext::DSC_template_param:
-      return AllowDefiningTypeSpec::YesButInvalid;
+  /// Handle the annotation token produced for
+  /// #pragma weak id = id...
+  void HandlePragmaWeakAlias();
 
-    case DeclSpecContext::DSC_template_type_arg:
-    case DeclSpecContext::DSC_type_specifier:
-      return AllowDefiningTypeSpec::NoButErrorRecovery;
+  /// Handle the annotation token produced for
+  /// #pragma redefine_extname...
+  void HandlePragmaRedefineExtname();
 
-    case DeclSpecContext::DSC_association:
-      return IsCPlusPlus ? AllowDefiningTypeSpec::NoButErrorRecovery
-                         : AllowDefiningTypeSpec::Yes;
+  /// Handle the annotation token produced for
+  /// #pragma STDC FP_CONTRACT...
+  void HandlePragmaFPContract();
 
-    case DeclSpecContext::DSC_trailing:
-    case DeclSpecContext::DSC_conv_operator:
-    case DeclSpecContext::DSC_template_arg:
-    case DeclSpecContext::DSC_new:
-      return AllowDefiningTypeSpec::No;
-    }
-    llvm_unreachable("Missing DeclSpecContext case");
-  }
+  /// Handle the annotation token produced for
+  /// #pragma STDC FENV_ACCESS...
+  void HandlePragmaFEnvAccess();
 
-  /// Is this a context in which an opaque-enum-declaration can appear?
-  static bool isOpaqueEnumDeclarationContext(DeclSpecContext DSC) {
-    switch (DSC) {
-    case DeclSpecContext::DSC_normal:
-    case DeclSpecContext::DSC_class:
-    case DeclSpecContext::DSC_top_level:
-      return true;
+  /// Handle the annotation token produced for
+  /// #pragma STDC FENV_ROUND...
+  void HandlePragmaFEnvRound();
 
-    case DeclSpecContext::DSC_alias_declaration:
-    case DeclSpecContext::DSC_objc_method_result:
-    case DeclSpecContext::DSC_condition:
-    case DeclSpecContext::DSC_template_param:
-    case DeclSpecContext::DSC_template_type_arg:
-    case DeclSpecContext::DSC_type_specifier:
-    case DeclSpecContext::DSC_trailing:
-    case DeclSpecContext::DSC_association:
-    case DeclSpecContext::DSC_conv_operator:
-    case DeclSpecContext::DSC_template_arg:
-    case DeclSpecContext::DSC_new:
+  /// Handle the annotation token produced for
+  /// #pragma STDC CX_LIMITED_RANGE...
+  void HandlePragmaCXLimitedRange();
 
-      return false;
-    }
-    llvm_unreachable("Missing DeclSpecContext case");
-  }
+  /// Handle the annotation token produced for
+  /// #pragma float_control
+  void HandlePragmaFloatControl();
 
-  /// Is this a context in which we can perform class template argument
-  /// deduction?
-  static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
-    switch (DSC) {
-    case DeclSpecContext::DSC_normal:
-    case DeclSpecContext::DSC_template_param:
-    case DeclSpecContext::DSC_template_arg:
-    case DeclSpecContext::DSC_class:
-    case DeclSpecContext::DSC_top_level:
-    case DeclSpecContext::DSC_condition:
-    case DeclSpecContext::DSC_type_specifier:
-    case DeclSpecContext::DSC_association:
-    case DeclSpecContext::DSC_conv_operator:
-    case DeclSpecContext::DSC_new:
-      return true;
+  /// \brief Handle the annotation token produced for
+  /// #pragma clang fp ...
+  void HandlePragmaFP();
 
-    case DeclSpecContext::DSC_objc_method_result:
-    case DeclSpecContext::DSC_template_type_arg:
-    case DeclSpecContext::DSC_trailing:
-    case DeclSpecContext::DSC_alias_declaration:
-      return false;
-    }
-    llvm_unreachable("Missing DeclSpecContext case");
-  }
+  /// Handle the annotation token produced for
+  /// #pragma OPENCL EXTENSION...
+  void HandlePragmaOpenCLExtension();
 
-  // Is this a context in which an implicit 'typename' is allowed?
-  static ImplicitTypenameContext
-  getImplicitTypenameContext(DeclSpecContext DSC) {
-    switch (DSC) {
-    case DeclSpecContext::DSC_class:
-    case DeclSpecContext::DSC_top_level:
-    case DeclSpecContext::DSC_type_specifier:
-    case DeclSpecContext::DSC_template_type_arg:
-    case DeclSpecContext::DSC_trailing:
-    case DeclSpecContext::DSC_alias_declaration:
-    case DeclSpecContext::DSC_template_param:
-    case DeclSpecContext::DSC_new:
-      return ImplicitTypenameContext::Yes;
+  /// Handle the annotation token produced for
+  /// #pragma clang __debug captured
+  StmtResult HandlePragmaCaptured();
 
-    case DeclSpecContext::DSC_normal:
-    case DeclSpecContext::DSC_objc_method_result:
-    case DeclSpecContext::DSC_condition:
-    case DeclSpecContext::DSC_template_arg:
-    case DeclSpecContext::DSC_conv_operator:
-    case DeclSpecContext::DSC_association:
-      return ImplicitTypenameContext::No;
-    }
-    llvm_unreachable("Missing DeclSpecContext case");
-  }
+  /// Handle the annotation token produced for
+  /// #pragma clang loop and #pragma unroll.
+  bool HandlePragmaLoopHint(LoopHint &Hint);
 
-  /// Information on a C++0x for-range-initializer found while parsing a
-  /// declaration which turns out to be a for-range-declaration.
-  struct ForRangeInit {
-    SourceLocation ColonLoc;
-    ExprResult RangeExpr;
-    SmallVector<MaterializeTemporaryExpr *, 8> LifetimeExtendTemps;
-    bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
-  };
-  struct ForRangeInfo : ForRangeInit {
-    StmtResult LoopVar;
-  };
+  bool ParsePragmaAttributeSubjectMatchRuleSet(
+      attr::ParsedSubjectMatchRuleSet &SubjectMatchRules,
+      SourceLocation &AnyLoc, SourceLocation &LastMatchRuleEndLoc);
 
-  DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
-                                  SourceLocation &DeclEnd,
-                                  ParsedAttributes &DeclAttrs,
-                                  ParsedAttributes &DeclSpecAttrs,
-                                  SourceLocation *DeclSpecStart = nullptr);
-  DeclGroupPtrTy
-  ParseSimpleDeclaration(DeclaratorContext Context, SourceLocation &DeclEnd,
-                         ParsedAttributes &DeclAttrs,
-                         ParsedAttributes &DeclSpecAttrs, bool RequireSemi,
-                         ForRangeInit *FRI = nullptr,
-                         SourceLocation *DeclSpecStart = nullptr);
-  bool MightBeDeclarator(DeclaratorContext Context);
-  DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, DeclaratorContext Context,
-                                ParsedAttributes &Attrs,
-                                ParsedTemplateInfo &TemplateInfo,
-                                SourceLocation *DeclEnd = nullptr,
-                                ForRangeInit *FRI = nullptr);
-  Decl *ParseDeclarationAfterDeclarator(Declarator &D,
-               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
-  bool ParseAsmAttributesAfterDeclarator(Declarator &D);
-  Decl *ParseDeclarationAfterDeclaratorAndAttributes(
-      Declarator &D,
-      const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
-      ForRangeInit *FRI = nullptr);
-  Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
-  Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
+  void HandlePragmaAttribute();
 
-  /// When in code-completion, skip parsing of the function/method body
-  /// unless the body contains the code-completion point.
-  ///
-  /// \returns true if the function body was skipped.
-  bool trySkippingFunctionBody();
+  ///@}
 
-  bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
-                        ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,
-                        DeclSpecContext DSC, ParsedAttributes &Attrs);
-  DeclSpecContext
-  getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
-  void
-  ParseDeclarationSpecifiers(DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
-                             AccessSpecifier AS = AS_none,
-                             DeclSpecContext DSC = DeclSpecContext::DSC_normal,
-                             LateParsedAttrList *LateAttrs = nullptr) {
-    return ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC, LateAttrs,
-                                      getImplicitTypenameContext(DSC));
-  }
-  void
-  ParseDeclarationSpecifiers(DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
-                             AccessSpecifier AS, DeclSpecContext DSC,
-                             LateParsedAttrList *LateAttrs,
-                             ImplicitTypenameContext AllowImplicitTypename);
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-  SourceLocation ParsePackIndexingType(DeclSpec &DS);
-  void AnnotateExistingIndexedTypeNamePack(ParsedType T,
-                                           SourceLocation StartLoc,
-                                           SourceLocation EndLoc);
+  /// \name Statements
+  /// Implementations are in ParseStmt.cpp
+  ///@{
 
-  bool DiagnoseMissingSemiAfterTagDefinition(
-      DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext,
-      LateParsedAttrList *LateAttrs = nullptr);
+  public:
 
-  void ParseSpecifierQualifierList(
-      DeclSpec &DS, AccessSpecifier AS = AS_none,
-      DeclSpecContext DSC = DeclSpecContext::DSC_normal) {
-    ParseSpecifierQualifierList(DS, getImplicitTypenameContext(DSC), AS, DSC);
-  }
+  /// A SmallVector of statements.
+  typedef SmallVector<Stmt *, 24> StmtVector;
 
-  void ParseSpecifierQualifierList(
-      DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,
-      AccessSpecifier AS = AS_none,
-      DeclSpecContext DSC = DeclSpecContext::DSC_normal);
+  /// The location of the first statement inside an else that might
+  /// have a missleading indentation. If there is no
+  /// MisleadingIndentationChecker on an else active, this location is invalid.
+  SourceLocation MisleadingIndentationElseLoc;
 
-  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
-                                  DeclaratorContext Context);
+  private:
 
-  void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
-                          const ParsedTemplateInfo &TemplateInfo,
-                          AccessSpecifier AS, DeclSpecContext DSC);
-  void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl,
-                     SkipBodyInfo *SkipBody = nullptr);
-  void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
-                            RecordDecl *TagDecl);
+  /// Flags describing a context in which we're parsing a statement.
+  enum class ParsedStmtContext {
+    /// This context permits declarations in language modes where declarations
+    /// are not statements.
+    AllowDeclarationsInC = 0x1,
+    /// This context permits standalone OpenMP directives.
+    AllowStandaloneOpenMPDirectives = 0x2,
+    /// This context is at the top level of a GNU statement expression.
+    InStmtExpr = 0x4,
 
-  void ParseStructDeclaration(
-      ParsingDeclSpec &DS,
-      llvm::function_ref<Decl *(ParsingFieldDeclarator &)> FieldsCallback,
-      LateParsedAttrList *LateFieldAttrs = nullptr);
+    /// The context of a regular substatement.
+    SubStmt = 0,
+    /// The context of a compound-statement.
+    Compound = AllowDeclarationsInC | AllowStandaloneOpenMPDirectives,
 
-  DeclGroupPtrTy ParseTopLevelStmtDecl();
+    LLVM_MARK_AS_BITMASK_ENUM(InStmtExpr)
+  };
 
-  bool isDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
-                              bool DisambiguatingWithExpression = false);
-  bool isTypeSpecifierQualifier();
+  /// Act on an expression statement that might be the last statement in a
+  /// GNU statement expression. Checks whether we are actually at the end of
+  /// a statement expression and builds a suitable expression statement.
+  StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx);
 
-  /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
-  /// is definitely a type-specifier.  Return false if it isn't part of a type
-  /// specifier or if we're not sure.
-  bool isKnownToBeTypeSpecifier(const Token &Tok) const;
+  //===--------------------------------------------------------------------===//
+  // C99 6.8: Statements and Blocks.
 
-  /// Return true if we know that we are definitely looking at a
-  /// decl-specifier, and isn't part of an expression such as a function-style
-  /// cast. Return false if it's no a decl-specifier, or we're not sure.
-  bool isKnownToBeDeclarationSpecifier() {
-    if (getLangOpts().CPlusPlus)
-      return isCXXDeclarationSpecifier(ImplicitTypenameContext::No) ==
-             TPResult::True;
-    return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
-  }
+  /// Parse a standalone statement (for instance, as the body of an 'if',
+  /// 'while', or 'for').
+  StmtResult
+  ParseStatement(SourceLocation *TrailingElseLoc = nullptr,
+                 ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt);
 
-  /// isDeclarationStatement - Disambiguates between a declaration or an
-  /// expression statement, when parsing function bodies.
+  /// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
+  ///       StatementOrDeclaration:
+  ///         statement
+  ///         declaration
   ///
-  /// \param DisambiguatingWithExpression - True to indicate that the purpose of
-  /// this check is to disambiguate between an expression and a declaration.
-  /// Returns true for declaration, false for expression.
-  bool isDeclarationStatement(bool DisambiguatingWithExpression = false) {
-    if (getLangOpts().CPlusPlus)
-      return isCXXDeclarationStatement(DisambiguatingWithExpression);
-    return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
-  }
+  ///       statement:
+  ///         labeled-statement
+  ///         compound-statement
+  ///         expression-statement
+  ///         selection-statement
+  ///         iteration-statement
+  ///         jump-statement
+  /// [C++]   declaration-statement
+  /// [C++]   try-block
+  /// [MS]    seh-try-block
+  /// [OBC]   objc-throw-statement
+  /// [OBC]   objc-try-catch-statement
+  /// [OBC]   objc-synchronized-statement
+  /// [GNU]   asm-statement
+  /// [OMP]   openmp-construct             [TODO]
+  ///
+  ///       labeled-statement:
+  ///         identifier ':' statement
+  ///         'case' constant-expression ':' statement
+  ///         'default' ':' statement
+  ///
+  ///       selection-statement:
+  ///         if-statement
+  ///         switch-statement
+  ///
+  ///       iteration-statement:
+  ///         while-statement
+  ///         do-statement
+  ///         for-statement
+  ///
+  ///       expression-statement:
+  ///         expression[opt] ';'
+  ///
+  ///       jump-statement:
+  ///         'goto' identifier ';'
+  ///         'continue' ';'
+  ///         'break' ';'
+  ///         'return' expression[opt] ';'
+  /// [GNU]   'goto' '*' expression ';'
+  ///
+  /// [OBC] objc-throw-statement:
+  /// [OBC]   '@' 'throw' expression ';'
+  /// [OBC]   '@' 'throw' ';'
+  ///
+  StmtResult ParseStatementOrDeclaration(
+      StmtVector &Stmts, ParsedStmtContext StmtCtx,
+      SourceLocation *TrailingElseLoc = nullptr);
 
-  /// isForInitDeclaration - Disambiguates between a declaration or an
-  /// expression in the context of the C 'clause-1' or the C++
-  // 'for-init-statement' part of a 'for' statement.
-  /// Returns true for declaration, false for expression.
-  bool isForInitDeclaration() {
-    if (getLangOpts().OpenMP)
-      Actions.OpenMP().startOpenMPLoop();
-    if (getLangOpts().CPlusPlus)
-      return Tok.is(tok::kw_using) ||
-             isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
-    return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
-  }
+  StmtResult ParseStatementOrDeclarationAfterAttributes(
+      StmtVector &Stmts, ParsedStmtContext StmtCtx,
+      SourceLocation *TrailingElseLoc, ParsedAttributes &DeclAttrs,
+      ParsedAttributes &DeclSpecAttrs);
+  
+  /// Parse an expression statement.
+  StmtResult ParseExprStatement(ParsedStmtContext StmtCtx);
 
-  /// Determine whether this is a C++1z for-range-identifier.
-  bool isForRangeIdentifier();
+  /// ParseLabeledStatement - We have an identifier and a ':' after it.
+  ///
+  ///       label:
+  ///         identifier ':'
+  /// [GNU]   identifier ':' attributes[opt]
+  ///
+  ///       labeled-statement:
+  ///         label statement
+  ///
+  StmtResult ParseLabeledStatement(ParsedAttributes &Attrs,
+                                   ParsedStmtContext StmtCtx);
 
-  /// Determine whether we are currently at the start of an Objective-C
-  /// class message that appears to be missing the open bracket '['.
-  bool isStartOfObjCClassMessageMissingOpenBracket();
+  /// ParseCaseStatement
+  ///       labeled-statement:
+  ///         'case' constant-expression ':' statement
+  /// [GNU]   'case' constant-expression '...' constant-expression ':' statement
+  ///
+  StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx,
+                                bool MissingCase = false,
+                                ExprResult Expr = ExprResult());
+  
+  /// ParseDefaultStatement
+  ///       labeled-statement:
+  ///         'default' ':' statement
+  /// Note that this does not parse the 'statement' at the end.
+  ///
+  StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx);
 
-  /// Starting with a scope specifier, identifier, or
-  /// template-id that refers to the current class, determine whether
-  /// this is a constructor declarator.
-  bool isConstructorDeclarator(
-      bool Unqualified, bool DeductionGuide = false,
-      DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
-      const ParsedTemplateInfo *TemplateInfo = nullptr);
+  StmtResult ParseCompoundStatement(bool isStmtExpr = false);
 
-  /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
-  /// whether the parens contain an expression or a type-id.
-  /// Returns true for a type-id and false for an expression.
-  bool isTypeIdInParens(bool &isAmbiguous) {
-    if (getLangOpts().CPlusPlus)
-      return isCXXTypeId(TentativeCXXTypeIdContext::InParens, isAmbiguous);
-    isAmbiguous = false;
-    return isTypeSpecifierQualifier();
-  }
-  bool isTypeIdInParens() {
-    bool isAmbiguous;
-    return isTypeIdInParens(isAmbiguous);
-  }
+  /// ParseCompoundStatement - Parse a "{}" block.
+  ///
+  ///       compound-statement: [C99 6.8.2]
+  ///         { block-item-list[opt] }
+  /// [GNU]   { label-declarations block-item-list } [TODO]
+  ///
+  ///       block-item-list:
+  ///         block-item
+  ///         block-item-list block-item
+  ///
+  ///       block-item:
+  ///         declaration
+  /// [GNU]   '__extension__' declaration
+  ///         statement
+  ///
+  /// [GNU] label-declarations:
+  /// [GNU]   label-declaration
+  /// [GNU]   label-declarations label-declaration
+  ///
+  /// [GNU] label-declaration:
+  /// [GNU]   '__label__' identifier-list ';'
+  ///
+  StmtResult ParseCompoundStatement(bool isStmtExpr,
+                                    unsigned ScopeFlags);
+  
+  /// Parse any pragmas at the start of the compound expression. We handle these
+  /// separately since some pragmas (FP_CONTRACT) must appear before any C
+  /// statement in the compound, but may be intermingled with other pragmas.
+  void ParseCompoundStatementLeadingPragmas();
 
-  /// Checks whether the current tokens form a type-id or an expression for the
-  /// purposes of use as the initial operand to a generic selection expression.
-  /// This requires special handling in C++ because it accepts either a type or
-  /// an expression, and we need to disambiguate which is which. However, we
-  /// cannot use the same logic as we've used for sizeof expressions, because
-  /// that logic relies on the operator only accepting a single argument,
-  /// whereas _Generic accepts a list of arguments.
-  bool isTypeIdForGenericSelection() {
-    if (getLangOpts().CPlusPlus) {
-      bool isAmbiguous;
-      return isCXXTypeId(TentativeCXXTypeIdContext::AsGenericSelectionArgument,
-                         isAmbiguous);
-    }
-    return isTypeSpecifierQualifier();
-  }
+  void DiagnoseLabelAtEndOfCompoundStatement();
+  
+  /// Consume any extra semi-colons resulting in null statements,
+  /// returning true if any tok::semi were consumed.
+  bool ConsumeNullStmt(StmtVector &Stmts);
+
+  /// ParseCompoundStatementBody - Parse a sequence of statements optionally
+  /// followed by a label and invoke the ActOnCompoundStmt action.  This expects
+  /// the '{' to be the current token, and consume the '}' at the end of the
+  /// block.  It does not manipulate the scope stack.
+  StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
+
+  /// ParseParenExprOrCondition:
+  /// [C  ]     '(' expression ')'
+  /// [C++]     '(' condition ')'
+  /// [C++1z]   '(' init-statement[opt] condition ')'
+  ///
+  /// This function parses and performs error recovery on the specified condition
+  /// or expression (depending on whether we're in C++ or C mode).  This function
+  /// goes out of its way to recover well.  It returns true if there was a parser
+  /// error (the right paren couldn't be found), which indicates that the caller
+  /// should try to recover harder.  It returns false if the condition is
+  /// successfully parsed.  Note that a successful parse can still have semantic
+  /// errors in the condition.
+  /// Additionally, it will assign the location of the outer-most '(' and ')',
+  /// to LParenLoc and RParenLoc, respectively.
+  bool ParseParenExprOrCondition(StmtResult *InitStmt,
+                                 Sema::ConditionResult &CondResult,
+                                 SourceLocation Loc, Sema::ConditionKind CK,
+                                 SourceLocation &LParenLoc,
+                                 SourceLocation &RParenLoc);
 
-  /// Checks if the current tokens form type-id or expression.
-  /// It is similar to isTypeIdInParens but does not suppose that type-id
-  /// is in parenthesis.
-  bool isTypeIdUnambiguously() {
-    if (getLangOpts().CPlusPlus) {
-      bool isAmbiguous;
-      return isCXXTypeId(TentativeCXXTypeIdContext::Unambiguous, isAmbiguous);
-    }
-    return isTypeSpecifierQualifier();
-  }
+  /// ParseIfStatement
+  ///       if-statement: [C99 6.8.4.1]
+  ///         'if' '(' expression ')' statement
+  ///         'if' '(' expression ')' statement 'else' statement
+  /// [C++]   'if' '(' condition ')' statement
+  /// [C++]   'if' '(' condition ')' statement 'else' statement
+  /// [C++23] 'if' '!' [opt] consteval compound-statement
+  /// [C++23] 'if' '!' [opt] consteval compound-statement 'else' statement
+  ///
+  StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
 
-  /// isCXXDeclarationStatement - C++-specialized function that disambiguates
-  /// between a declaration or an expression statement, when parsing function
-  /// bodies. Returns true for declaration, false for expression.
-  bool isCXXDeclarationStatement(bool DisambiguatingWithExpression = false);
+  /// ParseSwitchStatement
+  ///       switch-statement:
+  ///         'switch' '(' expression ')' statement
+  /// [C++]   'switch' '(' condition ')' statement
+  StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
 
-  /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
-  /// between a simple-declaration or an expression-statement.
-  /// If during the disambiguation process a parsing error is encountered,
-  /// the function returns true to let the declaration parsing code handle it.
-  /// Returns false if the statement is disambiguated as expression.
-  bool isCXXSimpleDeclaration(bool AllowForRangeDecl);
+  /// ParseWhileStatement
+  ///       while-statement: [C99 6.8.5.1]
+  ///         'while' '(' expression ')' statement
+  /// [C++]   'while' '(' condition ')' statement
+  StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
 
-  /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
-  /// a constructor-style initializer, when parsing declaration statements.
-  /// Returns true for function declarator and false for constructor-style
-  /// initializer. Sets 'IsAmbiguous' to true to indicate that this declaration
-  /// might be a constructor-style initializer.
-  /// If during the disambiguation process a parsing error is encountered,
-  /// the function returns true to let the declaration parsing code handle it.
-  bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr,
-                               ImplicitTypenameContext AllowImplicitTypename =
-                                   ImplicitTypenameContext::No);
+  /// ParseDoStatement
+  ///       do-statement: [C99 6.8.5.2]
+  ///         'do' statement 'while' '(' expression ')' ';'
+  /// Note: this lets the caller parse the end ';'.
+  StmtResult ParseDoStatement();
 
-  struct ConditionDeclarationOrInitStatementState;
-  enum class ConditionOrInitStatement {
-    Expression,    ///< Disambiguated as an expression (either kind).
-    ConditionDecl, ///< Disambiguated as the declaration form of condition.
-    InitStmtDecl,  ///< Disambiguated as a simple-declaration init-statement.
-    ForRangeDecl,  ///< Disambiguated as a for-range declaration.
-    Error          ///< Can't be any of the above!
-  };
-  /// Disambiguates between the different kinds of things that can happen
-  /// after 'if (' or 'switch ('. This could be one of two different kinds of
-  /// declaration (depending on whether there is a ';' later) or an expression.
-  ConditionOrInitStatement
-  isCXXConditionDeclarationOrInitStatement(bool CanBeInitStmt,
-                                           bool CanBeForRangeDecl);
+  /// ParseForStatement
+  ///       for-statement: [C99 6.8.5.3]
+  ///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
+  ///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
+  /// [C++]   'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
+  /// [C++]       statement
+  /// [C++0x] 'for'
+  ///             'co_await'[opt]    [Coroutines]
+  ///             '(' for-range-declaration ':' for-range-initializer ')'
+  ///             statement
+  /// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
+  /// [OBJC2] 'for' '(' expr 'in' expr ')' statement
+  ///
+  /// [C++] for-init-statement:
+  /// [C++]   expression-statement
+  /// [C++]   simple-declaration
+  /// [C++23] alias-declaration
+  ///
+  /// [C++0x] for-range-declaration:
+  /// [C++0x]   attribute-specifier-seq[opt] type-specifier-seq declarator
+  /// [C++0x] for-range-initializer:
+  /// [C++0x]   expression
+  /// [C++0x]   braced-init-list            [TODO]
+  StmtResult ParseForStatement(SourceLocation *TrailingElseLoc);
 
-  bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
-  bool isCXXTypeId(TentativeCXXTypeIdContext Context) {
-    bool isAmbiguous;
-    return isCXXTypeId(Context, isAmbiguous);
-  }
+  /// ParseGotoStatement
+  ///       jump-statement:
+  ///         'goto' identifier ';'
+  /// [GNU]   'goto' '*' expression ';'
+  ///
+  /// Note: this lets the caller parse the end ';'.
+  ///
+  StmtResult ParseGotoStatement();
 
-  /// TPResult - Used as the result value for functions whose purpose is to
-  /// disambiguate C++ constructs by "tentatively parsing" them.
-  enum class TPResult {
-    True, False, Ambiguous, Error
-  };
+  /// ParseContinueStatement
+  ///       jump-statement:
+  ///         'continue' ';'
+  ///
+  /// Note: this lets the caller parse the end ';'.
+  ///
+  StmtResult ParseContinueStatement();
 
-  /// Determine whether we could have an enum-base.
+  /// ParseBreakStatement
+  ///       jump-statement:
+  ///         'break' ';'
   ///
-  /// \p AllowSemi If \c true, then allow a ';' after the enum-base; otherwise
-  /// only consider this to be an enum-base if the next token is a '{'.
+  /// Note: this lets the caller parse the end ';'.
   ///
-  /// \return \c false if this cannot possibly be an enum base; \c true
-  /// otherwise.
-  bool isEnumBase(bool AllowSemi);
+  StmtResult ParseBreakStatement();
 
-  /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
-  /// declaration specifier, TPResult::False if it is not,
-  /// TPResult::Ambiguous if it could be either a decl-specifier or a
-  /// function-style cast, and TPResult::Error if a parsing error was
-  /// encountered. If it could be a braced C++11 function-style cast, returns
-  /// BracedCastResult.
-  /// Doesn't consume tokens.
-  TPResult
-  isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
-                            TPResult BracedCastResult = TPResult::False,
-                            bool *InvalidAsDeclSpec = nullptr);
+  /// ParseReturnStatement
+  ///       jump-statement:
+  ///         'return' expression[opt] ';'
+  ///         'return' braced-init-list ';'
+  ///         'co_return' expression[opt] ';'
+  ///         'co_return' braced-init-list ';'
+  StmtResult ParseReturnStatement();
 
-  /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
-  /// \c TPResult::Ambiguous, determine whether the decl-specifier would be
-  /// a type-specifier other than a cv-qualifier.
-  bool isCXXDeclarationSpecifierAType();
+  StmtResult ParsePragmaLoopHint(StmtVector &Stmts, ParsedStmtContext StmtCtx,
+                                 SourceLocation *TrailingElseLoc,
+                                 ParsedAttributes &Attrs);
 
-  /// Determine whether the current token sequence might be
-  ///   '<' template-argument-list '>'
-  /// rather than a less-than expression.
-  TPResult isTemplateArgumentList(unsigned TokensToSkip);
+  void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
 
-  /// Determine whether an '(' after an 'explicit' keyword is part of a C++20
-  /// 'explicit(bool)' declaration, in earlier language modes where that is an
-  /// extension.
-  TPResult isExplicitBool();
+  //===--------------------------------------------------------------------===//
+  // C++ 6: Statements and Blocks
 
-  /// Determine whether an identifier has been tentatively declared as a
-  /// non-type. Such tentative declarations should not be found to name a type
-  /// during a tentative parse, but also should not be annotated as a non-type.
-  bool isTentativelyDeclared(IdentifierInfo *II);
+  /// ParseCXXTryBlock - Parse a C++ try-block.
+  ///
+  ///       try-block:
+  ///         'try' compound-statement handler-seq
+  ///
+  StmtResult ParseCXXTryBlock();
 
-  // "Tentative parsing" functions, used for disambiguation. If a parsing error
-  // is encountered they will return TPResult::Error.
-  // Returning TPResult::True/False indicates that the ambiguity was
-  // resolved and tentative parsing may stop. TPResult::Ambiguous indicates
-  // that more tentative parsing is necessary for disambiguation.
-  // They all consume tokens, so backtracking should be used after calling them.
+  /// ParseCXXTryBlockCommon - Parse the common part of try-block and
+  /// function-try-block.
+  ///
+  ///       try-block:
+  ///         'try' compound-statement handler-seq
+  ///
+  ///       function-try-block:
+  ///         'try' ctor-initializer[opt] compound-statement handler-seq
+  ///
+  ///       handler-seq:
+  ///         handler handler-seq[opt]
+  ///
+  ///       [Borland] try-block:
+  ///         'try' compound-statement seh-except-block
+  ///         'try' compound-statement seh-finally-block
+  ///
+  StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
 
-  TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl);
-  TPResult TryParseTypeofSpecifier();
-  TPResult TryParseProtocolQualifiers();
-  TPResult TryParsePtrOperatorSeq();
-  TPResult TryParseOperatorId();
-  TPResult TryParseInitDeclaratorList(bool MayHaveTrailingReturnType = false);
-  TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
-                              bool mayHaveDirectInit = false,
-                              bool mayHaveTrailingReturnType = false);
-  TPResult TryParseParameterDeclarationClause(
-      bool *InvalidAsDeclaration = nullptr, bool VersusTemplateArg = false,
-      ImplicitTypenameContext AllowImplicitTypename =
-          ImplicitTypenameContext::No);
-  TPResult TryParseFunctionDeclarator(bool MayHaveTrailingReturnType = false);
-  bool NameAfterArrowIsNonType();
-  TPResult TryParseBracketDeclarator();
-  TPResult TryConsumeDeclarationSpecifier();
+  /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
+  ///
+  ///   handler:
+  ///     'catch' '(' exception-declaration ')' compound-statement
+  ///
+  ///   exception-declaration:
+  ///     attribute-specifier-seq[opt] type-specifier-seq declarator
+  ///     attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
+  ///     '...'
+  ///
+  StmtResult ParseCXXCatchBlock(bool FnCatch = false);
 
-  /// Try to skip a possibly empty sequence of 'attribute-specifier's without
-  /// full validation of the syntactic structure of attributes.
-  bool TrySkipAttributes();
+  //===--------------------------------------------------------------------===//
+  // MS: SEH Statements and Blocks
 
-  /// Diagnoses use of _ExtInt as being deprecated, and diagnoses use of
-  /// _BitInt as an extension when appropriate.
-  void DiagnoseBitIntUse(const Token &Tok);
+  /// ParseSEHTryBlockCommon
+  ///
+  /// seh-try-block:
+  ///   '__try' compound-statement seh-handler
+  ///
+  /// seh-handler:
+  ///   seh-except-block
+  ///   seh-finally-block
+  ///
+  StmtResult ParseSEHTryBlock();
 
-public:
-  TypeResult
-  ParseTypeName(SourceRange *Range = nullptr,
-                DeclaratorContext Context = DeclaratorContext::TypeName,
-                AccessSpecifier AS = AS_none, Decl **OwnedType = nullptr,
-                ParsedAttributes *Attrs = nullptr);
+  /// ParseSEHExceptBlock - Handle __except
+  ///
+  /// seh-except-block:
+  ///   '__except' '(' seh-filter-expression ')' compound-statement
+  ///
+  StmtResult ParseSEHExceptBlock(SourceLocation Loc);
 
-private:
-  void ParseBlockId(SourceLocation CaretLoc);
+  /// ParseSEHFinallyBlock - Handle __finally
+  ///
+  /// seh-finally-block:
+  ///   '__finally' compound-statement
+  ///
+  StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
 
-  /// Return true if the next token should be treated as a [[]] attribute,
-  /// or as a keyword that behaves like one.  The former is only true if
-  /// [[]] attributes are enabled, whereas the latter is true whenever
-  /// such a keyword appears.  The arguments are as for
-  /// isCXX11AttributeSpecifier.
-  bool isAllowedCXX11AttributeSpecifier(bool Disambiguate = false,
-                                        bool OuterMightBeMessageSend = false) {
-    return (Tok.isRegularKeywordAttribute() ||
-            isCXX11AttributeSpecifier(Disambiguate, OuterMightBeMessageSend) !=
-                CXX11AttributeKind::NotAttributeSpecifier);
-  }
+  StmtResult ParseSEHLeaveStatement();
 
-  // Check for the start of an attribute-specifier-seq in a context where an
-  // attribute is not allowed.
-  bool CheckProhibitedCXX11Attribute() {
-    assert(Tok.is(tok::l_square));
-    if (NextToken().isNot(tok::l_square))
-      return false;
-    return DiagnoseProhibitedCXX11Attribute();
-  }
+  Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
 
-  bool DiagnoseProhibitedCXX11Attribute();
-  void CheckMisplacedCXX11Attribute(ParsedAttributes &Attrs,
-                                    SourceLocation CorrectLocation) {
-    if (!Tok.isRegularKeywordAttribute() &&
-        (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
-        Tok.isNot(tok::kw_alignas))
-      return;
-    DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
-  }
-  void DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs,
-                                       SourceLocation CorrectLocation);
+  /// ParseFunctionTryBlock - Parse a C++ function-try-block.
+  ///
+  ///       function-try-block:
+  ///         'try' ctor-initializer[opt] compound-statement handler-seq
+  ///
+  Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
 
-  void stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, DeclSpec &DS,
-                                      TagUseKind TUK);
+  /// When in code-completion, skip parsing of the function/method body
+  /// unless the body contains the code-completion point.
+  ///
+  /// \returns true if the function body was skipped.
+  bool trySkippingFunctionBody();
 
-  // FixItLoc = possible correct location for the attributes
-  void ProhibitAttributes(ParsedAttributes &Attrs,
-                          SourceLocation FixItLoc = SourceLocation()) {
-    if (Attrs.Range.isInvalid())
-      return;
-    DiagnoseProhibitedAttributes(Attrs, FixItLoc);
-    Attrs.clear();
+  /// isDeclarationStatement - Disambiguates between a declaration or an
+  /// expression statement, when parsing function bodies.
+  ///
+  /// \param DisambiguatingWithExpression - True to indicate that the purpose of
+  /// this check is to disambiguate between an expression and a declaration.
+  /// Returns true for declaration, false for expression.
+  bool isDeclarationStatement(bool DisambiguatingWithExpression = false) {
+    if (getLangOpts().CPlusPlus)
+      return isCXXDeclarationStatement(DisambiguatingWithExpression);
+    return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
   }
 
-  void ProhibitAttributes(ParsedAttributesView &Attrs,
-                          SourceLocation FixItLoc = SourceLocation()) {
-    if (Attrs.Range.isInvalid())
-      return;
-    DiagnoseProhibitedAttributes(Attrs, FixItLoc);
-    Attrs.clearListOnly();
+  /// isForInitDeclaration - Disambiguates between a declaration or an
+  /// expression in the context of the C 'clause-1' or the C++
+  // 'for-init-statement' part of a 'for' statement.
+  /// Returns true for declaration, false for expression.
+  bool isForInitDeclaration() {
+    if (getLangOpts().OpenMP)
+      Actions.OpenMP().startOpenMPLoop();
+    if (getLangOpts().CPlusPlus)
+      return Tok.is(tok::kw_using) ||
+             isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
+    return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
   }
-  void DiagnoseProhibitedAttributes(const ParsedAttributesView &Attrs,
-                                    SourceLocation FixItLoc);
 
-  // Forbid C++11 and C23 attributes that appear on certain syntactic locations
-  // which standard permits but we don't supported yet, for example, attributes
-  // appertain to decl specifiers.
-  // For the most cases we don't want to warn on unknown type attributes, but
-  // left them to later diagnoses. However, for a few cases like module
-  // declarations and module import declarations, we should do it.
-  void ProhibitCXX11Attributes(ParsedAttributes &Attrs, unsigned AttrDiagID,
-                               unsigned KeywordDiagId,
-                               bool DiagnoseEmptyAttrs = false,
-                               bool WarnOnUnknownAttrs = false);
+  /// Determine whether this is a C++1z for-range-identifier.
+  bool isForRangeIdentifier();
 
-  /// Skip C++11 and C23 attributes and return the end location of the
-  /// last one.
-  /// \returns SourceLocation() if there are no attributes.
-  SourceLocation SkipCXX11Attributes();
+  ///@}
+
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-  /// Diagnose and skip C++11 and C23 attributes that appear in syntactic
-  /// locations where attributes are not allowed.
-  void DiagnoseAndSkipCXX11Attributes();
+  /// \name `inline asm` Statement
+  /// Implementations are in ParseStmtAsm.cpp
+  ///@{
 
-  /// Emit warnings for C++11 and C23 attributes that are in a position that
-  /// clang accepts as an extension.
-  void DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs);
+  public:
 
-  ExprResult ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName);
+  /// Parse an identifier in an MS-style inline assembly block.
+  ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
+                                  unsigned &NumLineToksConsumed,
+                                  bool IsUnevaluated);
 
-  bool
-  ParseAttributeArgumentList(const clang::IdentifierInfo &AttrName,
-                             SmallVectorImpl<Expr *> &Exprs,
-                             ParsedAttributeArgumentsProperties ArgsProperties);
+  private:
 
-  /// Parses syntax-generic attribute arguments for attributes which are
-  /// known to the implementation, and adds them to the given ParsedAttributes
-  /// list with the given attribute syntax. Returns the number of arguments
-  /// parsed for the attribute.
-  unsigned
-  ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
-                           ParsedAttributes &Attrs, SourceLocation *EndLoc,
-                           IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-                           ParsedAttr::Form Form);
+  /// ParseAsmStatement - Parse a GNU extended asm statement.
+  ///       asm-statement:
+  ///         gnu-asm-statement
+  ///         ms-asm-statement
+  ///
+  /// [GNU] gnu-asm-statement:
+  ///         'asm' asm-qualifier-list[opt] '(' asm-argument ')' ';'
+  ///
+  /// [GNU] asm-argument:
+  ///         asm-string-literal
+  ///         asm-string-literal ':' asm-operands[opt]
+  ///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+  ///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+  ///                 ':' asm-clobbers
+  ///
+  /// [GNU] asm-clobbers:
+  ///         asm-string-literal
+  ///         asm-clobbers ',' asm-string-literal
+  ///
+  StmtResult ParseAsmStatement(bool &msAsm);
 
-  enum ParseAttrKindMask {
-    PAKM_GNU = 1 << 0,
-    PAKM_Declspec = 1 << 1,
-    PAKM_CXX11 = 1 << 2,
-  };
+  /// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
+  /// this routine is called to collect the tokens for an MS asm statement.
+  ///
+  /// [MS]  ms-asm-statement:
+  ///         ms-asm-block
+  ///         ms-asm-block ms-asm-statement
+  ///
+  /// [MS]  ms-asm-block:
+  ///         '__asm' ms-asm-line '\n'
+  ///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
+  ///
+  /// [MS]  ms-asm-instruction-block
+  ///         ms-asm-line
+  ///         ms-asm-line '\n' ms-asm-instruction-block
+  ///
+  StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
 
-  /// \brief Parse attributes based on what syntaxes are desired, allowing for
-  /// the order to vary. e.g. with PAKM_GNU | PAKM_Declspec:
-  /// __attribute__((...)) __declspec(...) __attribute__((...)))
-  /// Note that Microsoft attributes (spelled with single square brackets) are
-  /// not supported by this because of parsing ambiguities with other
-  /// constructs.
+  /// ParseAsmOperands - Parse the asm-operands production as used by
+  /// asm-statement, assuming the leading ':' token was eaten.
   ///
-  /// There are some attribute parse orderings that should not be allowed in
-  /// arbitrary order. e.g.,
+  /// [GNU] asm-operands:
+  ///         asm-operand
+  ///         asm-operands ',' asm-operand
   ///
-  ///   [[]] __attribute__(()) int i; // OK
-  ///   __attribute__(()) [[]] int i; // Not OK
+  /// [GNU] asm-operand:
+  ///         asm-string-literal '(' expression ')'
+  ///         '[' identifier ']' asm-string-literal '(' expression ')'
   ///
-  /// Such situations should use the specific attribute parsing functionality.
-  void ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
-                       LateParsedAttrList *LateAttrs = nullptr);
-  /// \brief Possibly parse attributes based on what syntaxes are desired,
-  /// allowing for the order to vary.
-  bool MaybeParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
-                            LateParsedAttrList *LateAttrs = nullptr) {
-    if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec) ||
-        isAllowedCXX11AttributeSpecifier()) {
-      ParseAttributes(WhichAttrKinds, Attrs, LateAttrs);
-      return true;
-    }
-    return false;
-  }
+  //
+  // FIXME: Avoid unnecessary std::string trashing.
+  bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
+                           SmallVectorImpl<Expr *> &Constraints,
+                           SmallVectorImpl<Expr *> &Exprs);
 
-  void MaybeParseGNUAttributes(Declarator &D,
-                               LateParsedAttrList *LateAttrs = nullptr) {
-    if (Tok.is(tok::kw___attribute)) {
-      ParsedAttributes Attrs(AttrFactory);
-      ParseGNUAttributes(Attrs, LateAttrs, &D);
-      D.takeAttributes(Attrs);
-    }
-  }
+  class GNUAsmQualifiers {
+    unsigned Qualifiers = AQ_unspecified;
 
-  bool MaybeParseGNUAttributes(ParsedAttributes &Attrs,
-                               LateParsedAttrList *LateAttrs = nullptr) {
-    if (Tok.is(tok::kw___attribute)) {
-      ParseGNUAttributes(Attrs, LateAttrs);
-      return true;
-    }
-    return false;
-  }
+  public:
+    enum AQ {
+      AQ_unspecified = 0,
+      AQ_volatile    = 1,
+      AQ_inline      = 2,
+      AQ_goto        = 4,
+    };
+    static const char *getQualifierName(AQ Qualifier);
+    bool setAsmQualifier(AQ Qualifier);
+    inline bool isVolatile() const { return Qualifiers & AQ_volatile; };
+    inline bool isInline() const { return Qualifiers & AQ_inline; };
+    inline bool isGoto() const { return Qualifiers & AQ_goto; }
+  };
+  
+  // Determine if this is a GCC-style asm statement.
+  bool isGCCAsmStatement(const Token &TokAfterAsm) const;
 
-  bool ParseSingleGNUAttribute(ParsedAttributes &Attrs, SourceLocation &EndLoc,
-                               LateParsedAttrList *LateAttrs = nullptr,
-                               Declarator *D = nullptr);
-  void ParseGNUAttributes(ParsedAttributes &Attrs,
-                          LateParsedAttrList *LateAttrs = nullptr,
-                          Declarator *D = nullptr);
-  void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
-                             SourceLocation AttrNameLoc,
-                             ParsedAttributes &Attrs, SourceLocation *EndLoc,
-                             IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-                             ParsedAttr::Form Form, Declarator *D);
-  IdentifierLoc *ParseIdentifierLoc();
+  bool isGNUAsmQualifier(const Token &TokAfterAsm) const;
+  GNUAsmQualifiers::AQ getGNUAsmQualifier(const Token &Tok) const;
 
-  unsigned
-  ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
-                          ParsedAttributes &Attrs, SourceLocation *EndLoc,
-                          IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-                          ParsedAttr::Form Form);
+  /// parseGNUAsmQualifierListOpt - Parse a GNU extended asm qualifier list.
+  ///       asm-qualifier:
+  ///         volatile
+  ///         inline
+  ///         goto
+  ///
+  ///       asm-qualifier-list:
+  ///         asm-qualifier
+  ///         asm-qualifier-list asm-qualifier
+  bool parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ);
 
-  void ReplayOpenMPAttributeTokens(CachedTokens &OpenMPTokens) {
-    // If parsing the attributes found an OpenMP directive, emit those tokens
-    // to the parse stream now.
-    if (!OpenMPTokens.empty()) {
-      PP.EnterToken(Tok, /*IsReinject*/ true);
-      PP.EnterTokenStream(OpenMPTokens, /*DisableMacroExpansion*/ true,
-                          /*IsReinject*/ true);
-      ConsumeAnyToken(/*ConsumeCodeCompletionTok*/ true);
-    }
-  }
-  void MaybeParseCXX11Attributes(Declarator &D) {
-    if (isAllowedCXX11AttributeSpecifier()) {
-      ParsedAttributes Attrs(AttrFactory);
-      ParseCXX11Attributes(Attrs);
-      D.takeAttributes(Attrs);
-    }
-  }
+  ///@}
 
-  bool MaybeParseCXX11Attributes(ParsedAttributes &Attrs,
-                                 bool OuterMightBeMessageSend = false) {
-    if (isAllowedCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) {
-      ParseCXX11Attributes(Attrs);
-      return true;
-    }
-    return false;
-  }
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-  void ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,
-                                CachedTokens &OpenMPTokens);
+  /// \name C++ Templates
+  /// Implementations are in ParseTemplate.cpp
+  ///@{
 
-  void ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
-                                            CachedTokens &OpenMPTokens,
-                                            SourceLocation *EndLoc = nullptr);
-  void ParseCXX11AttributeSpecifier(ParsedAttributes &Attrs,
-                                    SourceLocation *EndLoc = nullptr) {
-    CachedTokens OpenMPTokens;
-    ParseCXX11AttributeSpecifierInternal(Attrs, OpenMPTokens, EndLoc);
-    ReplayOpenMPAttributeTokens(OpenMPTokens);
-  }
-  void ParseCXX11Attributes(ParsedAttributes &attrs);
-  /// Parses a C++11 (or C23)-style attribute argument list. Returns true
-  /// if this results in adding an attribute to the ParsedAttributes list.
-  bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
-                               SourceLocation AttrNameLoc,
-                               ParsedAttributes &Attrs, SourceLocation *EndLoc,
-                               IdentifierInfo *ScopeName,
-                               SourceLocation ScopeLoc,
-                               CachedTokens &OpenMPTokens);
+  public:
 
-  /// Parse a C++23 assume() attribute. Returns true on error.
-  bool ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
-                                  IdentifierInfo *AttrName,
-                                  SourceLocation AttrNameLoc,
-                                  SourceLocation *EndLoc,
-                                  ParsedAttr::Form Form);
+  typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
 
-  IdentifierInfo *TryParseCXX11AttributeIdentifier(
-      SourceLocation &Loc,
-      SemaCodeCompletion::AttributeCompletion Completion =
-          SemaCodeCompletion::AttributeCompletion::None,
-      const IdentifierInfo *EnclosingScope = nullptr);
+  /// Re-enter a possible template scope, creating as many template parameter
+  /// scopes as necessary.
+  /// \return The number of template parameter scopes entered.
+  unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D);
 
-  bool MaybeParseHLSLAnnotations(Declarator &D,
-                                 SourceLocation *EndLoc = nullptr,
-                                 bool CouldBeBitField = false) {
-    assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only");
-    if (Tok.is(tok::colon)) {
-      ParsedAttributes Attrs(AttrFactory);
-      ParseHLSLAnnotations(Attrs, EndLoc, CouldBeBitField);
-      D.takeAttributes(Attrs);
-      return true;
+  private:
+
+  /// The "depth" of the template parameters currently being parsed.
+  unsigned TemplateParameterDepth;
+
+  /// RAII class that manages the template parameter depth.
+  class TemplateParameterDepthRAII {
+    unsigned &Depth;
+    unsigned AddedLevels;
+  public:
+    explicit TemplateParameterDepthRAII(unsigned &Depth)
+      : Depth(Depth), AddedLevels(0) {}
+
+    ~TemplateParameterDepthRAII() {
+      Depth -= AddedLevels;
     }
-    return false;
-  }
 
-  void MaybeParseHLSLAnnotations(ParsedAttributes &Attrs,
-                                 SourceLocation *EndLoc = nullptr) {
-    assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only");
-    if (Tok.is(tok::colon))
-      ParseHLSLAnnotations(Attrs, EndLoc);
+    void operator++() {
+      ++Depth;
+      ++AddedLevels;
+    }
+    void addDepth(unsigned D) {
+      Depth += D;
+      AddedLevels += D;
+    }
+    void setAddedDepth(unsigned D) {
+      Depth = Depth - AddedLevels + D;
+      AddedLevels = D;
+    }
+
+    unsigned getDepth() const { return Depth; }
+    unsigned getOriginalDepth() const { return Depth - AddedLevels; }
+  };
+
+  /// Gathers and cleans up TemplateIdAnnotations when parsing of a
+  /// top-level declaration is finished.
+  SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
+
+  /// Don't destroy template annotations in MaybeDestroyTemplateIds even if
+  /// we're at the end of a declaration. Instead, we defer the destruction until
+  /// after a top-level declaration.
+  /// Use DelayTemplateIdDestructionRAII rather than setting it directly.
+  bool DelayTemplateIdDestruction = false;
+
+  void MaybeDestroyTemplateIds() {
+    if (DelayTemplateIdDestruction)
+      return;
+    if (!TemplateIds.empty() &&
+        (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens()))
+      DestroyTemplateIds();
   }
+  void DestroyTemplateIds();
+
+  /// RAII object to destroy TemplateIdAnnotations where possible, from a
+  /// likely-good position during parsing.
+  struct DestroyTemplateIdAnnotationsRAIIObj {
+    Parser &Self;
+
+    DestroyTemplateIdAnnotationsRAIIObj(Parser &Self) : Self(Self) {}
+    ~DestroyTemplateIdAnnotationsRAIIObj() { Self.MaybeDestroyTemplateIds(); }
+  };
 
-  void ParseHLSLAnnotations(ParsedAttributes &Attrs,
-                            SourceLocation *EndLoc = nullptr,
-                            bool CouldBeBitField = false);
-  Decl *ParseHLSLBuffer(SourceLocation &DeclEnd);
+  struct DelayTemplateIdDestructionRAII {
+    Parser &Self;
+    bool PrevDelayTemplateIdDestruction;
 
-  void MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) {
-    if ((getLangOpts().MicrosoftExt || getLangOpts().HLSL) &&
-        Tok.is(tok::l_square)) {
-      ParsedAttributes AttrsWithRange(AttrFactory);
-      ParseMicrosoftAttributes(AttrsWithRange);
-      Attrs.takeAllFrom(AttrsWithRange);
+    DelayTemplateIdDestructionRAII(Parser &Self,
+                                   bool DelayTemplateIdDestruction) noexcept
+        : Self(Self),
+          PrevDelayTemplateIdDestruction(Self.DelayTemplateIdDestruction) {
+      Self.DelayTemplateIdDestruction = DelayTemplateIdDestruction;
     }
-  }
-  void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs);
-  void ParseMicrosoftAttributes(ParsedAttributes &Attrs);
-  bool MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {
-    if (getLangOpts().DeclSpecKeyword && Tok.is(tok::kw___declspec)) {
-      ParseMicrosoftDeclSpecs(Attrs);
-      return true;
+
+    ~DelayTemplateIdDestructionRAII() noexcept {
+      Self.DelayTemplateIdDestruction = PrevDelayTemplateIdDestruction;
     }
-    return false;
-  }
-  void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs);
-  bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
-                                  SourceLocation AttrNameLoc,
-                                  ParsedAttributes &Attrs);
-  void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
-  void ParseWebAssemblyFuncrefTypeAttribute(ParsedAttributes &Attrs);
-  void DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
-  SourceLocation SkipExtendedMicrosoftTypeAttributes();
-  void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
-  void ParseNullabilityClassAttributes(ParsedAttributes &attrs);
-  void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
-  void ParseOpenCLKernelAttributes(ParsedAttributes &attrs);
-  void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
-  void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs);
-  void ParseCUDAFunctionAttributes(ParsedAttributes &attrs);
-  bool isHLSLQualifier(const Token &Tok) const;
-  void ParseHLSLQualifiers(ParsedAttributes &Attrs);
+  };
 
-  VersionTuple ParseVersionTuple(SourceRange &Range);
-  void ParseAvailabilityAttribute(IdentifierInfo &Availability,
-                                  SourceLocation AvailabilityLoc,
-                                  ParsedAttributes &attrs,
-                                  SourceLocation *endLoc,
-                                  IdentifierInfo *ScopeName,
-                                  SourceLocation ScopeLoc,
-                                  ParsedAttr::Form Form);
+  /// Identifiers which have been declared within a tentative parse.
+  SmallVector<const IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
 
-  std::optional<AvailabilitySpec> ParseAvailabilitySpec();
-  ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
+  /// Tracker for '<' tokens that might have been intended to be treated as an
+  /// angle bracket instead of a less-than comparison.
+  ///
+  /// This happens when the user intends to form a template-id, but typoes the
+  /// template-name or forgets a 'template' keyword for a dependent template
+  /// name.
+  ///
+  /// We track these locations from the point where we see a '<' with a
+  /// name-like expression on its left until we see a '>' or '>>' that might
+  /// match it.
+  struct AngleBracketTracker {
+    /// Flags used to rank candidate template names when there is more than one
+    /// '<' in a scope.
+    enum Priority : unsigned short {
+      /// A non-dependent name that is a potential typo for a template name.
+      PotentialTypo = 0x0,
+      /// A dependent name that might instantiate to a template-name.
+      DependentName = 0x2,
 
-  void ParseExternalSourceSymbolAttribute(IdentifierInfo &ExternalSourceSymbol,
-                                          SourceLocation Loc,
-                                          ParsedAttributes &Attrs,
-                                          SourceLocation *EndLoc,
-                                          IdentifierInfo *ScopeName,
-                                          SourceLocation ScopeLoc,
-                                          ParsedAttr::Form Form);
+      /// A space appears before the '<' token.
+      SpaceBeforeLess = 0x0,
+      /// No space before the '<' token
+      NoSpaceBeforeLess = 0x1,
 
-  void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
-                                       SourceLocation ObjCBridgeRelatedLoc,
-                                       ParsedAttributes &Attrs,
-                                       SourceLocation *EndLoc,
-                                       IdentifierInfo *ScopeName,
-                                       SourceLocation ScopeLoc,
-                                       ParsedAttr::Form Form);
+      LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ DependentName)
+    };
 
-  void ParseSwiftNewTypeAttribute(IdentifierInfo &AttrName,
-                                  SourceLocation AttrNameLoc,
-                                  ParsedAttributes &Attrs,
-                                  SourceLocation *EndLoc,
-                                  IdentifierInfo *ScopeName,
-                                  SourceLocation ScopeLoc,
-                                  ParsedAttr::Form Form);
+    struct Loc {
+      Expr *TemplateName;
+      SourceLocation LessLoc;
+      AngleBracketTracker::Priority Priority;
+      unsigned short ParenCount, BracketCount, BraceCount;
 
-  void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
-                                        SourceLocation AttrNameLoc,
-                                        ParsedAttributes &Attrs,
-                                        SourceLocation *EndLoc,
-                                        IdentifierInfo *ScopeName,
-                                        SourceLocation ScopeLoc,
-                                        ParsedAttr::Form Form);
+      bool isActive(Parser &P) const {
+        return P.ParenCount == ParenCount && P.BracketCount == BracketCount &&
+               P.BraceCount == BraceCount;
+      }
 
-  void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
-                                 SourceLocation AttrNameLoc,
-                                 ParsedAttributes &Attrs,
-                                 IdentifierInfo *ScopeName,
-                                 SourceLocation ScopeLoc,
-                                 ParsedAttr::Form Form);
+      bool isActiveOrNested(Parser &P) const {
+        return isActive(P) || P.ParenCount > ParenCount ||
+               P.BracketCount > BracketCount || P.BraceCount > BraceCount;
+      }
+    };
 
-  void DistributeCLateParsedAttrs(Decl *Dcl, LateParsedAttrList *LateAttrs);
+    SmallVector<Loc, 8> Locs;
 
-  void ParseBoundsAttribute(IdentifierInfo &AttrName,
-                            SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
-                            IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-                            ParsedAttr::Form Form);
+    /// Add an expression that might have been intended to be a template name.
+    /// In the case of ambiguity, we arbitrarily select the innermost such
+    /// expression, for example in 'foo < bar < baz', 'bar' is the current
+    /// candidate. No attempt is made to track that 'foo' is also a candidate
+    /// for the case where we see a second suspicious '>' token.
+    void add(Parser &P, Expr *TemplateName, SourceLocation LessLoc,
+             Priority Prio) {
+      if (!Locs.empty() && Locs.back().isActive(P)) {
+        if (Locs.back().Priority <= Prio) {
+          Locs.back().TemplateName = TemplateName;
+          Locs.back().LessLoc = LessLoc;
+          Locs.back().Priority = Prio;
+        }
+      } else {
+        Locs.push_back({TemplateName, LessLoc, Prio,
+                        P.ParenCount, P.BracketCount, P.BraceCount});
+      }
+    }
 
-  void ParseTypeofSpecifier(DeclSpec &DS);
-  SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
-  void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
-                                         SourceLocation StartLoc,
-                                         SourceLocation EndLoc);
-  void ParseAtomicSpecifier(DeclSpec &DS);
+    /// Mark the current potential missing template location as having been
+    /// handled (this happens if we pass a "corresponding" '>' or '>>' token
+    /// or leave a bracket scope).
+    void clear(Parser &P) {
+      while (!Locs.empty() && Locs.back().isActiveOrNested(P))
+        Locs.pop_back();
+    }
 
-  ExprResult ParseAlignArgument(StringRef KWName, SourceLocation Start,
-                                SourceLocation &EllipsisLoc, bool &IsType,
-                                ParsedType &Ty);
-  void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
-                               SourceLocation *endLoc = nullptr);
-  ExprResult ParseExtIntegerArgument();
+    /// Get the current enclosing expression that might hve been intended to be
+    /// a template name.
+    Loc *getCurrent(Parser &P) {
+      if (!Locs.empty() && Locs.back().isActive(P))
+        return &Locs.back();
+      return nullptr;
+    }
+  };
 
-  void ParsePtrauthQualifier(ParsedAttributes &Attrs);
+  AngleBracketTracker AngleBrackets;
 
-  VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
-  VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
-    return isCXX11VirtSpecifier(Tok);
-  }
-  void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface,
-                                          SourceLocation FriendLoc);
+  /// Contains information about any template-specific
+  /// information that has been parsed prior to parsing declaration
+  /// specifiers.
+  struct ParsedTemplateInfo {
+    ParsedTemplateInfo() : Kind(ParsedTemplateKind::NonTemplate), TemplateParams(nullptr) {}
 
-  bool isCXX11FinalKeyword() const;
-  bool isClassCompatibleKeyword() const;
+    ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
+                       bool isSpecialization,
+                       bool lastParameterListWasEmpty = false)
+      : Kind(isSpecialization? ParsedTemplateKind::ExplicitSpecialization : ParsedTemplateKind::Template),
+        TemplateParams(TemplateParams),
+        LastParameterListWasEmpty(lastParameterListWasEmpty) { }
 
-  /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
-  /// enter a new C++ declarator scope and exit it when the function is
-  /// finished.
-  class DeclaratorScopeObj {
-    Parser &P;
-    CXXScopeSpec &SS;
-    bool EnteredScope;
-    bool CreatedScope;
-  public:
-    DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
-      : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
+    explicit ParsedTemplateInfo(SourceLocation ExternLoc,
+                                SourceLocation TemplateLoc)
+      : Kind(ParsedTemplateKind::ExplicitInstantiation), TemplateParams(nullptr),
+        ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
+        LastParameterListWasEmpty(false){ }
 
-    void EnterDeclaratorScope() {
-      assert(!EnteredScope && "Already entered the scope!");
-      assert(SS.isSet() && "C++ scope was not set!");
+    ParsedTemplateKind Kind;
 
-      CreatedScope = true;
-      P.EnterScope(0); // Not a decl scope.
+    /// The template parameter lists, for template declarations
+    /// and explicit specializations.
+    TemplateParameterLists *TemplateParams;
 
-      if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
-        EnteredScope = true;
-    }
+    /// The location of the 'extern' keyword, if any, for an explicit
+    /// instantiation
+    SourceLocation ExternLoc;
 
-    ~DeclaratorScopeObj() {
-      if (EnteredScope) {
-        assert(SS.isSet() && "C++ scope was cleared ?");
-        P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
-      }
-      if (CreatedScope)
-        P.ExitScope();
-    }
-  };
+    /// The location of the 'template' keyword, for an explicit
+    /// instantiation.
+    SourceLocation TemplateLoc;
 
-  /// ParseDeclarator - Parse and verify a newly-initialized declarator.
-  void ParseDeclarator(Declarator &D);
-  /// A function that parses a variant of direct-declarator.
-  typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
-  void ParseDeclaratorInternal(Declarator &D,
-                               DirectDeclParseFunction DirectDeclParser);
+    /// Whether the last template parameter list was empty.
+    bool LastParameterListWasEmpty;
 
-  enum AttrRequirements {
-    AR_NoAttributesParsed = 0, ///< No attributes are diagnosed.
-    AR_GNUAttributesParsedAndRejected = 1 << 0, ///< Diagnose GNU attributes.
-    AR_GNUAttributesParsed = 1 << 1,
-    AR_CXX11AttributesParsed = 1 << 2,
-    AR_DeclspecAttributesParsed = 1 << 3,
-    AR_AllAttributesParsed = AR_GNUAttributesParsed |
-                             AR_CXX11AttributesParsed |
-                             AR_DeclspecAttributesParsed,
-    AR_VendorAttributesParsed = AR_GNUAttributesParsed |
-                                AR_DeclspecAttributesParsed
+    SourceRange getSourceRange() const LLVM_READONLY;
   };
 
-  void ParseTypeQualifierListOpt(
-      DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
-      bool AtomicAllowed = true, bool IdentifierRequired = false,
-      std::optional<llvm::function_ref<void()>> CodeCompletionHandler =
-          std::nullopt);
-  void ParseDirectDeclarator(Declarator &D);
-  void ParseDecompositionDeclarator(Declarator &D);
-  void ParseParenDeclarator(Declarator &D);
-  void ParseFunctionDeclarator(Declarator &D, ParsedAttributes &FirstArgAttrs,
-                               BalancedDelimiterTracker &Tracker,
-                               bool IsAmbiguous, bool RequiresArg = false);
-  void InitCXXThisScopeForDeclaratorIfRelevant(
-      const Declarator &D, const DeclSpec &DS,
-      std::optional<Sema::CXXThisScopeRAII> &ThisScope);
-  bool ParseRefQualifier(bool &RefQualifierIsLValueRef,
-                         SourceLocation &RefQualifierLoc);
-  bool isFunctionDeclaratorIdentifierList();
-  void ParseFunctionDeclaratorIdentifierList(
-         Declarator &D,
-         SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
-  void ParseParameterDeclarationClause(
-      Declarator &D, ParsedAttributes &attrs,
-      SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
-      SourceLocation &EllipsisLoc) {
-    return ParseParameterDeclarationClause(
-        D.getContext(), attrs, ParamInfo, EllipsisLoc,
-        D.getCXXScopeSpec().isSet() &&
-            D.isFunctionDeclaratorAFunctionDeclaration());
-  }
-  void ParseParameterDeclarationClause(
-      DeclaratorContext DeclaratorContext, ParsedAttributes &attrs,
-      SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
-      SourceLocation &EllipsisLoc, bool IsACXXFunctionDeclaration = false);
+  /// Lex a delayed template function for late parsing.
+  void LexTemplateFunctionForLateParsing(CachedTokens &Toks);
 
-  void ParseBracketDeclarator(Declarator &D);
-  void ParseMisplacedBracketDeclarator(Declarator &D);
-  bool MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS);
-  DeclSpec::TST TypeTransformTokToDeclSpec();
+  /// Late parse a C++ function template in Microsoft mode.
+  void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT);
+
+  static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
+
+  /// We've parsed something that could plausibly be intended to be a template
+  /// name (\p LHS) followed by a '<' token, and the following code can't possibly
+  /// be an expression. Determine if this is likely to be a template-id and if so,
+  /// diagnose it.
+  bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
+
+  void checkPotentialAngleBracket(ExprResult &PotentialTemplateName);
+  bool checkPotentialAngleBracketDelimiter(const AngleBracketTracker::Loc &,
+                                           const Token &OpToken);
+  bool checkPotentialAngleBracketDelimiter(const Token &OpToken) {
+    if (auto *Info = AngleBrackets.getCurrent(*this))
+      return checkPotentialAngleBracketDelimiter(*Info, OpToken);
+    return false;
+  }
 
   //===--------------------------------------------------------------------===//
-  // C++ 7: Declarations [dcl.dcl]
+  // C++ 14: Templates [temp]
 
-  CXX11AttributeKind
-  isCXX11AttributeSpecifier(bool Disambiguate = false,
-                            bool OuterMightBeMessageSend = false);
+  /// Parse a template declaration, explicit instantiation, or
+  /// explicit specialization.
+  DeclGroupPtrTy
+  ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
+                                       SourceLocation &DeclEnd,
+                                       ParsedAttributes &AccessAttrs);
 
-  void DiagnoseUnexpectedNamespace(NamedDecl *Context);
+  /// Parse a template declaration or an explicit specialization.
+  ///
+  /// Template declarations include one or more template parameter lists
+  /// and either the function or class template declaration. Explicit
+  /// specializations contain one or more 'template < >' prefixes
+  /// followed by a (possibly templated) declaration. Since the
+  /// syntactic form of both features is nearly identical, we parse all
+  /// of the template headers together and let semantic analysis sort
+  /// the declarations from the explicit specializations.
+  ///
+  ///       template-declaration: [C++ temp]
+  ///         'export'[opt] 'template' '<' template-parameter-list '>' declaration
+  ///
+  ///       template-declaration: [C++2a]
+  ///         template-head declaration
+  ///         template-head concept-definition
+  ///
+  ///       TODO: requires-clause
+  ///       template-head: [C++2a]
+  ///         'template' '<' template-parameter-list '>'
+  ///             requires-clause[opt]
+  ///
+  ///       explicit-specialization: [ C++ temp.expl.spec]
+  ///         'template' '<' '>' declaration
+  DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
+      DeclaratorContext Context, SourceLocation &DeclEnd,
+      ParsedAttributes &AccessAttrs, AccessSpecifier AS);
 
-  DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
-                                SourceLocation &DeclEnd,
-                                SourceLocation InlineLoc = SourceLocation());
+  clang::Parser::DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
+      DeclaratorContext Context, SourceLocation &DeclEnd, AccessSpecifier AS);
 
-  struct InnerNamespaceInfo {
-    SourceLocation NamespaceLoc;
-    SourceLocation InlineLoc;
-    SourceLocation IdentLoc;
-    IdentifierInfo *Ident;
-  };
-  using InnerNamespaceInfoList = llvm::SmallVector<InnerNamespaceInfo, 4>;
+  /// Parse a single declaration that declares a template,
+  /// template specialization, or explicit instantiation of a template.
+  ///
+  /// \param DeclEnd will receive the source location of the last token
+  /// within this declaration.
+  ///
+  /// \param AS the access specifier associated with this
+  /// declaration. Will be AS_none for namespace-scope declarations.
+  ///
+  /// \returns the new declaration.
+  DeclGroupPtrTy ParseDeclarationAfterTemplate(
+      DeclaratorContext Context, ParsedTemplateInfo &TemplateInfo,
+      ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
+      ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none);
 
-  void ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
-                           unsigned int index, SourceLocation &InlineLoc,
-                           ParsedAttributes &attrs,
-                           BalancedDelimiterTracker &Tracker);
-  Decl *ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context);
-  Decl *ParseExportDeclaration();
-  DeclGroupPtrTy ParseUsingDirectiveOrDeclaration(
-      DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
-      SourceLocation &DeclEnd, ParsedAttributes &Attrs);
-  Decl *ParseUsingDirective(DeclaratorContext Context,
-                            SourceLocation UsingLoc,
-                            SourceLocation &DeclEnd,
-                            ParsedAttributes &attrs);
+  /// ParseTemplateParameters - Parses a template-parameter-list enclosed in
+  /// angle brackets. Depth is the depth of this template-parameter-list, which
+  /// is the number of template headers directly enclosing this template header.
+  /// TemplateParams is the current list of template parameters we're building.
+  /// The template parameter we parse will be added to this list. LAngleLoc and
+  /// RAngleLoc will receive the positions of the '<' and '>', respectively,
+  /// that enclose this template parameter list.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool ParseTemplateParameters(MultiParseScope &TemplateScopes, unsigned Depth,
+                               SmallVectorImpl<NamedDecl *> &TemplateParams,
+                               SourceLocation &LAngleLoc,
+                               SourceLocation &RAngleLoc);
 
-  struct UsingDeclarator {
-    SourceLocation TypenameLoc;
-    CXXScopeSpec SS;
-    UnqualifiedId Name;
-    SourceLocation EllipsisLoc;
+  /// ParseTemplateParameterList - Parse a template parameter list. If
+  /// the parsing fails badly (i.e., closing bracket was left out), this
+  /// will try to put the token stream in a reasonable position (closing
+  /// a statement, etc.) and return false.
+  ///
+  ///       template-parameter-list:    [C++ temp]
+  ///         template-parameter
+  ///         template-parameter-list ',' template-parameter
+  bool ParseTemplateParameterList(unsigned Depth,
+                                  SmallVectorImpl<NamedDecl*> &TemplateParams);
 
-    void clear() {
-      TypenameLoc = EllipsisLoc = SourceLocation();
-      SS.clear();
-      Name.clear();
-    }
-  };
+  enum class TPResult;
 
-  bool ParseUsingDeclarator(DeclaratorContext Context, UsingDeclarator &D);
-  DeclGroupPtrTy ParseUsingDeclaration(DeclaratorContext Context,
-                                       const ParsedTemplateInfo &TemplateInfo,
-                                       SourceLocation UsingLoc,
-                                       SourceLocation &DeclEnd,
-                                       ParsedAttributes &Attrs,
-                                       AccessSpecifier AS = AS_none);
-  Decl *ParseAliasDeclarationAfterDeclarator(
-      const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
-      UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
-      ParsedAttributes &Attrs, Decl **OwnedType = nullptr);
+  /// Determine whether the parser is at the start of a template
+  /// type parameter.
+  TPResult isStartOfTemplateTypeParameter();
 
-  Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
-  Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
-                            SourceLocation AliasLoc, IdentifierInfo *Alias,
-                            SourceLocation &DeclEnd);
+  /// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
+  ///
+  ///       template-parameter: [C++ temp.param]
+  ///         type-parameter
+  ///         parameter-declaration
+  ///
+  ///       type-parameter: (See below)
+  ///         type-parameter-key ...[opt] identifier[opt]
+  ///         type-parameter-key identifier[opt] = type-id
+  /// (C++2a) type-constraint ...[opt] identifier[opt]
+  /// (C++2a) type-constraint identifier[opt] = type-id
+  ///         'template' '<' template-parameter-list '>' type-parameter-key
+  ///               ...[opt] identifier[opt]
+  ///         'template' '<' template-parameter-list '>' type-parameter-key
+  ///               identifier[opt] '=' id-expression
+  ///
+  ///       type-parameter-key:
+  ///         class
+  ///         typename
+  ///
+  NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position);
 
-  //===--------------------------------------------------------------------===//
-  // C++ 9: classes [class] and C structs/unions.
-  bool isValidAfterTypeSpecifier(bool CouldBeBitfield);
-  void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
-                           DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
-                           AccessSpecifier AS, bool EnteringContext,
-                           DeclSpecContext DSC, ParsedAttributes &Attributes);
-  void SkipCXXMemberSpecification(SourceLocation StartLoc,
-                                  SourceLocation AttrFixitLoc,
-                                  unsigned TagType,
-                                  Decl *TagDecl);
-  void ParseCXXMemberSpecification(SourceLocation StartLoc,
-                                   SourceLocation AttrFixitLoc,
-                                   ParsedAttributes &Attrs, unsigned TagType,
-                                   Decl *TagDecl);
-  ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
-                                       SourceLocation &EqualLoc);
-  bool
-  ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
-                                            VirtSpecifiers &VS,
-                                            ExprResult &BitfieldSize,
-                                            LateParsedAttrList &LateAttrs);
-  void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D,
-                                                               VirtSpecifiers &VS);
-  DeclGroupPtrTy ParseCXXClassMemberDeclaration(
-      AccessSpecifier AS, ParsedAttributes &Attr,
-      ParsedTemplateInfo &TemplateInfo,
-      ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
-  DeclGroupPtrTy
-  ParseCXXClassMemberDeclarationWithPragmas(AccessSpecifier &AS,
-                                            ParsedAttributes &AccessAttrs,
-                                            DeclSpec::TST TagType, Decl *Tag);
-  void ParseConstructorInitializer(Decl *ConstructorDecl);
-  MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
-  void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
-                                      Decl *ThisDecl);
+  /// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]).
+  /// Other kinds of template parameters are parsed in
+  /// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
+  ///
+  ///       type-parameter:     [C++ temp.param]
+  ///         'class' ...[opt][C++0x] identifier[opt]
+  ///         'class' identifier[opt] '=' type-id
+  ///         'typename' ...[opt][C++0x] identifier[opt]
+  ///         'typename' identifier[opt] '=' type-id
+  NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position);
 
-  //===--------------------------------------------------------------------===//
-  // C++ 10: Derived classes [class.derived]
-  TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
-                                    SourceLocation &EndLocation);
-  void ParseBaseClause(Decl *ClassDecl);
-  BaseResult ParseBaseSpecifier(Decl *ClassDecl);
-  AccessSpecifier getAccessSpecifierIfPresent() const;
+  /// ParseTemplateTemplateParameter - Handle the parsing of template
+  /// template parameters.
+  ///
+  ///       type-parameter:    [C++ temp.param]
+  ///         template-head type-parameter-key ...[opt] identifier[opt]
+  ///         template-head type-parameter-key identifier[opt] = id-expression
+  ///       type-parameter-key:
+  ///         'class'
+  ///         'typename'       [C++1z]
+  ///       template-head:     [C++2a]
+  ///         'template' '<' template-parameter-list '>'
+  ///             requires-clause[opt]
+  NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
 
-  bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
-                                    ParsedType ObjectType,
-                                    bool ObjectHadErrors,
-                                    SourceLocation TemplateKWLoc,
-                                    IdentifierInfo *Name,
-                                    SourceLocation NameLoc,
-                                    bool EnteringContext,
-                                    UnqualifiedId &Id,
-                                    bool AssumeTemplateId);
-  bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
-                                  ParsedType ObjectType,
-                                  UnqualifiedId &Result);
+  /// ParseNonTypeTemplateParameter - Handle the parsing of non-type
+  /// template parameters (e.g., in "template<int Size> class array;").
+  ///
+  ///       template-parameter:
+  ///         ...
+  ///         parameter-declaration
+  NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
 
-  //===--------------------------------------------------------------------===//
-  // OpenMP: Directives and clauses.
-  /// Parse clauses for '#pragma omp declare simd'.
-  DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
-                                            CachedTokens &Toks,
-                                            SourceLocation Loc);
+  /// Check whether the current token is a template-id annotation denoting a
+  /// type-constraint.
+  bool isTypeConstraintAnnotation();
 
-  /// Parse a property kind into \p TIProperty for the selector set \p Set and
-  /// selector \p Selector.
-  void parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
-                                 llvm::omp::TraitSet Set,
-                                 llvm::omp::TraitSelector Selector,
-                                 llvm::StringMap<SourceLocation> &Seen);
+  /// Try parsing a type-constraint at the current location.
+  ///
+  ///     type-constraint:
+  ///       nested-name-specifier[opt] concept-name
+  ///       nested-name-specifier[opt] concept-name
+  ///           '<' template-argument-list[opt] '>'[opt]
+  ///
+  /// \returns true if an error occurred, and false otherwise.
+  bool TryAnnotateTypeConstraint();
+
+  void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+                                 SourceLocation CorrectLoc,
+                                 bool AlreadyHasEllipsis,
+                                 bool IdentifierHasName);
+  void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+                                             Declarator &D);
+  // C++ 14.3: Template arguments [temp.arg]
+  typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
+
+  /// Parses a '>' at the end of a template list.
+  ///
+  /// If this function encounters '>>', '>>>', '>=', or '>>=', it tries
+  /// to determine if these tokens were supposed to be a '>' followed by
+  /// '>', '>>', '>=', or '>='. It emits an appropriate diagnostic if necessary.
+  ///
+  /// \param RAngleLoc the location of the consumed '>'.
+  ///
+  /// \param ConsumeLastToken if true, the '>' is consumed.
+  ///
+  /// \param ObjCGenericList if true, this is the '>' closing an Objective-C
+  /// type parameter or type argument list, rather than a C++ template parameter
+  /// or argument list.
+  ///
+  /// \returns true, if current token does not start with '>', false otherwise.
+  bool ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,
+                                      SourceLocation &RAngleLoc,
+                                      bool ConsumeLastToken,
+                                      bool ObjCGenericList);
+  
+  /// Parses a template-id that after the template name has
+  /// already been parsed.
+  ///
+  /// This routine takes care of parsing the enclosed template argument
+  /// list ('<' template-parameter-list [opt] '>') and placing the
+  /// results into a form that can be transferred to semantic analysis.
+  ///
+  /// \param ConsumeLastToken if true, then we will consume the last
+  /// token that forms the template-id. Otherwise, we will leave the
+  /// last token in the stream (e.g., so that it can be replaced with an
+  /// annotation token).
+  bool ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
+                                        SourceLocation &LAngleLoc,
+                                        TemplateArgList &TemplateArgs,
+                                        SourceLocation &RAngleLoc,
+                                        TemplateTy NameHint = nullptr);
 
-  /// Parse a selector kind into \p TISelector for the selector set \p Set.
-  void parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
-                                 llvm::omp::TraitSet Set,
-                                 llvm::StringMap<SourceLocation> &Seen);
+  /// Replace the tokens that form a simple-template-id with an
+  /// annotation token containing the complete template-id.
+  ///
+  /// The first token in the stream must be the name of a template that
+  /// is followed by a '<'. This routine will parse the complete
+  /// simple-template-id and replace the tokens with a single annotation
+  /// token with one of two different kinds: if the template-id names a
+  /// type (and \p AllowTypeAnnotation is true), the annotation token is
+  /// a type annotation that includes the optional nested-name-specifier
+  /// (\p SS). Otherwise, the annotation token is a template-id
+  /// annotation that does not include the optional
+  /// nested-name-specifier.
+  ///
+  /// \param Template  the declaration of the template named by the first
+  /// token (an identifier), as returned from \c Action::isTemplateName().
+  ///
+  /// \param TNK the kind of template that \p Template
+  /// refers to, as returned from \c Action::isTemplateName().
+  ///
+  /// \param SS if non-NULL, the nested-name-specifier that precedes
+  /// this template name.
+  ///
+  /// \param TemplateKWLoc if valid, specifies that this template-id
+  /// annotation was preceded by the 'template' keyword and gives the
+  /// location of that keyword. If invalid (the default), then this
+  /// template-id was not preceded by a 'template' keyword.
+  ///
+  /// \param AllowTypeAnnotation if true (the default), then a
+  /// simple-template-id that refers to a class template, template
+  /// template parameter, or other template that produces a type will be
+  /// replaced with a type annotation token. Otherwise, the
+  /// simple-template-id is always replaced with a template-id
+  /// annotation token.
+  ///
+  /// \param TypeConstraint if true, then this is actually a type-constraint,
+  /// meaning that the template argument list can be omitted (and the template in
+  /// question must be a concept).
+  ///
+  /// If an unrecoverable parse error occurs and no annotation token can be
+  /// formed, this function returns true.
+  ///
+  bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+                               CXXScopeSpec &SS,
+                               SourceLocation TemplateKWLoc,
+                               UnqualifiedId &TemplateName,
+                               bool AllowTypeAnnotation = true,
+                               bool TypeConstraint = false);
 
-  /// Parse a selector set kind into \p TISet.
-  void parseOMPTraitSetKind(OMPTraitSet &TISet,
-                            llvm::StringMap<SourceLocation> &Seen);
+  /// Replaces a template-id annotation token with a type
+  /// annotation token.
+  ///
+  /// If there was a failure when forming the type from the template-id,
+  /// a type annotation token will still be created, but will have a
+  /// NULL type pointer to signify an error.
+  ///
+  /// \param SS The scope specifier appearing before the template-id, if any.
+  ///
+  /// \param AllowImplicitTypename whether this is a context where T::type
+  /// denotes a dependent type.
+  /// \param IsClassName Is this template-id appearing in a context where we
+  /// know it names a class, such as in an elaborated-type-specifier or
+  /// base-specifier? ('typename' and 'template' are unneeded and disallowed
+  /// in those contexts.)
+  void
+  AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
+                                ImplicitTypenameContext AllowImplicitTypename,
+                                bool IsClassName = false);
 
-  /// Parses an OpenMP context property.
-  void parseOMPContextProperty(OMPTraitSelector &TISelector,
-                               llvm::omp::TraitSet Set,
-                               llvm::StringMap<SourceLocation> &Seen);
+  /// ParseTemplateArgumentList - Parse a C++ template-argument-list
+  /// (C++ [temp.names]). Returns true if there was an error.
+  ///
+  ///       template-argument-list: [C++ 14.2]
+  ///         template-argument
+  ///         template-argument-list ',' template-argument
+  ///
+  /// \param Template is only used for code completion, and may be null.
+  bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
+                                 TemplateTy Template, SourceLocation OpenLoc);
 
-  /// Parses an OpenMP context selector.
-  void parseOMPContextSelector(OMPTraitSelector &TISelector,
-                               llvm::omp::TraitSet Set,
-                               llvm::StringMap<SourceLocation> &SeenSelectors);
+  /// Parse a C++ template template argument.
+  ParsedTemplateArgument ParseTemplateTemplateArgument();
 
-  /// Parses an OpenMP context selector set.
-  void parseOMPContextSelectorSet(OMPTraitSet &TISet,
-                                  llvm::StringMap<SourceLocation> &SeenSets);
+  /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
+  ///
+  ///       template-argument: [C++ 14.2]
+  ///         constant-expression
+  ///         type-id
+  ///         id-expression
+  ///         braced-init-list  [C++26, DR]
+  ///
+  ParsedTemplateArgument ParseTemplateArgument();
 
-  /// Parses OpenMP context selectors.
-  bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI);
+  /// Parse a C++ explicit template instantiation
+  /// (C++ [temp.explicit]).
+  ///
+  ///       explicit-instantiation:
+  ///         'extern' [opt] 'template' declaration
+  ///
+  /// Note that the 'extern' is a GNU extension and C++11 feature.
+  DeclGroupPtrTy ParseExplicitInstantiation(DeclaratorContext Context,
+                                            SourceLocation ExternLoc,
+                                            SourceLocation TemplateLoc,
+                                            SourceLocation &DeclEnd,
+                                            ParsedAttributes &AccessAttrs,
+                                            AccessSpecifier AS = AS_none);
+  
+  /// \brief Parse a single declaration that declares a concept.
+  ///
+  /// \param DeclEnd will receive the source location of the last token
+  /// within this declaration.
+  ///
+  /// \returns the new declaration.
+  Decl *
+  ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
+                         SourceLocation &DeclEnd);
 
-  /// Parse an 'append_args' clause for '#pragma omp declare variant'.
-  bool parseOpenMPAppendArgs(SmallVectorImpl<OMPInteropInfo> &InteropInfos);
+  ///@}
 
-  /// Parse a `match` clause for an '#pragma omp declare variant'. Return true
-  /// if there was an error.
-  bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI,
-                                         OMPTraitInfo *ParentTI);
+  //
+  //
+  // -------------------------------------------------------------------------
+  //
+  //
 
-  /// Parse clauses for '#pragma omp declare variant'.
-  void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
-                                     SourceLocation Loc);
+  /// \name Tentative Parsing
+  /// Implementations are in ParseTentative.cpp
+  ///@{
 
-  /// Parse 'omp [begin] assume[s]' directive.
-  void ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
-                                   SourceLocation Loc);
+  public:
 
-  /// Parse 'omp end assumes' directive.
-  void ParseOpenMPEndAssumesDirective(SourceLocation Loc);
+  private:
 
-  /// Parses clauses for directive.
+  /// TentativeParsingAction - An object that is used as a kind of "tentative
+  /// parsing transaction". It gets instantiated to mark the token position and
+  /// after the token consumption is done, Commit() or Revert() is called to
+  /// either "commit the consumed tokens" or revert to the previously marked
+  /// token position. Example:
   ///
-  /// \param DKind Kind of current directive.
-  /// \param clauses for current directive.
-  /// \param start location for clauses of current directive
-  void ParseOpenMPClauses(OpenMPDirectiveKind DKind,
-                          SmallVectorImpl<clang::OMPClause *> &Clauses,
-                          SourceLocation Loc);
+  ///   TentativeParsingAction TPA(*this);
+  ///   ConsumeToken();
+  ///   ....
+  ///   TPA.Revert();
+  ///
+  /// If the Unannotated parameter is true, any token annotations created
+  /// during the tentative parse are reverted.
+  class TentativeParsingAction {
+    Parser &P;
+    PreferredTypeBuilder PrevPreferredType;
+    Token PrevTok;
+    size_t PrevTentativelyDeclaredIdentifierCount;
+    unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
+    bool isActive;
 
-  /// Parse clauses for '#pragma omp [begin] declare target'.
-  void ParseOMPDeclareTargetClauses(SemaOpenMP::DeclareTargetContextInfo &DTCI);
+  public:
+    explicit TentativeParsingAction(Parser &p, bool Unannotated = false)
+        : P(p), PrevPreferredType(P.PreferredType) {
+      PrevTok = P.Tok;
+      PrevTentativelyDeclaredIdentifierCount =
+          P.TentativelyDeclaredIdentifiers.size();
+      PrevParenCount = P.ParenCount;
+      PrevBracketCount = P.BracketCount;
+      PrevBraceCount = P.BraceCount;
+      P.PP.EnableBacktrackAtThisPos(Unannotated);
+      isActive = true;
+    }
+    void Commit() {
+      assert(isActive && "Parsing action was finished!");
+      P.TentativelyDeclaredIdentifiers.resize(
+          PrevTentativelyDeclaredIdentifierCount);
+      P.PP.CommitBacktrackedTokens();
+      isActive = false;
+    }
+    void Revert() {
+      assert(isActive && "Parsing action was finished!");
+      P.PP.Backtrack();
+      P.PreferredType = PrevPreferredType;
+      P.Tok = PrevTok;
+      P.TentativelyDeclaredIdentifiers.resize(
+          PrevTentativelyDeclaredIdentifierCount);
+      P.ParenCount = PrevParenCount;
+      P.BracketCount = PrevBracketCount;
+      P.BraceCount = PrevBraceCount;
+      isActive = false;
+    }
+    ~TentativeParsingAction() {
+      assert(!isActive && "Forgot to call Commit or Revert!");
+    }
+  };
 
-  /// Parse '#pragma omp end declare target'.
-  void ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
-                                         OpenMPDirectiveKind EndDKind,
-                                         SourceLocation Loc);
+  /// A TentativeParsingAction that automatically reverts in its destructor.
+  /// Useful for disambiguation parses that will always be reverted.
+  class RevertingTentativeParsingAction
+      : private Parser::TentativeParsingAction {
+  public:
+    using TentativeParsingAction::TentativeParsingAction;
 
-  /// Skip tokens until a `annot_pragma_openmp_end` was found. Emit a warning if
-  /// it is not the current token.
-  void skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind);
+    ~RevertingTentativeParsingAction() { Revert(); }
+  };
 
-  /// Check the \p FoundKind against the \p ExpectedKind, if not issue an error
-  /// that the "end" matching the "begin" directive of kind \p BeginKind was not
-  /// found. Finally, if the expected kind was found or if \p SkipUntilOpenMPEnd
-  /// is set, skip ahead using the helper `skipUntilPragmaOpenMPEnd`.
-  void parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
-                            OpenMPDirectiveKind ExpectedKind,
-                            OpenMPDirectiveKind FoundKind,
-                            SourceLocation MatchingLoc,
-                            SourceLocation FoundLoc,
-                            bool SkipUntilOpenMPEnd);
+  /// isCXXDeclarationStatement - C++-specialized function that disambiguates
+  /// between a declaration or an expression statement, when parsing function
+  /// bodies. Returns true for declaration, false for expression.
+  ///
+  ///         declaration-statement:
+  ///           block-declaration
+  ///
+  ///         block-declaration:
+  ///           simple-declaration
+  ///           asm-definition
+  ///           namespace-alias-definition
+  ///           using-declaration
+  ///           using-directive
+  /// [C++0x]   static_assert-declaration
+  ///
+  ///         asm-definition:
+  ///           'asm' '(' string-literal ')' ';'
+  ///
+  ///         namespace-alias-definition:
+  ///           'namespace' identifier = qualified-namespace-specifier ';'
+  ///
+  ///         using-declaration:
+  ///           'using' typename[opt] '::'[opt] nested-name-specifier
+  ///                 unqualified-id ';'
+  ///           'using' '::' unqualified-id ;
+  ///
+  ///         using-directive:
+  ///           'using' 'namespace' '::'[opt] nested-name-specifier[opt]
+  ///                 namespace-name ';'
+  ///
+  bool isCXXDeclarationStatement(bool DisambiguatingWithExpression = false);
 
-  /// Parses declarative OpenMP directives.
-  DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
-      AccessSpecifier &AS, ParsedAttributes &Attrs, bool Delayed = false,
-      DeclSpec::TST TagType = DeclSpec::TST_unspecified,
-      Decl *TagDecl = nullptr);
-  /// Parse 'omp declare reduction' construct.
-  DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
-  /// Parses initializer for provided omp_priv declaration inside the reduction
-  /// initializer.
-  void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);
+  /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
+  /// between a simple-declaration or an expression-statement.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  /// Returns false if the statement is disambiguated as expression.
+  ///
+  /// simple-declaration:
+  ///   decl-specifier-seq init-declarator-list[opt] ';'
+  ///   decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
+  ///                      brace-or-equal-initializer ';'    [C++17]
+  ///
+  /// (if AllowForRangeDecl specified)
+  /// for ( for-range-declaration : for-range-initializer ) statement
+  ///
+  /// for-range-declaration:
+  ///    decl-specifier-seq declarator
+  ///    decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
+  ///
+  /// In any of the above cases there can be a preceding attribute-specifier-seq,
+  /// but the caller is expected to handle that.
+  bool isCXXSimpleDeclaration(bool AllowForRangeDecl);
 
-  /// Parses 'omp declare mapper' directive.
-  DeclGroupPtrTy ParseOpenMPDeclareMapperDirective(AccessSpecifier AS);
-  /// Parses variable declaration in 'omp declare mapper' directive.
-  TypeResult parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
-                                             DeclarationName &Name,
-                                             AccessSpecifier AS = AS_none);
+  /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
+  /// a constructor-style initializer, when parsing declaration statements.
+  /// Returns true for function declarator and false for constructor-style
+  /// initializer. Sets 'IsAmbiguous' to true to indicate that this declaration
+  /// might be a constructor-style initializer.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  ///
+  /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+  ///         exception-specification[opt]
+  ///
+  bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr,
+                               ImplicitTypenameContext AllowImplicitTypename =
+                                   ImplicitTypenameContext::No);
 
-  /// Tries to parse cast part of OpenMP array shaping operation:
-  /// '[' expression ']' { '[' expression ']' } ')'.
-  bool tryParseOpenMPArrayShapingCastPart();
+  struct ConditionDeclarationOrInitStatementState;
+  enum class ConditionOrInitStatement {
+    Expression,    ///< Disambiguated as an expression (either kind).
+    ConditionDecl, ///< Disambiguated as the declaration form of condition.
+    InitStmtDecl,  ///< Disambiguated as a simple-declaration init-statement.
+    ForRangeDecl,  ///< Disambiguated as a for-range declaration.
+    Error          ///< Can't be any of the above!
+  };
 
-  /// Parses simple list of variables.
+  /// Disambiguates between a declaration in a condition, a
+  /// simple-declaration in an init-statement, and an expression for
+  /// a condition of a if/switch statement.
   ///
-  /// \param Kind Kind of the directive.
-  /// \param Callback Callback function to be called for the list elements.
-  /// \param AllowScopeSpecifier true, if the variables can have fully
-  /// qualified names.
+  ///       condition:
+  ///         expression
+  ///         type-specifier-seq declarator '=' assignment-expression
+  /// [C++11] type-specifier-seq declarator '=' initializer-clause
+  /// [C++11] type-specifier-seq declarator braced-init-list
+  /// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
+  ///             '=' assignment-expression
+  ///       simple-declaration:
+  ///         decl-specifier-seq init-declarator-list[opt] ';'
+  ///
+  /// Note that, unlike isCXXSimpleDeclaration, we must disambiguate all the way
+  /// to the ';' to disambiguate cases like 'int(x))' (an expression) from
+  /// 'int(x);' (a simple-declaration in an init-statement).
+  ConditionOrInitStatement
+  isCXXConditionDeclarationOrInitStatement(bool CanBeInitStmt,
+                                           bool CanBeForRangeDecl);
+
+  /// Determine whether the next set of tokens contains a type-id.
+  ///
+  /// The context parameter states what context we're parsing right
+  /// now, which affects how this routine copes with the token
+  /// following the type-id. If the context is
+  /// TentativeCXXTypeIdContext::InParens, we have already parsed the '(' and we
+  /// will cease lookahead when we hit the corresponding ')'. If the context is
+  /// TentativeCXXTypeIdContext::AsTemplateArgument, we've already parsed the '<'
+  /// or ',' before this template argument, and will cease lookahead when we hit a
+  /// '>', '>>' (in C++0x), or ','; or, in C++0x, an ellipsis immediately
+  /// preceding such. Returns true for a type-id and false for an expression.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  ///
+  /// type-id:
+  ///   type-specifier-seq abstract-declarator[opt]
+  ///
+  bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
+
+  bool isCXXTypeId(TentativeCXXTypeIdContext Context) {
+    bool isAmbiguous;
+    return isCXXTypeId(Context, isAmbiguous);
+  }
+
+  /// TPResult - Used as the result value for functions whose purpose is to
+  /// disambiguate C++ constructs by "tentatively parsing" them.
+  enum class TPResult {
+    True, False, Ambiguous, Error
+  };
+
+  /// Determine whether we could have an enum-base.
   ///
-  bool ParseOpenMPSimpleVarList(
-      OpenMPDirectiveKind Kind,
-      const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
-          Callback,
-      bool AllowScopeSpecifier);
-  /// Parses declarative or executable directive.
+  /// \p AllowSemi If \c true, then allow a ';' after the enum-base; otherwise
+  /// only consider this to be an enum-base if the next token is a '{'.
   ///
-  /// \param StmtCtx The context in which we're parsing the directive.
-  /// \param ReadDirectiveWithinMetadirective true if directive is within a
-  /// metadirective and therefore ends on the closing paren.
-  StmtResult ParseOpenMPDeclarativeOrExecutableDirective(
-      ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false);
+  /// \return \c false if this cannot possibly be an enum base; \c true
+  /// otherwise.
+  bool isEnumBase(bool AllowSemi);
 
-  /// Parses executable directive.
+  /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
+  /// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could
+  /// be either a decl-specifier or a function-style cast, and TPResult::Error
+  /// if a parsing error was found and reported.
   ///
-  /// \param StmtCtx The context in which we're parsing the directive.
-  /// \param DKind The kind of the executable directive.
-  /// \param Loc Source location of the beginning of the directive.
-  /// \param ReadDirectiveWithinMetadirective true if directive is within a
-  /// metadirective and therefore ends on the closing paren.
-  StmtResult
-  ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
-                                 OpenMPDirectiveKind DKind, SourceLocation Loc,
-                                 bool ReadDirectiveWithinMetadirective);
-
-  /// Parses informational directive.
+  /// Does not consume tokens.
   ///
-  /// \param StmtCtx The context in which we're parsing the directive.
-  /// \param DKind The kind of the informational directive.
-  /// \param Loc Source location of the beginning of the directive.
-  /// \param ReadDirectiveWithinMetadirective true if directive is within a
-  /// metadirective and therefore ends on the closing paren.
-  StmtResult ParseOpenMPInformationalDirective(
-      ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc,
-      bool ReadDirectiveWithinMetadirective);
-
-  /// Parses clause of kind \a CKind for directive of a kind \a Kind.
+  /// If InvalidAsDeclSpec is not null, some cases that would be ill-formed as
+  /// declaration specifiers but possibly valid as some other kind of construct
+  /// return TPResult::Ambiguous instead of TPResult::False. When this happens,
+  /// the intent is to keep trying to disambiguate, on the basis that we might
+  /// find a better reason to treat this construct as a declaration later on.
+  /// When this happens and the name could possibly be valid in some other
+  /// syntactic context, *InvalidAsDeclSpec is set to 'true'. The current cases
+  /// that trigger this are:
   ///
-  /// \param DKind Kind of current directive.
-  /// \param CKind Kind of current clause.
-  /// \param FirstClause true, if this is the first clause of a kind \a CKind
-  /// in current directive.
+  ///   * When parsing X::Y (with no 'typename') where X is dependent
+  ///   * When parsing X<Y> where X is undeclared
   ///
-  OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind,
-                               OpenMPClauseKind CKind, bool FirstClause);
-  /// Parses clause with a single expression of a kind \a Kind.
+  ///         decl-specifier:
+  ///           storage-class-specifier
+  ///           type-specifier
+  ///           function-specifier
+  ///           'friend'
+  ///           'typedef'
+  /// [C++11]   'constexpr'
+  /// [C++20]   'consteval'
+  /// [GNU]     attributes declaration-specifiers[opt]
   ///
-  /// \param Kind Kind of current clause.
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  /// nullptr.
+  ///         storage-class-specifier:
+  ///           'register'
+  ///           'static'
+  ///           'extern'
+  ///           'mutable'
+  ///           'auto'
+  /// [GNU]     '__thread'
+  /// [C++11]   'thread_local'
+  /// [C11]     '_Thread_local'
   ///
-  OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
-                                         bool ParseOnly);
-  /// Parses simple clause of a kind \a Kind.
+  ///         function-specifier:
+  ///           'inline'
+  ///           'virtual'
+  ///           'explicit'
   ///
-  /// \param Kind Kind of current clause.
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  /// nullptr.
+  ///         typedef-name:
+  ///           identifier
   ///
-  OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind, bool ParseOnly);
-  /// Parses indirect clause
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  // false;
-  bool ParseOpenMPIndirectClause(SemaOpenMP::DeclareTargetContextInfo &DTCI,
-                                 bool ParseOnly);
-  /// Parses clause with a single expression and an additional argument
-  /// of a kind \a Kind.
+  ///         type-specifier:
+  ///           simple-type-specifier
+  ///           class-specifier
+  ///           enum-specifier
+  ///           elaborated-type-specifier
+  ///           typename-specifier
+  ///           cv-qualifier
   ///
-  /// \param DKind Directive kind.
-  /// \param Kind Kind of current clause.
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  /// nullptr.
+  ///         simple-type-specifier:
+  ///           '::'[opt] nested-name-specifier[opt] type-name
+  ///           '::'[opt] nested-name-specifier 'template'
+  ///                 simple-template-id                              [TODO]
+  ///           'char'
+  ///           'wchar_t'
+  ///           'bool'
+  ///           'short'
+  ///           'int'
+  ///           'long'
+  ///           'signed'
+  ///           'unsigned'
+  ///           'float'
+  ///           'double'
+  ///           'void'
+  /// [GNU]     typeof-specifier
+  /// [GNU]     '_Complex'
+  /// [C++11]   'auto'
+  /// [GNU]     '__auto_type'
+  /// [C++11]   'decltype' ( expression )
+  /// [C++1y]   'decltype' ( 'auto' )
   ///
-  OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
-                                                OpenMPClauseKind Kind,
-                                                bool ParseOnly);
-
-  /// Parses the 'sizes' clause of a '#pragma omp tile' directive.
-  OMPClause *ParseOpenMPSizesClause();
-
-  /// Parses the 'permutation' clause of a '#pragma omp interchange' directive.
-  OMPClause *ParseOpenMPPermutationClause();
-
-  /// Parses clause without any additional arguments.
+  ///         type-name:
+  ///           class-name
+  ///           enum-name
+  ///           typedef-name
   ///
-  /// \param Kind Kind of current clause.
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  /// nullptr.
+  ///         elaborated-type-specifier:
+  ///           class-key '::'[opt] nested-name-specifier[opt] identifier
+  ///           class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
+  ///               simple-template-id
+  ///           'enum' '::'[opt] nested-name-specifier[opt] identifier
   ///
-  OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly = false);
-  /// Parses clause with the list of variables of a kind \a Kind.
+  ///         enum-name:
+  ///           identifier
   ///
-  /// \param Kind Kind of current clause.
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  /// nullptr.
+  ///         enum-specifier:
+  ///           'enum' identifier[opt] '{' enumerator-list[opt] '}'
+  ///           'enum' identifier[opt] '{' enumerator-list ',' '}'
   ///
-  OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
-                                      OpenMPClauseKind Kind, bool ParseOnly);
-
-  /// Parses a clause consisting of a list of expressions.
+  ///         class-specifier:
+  ///           class-head '{' member-specification[opt] '}'
   ///
-  /// \param Kind          The clause to parse.
-  /// \param ClauseNameLoc [out] The location of the clause name.
-  /// \param OpenLoc       [out] The location of '('.
-  /// \param CloseLoc      [out] The location of ')'.
-  /// \param Exprs         [out] The parsed expressions.
-  /// \param ReqIntConst   If true, each expression must be an integer constant.
+  ///         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]
   ///
-  /// \return Whether the clause was parsed successfully.
-  bool ParseOpenMPExprListClause(OpenMPClauseKind Kind,
-                                 SourceLocation &ClauseNameLoc,
-                                 SourceLocation &OpenLoc,
-                                 SourceLocation &CloseLoc,
-                                 SmallVectorImpl<Expr *> &Exprs,
-                                 bool ReqIntConst = false);
-
-  /// Parses and creates OpenMP 5.0 iterators expression:
-  /// <iterators> = 'iterator' '(' { [ <iterator-type> ] identifier =
-  /// <range-specification> }+ ')'
-  ExprResult ParseOpenMPIteratorsExpr();
-
-  /// Parses allocators and traits in the context of the uses_allocator clause.
-  /// Expected format:
-  /// '(' { <allocator> [ '(' <allocator_traits> ')' ] }+ ')'
-  OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind);
-
-  /// Parses the 'interop' parts of the 'append_args' and 'init' clauses.
-  bool ParseOMPInteropInfo(OMPInteropInfo &InteropInfo, OpenMPClauseKind Kind);
-
-  /// Parses clause with an interop variable of kind \a Kind.
+  ///         class-key:
+  ///           'class'
+  ///           'struct'
+  ///           'union'
   ///
-  /// \param Kind Kind of current clause.
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  /// nullptr.
-  //
-  OMPClause *ParseOpenMPInteropClause(OpenMPClauseKind Kind, bool ParseOnly);
-
-  /// Parses a ompx_attribute clause
+  ///         cv-qualifier:
+  ///           'const'
+  ///           'volatile'
+  /// [GNU]     restrict
   ///
-  /// \param ParseOnly true to skip the clause's semantic actions and return
-  /// nullptr.
-  //
-  OMPClause *ParseOpenMPOMPXAttributesClause(bool ParseOnly);
-
-public:
-  /// Parses simple expression in parens for single-expression clauses of OpenMP
-  /// constructs.
-  /// \param RLoc Returned location of right paren.
-  ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc,
-                                   bool IsAddressOfOperand = false);
-
-  /// Parses a reserved locator like 'omp_all_memory'.
-  bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
-                                  SemaOpenMP::OpenMPVarListDataTy &Data,
-                                  const LangOptions &LangOpts);
-  /// Parses clauses with list.
-  bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind,
-                          SmallVectorImpl<Expr *> &Vars,
-                          SemaOpenMP::OpenMPVarListDataTy &Data);
-  bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
-                          bool ObjectHadErrors, bool EnteringContext,
-                          bool AllowDestructorName, bool AllowConstructorName,
-                          bool AllowDeductionGuide,
-                          SourceLocation *TemplateKWLoc, UnqualifiedId &Result);
-
-  /// Parses the mapper modifier in map, to, and from clauses.
-  bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data);
-  /// Parses map-type-modifiers in map clause.
-  /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
-  /// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
-  bool parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data);
-
-  //===--------------------------------------------------------------------===//
-  // OpenACC Parsing.
-
-  /// Placeholder for now, should just ignore the directives after emitting a
-  /// diagnostic. Eventually will be split into a few functions to parse
-  /// different situations.
-public:
-  DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS,
-                                           ParsedAttributes &Attrs,
-                                           DeclSpec::TST TagType,
-                                           Decl *TagDecl);
-  StmtResult ParseOpenACCDirectiveStmt();
-
-private:
-  /// A struct to hold the information that got parsed by ParseOpenACCDirective,
-  /// so that the callers of it can use that to construct the appropriate AST
-  /// nodes.
-  struct OpenACCDirectiveParseInfo {
-    OpenACCDirectiveKind DirKind;
-    SourceLocation StartLoc;
-    SourceLocation DirLoc;
-    SourceLocation LParenLoc;
-    SourceLocation RParenLoc;
-    SourceLocation EndLoc;
-    SourceLocation MiscLoc;
-    OpenACCAtomicKind AtomicKind;
-    SmallVector<Expr *> Exprs;
-    SmallVector<OpenACCClause *> Clauses;
-    // TODO OpenACC: As we implement support for the Atomic, Routine, and Cache
-    // constructs, we likely want to put that information in here as well.
-  };
-
-  struct OpenACCWaitParseInfo {
-    bool Failed = false;
-    Expr *DevNumExpr = nullptr;
-    SourceLocation QueuesLoc;
-    SmallVector<Expr *> QueueIdExprs;
-
-    SmallVector<Expr *> getAllExprs() {
-      SmallVector<Expr *> Out;
-      Out.push_back(DevNumExpr);
-      llvm::append_range(Out, QueueIdExprs);
-      return Out;
-    }
-  };
-  struct OpenACCCacheParseInfo {
-    bool Failed = false;
-    SourceLocation ReadOnlyLoc;
-    SmallVector<Expr *> Vars;
-  };
-
-  /// Represents the 'error' state of parsing an OpenACC Clause, and stores
-  /// whether we can continue parsing, or should give up on the directive.
-  enum class OpenACCParseCanContinue { Cannot = 0, Can = 1 };
-
-  /// A type to represent the state of parsing an OpenACC Clause. Situations
-  /// that result in an OpenACCClause pointer are a success and can continue
-  /// parsing, however some other situations can also continue.
-  /// FIXME: This is better represented as a std::expected when we get C++23.
-  using OpenACCClauseParseResult =
-      llvm::PointerIntPair<OpenACCClause *, 1, OpenACCParseCanContinue>;
-
-  OpenACCClauseParseResult OpenACCCanContinue();
-  OpenACCClauseParseResult OpenACCCannotContinue();
-  OpenACCClauseParseResult OpenACCSuccess(OpenACCClause *Clause);
-
-  /// Parses the OpenACC directive (the entire pragma) including the clause
-  /// list, but does not produce the main AST node.
-  OpenACCDirectiveParseInfo ParseOpenACCDirective();
-  /// Helper that parses an ID Expression based on the language options.
-  ExprResult ParseOpenACCIDExpression();
-  /// Parses the variable list for the `cache` construct.
-  OpenACCCacheParseInfo ParseOpenACCCacheVarList();
-  /// Parses the 'modifier-list' for copy, copyin, copyout, create.
-  OpenACCModifierKind tryParseModifierList(OpenACCClauseKind CK);
+  TPResult
+  isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
+                            TPResult BracedCastResult = TPResult::False,
+                            bool *InvalidAsDeclSpec = nullptr);
 
-  using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
-  /// Parses a single variable in a variable list for OpenACC.
-  OpenACCVarParseResult ParseOpenACCVar(OpenACCDirectiveKind DK,
-                                        OpenACCClauseKind CK);
-  /// Parses the variable list for the variety of places that take a var-list.
-  llvm::SmallVector<Expr *> ParseOpenACCVarList(OpenACCDirectiveKind DK,
-                                                OpenACCClauseKind CK);
-  /// Parses any parameters for an OpenACC Clause, including required/optional
-  /// parens.
-  OpenACCClauseParseResult
-  ParseOpenACCClauseParams(ArrayRef<const OpenACCClause *> ExistingClauses,
-                           OpenACCDirectiveKind DirKind, OpenACCClauseKind Kind,
-                           SourceLocation ClauseLoc);
-  /// Parses a single clause in a clause-list for OpenACC. Returns nullptr on
-  /// error.
-  OpenACCClauseParseResult
-  ParseOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
-                     OpenACCDirectiveKind DirKind);
-  /// Parses the clause-list for an OpenACC directive.
-  SmallVector<OpenACCClause *>
-  ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
-  OpenACCWaitParseInfo ParseOpenACCWaitArgument(SourceLocation Loc,
-                                                bool IsDirective);
-  /// Parses the clause of the 'bind' argument, which can be a string literal or
-  /// an identifier.
-  std::variant<std::monostate, StringLiteral *, IdentifierInfo *>
-  ParseOpenACCBindClauseArgument();
+  /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
+  /// \c TPResult::Ambiguous, determine whether the decl-specifier would be
+  /// a type-specifier other than a cv-qualifier.
+  bool isCXXDeclarationSpecifierAType();
 
-  /// A type to represent the state of parsing after an attempt to parse an
-  /// OpenACC int-expr. This is useful to determine whether an int-expr list can
-  /// continue parsing after a failed int-expr.
-  using OpenACCIntExprParseResult =
-      std::pair<ExprResult, OpenACCParseCanContinue>;
-  /// Parses the clause kind of 'int-expr', which can be any integral
-  /// expression.
-  OpenACCIntExprParseResult ParseOpenACCIntExpr(OpenACCDirectiveKind DK,
-                                                OpenACCClauseKind CK,
-                                                SourceLocation Loc);
-  /// Parses the argument list for 'num_gangs', which allows up to 3
-  /// 'int-expr's.
-  bool ParseOpenACCIntExprList(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
-                               SourceLocation Loc,
-                               llvm::SmallVectorImpl<Expr *> &IntExprs);
-  /// Parses the 'device-type-list', which is a list of identifiers.
-  bool ParseOpenACCDeviceTypeList(llvm::SmallVector<IdentifierLoc> &Archs);
-  /// Parses the 'async-argument', which is an integral value with two
-  /// 'special' values that are likely negative (but come from Macros).
-  OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
-                                                      OpenACCClauseKind CK,
-                                                      SourceLocation Loc);
+  /// Determine whether we might be looking at the '<' template-argument-list '>'
+  /// of a template-id or simple-template-id, rather than a less-than comparison.
+  /// This will often fail and produce an ambiguity, but should never be wrong
+  /// if it returns True or False.
+  TPResult isTemplateArgumentList(unsigned TokensToSkip);
 
-  /// Parses the 'size-expr', which is an integral value, or an asterisk.
-  /// Asterisk is represented by a OpenACCAsteriskSizeExpr
-  ExprResult ParseOpenACCSizeExpr(OpenACCClauseKind CK);
-  /// Parses a comma delimited list of 'size-expr's.
-  bool ParseOpenACCSizeExprList(OpenACCClauseKind CK,
-                                llvm::SmallVectorImpl<Expr *> &SizeExprs);
-  /// Parses a 'gang-arg-list', used for the 'gang' clause.
-  bool ParseOpenACCGangArgList(SourceLocation GangLoc,
-                               llvm::SmallVectorImpl<OpenACCGangKind> &GKs,
-                               llvm::SmallVectorImpl<Expr *> &IntExprs);
+  /// Determine whether an '(' after an 'explicit' keyword is part of a C++20
+  /// 'explicit(bool)' declaration, in earlier language modes where that is an
+  /// extension.
+  TPResult isExplicitBool();
 
-  using OpenACCGangArgRes = std::pair<OpenACCGangKind, ExprResult>;
-  /// Parses a 'gang-arg', used for the 'gang' clause. Returns a pair of the
-  /// ExprResult (which contains the validity of the expression), plus the gang
-  /// kind for the current argument.
-  OpenACCGangArgRes ParseOpenACCGangArg(SourceLocation GangLoc);
-  /// Parses a 'condition' expr, ensuring it results in a
-  ExprResult ParseOpenACCConditionExpr();
-  DeclGroupPtrTy
-  ParseOpenACCAfterRoutineDecl(AccessSpecifier &AS, ParsedAttributes &Attrs,
-                               DeclSpec::TST TagType, Decl *TagDecl,
-                               OpenACCDirectiveParseInfo &DirInfo);
-  StmtResult ParseOpenACCAfterRoutineStmt(OpenACCDirectiveParseInfo &DirInfo);
+  /// Determine whether an identifier has been tentatively declared as a
+  /// non-type. Such tentative declarations should not be found to name a type
+  /// during a tentative parse, but also should not be annotated as a non-type.
+  bool isTentativelyDeclared(IdentifierInfo *II);
 
-private:
-  //===--------------------------------------------------------------------===//
-  // C++ 14: Templates [temp]
+  // "Tentative parsing" functions, used for disambiguation. If a parsing error
+  // is encountered they will return TPResult::Error.
+  // Returning TPResult::True/False indicates that the ambiguity was
+  // resolved and tentative parsing may stop. TPResult::Ambiguous indicates
+  // that more tentative parsing is necessary for disambiguation.
+  // They all consume tokens, so backtracking should be used after calling them.
 
-  // C++ 14.1: Template Parameters [temp.param]
-  DeclGroupPtrTy
-  ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
-                                       SourceLocation &DeclEnd,
-                                       ParsedAttributes &AccessAttrs);
-  DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
-      DeclaratorContext Context, SourceLocation &DeclEnd,
-      ParsedAttributes &AccessAttrs, AccessSpecifier AS);
-  clang::Parser::DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
-      DeclaratorContext Context, SourceLocation &DeclEnd, AccessSpecifier AS);
-  DeclGroupPtrTy ParseDeclarationAfterTemplate(
-      DeclaratorContext Context, ParsedTemplateInfo &TemplateInfo,
-      ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
-      ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none);
-  bool ParseTemplateParameters(MultiParseScope &TemplateScopes, unsigned Depth,
-                               SmallVectorImpl<NamedDecl *> &TemplateParams,
-                               SourceLocation &LAngleLoc,
-                               SourceLocation &RAngleLoc);
-  bool ParseTemplateParameterList(unsigned Depth,
-                                  SmallVectorImpl<NamedDecl*> &TemplateParams);
-  TPResult isStartOfTemplateTypeParameter();
-  NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position);
-  NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position);
-  NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
-  NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
-  bool isTypeConstraintAnnotation();
-  bool TryAnnotateTypeConstraint();
-  void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
-                                 SourceLocation CorrectLoc,
-                                 bool AlreadyHasEllipsis,
-                                 bool IdentifierHasName);
-  void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
-                                             Declarator &D);
-  // C++ 14.3: Template arguments [temp.arg]
-  typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
+  /// simple-declaration:
+  ///   decl-specifier-seq init-declarator-list[opt] ';'
+  ///
+  /// (if AllowForRangeDecl specified)
+  /// for ( for-range-declaration : for-range-initializer ) statement
+  /// for-range-declaration:
+  ///    attribute-specifier-seqopt type-specifier-seq declarator
+  ///
+  TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl);
 
-  bool ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,
-                                      SourceLocation &RAngleLoc,
-                                      bool ConsumeLastToken,
-                                      bool ObjCGenericList);
-  bool ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
-                                        SourceLocation &LAngleLoc,
-                                        TemplateArgList &TemplateArgs,
-                                        SourceLocation &RAngleLoc,
-                                        TemplateTy NameHint = nullptr);
+  /// [GNU] typeof-specifier:
+  ///         'typeof' '(' expressions ')'
+  ///         'typeof' '(' type-name ')'
+  ///
+  TPResult TryParseTypeofSpecifier();
 
-  bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
-                               CXXScopeSpec &SS,
-                               SourceLocation TemplateKWLoc,
-                               UnqualifiedId &TemplateName,
-                               bool AllowTypeAnnotation = true,
-                               bool TypeConstraint = false);
-  void
-  AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
-                                ImplicitTypenameContext AllowImplicitTypename,
-                                bool IsClassName = false);
-  bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
-                                 TemplateTy Template, SourceLocation OpenLoc);
-  ParsedTemplateArgument ParseTemplateTemplateArgument();
-  ParsedTemplateArgument ParseTemplateArgument();
-  DeclGroupPtrTy ParseExplicitInstantiation(DeclaratorContext Context,
-                                            SourceLocation ExternLoc,
-                                            SourceLocation TemplateLoc,
-                                            SourceLocation &DeclEnd,
-                                            ParsedAttributes &AccessAttrs,
-                                            AccessSpecifier AS = AS_none);
-  // C++2a: Template, concept definition [temp]
-  Decl *
-  ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
-                         SourceLocation &DeclEnd);
+  /// [ObjC] protocol-qualifiers:
+  ///         '<' identifier-list '>'
+  TPResult TryParseProtocolQualifiers();
 
-  /// Parse the given string as a type.
+  TPResult TryParsePtrOperatorSeq();
+
+  ///         operator-function-id:
+  ///           'operator' operator
   ///
-  /// This is a dangerous utility function currently employed only by API notes.
-  /// It is not a general entry-point for safely parsing types from strings.
+  ///         operator: one of
+  ///           new  delete  new[]  delete[]  +  -  *  /  %  ^  [...]
   ///
-  /// \param TypeStr The string to be parsed as a type.
-  /// \param Context The name of the context in which this string is being
-  /// parsed, which will be used in diagnostics.
-  /// \param IncludeLoc The location at which this parse was triggered.
-  TypeResult ParseTypeFromString(StringRef TypeStr, StringRef Context,
-                                 SourceLocation IncludeLoc);
+  ///         conversion-function-id:
+  ///           'operator' conversion-type-id
+  ///
+  ///         conversion-type-id:
+  ///           type-specifier-seq conversion-declarator[opt]
+  ///
+  ///         conversion-declarator:
+  ///           ptr-operator conversion-declarator[opt]
+  ///
+  ///         literal-operator-id:
+  ///           'operator' string-literal identifier
+  ///           'operator' user-defined-string-literal
+  TPResult TryParseOperatorId();
 
-  //===--------------------------------------------------------------------===//
-  // Modules
-  DeclGroupPtrTy ParseModuleDecl(Sema::ModuleImportState &ImportState);
-  Decl *ParseModuleImport(SourceLocation AtLoc,
-                          Sema::ModuleImportState &ImportState);
-  bool parseMisplacedModuleImport();
-  bool tryParseMisplacedModuleImport() {
-    tok::TokenKind Kind = Tok.getKind();
-    if (Kind == tok::annot_module_begin || Kind == tok::annot_module_end ||
-        Kind == tok::annot_module_include)
-      return parseMisplacedModuleImport();
-    return false;
-  }
+  /// Tentatively parse an init-declarator-list in order to disambiguate it from
+  /// an expression.
+  ///
+  ///       init-declarator-list:
+  ///         init-declarator
+  ///         init-declarator-list ',' init-declarator
+  ///
+  ///       init-declarator:
+  ///         declarator initializer[opt]
+  /// [GNU]   declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
+  ///
+  ///       initializer:
+  ///         brace-or-equal-initializer
+  ///         '(' expression-list ')'
+  ///
+  ///       brace-or-equal-initializer:
+  ///         '=' initializer-clause
+  /// [C++11] braced-init-list
+  ///
+  ///       initializer-clause:
+  ///         assignment-expression
+  ///         braced-init-list
+  ///
+  ///       braced-init-list:
+  ///         '{' initializer-list ','[opt] '}'
+  ///         '{' '}'
+  ///
+  TPResult TryParseInitDeclaratorList(bool MayHaveTrailingReturnType = false);
 
-  bool ParseModuleName(SourceLocation UseLoc,
-                       SmallVectorImpl<IdentifierLoc> &Path, bool IsImport);
+  ///         declarator:
+  ///           direct-declarator
+  ///           ptr-operator declarator
+  ///
+  ///         direct-declarator:
+  ///           declarator-id
+  ///           direct-declarator '(' parameter-declaration-clause ')'
+  ///                 cv-qualifier-seq[opt] exception-specification[opt]
+  ///           direct-declarator '[' constant-expression[opt] ']'
+  ///           '(' declarator ')'
+  /// [GNU]     '(' attributes declarator ')'
+  ///
+  ///         abstract-declarator:
+  ///           ptr-operator abstract-declarator[opt]
+  ///           direct-abstract-declarator
+  ///
+  ///         direct-abstract-declarator:
+  ///           direct-abstract-declarator[opt]
+  ///                 '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+  ///                 exception-specification[opt]
+  ///           direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
+  ///           '(' abstract-declarator ')'
+  /// [C++0x]   ...
+  ///
+  ///         ptr-operator:
+  ///           '*' cv-qualifier-seq[opt]
+  ///           '&'
+  /// [C++0x]   '&&'                                                        [TODO]
+  ///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
+  ///
+  ///         cv-qualifier-seq:
+  ///           cv-qualifier cv-qualifier-seq[opt]
+  ///
+  ///         cv-qualifier:
+  ///           'const'
+  ///           'volatile'
+  ///
+  ///         declarator-id:
+  ///           '...'[opt] id-expression
+  ///
+  ///         id-expression:
+  ///           unqualified-id
+  ///           qualified-id                                                [TODO]
+  ///
+  ///         unqualified-id:
+  ///           identifier
+  ///           operator-function-id
+  ///           conversion-function-id
+  ///           literal-operator-id
+  ///           '~' class-name                                              [TODO]
+  ///           '~' decltype-specifier                                      [TODO]
+  ///           template-id                                                 [TODO]
+  ///
+  TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
+                              bool mayHaveDirectInit = false,
+                              bool mayHaveTrailingReturnType = false);
 
-  //===--------------------------------------------------------------------===//
-  // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
-  ExprResult ParseTypeTrait();
+  /// parameter-declaration-clause:
+  ///   parameter-declaration-list[opt] '...'[opt]
+  ///   parameter-declaration-list ',' '...'
+  ///
+  /// parameter-declaration-list:
+  ///   parameter-declaration
+  ///   parameter-declaration-list ',' parameter-declaration
+  ///
+  /// parameter-declaration:
+  ///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
+  ///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
+  ///     '=' assignment-expression
+  ///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
+  ///     attributes[opt]
+  ///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
+  ///     attributes[opt] '=' assignment-expression
+  ///
+  TPResult TryParseParameterDeclarationClause(
+      bool *InvalidAsDeclaration = nullptr, bool VersusTemplateArg = false,
+      ImplicitTypenameContext AllowImplicitTypename =
+          ImplicitTypenameContext::No);
 
-  //===--------------------------------------------------------------------===//
-  // Embarcadero: Arary and Expression Traits
-  ExprResult ParseArrayTypeTrait();
-  ExprResult ParseExpressionTrait();
+  /// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
+  /// parsing as a function declarator.
+  /// If TryParseFunctionDeclarator fully parsed the function declarator, it will
+  /// return TPResult::Ambiguous, otherwise it will return either False() or
+  /// Error().
+  ///
+  /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
+  ///         exception-specification[opt]
+  ///
+  /// exception-specification:
+  ///   'throw' '(' type-id-list[opt] ')'
+  ///
+  TPResult TryParseFunctionDeclarator(bool MayHaveTrailingReturnType = false);
 
-  ExprResult ParseBuiltinPtrauthTypeDiscriminator();
+  // When parsing an identifier after an arrow it may be a member expression,
+  // in which case we should not annotate it as an independant expression
+  // so we just lookup that name, if it's not a type the construct is not
+  // a function declaration.
+  bool NameAfterArrowIsNonType();
+
+  /// '[' constant-expression[opt] ']'
+  ///
+  TPResult TryParseBracketDeclarator();
+
+  /// Try to consume a token sequence that we've already identified as
+  /// (potentially) starting a decl-specifier.
+  TPResult TryConsumeDeclarationSpecifier();
+
+  /// Try to skip a possibly empty sequence of 'attribute-specifier's without
+  /// full validation of the syntactic structure of attributes.
+  bool TrySkipAttributes();
 
   //===--------------------------------------------------------------------===//
-  // Preprocessor code-completion pass-through
-  void CodeCompleteDirective(bool InConditional) override;
-  void CodeCompleteInConditionalExclusion() override;
-  void CodeCompleteMacroName(bool IsDefinition) override;
-  void CodeCompletePreprocessorExpression() override;
-  void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
-                                 unsigned ArgumentIndex) override;
-  void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) override;
-  void CodeCompleteNaturalLanguage() override;
+  // C++ 7: Declarations [dcl.dcl]
 
-  class GNUAsmQualifiers {
-    unsigned Qualifiers = AQ_unspecified;
+  /// Returns true if this is a C++11 attribute-specifier. Per
+  /// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens
+  /// always introduce an attribute. In Objective-C++11, this rule does not
+  /// apply if either '[' begins a message-send.
+  ///
+  /// If Disambiguate is true, we try harder to determine whether a '[[' starts
+  /// an attribute-specifier, and return
+  /// CXX11AttributeKind::InvalidAttributeSpecifier if not.
+  ///
+  /// If OuterMightBeMessageSend is true, we assume the outer '[' is either an
+  /// Obj-C message send or the start of an attribute. Otherwise, we assume it
+  /// is not an Obj-C message send.
+  ///
+  /// C++11 [dcl.attr.grammar]:
+  ///
+  ///     attribute-specifier:
+  ///         '[' '[' attribute-list ']' ']'
+  ///         alignment-specifier
+  ///
+  ///     attribute-list:
+  ///         attribute[opt]
+  ///         attribute-list ',' attribute[opt]
+  ///         attribute '...'
+  ///         attribute-list ',' attribute '...'
+  ///
+  ///     attribute:
+  ///         attribute-token attribute-argument-clause[opt]
+  ///
+  ///     attribute-token:
+  ///         identifier
+  ///         identifier '::' identifier
+  ///
+  ///     attribute-argument-clause:
+  ///         '(' balanced-token-seq ')'
+  CXX11AttributeKind
+  isCXX11AttributeSpecifier(bool Disambiguate = false,
+                            bool OuterMightBeMessageSend = false);
 
-  public:
-    enum AQ {
-      AQ_unspecified = 0,
-      AQ_volatile    = 1,
-      AQ_inline      = 2,
-      AQ_goto        = 4,
-    };
-    static const char *getQualifierName(AQ Qualifier);
-    bool setAsmQualifier(AQ Qualifier);
-    inline bool isVolatile() const { return Qualifiers & AQ_volatile; };
-    inline bool isInline() const { return Qualifiers & AQ_inline; };
-    inline bool isGoto() const { return Qualifiers & AQ_goto; }
-  };
-  bool isGCCAsmStatement(const Token &TokAfterAsm) const;
-  bool isGNUAsmQualifier(const Token &TokAfterAsm) const;
-  GNUAsmQualifiers::AQ getGNUAsmQualifier(const Token &Tok) const;
-  bool parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ);
+  ///@}
 };
 
 }  // end namespace clang
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index e76435d0e9de7..c1141fc939f69 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -21,7 +21,6 @@
 
 using namespace clang;
 
-/// Parse the optional ("message") part of a deleted-function-body.
 StringLiteral *Parser::ParseCXXDeletedFunctionMessage() {
   if (!Tok.is(tok::l_paren))
     return nullptr;
@@ -48,9 +47,6 @@ StringLiteral *Parser::ParseCXXDeletedFunctionMessage() {
   return Message;
 }
 
-/// If we've encountered '= delete' in a context where it is ill-formed, such
-/// as in the declaration of a non-function, also skip the ("message") part if
-/// it is present to avoid issuing further diagnostics.
 void Parser::SkipDeletedFunctionBody() {
   if (!Tok.is(tok::l_paren))
     return;
@@ -64,9 +60,6 @@ void Parser::SkipDeletedFunctionBody() {
     BT.consumeClose();
 }
 
-/// ParseCXXInlineMethodDef - We parsed and verified that the specified
-/// Declarator is a well formed C++ inline method definition. Now lex its body
-/// and store its tokens for parsing after the C++ class is complete.
 NamedDecl *Parser::ParseCXXInlineMethodDef(
     AccessSpecifier AS, const ParsedAttributesView &AccessAttrs,
     ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo,
@@ -238,10 +231,6 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
   return FnD;
 }
 
-/// ParseCXXNonStaticMemberInitializer - We parsed and verified that the
-/// specified Declarator is a well formed C++ non-static data member
-/// declaration. Now lex its initializer and store its tokens for parsing
-/// after the class is complete.
 void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) {
   assert(Tok.isOneOf(tok::l_brace, tok::equal) &&
          "Current token not a '{' or '='!");
@@ -333,8 +322,6 @@ void Parser::LateParsedPragma::ParseLexedPragmas() {
   Self->ParseLexedPragma(*this);
 }
 
-/// Utility to re-enter a possibly-templated scope while parsing its
-/// late-parsed components.
 struct Parser::ReenterTemplateScopeRAII {
   Parser &P;
   MultiParseScope Scopes;
@@ -349,7 +336,6 @@ struct Parser::ReenterTemplateScopeRAII {
   }
 };
 
-/// Utility to re-enter a class scope while parsing its late-parsed components.
 struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII {
   ParsingClass &Class;
 
@@ -375,10 +361,6 @@ struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII {
   }
 };
 
-/// ParseLexedMethodDeclarations - We finished parsing the member
-/// specification of a top (non-nested) C++ class. Now go over the
-/// stack of method declarations with some parts for which parsing was
-/// delayed (such as default arguments) and parse them.
 void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
   ReenterClassScopeRAII InClassScope(*this, Class);
 
@@ -583,9 +565,6 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
   Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
 }
 
-/// ParseLexedMethodDefs - We finished parsing the member specification of a top
-/// (non-nested) C++ class. Now go over the stack of lexed methods that were
-/// collected during its parsing and parse them all.
 void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
   ReenterClassScopeRAII InClassScope(*this, Class);
 
@@ -664,9 +643,6 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
   ParseFunctionStatementBody(LM.D, FnScope);
 }
 
-/// ParseLexedMemberInitializers - We finished parsing the member specification
-/// of a top (non-nested) C++ class. Now go over the stack of lexed data member
-/// initializers that were collected during its parsing and parse them all.
 void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
   ReenterClassScopeRAII InClassScope(*this, Class);
 
@@ -734,8 +710,6 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
     ConsumeAnyToken();
 }
 
-/// Wrapper class which calls ParseLexedAttribute, after setting up the
-/// scope appropriately.
 void Parser::ParseLexedAttributes(ParsingClass &Class) {
   ReenterClassScopeRAII InClassScope(*this, Class);
 
@@ -743,7 +717,6 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) {
     LateD->ParseLexedAttributes();
 }
 
-/// Parse all attributes in LAs, and attach them to Decl D.
 void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
                                      bool EnterScope, bool OnDefinition) {
   assert(LAs.parseSoon() &&
@@ -757,11 +730,6 @@ void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
   LAs.clear();
 }
 
-/// Finish parsing an attribute for which parsing was delayed.
-/// This will be called at the end of parsing a class declaration
-/// for each LateParsedAttribute. We consume the saved tokens and
-/// create an attribute with the arguments filled in. We add this
-/// to the Attribute list for the decl.
 void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
                                  bool EnterScope, bool OnDefinition) {
   // Create a fake EOF so that attribute parsing won't go off the end of the
@@ -865,12 +833,6 @@ void Parser::ParseLexedPragma(LateParsedPragma &LP) {
   }
 }
 
-/// ConsumeAndStoreUntil - Consume and store the token at the passed token
-/// container until the token 'T' is reached (which gets
-/// consumed/stored too, if ConsumeFinalToken).
-/// If StopAtSemi is true, then we will stop early at a ';' character.
-/// Returns true if token 'T1' or 'T2' was found.
-/// NOTE: This is a specialized version of Parser::SkipUntil.
 bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
                                   CachedTokens &Toks,
                                   bool StopAtSemi, bool ConsumeFinalToken) {
@@ -953,12 +915,6 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
   }
 }
 
-/// Consume tokens and store them in the passed token container until
-/// we've passed the try keyword and constructor initializers and have consumed
-/// the opening brace of the function body. The opening brace will be consumed
-/// if and only if there was no error.
-///
-/// \return True on error.
 bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
   if (Tok.is(tok::kw_try)) {
     Toks.push_back(Tok);
@@ -1170,8 +1126,6 @@ bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
   }
 }
 
-/// Consume and store tokens from the '?' to the ':' in a conditional
-/// expression.
 bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {
   // Consume '?'.
   assert(Tok.is(tok::question));
@@ -1195,12 +1149,6 @@ bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {
   return true;
 }
 
-/// ConsumeAndStoreInitializer - Consume and store the token at the passed token
-/// container until the end of the current initializer expression (either a
-/// default argument or an in-class initializer for a non-static data member).
-///
-/// Returns \c true if we reached the end of something initializer-shaped,
-/// \c false if we bailed out.
 bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
                                         CachedInitKind CIK) {
   // We always want this function to consume at least one token if not at EOF.
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4cfb8de615f05..0771a7a118f02 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -44,11 +44,6 @@ using namespace clang;
 // C99 6.7: Declarations.
 //===----------------------------------------------------------------------===//
 
-/// ParseTypeName
-///       type-name: [C99 6.7.6]
-///         specifier-qualifier-list abstract-declarator[opt]
-///
-/// Called type-id in C++.
 TypeResult Parser::ParseTypeName(SourceRange *Range, DeclaratorContext Context,
                                  AccessSpecifier AS, Decl **OwnedType,
                                  ParsedAttributes *Attrs) {
@@ -148,20 +143,6 @@ void Parser::ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
   } while (MoreToParse);
 }
 
-/// ParseSingleGNUAttribute - Parse a single GNU attribute.
-///
-/// [GNU]  attrib:
-///          empty
-///          attrib-name
-///          attrib-name '(' identifier ')'
-///          attrib-name '(' identifier ',' nonempty-expr-list ')'
-///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
-///
-/// [GNU]  attrib-name:
-///          identifier
-///          typespec
-///          typequal
-///          storageclass
 bool Parser::ParseSingleGNUAttribute(ParsedAttributes &Attrs,
                                      SourceLocation &EndLoc,
                                      LateParsedAttrList *LateAttrs,
@@ -228,47 +209,6 @@ bool Parser::ParseSingleGNUAttribute(ParsedAttributes &Attrs,
   return false;
 }
 
-/// ParseGNUAttributes - Parse a non-empty attributes list.
-///
-/// [GNU] attributes:
-///         attribute
-///         attributes attribute
-///
-/// [GNU]  attribute:
-///          '__attribute__' '(' '(' attribute-list ')' ')'
-///
-/// [GNU]  attribute-list:
-///          attrib
-///          attribute_list ',' attrib
-///
-/// [GNU]  attrib:
-///          empty
-///          attrib-name
-///          attrib-name '(' identifier ')'
-///          attrib-name '(' identifier ',' nonempty-expr-list ')'
-///          attrib-name '(' argument-expression-list [C99 6.5.2] ')'
-///
-/// [GNU]  attrib-name:
-///          identifier
-///          typespec
-///          typequal
-///          storageclass
-///
-/// Whether an attribute takes an 'identifier' is determined by the
-/// attrib-name. GCC's behavior here is not worth imitating:
-///
-///  * In C mode, if the attribute argument list starts with an identifier
-///    followed by a ',' or an ')', and the identifier doesn't resolve to
-///    a type, it is parsed as an identifier. If the attribute actually
-///    wanted an expression, it's out of luck (but it turns out that no
-///    attributes work that way, because C constant expressions are very
-///    limited).
-///  * In C++ mode, if the attribute argument list starts with an identifier,
-///    and the attribute *wants* an identifier, it is parsed as an identifier.
-///    At block scope, any additional tokens between the identifier and the
-///    ',' or ')' are ignored, otherwise they produce a parse error.
-///
-/// We follow the C++ model, but don't allow junk after the identifier.
 void Parser::ParseGNUAttributes(ParsedAttributes &Attrs,
                                 LateParsedAttrList *LateAttrs, Declarator *D) {
   assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
@@ -697,8 +637,6 @@ unsigned Parser::ParseAttributeArgsCommon(
   return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.get().isNull());
 }
 
-/// Parse the arguments to a parameterized GNU attribute or
-/// a C++11 attribute in "gnu" namespace.
 void Parser::ParseGNUAttributeArgs(
     IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
     ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
@@ -949,12 +887,6 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
   return true;
 }
 
-/// [MS] decl-specifier:
-///             __declspec ( extended-decl-modifier-seq )
-///
-/// [MS] extended-decl-modifier-seq:
-///             extended-decl-modifier[opt]
-///             extended-decl-modifier extended-decl-modifier-seq
 void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {
   assert(getLangOpts().DeclSpecKeyword && "__declspec keyword is not enabled");
   assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
@@ -1186,14 +1118,6 @@ static bool VersionNumberSeparator(const char Separator) {
   return (Separator == '.' || Separator == '_');
 }
 
-/// Parse a version number.
-///
-/// version:
-///   simple-integer
-///   simple-integer '.' simple-integer
-///   simple-integer '_' simple-integer
-///   simple-integer '.' simple-integer '.' simple-integer
-///   simple-integer '_' simple-integer '_' simple-integer
 VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
   Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
 
@@ -1305,31 +1229,6 @@ VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {
   return VersionTuple(Major, Minor, Subminor);
 }
 
-/// Parse the contents of the "availability" attribute.
-///
-/// availability-attribute:
-///   'availability' '(' platform ',' opt-strict version-arg-list,
-///                      opt-replacement, opt-message')'
-///
-/// platform:
-///   identifier
-///
-/// opt-strict:
-///   'strict' ','
-///
-/// version-arg-list:
-///   version-arg
-///   version-arg ',' version-arg-list
-///
-/// version-arg:
-///   'introduced' '=' version
-///   'deprecated' '=' version
-///   'obsoleted' = version
-///   'unavailable'
-/// opt-replacement:
-///   'replacement' '=' <string>
-/// opt-message:
-///   'message' '=' <string>
 void Parser::ParseAvailabilityAttribute(
     IdentifierInfo &Availability, SourceLocation AvailabilityLoc,
     ParsedAttributes &attrs, SourceLocation *endLoc, IdentifierInfo *ScopeName,
@@ -1555,20 +1454,6 @@ void Parser::ParseAvailabilityAttribute(
                StrictLoc, ReplacementExpr.get(), EnvironmentLoc);
 }
 
-/// Parse the contents of the "external_source_symbol" attribute.
-///
-/// external-source-symbol-attribute:
-///   'external_source_symbol' '(' keyword-arg-list ')'
-///
-/// keyword-arg-list:
-///   keyword-arg
-///   keyword-arg ',' keyword-arg-list
-///
-/// keyword-arg:
-///   'language' '=' <string>
-///   'defined_in' '=' <string>
-///   'USR' '=' <string>
-///   'generated_declaration'
 void Parser::ParseExternalSourceSymbolAttribute(
     IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc,
     ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
@@ -1687,17 +1572,6 @@ void Parser::ParseExternalSourceSymbolAttribute(
                ScopeName, ScopeLoc, Args, std::size(Args), Form);
 }
 
-/// Parse the contents of the "objc_bridge_related" attribute.
-/// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
-/// related_class:
-///     Identifier
-///
-/// opt-class_method:
-///     Identifier: | <empty>
-///
-/// opt-instance_method:
-///     Identifier | <empty>
-///
 void Parser::ParseObjCBridgeRelatedAttribute(
     IdentifierInfo &ObjCBridgeRelated, SourceLocation ObjCBridgeRelatedLoc,
     ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
@@ -1867,14 +1741,6 @@ void Parser::ParseTypeTagForDatatypeAttribute(
     *EndLoc = T.getCloseLocation();
 }
 
-/// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
-/// of a C++11 attribute-specifier in a location where an attribute is not
-/// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
-/// situation.
-///
-/// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
-/// this doesn't appear to actually be an attribute-specifier, and the caller
-/// should try to parse it.
 bool Parser::DiagnoseProhibitedCXX11Attribute() {
   assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));
 
@@ -1901,10 +1767,6 @@ bool Parser::DiagnoseProhibitedCXX11Attribute() {
   llvm_unreachable("All cases handled above.");
 }
 
-/// We have found the opening square brackets of a C++11
-/// attribute-specifier in a location where an attribute is not permitted, but
-/// we know where the attributes ought to be written. Parse them anyway, and
-/// provide a fixit moving them to the right place.
 void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs,
                                              SourceLocation CorrectLocation) {
   assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||
@@ -1997,13 +1859,6 @@ void Parser::DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs) {
   }
 }
 
-// Usually, `__attribute__((attrib)) class Foo {} var` means that attribute
-// applies to var, not the type Foo.
-// As an exception to the rule, __declspec(align(...)) before the
-// class-key affects the type instead of the variable.
-// Also, Microsoft-style [attributes] seem to affect the type instead of the
-// variable.
-// This function moves attributes that should apply to the type off DS to Attrs.
 void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs,
                                             DeclSpec &DS, TagUseKind TUK) {
   if (TUK == TagUseKind::Reference)
@@ -2024,22 +1879,6 @@ void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs,
   }
 }
 
-/// ParseDeclaration - Parse a full 'declaration', which consists of
-/// declaration-specifiers, some number of declarators, and a semicolon.
-/// 'Context' should be a DeclaratorContext value.  This returns the
-/// location of the semicolon in DeclEnd.
-///
-///       declaration: [C99 6.7]
-///         block-declaration ->
-///           simple-declaration
-///           others                   [FIXME]
-/// [C++]   template-declaration
-/// [C++]   namespace-definition
-/// [C++]   using-directive
-/// [C++]   using-declaration
-/// [C++11/C11] static_assert-declaration
-///         others... [FIXME]
-///
 Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
                                                 SourceLocation &DeclEnd,
                                                 ParsedAttributes &DeclAttrs,
@@ -2097,27 +1936,6 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
   return Actions.ConvertDeclToDeclGroup(SingleDecl);
 }
 
-///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
-///         declaration-specifiers init-declarator-list[opt] ';'
-/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
-///             init-declarator-list ';'
-///[C90/C++]init-declarator-list ';'                             [TODO]
-/// [OMP]   threadprivate-directive
-/// [OMP]   allocate-directive                                   [TODO]
-///
-///       for-range-declaration: [C++11 6.5p1: stmt.ranged]
-///         attribute-specifier-seq[opt] type-specifier-seq declarator
-///
-/// If RequireSemi is false, this does not check for a ';' at the end of the
-/// declaration.  If it is true, it checks for and eats it.
-///
-/// If FRI is non-null, we might be parsing a for-range-declaration instead
-/// of a simple-declaration. If we find that we are, we also parse the
-/// for-range-initializer, and place it here.
-///
-/// DeclSpecStart is used when decl-specifiers are parsed before parsing
-/// the Declaration. The SourceLocation for this Decl is set to
-/// DeclSpecStart if DeclSpecStart is non-null.
 Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(
     DeclaratorContext Context, SourceLocation &DeclEnd,
     ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,
@@ -2168,8 +1986,6 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(
   return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
 }
 
-/// Returns true if this might be the start of a declarator, or a common typo
-/// for a declarator.
 bool Parser::MightBeDeclarator(DeclaratorContext Context) {
   switch (Tok.getKind()) {
   case tok::annot_cxxscope:
@@ -2234,9 +2050,6 @@ bool Parser::MightBeDeclarator(DeclaratorContext Context) {
   }
 }
 
-/// Skip until we reach something which seems like a sensible place to pick
-/// up parsing after a malformed declaration. This will sometimes stop sooner
-/// than SkipUntil(tok::r_brace) would, but will never stop later.
 void Parser::SkipMalformedDecl() {
   while (true) {
     switch (Tok.getKind()) {
@@ -2316,9 +2129,6 @@ void Parser::SkipMalformedDecl() {
   }
 }
 
-/// ParseDeclGroup - Having concluded that this is either a function
-/// definition or a group of object declarations, actually parse the
-/// result.
 Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
                                               DeclaratorContext Context,
                                               ParsedAttributes &Attrs,
@@ -2634,8 +2444,6 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
   return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
 }
 
-/// Parse an optional simple-asm-expr and attributes, and attach them to a
-/// declarator. Returns true on an error.
 bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
   // If a simple-asm-expr is present, parse it.
   if (Tok.is(tok::kw_asm)) {
@@ -2654,28 +2462,6 @@ bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {
   return false;
 }
 
-/// Parse 'declaration' after parsing 'declaration-specifiers
-/// declarator'. This method parses the remainder of the declaration
-/// (including any attributes or initializer, among other things) and
-/// finalizes the declaration.
-///
-///       init-declarator: [C99 6.7]
-///         declarator
-///         declarator '=' initializer
-/// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
-/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
-/// [C++]   declarator initializer[opt]
-///
-/// [C++] initializer:
-/// [C++]   '=' initializer-clause
-/// [C++]   '(' expression-list ')'
-/// [C++0x] '=' 'default'                                                [TODO]
-/// [C++0x] '=' 'delete'
-/// [C++0x] braced-init-list
-///
-/// According to the standard grammar, =default and =delete are function
-/// definitions, but that definitely doesn't fit with the parser here.
-///
 Decl *Parser::ParseDeclarationAfterDeclarator(
     Declarator &D, const ParsedTemplateInfo &TemplateInfo) {
   if (ParseAsmAttributesAfterDeclarator(D))
@@ -2941,12 +2727,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
   return OuterDecl ? OuterDecl : ThisDecl;
 }
 
-/// ParseSpecifierQualifierList
-///        specifier-qualifier-list:
-///          type-specifier specifier-qualifier-list[opt]
-///          type-qualifier specifier-qualifier-list[opt]
-/// [GNU]    attributes     specifier-qualifier-list[opt]
-///
 void Parser::ParseSpecifierQualifierList(
     DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,
     AccessSpecifier AS, DeclSpecContext DSC) {
@@ -3023,15 +2803,6 @@ static bool isValidAfterIdentifierInDeclarator(const Token &T) {
                    tok::colon);
 }
 
-/// ParseImplicitInt - This method is called when we have an non-typename
-/// identifier in a declspec (which normally terminates the decl spec) when
-/// the declspec has no type specifier.  In this case, the declspec is either
-/// malformed or is "implicit int" (in K&R and C89).
-///
-/// This method handles diagnosing this prettily and returns false if the
-/// declspec is done being processed.  If it recovers and thinks there may be
-/// other pieces of declspec after it, it returns true.
-///
 bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
                               ParsedTemplateInfo &TemplateInfo,
                               AccessSpecifier AS, DeclSpecContext DSC,
@@ -3258,11 +3029,6 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
   return true;
 }
 
-/// Determine the declaration specifier context from the declarator
-/// context.
-///
-/// \param Context the declarator context, which is one of the
-/// DeclaratorContext enumerator values.
 Parser::DeclSpecContext
 Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {
   switch (Context) {
@@ -3312,12 +3078,6 @@ Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {
   llvm_unreachable("Missing DeclaratorContext case");
 }
 
-/// ParseAlignArgument - Parse the argument to an alignment-specifier.
-///
-/// [C11]   type-id
-/// [C11]   constant-expression
-/// [C++0x] type-id ...[opt]
-/// [C++0x] assignment-expression ...[opt]
 ExprResult Parser::ParseAlignArgument(StringRef KWName, SourceLocation Start,
                                       SourceLocation &EllipsisLoc, bool &IsType,
                                       ParsedType &TypeResult) {
@@ -3341,14 +3101,6 @@ ExprResult Parser::ParseAlignArgument(StringRef KWName, SourceLocation Start,
   return ER;
 }
 
-/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
-/// attribute to Attrs.
-///
-/// alignment-specifier:
-/// [C11]   '_Alignas' '(' type-id ')'
-/// [C11]   '_Alignas' '(' constant-expression ')'
-/// [C++11] 'alignas' '(' type-id ...[opt] ')'
-/// [C++11] 'alignas' '(' assignment-expression ...[opt] ')'
 void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
                                      SourceLocation *EndLoc) {
   assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
@@ -3401,10 +3153,6 @@ void Parser::DistributeCLateParsedAttrs(Decl *Dcl,
   }
 }
 
-/// type-qualifier:
-///    ('__ptrauth') '(' constant-expression
-///                   (',' constant-expression)[opt]
-///                   (',' constant-expression)[opt] ')'
 void Parser::ParsePtrauthQualifier(ParsedAttributes &Attrs) {
   assert(Tok.is(tok::kw___ptrauth));
 
@@ -3440,8 +3188,6 @@ void Parser::ParsePtrauthQualifier(ParsedAttributes &Attrs) {
                                          /*IsRegularKeywordAttribute=*/false));
 }
 
-/// Bounds attributes (e.g., counted_by):
-///   AttrName '(' expression ')'
 void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName,
                                   SourceLocation AttrNameLoc,
                                   ParsedAttributes &Attrs,
@@ -3508,13 +3254,6 @@ ExprResult Parser::ParseExtIntegerArgument() {
   return ER;
 }
 
-/// Determine whether we're looking at something that might be a declarator
-/// in a simple-declaration. If it can't possibly be a declarator, maybe
-/// diagnose a missing semicolon after a prior tag definition in the decl
-/// specifier.
-///
-/// \return \c true if an error occurred and this can't be any kind of
-/// declaration.
 bool
 Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
                                               DeclSpecContext DSContext,
@@ -3619,33 +3358,6 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
   return false;
 }
 
-/// ParseDeclarationSpecifiers
-///       declaration-specifiers: [C99 6.7]
-///         storage-class-specifier declaration-specifiers[opt]
-///         type-specifier declaration-specifiers[opt]
-/// [C99]   function-specifier declaration-specifiers[opt]
-/// [C11]   alignment-specifier declaration-specifiers[opt]
-/// [GNU]   attributes declaration-specifiers[opt]
-/// [Clang] '__module_private__' declaration-specifiers[opt]
-/// [ObjC1] '__kindof' declaration-specifiers[opt]
-///
-///       storage-class-specifier: [C99 6.7.1]
-///         'typedef'
-///         'extern'
-///         'static'
-///         'auto'
-///         'register'
-/// [C++]   'mutable'
-/// [C++11] 'thread_local'
-/// [C11]   '_Thread_local'
-/// [GNU]   '__thread'
-///       function-specifier: [C99 6.7.4]
-/// [C99]   'inline'
-/// [C++]   'virtual'
-/// [C++]   'explicit'
-/// [OpenCL] '__kernel'
-///       'friend': [C++ dcl.friend]
-///       'constexpr': [C++0x dcl.constexpr]
 void Parser::ParseDeclarationSpecifiers(
     DeclSpec &DS, ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,
     DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
@@ -4975,27 +4687,6 @@ static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS,
   }
 }
 
-/// ParseStructDeclaration - Parse a struct declaration without the terminating
-/// semicolon.
-///
-/// Note that a struct declaration refers to a declaration in a struct,
-/// not to the declaration of a struct.
-///
-///       struct-declaration:
-/// [C23]   attributes-specifier-seq[opt]
-///           specifier-qualifier-list struct-declarator-list
-/// [GNU]   __extension__ struct-declaration
-/// [GNU]   specifier-qualifier-list
-///       struct-declarator-list:
-///         struct-declarator
-///         struct-declarator-list ',' struct-declarator
-/// [GNU]   struct-declarator-list ',' attributes[opt] struct-declarator
-///       struct-declarator:
-///         declarator
-/// [GNU]   declarator attributes[opt]
-///         declarator[opt] ':' constant-expression
-/// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
-///
 void Parser::ParseStructDeclaration(
     ParsingDeclSpec &DS,
     llvm::function_ref<Decl *(ParsingFieldDeclarator &)> FieldsCallback,
@@ -5099,11 +4790,6 @@ void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs, bool EnterScope,
   LAs.clear();
 }
 
-/// Finish parsing an attribute for which parsing was delayed.
-/// This will be called at the end of parsing a class declaration
-/// for each LateParsedAttribute. We consume the saved tokens and
-/// create an attribute with the arguments filled in. We add this
-/// to the Attribute list for the decl.
 void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
                                   ParsedAttributes *OutAttrs) {
   // Create a fake EOF so that attribute parsing won't go off the end of the
@@ -5153,16 +4839,6 @@ void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
   }
 }
 
-/// ParseStructUnionBody
-///       struct-contents:
-///         struct-declaration-list
-/// [EXT]   empty
-/// [GNU]   "struct-declaration-list" without terminating ';'
-///       struct-declaration-list:
-///         struct-declaration
-///         struct-declaration-list struct-declaration
-/// [OBC]   '@' 'defs' '(' class-name ')'
-///
 void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
                                   DeclSpec::TST TagType, RecordDecl *TagDecl) {
   PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
@@ -5299,36 +4975,6 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
   Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());
 }
 
-/// ParseEnumSpecifier
-///       enum-specifier: [C99 6.7.2.2]
-///         'enum' identifier[opt] '{' enumerator-list '}'
-///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
-/// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ',' [opt]
-///                                                 '}' attributes[opt]
-/// [MS]    'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
-///                                                 '}'
-///         'enum' identifier
-/// [GNU]   'enum' attributes[opt] identifier
-///
-/// [C++11] enum-head '{' enumerator-list[opt] '}'
-/// [C++11] enum-head '{' enumerator-list ','  '}'
-///
-///       enum-head: [C++11]
-///         enum-key attribute-specifier-seq[opt] identifier[opt] enum-base[opt]
-///         enum-key attribute-specifier-seq[opt] nested-name-specifier
-///             identifier enum-base[opt]
-///
-///       enum-key: [C++11]
-///         'enum'
-///         'enum' 'class'
-///         'enum' 'struct'
-///
-///       enum-base: [C++11]
-///         ':' type-specifier-seq
-///
-/// [C++] elaborated-type-specifier:
-/// [C++]   'enum' nested-name-specifier[opt] identifier
-///
 void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
                                 const ParsedTemplateInfo &TemplateInfo,
                                 AccessSpecifier AS, DeclSpecContext DSC) {
@@ -5712,16 +5358,6 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
-/// ParseEnumBody - Parse a {} enclosed enumerator-list.
-///       enumerator-list:
-///         enumerator
-///         enumerator-list ',' enumerator
-///       enumerator:
-///         enumeration-constant attributes[opt]
-///         enumeration-constant attributes[opt] '=' constant-expression
-///       enumeration-constant:
-///         identifier
-///
 void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl,
                            SkipBodyInfo *SkipBody) {
   // Enter the scope of the enum body and start the definition.
@@ -5860,9 +5496,6 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl,
   }
 }
 
-/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
-/// is definitely a type-specifier.  Return false if it isn't part of a type
-/// specifier or if we're not sure.
 bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
   switch (Tok.getKind()) {
   default: return false;
@@ -5918,8 +5551,6 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
   }
 }
 
-/// isTypeSpecifierQualifier - Return true if the current token could be the
-/// start of a specifier-qualifier-list.
 bool Parser::isTypeSpecifierQualifier() {
   switch (Tok.getKind()) {
   default: return false;
@@ -6098,13 +5729,6 @@ Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() {
   return Actions.BuildDeclaratorGroup(DeclsInGroup);
 }
 
-/// isDeclarationSpecifier() - Return true if the current token is part of a
-/// declaration specifier.
-///
-/// \param AllowImplicitTypename whether this is a context where T::type [T
-/// dependent] can appear.
-/// \param DisambiguatingWithExpression True to indicate that the purpose of
-/// this check is to disambiguate between an expression and a declaration.
 bool Parser::isDeclarationSpecifier(
     ImplicitTypenameContext AllowImplicitTypename,
     bool DisambiguatingWithExpression) {
@@ -6498,18 +6122,6 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
   return IsConstructor;
 }
 
-/// ParseTypeQualifierListOpt
-///          type-qualifier-list: [C99 6.7.5]
-///            type-qualifier
-/// [vendor]   attributes
-///              [ only if AttrReqs & AR_VendorAttributesParsed ]
-///            type-qualifier-list type-qualifier
-/// [vendor]   type-qualifier-list attributes
-///              [ only if AttrReqs & AR_VendorAttributesParsed ]
-/// [C++0x]    attribute-specifier[opt] is allowed before cv-qualifier-seq
-///              [ only if AttReqs & AR_CXX11AttributesParsed ]
-/// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
-/// AttrRequirements bitmask values.
 void Parser::ParseTypeQualifierListOpt(
     DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed,
     bool IdentifierRequired,
@@ -6677,7 +6289,6 @@ void Parser::ParseTypeQualifierListOpt(
   }
 }
 
-/// ParseDeclarator - Parse and verify a newly-initialized declarator.
 void Parser::ParseDeclarator(Declarator &D) {
   /// This implements the 'declarator' production in the C grammar, then checks
   /// for well-formedness and issues diagnostics.
@@ -6725,31 +6336,6 @@ static bool isPipeDeclarator(const Declarator &D) {
   return false;
 }
 
-/// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
-/// is parsed by the function passed to it. Pass null, and the direct-declarator
-/// isn't parsed at all, making this function effectively parse the C++
-/// ptr-operator production.
-///
-/// If the grammar of this construct is extended, matching changes must also be
-/// made to TryParseDeclarator and MightBeDeclarator, and possibly to
-/// isConstructorDeclarator.
-///
-///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
-/// [C]     pointer[opt] direct-declarator
-/// [C++]   direct-declarator
-/// [C++]   ptr-operator declarator
-///
-///       pointer: [C99 6.7.5]
-///         '*' type-qualifier-list[opt]
-///         '*' type-qualifier-list[opt] pointer
-///
-///       ptr-operator:
-///         '*' cv-qualifier-seq[opt]
-///         '&'
-/// [C++0x] '&&'
-/// [GNU]   '&' restrict[opt] attributes[opt]
-/// [GNU?]  '&&' restrict[opt] attributes[opt]
-///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
 void Parser::ParseDeclaratorInternal(Declarator &D,
                                      DirectDeclParseFunction DirectDeclParser) {
   if (Diags.hasAllExtensionsSilenced())
@@ -6950,52 +6536,6 @@ static SourceLocation getMissingDeclaratorIdLoc(Declarator &D,
   return Loc;
 }
 
-/// ParseDirectDeclarator
-///       direct-declarator: [C99 6.7.5]
-/// [C99]   identifier
-///         '(' declarator ')'
-/// [GNU]   '(' attributes declarator ')'
-/// [C90]   direct-declarator '[' constant-expression[opt] ']'
-/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
-/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
-/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
-/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
-/// [C++11] direct-declarator '[' constant-expression[opt] ']'
-///                    attribute-specifier-seq[opt]
-///         direct-declarator '(' parameter-type-list ')'
-///         direct-declarator '(' identifier-list[opt] ')'
-/// [GNU]   direct-declarator '(' parameter-forward-declarations
-///                    parameter-type-list[opt] ')'
-/// [C++]   direct-declarator '(' parameter-declaration-clause ')'
-///                    cv-qualifier-seq[opt] exception-specification[opt]
-/// [C++11] direct-declarator '(' parameter-declaration-clause ')'
-///                    attribute-specifier-seq[opt] cv-qualifier-seq[opt]
-///                    ref-qualifier[opt] exception-specification[opt]
-/// [C++]   declarator-id
-/// [C++11] declarator-id attribute-specifier-seq[opt]
-///
-///       declarator-id: [C++ 8]
-///         '...'[opt] id-expression
-///         '::'[opt] nested-name-specifier[opt] type-name
-///
-///       id-expression: [C++ 5.1]
-///         unqualified-id
-///         qualified-id
-///
-///       unqualified-id: [C++ 5.1]
-///         identifier
-///         operator-function-id
-///         conversion-function-id
-///          '~' class-name
-///         template-id
-///
-/// C++17 adds the following, which we also handle here:
-///
-///       simple-declaration:
-///         <decl-spec> '[' identifier-list ']' brace-or-equal-initializer ';'
-///
-/// Note, any additional constructs added here may need corresponding changes
-/// in isConstructorDeclarator.
 void Parser::ParseDirectDeclarator(Declarator &D) {
   DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
 
@@ -7470,19 +7010,6 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) {
                                     T.getCloseLocation());
 }
 
-/// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
-/// only called before the identifier, so these are most likely just grouping
-/// parens for precedence.  If we find that these are actually function
-/// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
-///
-///       direct-declarator:
-///         '(' declarator ')'
-/// [GNU]   '(' attributes declarator ')'
-///         direct-declarator '(' parameter-type-list ')'
-///         direct-declarator '(' identifier-list[opt] ')'
-/// [GNU]   direct-declarator '(' parameter-forward-declarations
-///                    parameter-type-list[opt] ')'
-///
 void Parser::ParseParenDeclarator(Declarator &D) {
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
@@ -7625,26 +7152,6 @@ void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
                     IsCXX11MemberFunction);
 }
 
-/// ParseFunctionDeclarator - We are after the identifier and have parsed the
-/// declarator D up to a paren, which indicates that we are parsing function
-/// arguments.
-///
-/// If FirstArgAttrs is non-null, then the caller parsed those attributes
-/// immediately after the open paren - they will be applied to the DeclSpec
-/// of the first parameter.
-///
-/// If RequiresArg is true, then the first argument of the function is required
-/// to be present and required to not be an identifier list.
-///
-/// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
-/// (C++11) ref-qualifier[opt], exception-specification[opt],
-/// (C++11) attribute-specifier-seq[opt], (C++11) trailing-return-type[opt] and
-/// (C++2a) the trailing requires-clause.
-///
-/// [C++11] exception-specification:
-///           dynamic-exception-specification
-///           noexcept-specification
-///
 void Parser::ParseFunctionDeclarator(Declarator &D,
                                      ParsedAttributes &FirstArgAttrs,
                                      BalancedDelimiterTracker &Tracker,
@@ -7841,8 +7348,6 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
                 std::move(FnAttrs), EndLoc);
 }
 
-/// ParseRefQualifier - Parses a member function ref-qualifier. Returns
-/// true if a ref-qualifier is found.
 bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,
                                SourceLocation &RefQualifierLoc) {
   if (Tok.isOneOf(tok::amp, tok::ampamp)) {
@@ -7857,11 +7362,6 @@ bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,
   return false;
 }
 
-/// isFunctionDeclaratorIdentifierList - This parameter list may have an
-/// identifier list form for a K&R-style function:  void foo(a,b,c)
-///
-/// Note that identifier-lists are only allowed for normal declarators, not for
-/// abstract-declarators.
 bool Parser::isFunctionDeclaratorIdentifierList() {
   return !getLangOpts().requiresStrictPrototypes()
          && Tok.is(tok::identifier)
@@ -7885,15 +7385,6 @@ bool Parser::isFunctionDeclaratorIdentifierList() {
              (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)));
 }
 
-/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
-/// we found a K&R-style identifier list instead of a typed parameter list.
-///
-/// After returning, ParamInfo will hold the parsed parameters.
-///
-///       identifier-list: [C99 6.7.5]
-///         identifier
-///         identifier-list ',' identifier
-///
 void Parser::ParseFunctionDeclaratorIdentifierList(
        Declarator &D,
        SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {
@@ -7943,38 +7434,6 @@ void Parser::ParseFunctionDeclaratorIdentifierList(
   } while (TryConsumeToken(tok::comma));
 }
 
-/// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
-/// after the opening parenthesis. This function will not parse a K&R-style
-/// identifier list.
-///
-/// DeclContext is the context of the declarator being parsed.  If FirstArgAttrs
-/// is non-null, then the caller parsed those attributes immediately after the
-/// open paren - they will be applied to the DeclSpec of the first parameter.
-///
-/// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
-/// be the location of the ellipsis, if any was parsed.
-///
-///       parameter-type-list: [C99 6.7.5]
-///         parameter-list
-///         parameter-list ',' '...'
-/// [C++]   parameter-list '...'
-///
-///       parameter-list: [C99 6.7.5]
-///         parameter-declaration
-///         parameter-list ',' parameter-declaration
-///
-///       parameter-declaration: [C99 6.7.5]
-///         declaration-specifiers declarator
-/// [C++]   declaration-specifiers declarator '=' assignment-expression
-/// [C++11]                                       initializer-clause
-/// [GNU]   declaration-specifiers declarator attributes
-///         declaration-specifiers abstract-declarator[opt]
-/// [C++]   declaration-specifiers abstract-declarator[opt]
-///           '=' assignment-expression
-/// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
-/// [C++11] attribute-specifier-seq parameter-declaration
-/// [C++2b] attribute-specifier-seq 'this' parameter-declaration
-///
 void Parser::ParseParameterDeclarationClause(
     DeclaratorContext DeclaratorCtx, ParsedAttributes &FirstArgAttrs,
     SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
@@ -8253,13 +7712,6 @@ void Parser::ParseParameterDeclarationClause(
   } while (TryConsumeToken(tok::comma));
 }
 
-/// [C90]   direct-declarator '[' constant-expression[opt] ']'
-/// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
-/// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
-/// [C99]   direct-declarator '[' type-qual-list 'static' assignment-expr ']'
-/// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
-/// [C++11] direct-declarator '[' constant-expression[opt] ']'
-///                           attribute-specifier-seq[opt]
 void Parser::ParseBracketDeclarator(Declarator &D) {
   if (CheckProhibitedCXX11Attribute())
     return;
@@ -8375,7 +7827,6 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
       std::move(DS.getAttributes()), T.getCloseLocation());
 }
 
-/// Diagnose brackets before an identifier.
 void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
   assert(Tok.is(tok::l_square) && "Missing opening bracket");
   assert(!D.mayOmitIdentifier() && "Declarator cannot omit identifier");
@@ -8464,18 +7915,6 @@ void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
   }
 }
 
-/// [GNU]   typeof-specifier:
-///           typeof ( expressions )
-///           typeof ( type-name )
-/// [GNU/C++] typeof unary-expression
-/// [C23]   typeof-specifier:
-///           typeof '(' typeof-specifier-argument ')'
-///           typeof_unqual '(' typeof-specifier-argument ')'
-///
-///         typeof-specifier-argument:
-///           expression
-///           type-name
-///
 void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
   assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
          "Not a typeof specifier");
@@ -8549,9 +7988,6 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
-/// [C11]   atomic-specifier:
-///           _Atomic ( type-name )
-///
 void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
   assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) &&
          "Not an atomic specifier");
@@ -8584,8 +8020,6 @@ void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
-/// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
-/// from TryAltiVecVectorToken.
 bool Parser::TryAltiVecVectorTokenOutOfLine() {
   Token Next = NextToken();
   switch (Next.getKind()) {
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 7e0a8af07a3be..822e2ed7f0a5e 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -34,33 +34,6 @@
 
 using namespace clang;
 
-/// 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) {
@@ -250,7 +223,6 @@ Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,
                                         ImplicitUsingDirectiveDecl);
 }
 
-/// ParseInnerNamespace - Parse the contents of a namespace.
 void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
                                  unsigned int index, SourceLocation &InlineLoc,
                                  ParsedAttributes &attrs,
@@ -289,9 +261,6 @@ void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
   Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation());
 }
 
-/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
-/// alias definition.
-///
 Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
                                   SourceLocation AliasLoc,
                                   IdentifierInfo *Alias,
@@ -343,13 +312,6 @@ Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
                                         Alias, SS, IdentLoc, Ident);
 }
 
-/// 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) {
   assert(isTokenStringLiteral() && "Not a string literal!");
   ExprResult Lang = ParseUnevaluatedStringLiteralExpression();
@@ -434,20 +396,6 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
                      : nullptr;
 }
 
-/// 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() {
   assert(Tok.is(tok::kw_export));
   SourceLocation ExportLoc = ConsumeToken();
@@ -492,8 +440,6 @@ Decl *Parser::ParseExportDeclaration() {
                                        T.getCloseLocation());
 }
 
-/// 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) {
@@ -534,16 +480,6 @@ Parser::DeclGroupPtrTy Parser::ParseUsingDirectiveOrDeclaration(
                                AS_none);
 }
 
-/// 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,
@@ -610,11 +546,6 @@ Decl *Parser::ParseUsingDirective(DeclaratorContext Context,
                                      IdentLoc, NamespcName, 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) {
   D.clear();
@@ -685,29 +616,6 @@ bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
   return false;
 }
 
-/// 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,
@@ -1012,14 +920,6 @@ static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr,
   return FixItHint::CreateInsertion(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) {
   assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
          "Not a static_assert declaration");
@@ -1121,11 +1021,6 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
                                               T.getCloseLocation());
 }
 
-/// ParseDecltypeSpecifier - Parse a C++11 decltype specifier.
-///
-/// 'decltype' ( expression )
-/// 'decltype' ( 'auto' )      [C++1y]
-///
 SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
   assert(Tok.isOneOf(tok::kw_decltype, tok::annot_decltype) &&
          "Not a decltype specifier");
@@ -1391,24 +1286,6 @@ bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {
   return true;
 }
 
-/// 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) {
   // Ignore attempts to use typename
@@ -1569,9 +1446,6 @@ 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) {
   // This switch enumerates the valid "follow" set for type-specifiers.
   switch (Tok.getKind()) {
@@ -1672,46 +1546,6 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
   return false;
 }
 
-/// 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,
@@ -2409,13 +2243,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
   }
 }
 
-/// 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) {
   assert(Tok.is(tok::colon) && "Not a base clause");
   ConsumeToken();
@@ -2445,17 +2272,6 @@ void Parser::ParseBaseClause(Decl *ClassDecl) {
   Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo);
 }
 
-/// 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) {
   bool IsVirtual = false;
   SourceLocation StartLoc = Tok.getLocation();
@@ -2529,13 +2345,6 @@ BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
                                     EllipsisLoc);
 }
 
-/// getAccessSpecifierIfPresent - Determine whether the next token is
-/// a C++ access-specifier.
-///
-///       access-specifier: [C++ class.derived]
-///         'private'
-///         'protected'
-///         'public'
 AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
   switch (Tok.getKind()) {
   default:
@@ -2549,10 +2358,6 @@ 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) {
   DeclaratorChunk::FunctionTypeInfo &FTI = DeclaratorInfo.getFunctionTypeInfo();
@@ -2594,13 +2399,6 @@ void Parser::HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo,
   }
 }
 
-/// 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 {
   if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier))
     return VirtSpecifiers::VS_None;
@@ -2637,11 +2435,6 @@ VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
   return VirtSpecifiers::VS_None;
 }
 
-/// 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) {
@@ -2687,8 +2480,6 @@ void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
   }
 }
 
-/// isCXX11FinalKeyword - Determine whether the next token is a C++11
-/// 'final' or Microsoft 'sealed' contextual keyword.
 bool Parser::isCXX11FinalKeyword() const {
   VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
   return Specifier == VirtSpecifiers::VS_Final ||
@@ -2696,8 +2487,6 @@ bool Parser::isCXX11FinalKeyword() const {
          Specifier == VirtSpecifiers::VS_Sealed;
 }
 
-/// isClassCompatibleKeyword - Determine whether the next token is a C++11
-/// 'final' or Microsoft 'sealed' or 'abstract' contextual keywords.
 bool Parser::isClassCompatibleKeyword() const {
   VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
   return Specifier == VirtSpecifiers::VS_Final ||
@@ -2706,8 +2495,6 @@ bool Parser::isClassCompatibleKeyword() const {
          Specifier == VirtSpecifiers::VS_Abstract;
 }
 
-/// 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) {
@@ -2793,8 +2580,6 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
   return false;
 }
 
-/// Look for declaration specifiers possibly occurring after C++11
-/// virt-specifier-seq and diagnose them.
 void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
     Declarator &D, VirtSpecifiers &VS) {
   DeclSpec DS(AttrFactory);
@@ -2848,56 +2633,6 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
   }
 }
 
-/// 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) {
@@ -3506,26 +3241,6 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
   return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
 }
 
-/// 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) {
   assert(Tok.isOneOf(tok::equal, tok::l_brace) &&
@@ -3747,12 +3462,6 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
   }
 }
 
-/// 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,
@@ -4020,27 +3729,6 @@ void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {
   Tok.setKind(tok::r_brace);
 }
 
-/// 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) {
   assert(Tok.is(tok::colon) &&
          "Constructor initializer always starts with ':'");
@@ -4092,18 +3780,6 @@ void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
                                AnyErrors);
 }
 
-/// 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 '::'[opt] nested-name-specifier[opt]
   CXXScopeSpec SS;
@@ -4215,15 +3891,6 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
     return Diag(Tok, diag::err_expected) << tok::l_paren;
 }
 
-/// 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,
@@ -4343,17 +4010,6 @@ static void diagnoseDynamicExceptionSpecification(Parser &P, SourceRange Range,
   }
 }
 
-/// 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) {
@@ -4410,8 +4066,6 @@ ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
   return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
 }
 
-/// ParseTrailingReturnType - Parse a trailing return type on a new-style
-/// function declaration.
 TypeResult Parser::ParseTrailingReturnType(SourceRange &Range,
                                            bool MayBeFollowedByDirectInit) {
   assert(Tok.is(tok::arrow) && "expected arrow");
@@ -4423,7 +4077,6 @@ TypeResult Parser::ParseTrailingReturnType(SourceRange &Range,
                                    : DeclaratorContext::TrailingReturn);
 }
 
-/// Parse a requires-clause as part of a function declaration.
 void Parser::ParseTrailingRequiresClause(Declarator &D) {
   assert(Tok.is(tok::kw_requires) && "expected requires");
 
@@ -4497,9 +4150,6 @@ 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) {
@@ -4509,20 +4159,12 @@ Sema::ParsingClassState Parser::PushParsingClass(Decl *ClassDecl,
   return Actions.PushParsingClass();
 }
 
-/// Deallocate the given parsed class and all of its nested
-/// classes.
 void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
   for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
     delete Class->LateParsedDeclarations[I];
   delete 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) {
   assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
 
@@ -4556,15 +4198,6 @@ void Parser::PopParsingClass(Sema::ParsingClassState state) {
       new LateParsedClass(this, Victim));
 }
 
-/// 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) {
@@ -4718,7 +4351,6 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
   }
 }
 
-/// Parse the argument to C++23's [[assume()]] attribute.
 bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
                                         IdentifierInfo *AttrName,
                                         SourceLocation AttrNameLoc,
@@ -4774,20 +4406,6 @@ bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
   return false;
 }
 
-/// 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,
@@ -4886,30 +4504,6 @@ bool Parser::ParseCXX11AttributeArgs(
   return true;
 }
 
-/// 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) {
@@ -5064,10 +4658,6 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
     SkipUntil(tok::r_square);
 }
 
-/// ParseCXX11Attributes - Parse a C++11 or C23 attribute-specifier-seq.
-///
-/// attribute-specifier-seq:
-///       attribute-specifier-seq[opt] attribute-specifier
 void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) {
   SourceLocation StartLoc = Tok.getLocation();
   SourceLocation EndLoc = StartLoc;
@@ -5125,7 +4715,6 @@ SourceLocation Parser::SkipCXX11Attributes() {
   return EndLoc;
 }
 
-/// Parse uuid() attribute when it appears in a [] Microsoft attribute.
 void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {
   assert(Tok.is(tok::identifier) && "Not a Microsoft attribute list");
   IdentifierInfo *UuidIdent = Tok.getIdentifierInfo();
@@ -5210,14 +4799,6 @@ 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) {
   assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
 
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 4b5d677f4ba87..11cfbbe790418 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -43,113 +43,17 @@
 #include <optional>
 using namespace clang;
 
-/// Simple precedence-based parser for binary/ternary operators.
-///
-/// Note: we diverge from the C99 grammar when parsing the assignment-expression
-/// production.  C99 specifies that the LHS of an assignment operator should be
-/// parsed as a unary-expression, but consistency dictates that it be a
-/// conditional-expession.  In practice, the important thing here is that the
-/// LHS of an assignment has to be an l-value, which productions between
-/// unary-expression and conditional-expression don't produce.  Because we want
-/// consistency, we parse the LHS as a conditional-expression, then check for
-/// l-value-ness in semantic analysis stages.
-///
-/// \verbatim
-///       pm-expression: [C++ 5.5]
-///         cast-expression
-///         pm-expression '.*' cast-expression
-///         pm-expression '->*' cast-expression
-///
-///       multiplicative-expression: [C99 6.5.5]
-///     Note: in C++, apply pm-expression instead of cast-expression
-///         cast-expression
-///         multiplicative-expression '*' cast-expression
-///         multiplicative-expression '/' cast-expression
-///         multiplicative-expression '%' cast-expression
-///
-///       additive-expression: [C99 6.5.6]
-///         multiplicative-expression
-///         additive-expression '+' multiplicative-expression
-///         additive-expression '-' multiplicative-expression
-///
-///       shift-expression: [C99 6.5.7]
-///         additive-expression
-///         shift-expression '<<' additive-expression
-///         shift-expression '>>' additive-expression
-///
-///       compare-expression: [C++20 expr.spaceship]
-///         shift-expression
-///         compare-expression '<=>' shift-expression
-///
-///       relational-expression: [C99 6.5.8]
-///         compare-expression
-///         relational-expression '<' compare-expression
-///         relational-expression '>' compare-expression
-///         relational-expression '<=' compare-expression
-///         relational-expression '>=' compare-expression
-///
-///       equality-expression: [C99 6.5.9]
-///         relational-expression
-///         equality-expression '==' relational-expression
-///         equality-expression '!=' relational-expression
-///
-///       AND-expression: [C99 6.5.10]
-///         equality-expression
-///         AND-expression '&' equality-expression
-///
-///       exclusive-OR-expression: [C99 6.5.11]
-///         AND-expression
-///         exclusive-OR-expression '^' AND-expression
-///
-///       inclusive-OR-expression: [C99 6.5.12]
-///         exclusive-OR-expression
-///         inclusive-OR-expression '|' exclusive-OR-expression
-///
-///       logical-AND-expression: [C99 6.5.13]
-///         inclusive-OR-expression
-///         logical-AND-expression '&&' inclusive-OR-expression
-///
-///       logical-OR-expression: [C99 6.5.14]
-///         logical-AND-expression
-///         logical-OR-expression '||' logical-AND-expression
-///
-///       conditional-expression: [C99 6.5.15]
-///         logical-OR-expression
-///         logical-OR-expression '?' expression ':' conditional-expression
-/// [GNU]   logical-OR-expression '?' ':' conditional-expression
-/// [C++] the third operand is an assignment-expression
-///
-///       assignment-expression: [C99 6.5.16]
-///         conditional-expression
-///         unary-expression assignment-operator assignment-expression
-/// [C++]   throw-expression [C++ 15]
-///
-///       assignment-operator: one of
-///         = *= /= %= += -= <<= >>= &= ^= |=
-///
-///       expression: [C99 6.5.17]
-///         assignment-expression ...[opt]
-///         expression ',' assignment-expression ...[opt]
-/// \endverbatim
 ExprResult Parser::ParseExpression(TypeCastState isTypeCast) {
   ExprResult LHS(ParseAssignmentExpression(isTypeCast));
   return ParseRHSOfBinaryExpression(LHS, prec::Comma);
 }
 
-/// This routine is called when the '@' is seen and consumed.
-/// Current token is an Identifier and is not a 'try'. This
-/// routine is necessary to disambiguate \@try-statement from,
-/// for example, \@encode-expression.
-///
 ExprResult
 Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
   ExprResult LHS(ParseObjCAtExpression(AtLoc));
   return ParseRHSOfBinaryExpression(LHS, prec::Comma);
 }
 
-/// This routine is called when a leading '__extension__' is seen and
-/// consumed.  This is necessary because the token gets consumed in the
-/// process of disambiguating between an expression and a declaration.
 ExprResult
 Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
   ExprResult LHS(true);
@@ -167,7 +71,6 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
   return ParseRHSOfBinaryExpression(LHS, prec::Comma);
 }
 
-/// Parse an expr that doesn't include (top-level) commas.
 ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
   if (Tok.is(tok::code_completion)) {
     cutOffParsing();
@@ -201,15 +104,6 @@ ExprResult Parser::ParseConditionalExpression() {
   return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
 }
 
-/// Parse an assignment expression where part of an Objective-C message
-/// send has already been parsed.
-///
-/// In this case \p LBracLoc indicates the location of the '[' of the message
-/// send, and either \p ReceiverName or \p ReceiverExpr is non-null indicating
-/// the receiver of the message.
-///
-/// Since this handles full assignment-expression's, it handles postfix
-/// expressions and other binary operators for these expressions as well.
 ExprResult
 Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
                                                     SourceLocation SuperLoc,
@@ -281,12 +175,6 @@ ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) {
   return Actions.ActOnCaseExpr(CaseLoc, Res);
 }
 
-/// Parse a constraint-expression.
-///
-/// \verbatim
-///       constraint-expression: C++2a[temp.constr.decl]p1
-///         logical-or-expression
-/// \endverbatim
 ExprResult Parser::ParseConstraintExpression() {
   EnterExpressionEvaluationContext ConstantEvaluated(
       Actions, Sema::ExpressionEvaluationContext::Unevaluated);
@@ -299,15 +187,6 @@ ExprResult Parser::ParseConstraintExpression() {
   return Res;
 }
 
-/// \brief Parse a constraint-logical-and-expression.
-///
-/// \verbatim
-///       C++2a[temp.constr.decl]p1
-///       constraint-logical-and-expression:
-///         primary-expression
-///         constraint-logical-and-expression '&&' primary-expression
-///
-/// \endverbatim
 ExprResult
 Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) {
   EnterExpressionEvaluationContext ConstantEvaluated(
@@ -390,16 +269,6 @@ Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) {
   return LHS;
 }
 
-/// \brief Parse a constraint-logical-or-expression.
-///
-/// \verbatim
-///       C++2a[temp.constr.decl]p1
-///       constraint-logical-or-expression:
-///         constraint-logical-and-expression
-///         constraint-logical-or-expression '||'
-///             constraint-logical-and-expression
-///
-/// \endverbatim
 ExprResult
 Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) {
   ExprResult LHS(ParseConstraintLogicalAndExpression(IsTrailingRequiresClause));
@@ -445,8 +314,6 @@ bool Parser::isFoldOperator(tok::TokenKind Kind) const {
   return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true));
 }
 
-/// Parse a binary expression that starts with \p LHS and has a
-/// precedence of at least \p MinPrec.
 ExprResult
 Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
   prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
@@ -717,12 +584,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
   }
 }
 
-/// Parse a cast-expression, unary-expression or primary-expression, based
-/// on \p ExprType.
-///
-/// \p isAddressOfOperand exists because an id-expression that is the
-/// operand of address-of gets special treatment due to member pointers.
-///
 ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
                                        bool isAddressOfOperand,
                                        TypeCastState isTypeCast,
@@ -881,191 +742,6 @@ ExprResult Parser::ParseBuiltinPtrauthTypeDiscriminator() {
       /*isType=*/true, Ty.get().getAsOpaquePtr(), SourceRange(Loc, EndLoc));
 }
 
-/// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
-/// a unary-expression.
-///
-/// \p isAddressOfOperand exists because an id-expression that is the operand
-/// of address-of gets special treatment due to member pointers. NotCastExpr
-/// is set to true if the token is not the start of a cast-expression, and no
-/// diagnostic is emitted in this case and no tokens are consumed.
-///
-/// \verbatim
-///       cast-expression: [C99 6.5.4]
-///         unary-expression
-///         '(' type-name ')' cast-expression
-///
-///       unary-expression:  [C99 6.5.3]
-///         postfix-expression
-///         '++' unary-expression
-///         '--' unary-expression
-/// [Coro]  'co_await' cast-expression
-///         unary-operator cast-expression
-///         'sizeof' unary-expression
-///         'sizeof' '(' type-name ')'
-/// [C++11] 'sizeof' '...' '(' identifier ')'
-/// [GNU]   '__alignof' unary-expression
-/// [GNU]   '__alignof' '(' type-name ')'
-/// [C11]   '_Alignof' '(' type-name ')'
-/// [C++11] 'alignof' '(' type-id ')'
-/// [C2y]   '_Countof' unary-expression
-/// [C2y]   '_Countof' '(' type-name ')'
-/// [GNU]   '&&' identifier
-/// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7]
-/// [C++]   new-expression
-/// [C++]   delete-expression
-///
-///       unary-operator: one of
-///         '&'  '*'  '+'  '-'  '~'  '!'
-/// [GNU]   '__extension__'  '__real'  '__imag'
-///
-///       primary-expression: [C99 6.5.1]
-/// [C99]   identifier
-/// [C++]   id-expression
-///         constant
-///         string-literal
-/// [C++]   boolean-literal  [C++ 2.13.5]
-/// [C++11] 'nullptr'        [C++11 2.14.7]
-/// [C++11] user-defined-literal
-///         '(' expression ')'
-/// [C11]   generic-selection
-/// [C++2a] requires-expression
-///         '__func__'        [C99 6.4.2.2]
-/// [GNU]   '__FUNCTION__'
-/// [MS]    '__FUNCDNAME__'
-/// [MS]    'L__FUNCTION__'
-/// [MS]    '__FUNCSIG__'
-/// [MS]    'L__FUNCSIG__'
-/// [GNU]   '__PRETTY_FUNCTION__'
-/// [GNU]   '(' compound-statement ')'
-/// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
-/// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
-/// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
-///                                     assign-expr ')'
-/// [GNU]   '__builtin_FILE' '(' ')'
-/// [CLANG] '__builtin_FILE_NAME' '(' ')'
-/// [GNU]   '__builtin_FUNCTION' '(' ')'
-/// [MS]    '__builtin_FUNCSIG' '(' ')'
-/// [GNU]   '__builtin_LINE' '(' ')'
-/// [CLANG] '__builtin_COLUMN' '(' ')'
-/// [GNU]   '__builtin_source_location' '(' ')'
-/// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
-/// [GNU]   '__null'
-/// [OBJC]  '[' objc-message-expr ']'
-/// [OBJC]  '\@selector' '(' objc-selector-arg ')'
-/// [OBJC]  '\@protocol' '(' identifier ')'
-/// [OBJC]  '\@encode' '(' type-name ')'
-/// [OBJC]  objc-string-literal
-/// [C++]   simple-type-specifier '(' expression-list[opt] ')'      [C++ 5.2.3]
-/// [C++11] simple-type-specifier braced-init-list                  [C++11 5.2.3]
-/// [C++]   typename-specifier '(' expression-list[opt] ')'         [C++ 5.2.3]
-/// [C++11] typename-specifier braced-init-list                     [C++11 5.2.3]
-/// [C++]   'const_cast' '<' type-name '>' '(' expression ')'       [C++ 5.2p1]
-/// [C++]   'dynamic_cast' '<' type-name '>' '(' expression ')'     [C++ 5.2p1]
-/// [C++]   'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
-/// [C++]   'static_cast' '<' type-name '>' '(' expression ')'      [C++ 5.2p1]
-/// [C++]   'typeid' '(' expression ')'                             [C++ 5.2p1]
-/// [C++]   'typeid' '(' type-id ')'                                [C++ 5.2p1]
-/// [C++]   'this'          [C++ 9.3.2]
-/// [G++]   unary-type-trait '(' type-id ')'
-/// [G++]   binary-type-trait '(' type-id ',' type-id ')'           [TODO]
-/// [EMBT]  array-type-trait '(' type-id ',' integer ')'
-/// [clang] '^' block-literal
-///
-///       constant: [C99 6.4.4]
-///         integer-constant
-///         floating-constant
-///         enumeration-constant -> identifier
-///         character-constant
-///
-///       id-expression: [C++ 5.1]
-///                   unqualified-id
-///                   qualified-id
-///
-///       unqualified-id: [C++ 5.1]
-///                   identifier
-///                   operator-function-id
-///                   conversion-function-id
-///                   '~' class-name
-///                   template-id
-///
-///       new-expression: [C++ 5.3.4]
-///                   '::'[opt] 'new' new-placement[opt] new-type-id
-///                                     new-initializer[opt]
-///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
-///                                     new-initializer[opt]
-///
-///       delete-expression: [C++ 5.3.5]
-///                   '::'[opt] 'delete' cast-expression
-///                   '::'[opt] 'delete' '[' ']' cast-expression
-///
-/// [GNU/Embarcadero] unary-type-trait:
-///                   '__is_arithmetic'
-///                   '__is_floating_point'
-///                   '__is_integral'
-///                   '__is_lvalue_expr'
-///                   '__is_rvalue_expr'
-///                   '__is_complete_type'
-///                   '__is_void'
-///                   '__is_array'
-///                   '__is_function'
-///                   '__is_reference'
-///                   '__is_lvalue_reference'
-///                   '__is_rvalue_reference'
-///                   '__is_fundamental'
-///                   '__is_object'
-///                   '__is_scalar'
-///                   '__is_compound'
-///                   '__is_pointer'
-///                   '__is_member_object_pointer'
-///                   '__is_member_function_pointer'
-///                   '__is_member_pointer'
-///                   '__is_const'
-///                   '__is_volatile'
-///                   '__is_trivial'
-///                   '__is_standard_layout'
-///                   '__is_signed'
-///                   '__is_unsigned'
-///
-/// [GNU] unary-type-trait:
-///                   '__has_nothrow_assign'
-///                   '__has_nothrow_copy'
-///                   '__has_nothrow_constructor'
-///                   '__has_trivial_assign'                  [TODO]
-///                   '__has_trivial_copy'                    [TODO]
-///                   '__has_trivial_constructor'
-///                   '__has_trivial_destructor'
-///                   '__has_virtual_destructor'
-///                   '__is_abstract'                         [TODO]
-///                   '__is_class'
-///                   '__is_empty'                            [TODO]
-///                   '__is_enum'
-///                   '__is_final'
-///                   '__is_pod'
-///                   '__is_polymorphic'
-///                   '__is_sealed'                           [MS]
-///                   '__is_trivial'
-///                   '__is_union'
-///                   '__has_unique_object_representations'
-///
-/// [Clang] unary-type-trait:
-///                   '__is_aggregate'
-///                   '__trivially_copyable'
-///
-///       binary-type-trait:
-/// [GNU]             '__is_base_of'
-/// [MS]              '__is_convertible_to'
-///                   '__is_convertible'
-///                   '__is_same'
-///
-/// [Embarcadero] array-type-trait:
-///                   '__array_rank'
-///                   '__array_extent'
-///
-/// [Embarcadero] expression-trait:
-///                   '__is_lvalue_expr'
-///                   '__is_rvalue_expr'
-/// \endverbatim
-///
 ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
                                        bool isAddressOfOperand,
                                        bool &NotCastExpr,
@@ -1985,27 +1661,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
   return Res;
 }
 
-/// Once the leading part of a postfix-expression is parsed, this
-/// method parses any suffixes that apply.
-///
-/// \verbatim
-///       postfix-expression: [C99 6.5.2]
-///         primary-expression
-///         postfix-expression '[' expression ']'
-///         postfix-expression '[' braced-init-list ']'
-///         postfix-expression '[' expression-list [opt] ']'  [C++23 12.4.5]
-///         postfix-expression '(' argument-expression-list[opt] ')'
-///         postfix-expression '.' identifier
-///         postfix-expression '->' identifier
-///         postfix-expression '++'
-///         postfix-expression '--'
-///         '(' type-name ')' '{' initializer-list '}'
-///         '(' type-name ')' '{' initializer-list ',' '}'
-///
-///       argument-expression-list: [C99 6.5.2]
-///         argument-expression ...[opt]
-///         argument-expression-list ',' assignment-expression ...[opt]
-/// \endverbatim
 ExprResult
 Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
   // Now that the primary-expression piece of the postfix-expression has been
@@ -2428,38 +2083,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
   }
 }
 
-/// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/
-/// vec_step and we are at the start of an expression or a parenthesized
-/// type-id. OpTok is the operand token (typeof/sizeof/alignof). Returns the
-/// expression (isCastExpr == false) or the type (isCastExpr == true).
-///
-/// \verbatim
-///       unary-expression:  [C99 6.5.3]
-///         'sizeof' unary-expression
-///         'sizeof' '(' type-name ')'
-/// [Clang] '__datasizeof' unary-expression
-/// [Clang] '__datasizeof' '(' type-name ')'
-/// [GNU]   '__alignof' unary-expression
-/// [GNU]   '__alignof' '(' type-name ')'
-/// [C11]   '_Alignof' '(' type-name ')'
-/// [C++0x] 'alignof' '(' type-id ')'
-///
-/// [GNU]   typeof-specifier:
-///           typeof ( expressions )
-///           typeof ( type-name )
-/// [GNU/C++] typeof unary-expression
-/// [C23]   typeof-specifier:
-///           typeof '(' typeof-specifier-argument ')'
-///           typeof_unqual '(' typeof-specifier-argument ')'
-///
-///         typeof-specifier-argument:
-///           expression
-///           type-name
-///
-/// [OpenCL 1.1 6.11.12] vec_step built-in function:
-///           vec_step ( expressions )
-///           vec_step ( type-name )
-/// \endverbatim
 ExprResult
 Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
                                            bool &isCastExpr,
@@ -2560,8 +2183,6 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
   return Operand;
 }
 
-/// Parse a __builtin_sycl_unique_stable_name expression.  Accepts a type-id as
-/// a parameter.
 ExprResult Parser::ParseSYCLUniqueStableNameExpression() {
   assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) &&
          "Not __builtin_sycl_unique_stable_name");
@@ -2588,22 +2209,6 @@ ExprResult Parser::ParseSYCLUniqueStableNameExpression() {
       OpLoc, T.getOpenLocation(), T.getCloseLocation(), Ty.get());
 }
 
-/// Parse a sizeof or alignof expression.
-///
-/// \verbatim
-///       unary-expression:  [C99 6.5.3]
-///         'sizeof' unary-expression
-///         'sizeof' '(' type-name ')'
-/// [C++11] 'sizeof' '...' '(' identifier ')'
-/// [Clang] '__datasizeof' unary-expression
-/// [Clang] '__datasizeof' '(' type-name ')'
-/// [GNU]   '__alignof' unary-expression
-/// [GNU]   '__alignof' '(' type-name ')'
-/// [C11]   '_Alignof' '(' type-name ')'
-/// [C++11] 'alignof' '(' type-id ')'
-/// [C2y]   '_Countof' unary-expression
-/// [C2y]   '_Countof' '(' type-name ')'
-/// \endverbatim
 ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
   assert(Tok.isOneOf(tok::kw_sizeof, tok::kw___datasizeof, tok::kw___alignof,
                      tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step,
@@ -2731,29 +2336,6 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
   return Operand;
 }
 
-/// ParseBuiltinPrimaryExpression
-///
-/// \verbatim
-///       primary-expression: [C99 6.5.1]
-/// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
-/// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
-/// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
-///                                     assign-expr ')'
-/// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
-/// [GNU]   '__builtin_FILE' '(' ')'
-/// [CLANG] '__builtin_FILE_NAME' '(' ')'
-/// [GNU]   '__builtin_FUNCTION' '(' ')'
-/// [MS]    '__builtin_FUNCSIG' '(' ')'
-/// [GNU]   '__builtin_LINE' '(' ')'
-/// [CLANG] '__builtin_COLUMN' '(' ')'
-/// [GNU]   '__builtin_source_location' '(' ')'
-/// [OCL]   '__builtin_astype' '(' assignment-expression ',' type-name ')'
-///
-/// [GNU] offsetof-member-designator:
-/// [GNU]   identifier
-/// [GNU]   offsetof-member-designator '.' identifier
-/// [GNU]   offsetof-member-designator '[' expression ']'
-/// \endverbatim
 ExprResult Parser::ParseBuiltinPrimaryExpression() {
   ExprResult Res;
   const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
@@ -3049,33 +2631,6 @@ bool Parser::tryParseOpenMPArrayShapingCastPart() {
   return !ErrorFound;
 }
 
-/// ParseParenExpression - This parses the unit that starts with a '(' token,
-/// based on what is allowed by ExprType.  The actual thing parsed is returned
-/// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
-/// not the parsed cast-expression.
-///
-/// \verbatim
-///       primary-expression: [C99 6.5.1]
-///         '(' expression ')'
-/// [GNU]   '(' compound-statement ')'      (if !ParenExprOnly)
-///       postfix-expression: [C99 6.5.2]
-///         '(' type-name ')' '{' initializer-list '}'
-///         '(' type-name ')' '{' initializer-list ',' '}'
-///       cast-expression: [C99 6.5.4]
-///         '(' type-name ')' cast-expression
-/// [ARC]   bridged-cast-expression
-/// [ARC] bridged-cast-expression:
-///         (__bridge type-name) cast-expression
-///         (__bridge_transfer type-name) cast-expression
-///         (__bridge_retained type-name) cast-expression
-///       fold-expression: [C++1z]
-///         '(' cast-expression fold-operator '...' ')'
-///         '(' '...' fold-operator cast-expression ')'
-///         '(' cast-expression fold-operator '...'
-///                 fold-operator cast-expression ')'
-/// [OPENMP] Array shaping operation
-///       '(' '[' expression ']' { '[' expression ']' } cast-expression
-/// \endverbatim
 ExprResult
 Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
                              bool isTypeCast, ParsedType &CastTy,
@@ -3421,14 +2976,6 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
   return Result;
 }
 
-/// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
-/// and we are at the left brace.
-///
-/// \verbatim
-///       postfix-expression: [C99 6.5.2]
-///         '(' type-name ')' '{' initializer-list '}'
-///         '(' type-name ')' '{' initializer-list ',' '}'
-/// \endverbatim
 ExprResult
 Parser::ParseCompoundLiteralExpression(ParsedType Ty,
                                        SourceLocation LParenLoc,
@@ -3443,14 +2990,6 @@ Parser::ParseCompoundLiteralExpression(ParsedType Ty,
   return Result;
 }
 
-/// ParseStringLiteralExpression - This handles the various token types that
-/// form string literals, and also handles string concatenation [C99 5.1.1.2,
-/// translation phase #6].
-///
-/// \verbatim
-///       primary-expression: [C99 6.5.1]
-///         string-literal
-/// \verbatim
 ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral) {
   return ParseStringLiteralExpression(AllowUserDefinedLiteral,
                                       /*Unevaluated=*/false);
@@ -3487,25 +3026,6 @@ ExprResult Parser::ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
                                                             : nullptr);
 }
 
-/// ParseGenericSelectionExpression - Parse a C11 generic-selection
-/// [C11 6.5.1.1].
-///
-/// \verbatim
-///    generic-selection:
-///           _Generic ( assignment-expression , generic-assoc-list )
-///    generic-assoc-list:
-///           generic-association
-///           generic-assoc-list , generic-association
-///    generic-association:
-///           type-name : assignment-expression
-///           default : assignment-expression
-/// \endverbatim
-///
-/// As an extension, Clang also accepts:
-/// \verbatim
-///   generic-selection:
-///          _Generic ( type-name, generic-assoc-list )
-/// \endverbatim
 ExprResult Parser::ParseGenericSelectionExpression() {
   assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected");
 
@@ -3604,14 +3124,6 @@ ExprResult Parser::ParseGenericSelectionExpression() {
       ExprOrTy, Types, Exprs);
 }
 
-/// Parse A C++1z fold-expression after the opening paren and optional
-/// left-hand-side expression.
-///
-/// \verbatim
-///   fold-expression:
-///       ( cast-expression fold-operator ... )
-///       ( ... fold-operator cast-expression )
-///       ( cast-expression fold-operator ... fold-operator cast-expression )
 ExprResult Parser::ParseFoldExpression(ExprResult LHS,
                                        BalancedDelimiterTracker &T) {
   if (LHS.isInvalid()) {
@@ -3683,28 +3195,6 @@ void Parser::injectEmbedTokens() {
   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
 }
 
-/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
-///
-/// \verbatim
-///       argument-expression-list:
-///         assignment-expression
-///         argument-expression-list , assignment-expression
-///
-/// [C++] expression-list:
-/// [C++]   assignment-expression
-/// [C++]   expression-list , assignment-expression
-///
-/// [C++0x] expression-list:
-/// [C++0x]   initializer-list
-///
-/// [C++0x] initializer-list
-/// [C++0x]   initializer-clause ...[opt]
-/// [C++0x]   initializer-list , initializer-clause ...[opt]
-///
-/// [C++0x] initializer-clause:
-/// [C++0x]   assignment-expression
-/// [C++0x]   braced-init-list
-/// \endverbatim
 bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
                                  llvm::function_ref<void()> ExpressionStarts,
                                  bool FailImmediatelyOnInvalidExpr,
@@ -3763,14 +3253,6 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
   return SawError;
 }
 
-/// ParseSimpleExpressionList - A simple comma-separated list of expressions,
-/// used for misc language extensions.
-///
-/// \verbatim
-///       simple-expression-list:
-///         assignment-expression
-///         simple-expression-list , assignment-expression
-/// \endverbatim
 bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) {
   while (true) {
     ExprResult Expr = ParseAssignmentExpression();
@@ -3791,12 +3273,6 @@ bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs) {
   }
 }
 
-/// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
-///
-/// \verbatim
-/// [clang] block-id:
-/// [clang]   specifier-qualifier-list block-declarator
-/// \endverbatim
 void Parser::ParseBlockId(SourceLocation CaretLoc) {
   if (Tok.is(tok::code_completion)) {
     cutOffParsing();
@@ -3821,16 +3297,6 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) {
   Actions.ActOnBlockArguments(CaretLoc, DeclaratorInfo, getCurScope());
 }
 
-/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
-/// like ^(int x){ return x+1; }
-///
-/// \verbatim
-///         block-literal:
-/// [clang]   '^' block-args[opt] compound-statement
-/// [clang]   '^' block-id compound-statement
-/// [clang] block-args:
-/// [clang]   '(' parameter-list ')'
-/// \endverbatim
 ExprResult Parser::ParseBlockLiteralExpression() {
   assert(Tok.is(tok::caret) && "block literal starts with ^");
   SourceLocation CaretLoc = ConsumeToken();
@@ -3929,10 +3395,6 @@ ExprResult Parser::ParseBlockLiteralExpression() {
   return Result;
 }
 
-/// ParseObjCBoolLiteral - This handles the objective-c Boolean literals.
-///
-///         '__objc_yes'
-///         '__objc_no'
 ExprResult Parser::ParseObjCBoolLiteral() {
   tok::TokenKind Kind = Tok.getKind();
   return Actions.ObjC().ActOnObjCBoolLiteral(ConsumeToken(), Kind);
@@ -3978,11 +3440,6 @@ static bool CheckAvailabilitySpecList(Parser &P,
   return !Valid;
 }
 
-/// Parse availability query specification.
-///
-///  availability-spec:
-///     '*'
-///     identifier version-tuple
 std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
   if (Tok.is(tok::star)) {
     return AvailabilitySpec(ConsumeToken());
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 32b08a12a3bb6..bbfcf989e56f1 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -46,7 +46,6 @@ static int SelectDigraphErrorMessage(tok::TokenKind Kind) {
   }
 }
 
-// Are the two tokens adjacent in the same source file?
 bool Parser::areTokensAdjacent(const Token &First, const Token &Second) {
   SourceManager &SM = PP.getSourceManager();
   SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation());
@@ -82,8 +81,6 @@ static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken,
     PP.EnterToken(DigraphToken, /*IsReinject*/ true);
 }
 
-// Check for '<::' which should be '< ::' instead of '[:' when following
-// a template name.
 void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
                                         bool EnteringContext,
                                         IdentifierInfo &II, CXXScopeSpec &SS) {
@@ -107,55 +104,6 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
              /*AtDigraph*/false);
 }
 
-/// Parse global scope or nested-name-specifier if present.
-///
-/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
-/// may be preceded by '::'). Note that this routine will not parse ::new or
-/// ::delete; it will just leave them in the token stream.
-///
-///       '::'[opt] nested-name-specifier
-///       '::'
-///
-///       nested-name-specifier:
-///         type-name '::'
-///         namespace-name '::'
-///         nested-name-specifier identifier '::'
-///         nested-name-specifier 'template'[opt] simple-template-id '::'
-///
-///
-/// \param SS the scope specifier that will be set to the parsed
-/// nested-name-specifier (or empty)
-///
-/// \param ObjectType if this nested-name-specifier is being parsed following
-/// the "." or "->" of a member access expression, this parameter provides the
-/// type of the object whose members are being accessed.
-///
-/// \param ObjectHadErrors if this unqualified-id occurs within a member access
-/// expression, indicates whether the original subexpressions had any errors.
-/// When true, diagnostics for missing 'template' keyword will be supressed.
-///
-/// \param EnteringContext whether we will be entering into the context of
-/// the nested-name-specifier after parsing it.
-///
-/// \param MayBePseudoDestructor When non-NULL, points to a flag that
-/// indicates whether this nested-name-specifier may be part of a
-/// pseudo-destructor name. In this case, the flag will be set false
-/// if we don't actually end up parsing a destructor name. Moreover,
-/// if we do end up determining that we are parsing a destructor name,
-/// the last component of the nested-name-specifier is not parsed as
-/// part of the scope specifier.
-///
-/// \param IsTypename If \c true, this nested-name-specifier is known to be
-/// part of a type name. This is used to improve error recovery.
-///
-/// \param LastII When non-NULL, points to an IdentifierInfo* that will be
-/// filled in with the leading identifier in the last component of the
-/// nested-name-specifier, if any.
-///
-/// \param OnlyNamespace If true, only considers namespaces in lookup.
-///
-///
-/// \returns true if there was an error parsing a scope specifier
 bool Parser::ParseOptionalCXXScopeSpecifier(
     CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors,
     bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename,
@@ -707,48 +655,6 @@ Parser::tryParseCXXPackIndexingExpression(ExprResult PackIdExpression) {
   return E;
 }
 
-/// ParseCXXIdExpression - Handle id-expression.
-///
-///       id-expression:
-///         unqualified-id
-///         qualified-id
-///
-///       qualified-id:
-///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
-///         '::' identifier
-///         '::' operator-function-id
-///         '::' template-id
-///
-/// NOTE: The standard specifies that, for qualified-id, the parser does not
-/// expect:
-///
-///   '::' conversion-function-id
-///   '::' '~' class-name
-///
-/// This may cause a slight inconsistency on diagnostics:
-///
-/// class C {};
-/// namespace A {}
-/// void f() {
-///   :: A :: ~ C(); // Some Sema error about using destructor with a
-///                  // namespace.
-///   :: ~ C(); // Some Parser error like 'unexpected ~'.
-/// }
-///
-/// We simplify the parser a bit and make it work like:
-///
-///       qualified-id:
-///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
-///         '::' unqualified-id
-///
-/// That way Sema can handle and report similar errors for namespaces and the
-/// global scope.
-///
-/// The isAddressOfOperand parameter indicates that this id-expression is a
-/// direct operand of the address-of operator. This is, besides member contexts,
-/// the only place where a qualified-id naming a non-static class member may
-/// appear.
-///
 ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
   // qualified-id:
   //   '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
@@ -773,51 +679,6 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
   return Result;
 }
 
-/// ParseLambdaExpression - Parse a C++11 lambda expression.
-///
-///       lambda-expression:
-///         lambda-introducer lambda-declarator compound-statement
-///         lambda-introducer '<' template-parameter-list '>'
-///             requires-clause[opt] lambda-declarator compound-statement
-///
-///       lambda-introducer:
-///         '[' lambda-capture[opt] ']'
-///
-///       lambda-capture:
-///         capture-default
-///         capture-list
-///         capture-default ',' capture-list
-///
-///       capture-default:
-///         '&'
-///         '='
-///
-///       capture-list:
-///         capture
-///         capture-list ',' capture
-///
-///       capture:
-///         simple-capture
-///         init-capture     [C++1y]
-///
-///       simple-capture:
-///         identifier
-///         '&' identifier
-///         'this'
-///
-///       init-capture:      [C++1y]
-///         identifier initializer
-///         '&' identifier initializer
-///
-///       lambda-declarator:
-///         lambda-specifiers     [C++23]
-///         '(' parameter-declaration-clause ')' lambda-specifiers
-///             requires-clause[opt]
-///
-///       lambda-specifiers:
-///         decl-specifier-seq[opt] noexcept-specifier[opt]
-///             attribute-specifier-seq[opt] trailing-return-type[opt]
-///
 ExprResult Parser::ParseLambdaExpression() {
   // Parse lambda-introducer.
   LambdaIntroducer Intro;
@@ -831,10 +692,6 @@ ExprResult Parser::ParseLambdaExpression() {
   return ParseLambdaExpressionAfterIntroducer(Intro);
 }
 
-/// Use lookahead and potentially tentative parsing to determine if we are
-/// looking at a C++11 lambda expression, and parse it if we are.
-///
-/// If we are not looking at a lambda expression, returns ExprError().
 ExprResult Parser::TryParseLambdaExpression() {
   assert(getLangOpts().CPlusPlus && Tok.is(tok::l_square) &&
          "Not at the start of a possible lambda expression.");
@@ -899,15 +756,6 @@ ExprResult Parser::TryParseLambdaExpression() {
   return ParseLambdaExpressionAfterIntroducer(Intro);
 }
 
-/// Parse a lambda introducer.
-/// \param Intro A LambdaIntroducer filled in with information about the
-///        contents of the lambda-introducer.
-/// \param Tentative If non-null, we are disambiguating between a
-///        lambda-introducer and some other construct. In this mode, we do not
-///        produce any diagnostics or take any other irreversible action unless
-///        we're sure that this is a lambda-expression.
-/// \return \c true if parsing (or disambiguation) failed with a diagnostic and
-///         the caller should bail out / recover.
 bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
                                    LambdaIntroducerTentativeParse *Tentative) {
   if (Tentative)
@@ -1353,8 +1201,6 @@ static void DiagnoseStaticSpecifierRestrictions(Parser &P,
   }
 }
 
-/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda
-/// expression.
 ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
                      LambdaIntroducer &Intro) {
   SourceLocation LambdaBeginLoc = Intro.Range.getBegin();
@@ -1648,17 +1494,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
   return ExprError();
 }
 
-/// ParseCXXCasts - This handles the various ways to cast expressions to another
-/// type.
-///
-///       postfix-expression: [C++ 5.2p1]
-///         'dynamic_cast' '<' type-name '>' '(' expression ')'
-///         'static_cast' '<' type-name '>' '(' expression ')'
-///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
-///         'const_cast' '<' type-name '>' '(' expression ')'
-///
-/// C++ for OpenCL s2.3.1 adds:
-///         'addrspace_cast' '<' type-name '>' '(' expression ')'
 ExprResult Parser::ParseCXXCasts() {
   tok::TokenKind Kind = Tok.getKind();
   const char *CastName = nullptr; // For error messages
@@ -1721,12 +1556,6 @@ ExprResult Parser::ParseCXXCasts() {
   return Result;
 }
 
-/// ParseCXXTypeid - This handles the C++ typeid expression.
-///
-///       postfix-expression: [C++ 5.2p1]
-///         'typeid' '(' expression ')'
-///         'typeid' '(' type-id ')'
-///
 ExprResult Parser::ParseCXXTypeid() {
   assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
 
@@ -1789,11 +1618,6 @@ ExprResult Parser::ParseCXXTypeid() {
   return Result;
 }
 
-/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
-///
-///         '__uuidof' '(' expression ')'
-///         '__uuidof' '(' type-id ')'
-///
 ExprResult Parser::ParseCXXUuidof() {
   assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");
 
@@ -1838,37 +1662,6 @@ ExprResult Parser::ParseCXXUuidof() {
   return Result;
 }
 
-/// Parse a C++ pseudo-destructor expression after the base,
-/// . or -> operator, and nested-name-specifier have already been
-/// parsed. We're handling this fragment of the grammar:
-///
-///       postfix-expression: [C++2a expr.post]
-///         postfix-expression . template[opt] id-expression
-///         postfix-expression -> template[opt] id-expression
-///
-///       id-expression:
-///         qualified-id
-///         unqualified-id
-///
-///       qualified-id:
-///         nested-name-specifier template[opt] unqualified-id
-///
-///       nested-name-specifier:
-///         type-name ::
-///         decltype-specifier ::    FIXME: not implemented, but probably only
-///                                         allowed in C++ grammar by accident
-///         nested-name-specifier identifier ::
-///         nested-name-specifier template[opt] simple-template-id ::
-///         [...]
-///
-///       unqualified-id:
-///         ~ type-name
-///         ~ decltype-specifier
-///         [...]
-///
-/// ... where the all but the last component of the nested-name-specifier
-/// has already been parsed, and the base expression is not of a non-dependent
-/// class type.
 ExprResult
 Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
                                  tok::TokenKind OpKind,
@@ -1950,20 +1743,11 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
                                            SecondTypeName);
 }
 
-/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
-///
-///       boolean-literal: [C++ 2.13.5]
-///         'true'
-///         'false'
 ExprResult Parser::ParseCXXBoolLiteral() {
   tok::TokenKind Kind = Tok.getKind();
   return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);
 }
 
-/// ParseThrowExpression - This handles the C++ throw expression.
-///
-///       throw-expression: [C++ 15]
-///         'throw' assignment-expression[opt]
 ExprResult Parser::ParseThrowExpression() {
   assert(Tok.is(tok::kw_throw) && "Not throw!");
   SourceLocation ThrowLoc = ConsumeToken();           // Eat the throw token.
@@ -1987,10 +1771,6 @@ ExprResult Parser::ParseThrowExpression() {
   }
 }
 
-/// Parse the C++ Coroutines co_yield expression.
-///
-///       co_yield-expression:
-///         'co_yield' assignment-expression[opt]
 ExprResult Parser::ParseCoyieldExpression() {
   assert(Tok.is(tok::kw_co_yield) && "Not co_yield!");
 
@@ -2002,30 +1782,12 @@ ExprResult Parser::ParseCoyieldExpression() {
   return Expr;
 }
 
-/// ParseCXXThis - This handles the C++ 'this' pointer.
-///
-/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
-/// a non-lvalue expression whose value is the address of the object for which
-/// the function is called.
 ExprResult Parser::ParseCXXThis() {
   assert(Tok.is(tok::kw_this) && "Not 'this'!");
   SourceLocation ThisLoc = ConsumeToken();
   return Actions.ActOnCXXThis(ThisLoc);
 }
 
-/// ParseCXXTypeConstructExpression - Parse construction of a specified type.
-/// Can be interpreted either as function-style casting ("int(x)")
-/// or class type construction ("ClassType(x,y,z)")
-/// or creation of a value-initialized type ("int()").
-/// See [C++ 5.2.3].
-///
-///       postfix-expression: [C++ 5.2p1]
-///         simple-type-specifier '(' expression-list[opt] ')'
-/// [C++0x] simple-type-specifier braced-init-list
-///         typename-specifier '(' expression-list[opt] ')'
-/// [C++0x] typename-specifier braced-init-list
-///
-/// In C++1z onwards, the type specifier can also be a template-name.
 ExprResult
 Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
   Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
@@ -2111,37 +1873,6 @@ Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
   return DG;
 }
 
-/// ParseCXXCondition - if/switch/while condition expression.
-///
-///       condition:
-///         expression
-///         type-specifier-seq declarator '=' assignment-expression
-/// [C++11] type-specifier-seq declarator '=' initializer-clause
-/// [C++11] type-specifier-seq declarator braced-init-list
-/// [Clang] type-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
-///             brace-or-equal-initializer
-/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
-///             '=' assignment-expression
-///
-/// In C++1z, a condition may in some contexts be preceded by an
-/// optional init-statement. This function will parse that too.
-///
-/// \param InitStmt If non-null, an init-statement is permitted, and if present
-/// will be parsed and stored here.
-///
-/// \param Loc The location of the start of the statement that requires this
-/// condition, e.g., the "for" in a for loop.
-///
-/// \param MissingOK Whether an empty condition is acceptable here. Otherwise
-/// it is considered an error to be recovered from.
-///
-/// \param FRI If non-null, a for range declaration is permitted, and if
-/// present will be parsed and stored here, and a null result will be returned.
-///
-/// \param EnterForConditionScope If true, enter a continue/break scope at the
-/// appropriate moment for a 'for' loop.
-///
-/// \returns The parsed condition.
 Sema::ConditionResult
 Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,
                           Sema::ConditionKind CK, bool MissingOK,
@@ -2330,32 +2061,6 @@ Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,
   return Actions.ActOnConditionVariable(DeclOut, Loc, CK);
 }
 
-/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
-/// This should only be called when the current token is known to be part of
-/// simple-type-specifier.
-///
-///       simple-type-specifier:
-///         '::'[opt] nested-name-specifier[opt] type-name
-///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
-///         char
-///         wchar_t
-///         bool
-///         short
-///         int
-///         long
-///         signed
-///         unsigned
-///         float
-///         double
-///         void
-/// [GNU]   typeof-specifier
-/// [C++0x] auto               [TODO]
-///
-///       type-name:
-///         class-name
-///         enum-name
-///         typedef-name
-///
 void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
   DS.SetRangeStart(Tok.getLocation());
   const char *PrevSpec;
@@ -2507,17 +2212,6 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
   DS.Finish(Actions, Policy);
 }
 
-/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
-/// [dcl.name]), which is a non-empty sequence of type-specifiers,
-/// e.g., "const short int". Note that the DeclSpec is *not* finished
-/// by parsing the type-specifier-seq, because these sequences are
-/// typically followed by some form of declarator. Returns true and
-/// emits diagnostics if this is not a type-specifier-seq, false
-/// otherwise.
-///
-///   type-specifier-seq: [C++ 8.1]
-///     type-specifier type-specifier-seq[opt]
-///
 bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS, DeclaratorContext Context) {
   ParseSpecifierQualifierList(DS, AS_none,
                               getDeclSpecContextFromDeclaratorContext(Context));
@@ -2525,41 +2219,6 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS, DeclaratorContext Context) {
   return false;
 }
 
-/// Finish parsing a C++ unqualified-id that is a template-id of
-/// some form.
-///
-/// This routine is invoked when a '<' is encountered after an identifier or
-/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine
-/// whether the unqualified-id is actually a template-id. This routine will
-/// then parse the template arguments and form the appropriate template-id to
-/// return to the caller.
-///
-/// \param SS the nested-name-specifier that precedes this template-id, if
-/// we're actually parsing a qualified-id.
-///
-/// \param ObjectType if this unqualified-id occurs within a member access
-/// expression, the type of the base object whose member is being accessed.
-///
-/// \param ObjectHadErrors this unqualified-id occurs within a member access
-/// expression, indicates whether the original subexpressions had any errors.
-///
-/// \param Name for constructor and destructor names, this is the actual
-/// identifier that may be a template-name.
-///
-/// \param NameLoc the location of the class-name in a constructor or
-/// destructor.
-///
-/// \param EnteringContext whether we're entering the scope of the
-/// nested-name-specifier.
-///
-/// \param Id as input, describes the template-name or operator-function-id
-/// that precedes the '<'. If template arguments were parsed successfully,
-/// will be updated with the template-id.
-///
-/// \param AssumeTemplateId When true, this routine will assume that the name
-/// refers to a template without performing name lookup to verify.
-///
-/// \returns true if a parse error occurred, false otherwise.
 bool Parser::ParseUnqualifiedIdTemplateId(
     CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors,
     SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc,
@@ -2715,46 +2374,6 @@ bool Parser::ParseUnqualifiedIdTemplateId(
   return false;
 }
 
-/// Parse an operator-function-id or conversion-function-id as part
-/// of a C++ unqualified-id.
-///
-/// This routine is responsible only for parsing the operator-function-id or
-/// conversion-function-id; it does not handle template arguments in any way.
-///
-/// \code
-///       operator-function-id: [C++ 13.5]
-///         'operator' operator
-///
-///       operator: one of
-///            new   delete  new[]   delete[]
-///            +     -    *  /    %  ^    &   |   ~
-///            !     =    <  >    += -=   *=  /=  %=
-///            ^=    &=   |= <<   >> >>= <<=  ==  !=
-///            <=    >=   && ||   ++ --   ,   ->* ->
-///            ()    []   <=>
-///
-///       conversion-function-id: [C++ 12.3.2]
-///         operator conversion-type-id
-///
-///       conversion-type-id:
-///         type-specifier-seq conversion-declarator[opt]
-///
-///       conversion-declarator:
-///         ptr-operator conversion-declarator[opt]
-/// \endcode
-///
-/// \param SS The nested-name-specifier that preceded this unqualified-id. If
-/// non-empty, then we are parsing the unqualified-id of a qualified-id.
-///
-/// \param EnteringContext whether we are entering the scope of the
-/// nested-name-specifier.
-///
-/// \param ObjectType if this unqualified-id occurs within a member access
-/// expression, the type of the base object whose member is being accessed.
-///
-/// \param Result on a successful parse, contains the parsed unqualified-id.
-///
-/// \returns true if parsing fails, false otherwise.
 bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
                                         ParsedType ObjectType,
                                         UnqualifiedId &Result) {
@@ -2957,42 +2576,6 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
   return false;
 }
 
-/// Parse a C++ unqualified-id (or a C identifier), which describes the
-/// name of an entity.
-///
-/// \code
-///       unqualified-id: [C++ expr.prim.general]
-///         identifier
-///         operator-function-id
-///         conversion-function-id
-/// [C++0x] literal-operator-id [TODO]
-///         ~ class-name
-///         template-id
-///
-/// \endcode
-///
-/// \param SS The nested-name-specifier that preceded this unqualified-id. If
-/// non-empty, then we are parsing the unqualified-id of a qualified-id.
-///
-/// \param ObjectType if this unqualified-id occurs within a member access
-/// expression, the type of the base object whose member is being accessed.
-///
-/// \param ObjectHadErrors if this unqualified-id occurs within a member access
-/// expression, indicates whether the original subexpressions had any errors.
-/// When true, diagnostics for missing 'template' keyword will be supressed.
-///
-/// \param EnteringContext whether we are entering the scope of the
-/// nested-name-specifier.
-///
-/// \param AllowDestructorName whether we allow parsing of a destructor name.
-///
-/// \param AllowConstructorName whether we allow parsing a constructor name.
-///
-/// \param AllowDeductionGuide whether we allow parsing a deduction guide name.
-///
-/// \param Result on a successful parse, contains the parsed unqualified-id.
-///
-/// \returns true if parsing fails, false otherwise.
 bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
                                 bool ObjectHadErrors, bool EnteringContext,
                                 bool AllowDestructorName,
@@ -3281,34 +2864,6 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
   }
 }
 
-/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
-/// memory in a typesafe manner and call constructors.
-///
-/// This method is called to parse the new expression after the optional :: has
-/// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
-/// is its location.  Otherwise, "Start" is the location of the 'new' token.
-///
-///        new-expression:
-///                   '::'[opt] 'new' new-placement[opt] new-type-id
-///                                     new-initializer[opt]
-///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
-///                                     new-initializer[opt]
-///
-///        new-placement:
-///                   '(' expression-list ')'
-///
-///        new-type-id:
-///                   type-specifier-seq new-declarator[opt]
-/// [GNU]             attributes type-specifier-seq new-declarator[opt]
-///
-///        new-declarator:
-///                   ptr-operator new-declarator[opt]
-///                   direct-new-declarator
-///
-///        new-initializer:
-///                   '(' expression-list[opt] ')'
-/// [C++0x]           braced-init-list
-///
 ExprResult
 Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
   assert(Tok.is(tok::kw_new) && "expected 'new' token");
@@ -3441,13 +2996,6 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
                              TypeIdParens, DeclaratorInfo, Initializer.get());
 }
 
-/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
-/// passed to ParseDeclaratorInternal.
-///
-///        direct-new-declarator:
-///                   '[' expression[opt] ']'
-///                   direct-new-declarator '[' constant-expression ']'
-///
 void Parser::ParseDirectNewDeclarator(Declarator &D) {
   // Parse the array dimensions.
   bool First = true;
@@ -3486,16 +3034,6 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
   }
 }
 
-/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
-/// This ambiguity appears in the syntax of the C++ new operator.
-///
-///        new-expression:
-///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
-///                                     new-initializer[opt]
-///
-///        new-placement:
-///                   '(' expression-list ')'
-///
 bool Parser::ParseExpressionListOrTypeId(
                                    SmallVectorImpl<Expr*> &PlacementArgs,
                                          Declarator &D) {
@@ -3511,17 +3049,6 @@ bool Parser::ParseExpressionListOrTypeId(
   return ParseExpressionList(PlacementArgs);
 }
 
-/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
-/// to free memory allocated by new.
-///
-/// This method is called to parse the 'delete' expression after the optional
-/// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
-/// and "Start" is its location.  Otherwise, "Start" is the location of the
-/// 'delete' token.
-///
-///        delete-expression:
-///                   '::'[opt] 'delete' cast-expression
-///                   '::'[opt] 'delete' '[' ']' cast-expression
 ExprResult
 Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
   assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");
@@ -3605,30 +3132,6 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
   return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get());
 }
 
-/// ParseRequiresExpression - Parse a C++2a requires-expression.
-/// C++2a [expr.prim.req]p1
-///     A requires-expression provides a concise way to express requirements on
-///     template arguments. A requirement is one that can be checked by name
-///     lookup (6.4) or by checking properties of types and expressions.
-///
-///     requires-expression:
-///         'requires' requirement-parameter-list[opt] requirement-body
-///
-///     requirement-parameter-list:
-///         '(' parameter-declaration-clause[opt] ')'
-///
-///     requirement-body:
-///         '{' requirement-seq '}'
-///
-///     requirement-seq:
-///         requirement
-///         requirement-seq requirement
-///
-///     requirement:
-///         simple-requirement
-///         type-requirement
-///         compound-requirement
-///         nested-requirement
 ExprResult Parser::ParseRequiresExpression() {
   assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword");
   SourceLocation RequiresKWLoc = ConsumeToken(); // Consume 'requires'
@@ -3953,17 +3456,6 @@ static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) {
   }
 }
 
-/// Parse the built-in type-trait pseudo-functions that allow
-/// implementation of the TR1/C++11 type traits templates.
-///
-///       primary-expression:
-///          unary-type-trait '(' type-id ')'
-///          binary-type-trait '(' type-id ',' type-id ')'
-///          type-trait '(' type-id-seq ')'
-///
-///       type-id-seq:
-///          type-id ...[opt] type-id-seq[opt]
-///
 ExprResult Parser::ParseTypeTrait() {
   tok::TokenKind Kind = Tok.getKind();
 
@@ -4006,13 +3498,6 @@ ExprResult Parser::ParseTypeTrait() {
   return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc);
 }
 
-/// ParseArrayTypeTrait - Parse the built-in array type-trait
-/// pseudo-functions.
-///
-///       primary-expression:
-/// [Embarcadero]     '__array_rank' '(' type-id ')'
-/// [Embarcadero]     '__array_extent' '(' type-id ',' expression ')'
-///
 ExprResult Parser::ParseArrayTypeTrait() {
   ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind());
   SourceLocation Loc = ConsumeToken();
@@ -4054,12 +3539,6 @@ ExprResult Parser::ParseArrayTypeTrait() {
   llvm_unreachable("Invalid ArrayTypeTrait!");
 }
 
-/// ParseExpressionTrait - Parse built-in expression-trait
-/// pseudo-functions like __is_lvalue_expr( xxx ).
-///
-///       primary-expression:
-/// [Embarcadero]     expression-trait '(' expression ')'
-///
 ExprResult Parser::ParseExpressionTrait() {
   ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind());
   SourceLocation Loc = ConsumeToken();
@@ -4076,10 +3555,6 @@ ExprResult Parser::ParseExpressionTrait() {
                                       T.getCloseLocation());
 }
 
-
-/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
-/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
-/// based on the context past the parens.
 ExprResult
 Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
                                          ParsedType &CastTy,
@@ -4233,7 +3708,6 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
   return Result;
 }
 
-/// Parse a __builtin_bit_cast(T, E).
 ExprResult Parser::ParseBuiltinBitCast() {
   SourceLocation KWLoc = ConsumeToken();
 
diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index a4ac692f429f7..af32b5d3b3ca0 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -24,10 +24,6 @@
 #include "llvm/ADT/SmallString.h"
 using namespace clang;
 
-
-/// MayBeDesignationStart - Return true if the current token might be the start
-/// of a designator.  If we can tell it is impossible that it is a designator,
-/// return false.
 bool Parser::MayBeDesignationStart() {
   switch (Tok.getKind()) {
   default:
@@ -119,48 +115,6 @@ static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,
     P.Diag(Loc, diag::err_expected_equal_designator);
 }
 
-/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
-/// checking to see if the token stream starts with a designator.
-///
-/// C99:
-///
-///       designation:
-///         designator-list '='
-/// [GNU]   array-designator
-/// [GNU]   identifier ':'
-///
-///       designator-list:
-///         designator
-///         designator-list designator
-///
-///       designator:
-///         array-designator
-///         '.' identifier
-///
-///       array-designator:
-///         '[' constant-expression ']'
-/// [GNU]   '[' constant-expression '...' constant-expression ']'
-///
-/// C++20:
-///
-///       designated-initializer-list:
-///         designated-initializer-clause
-///         designated-initializer-list ',' designated-initializer-clause
-///
-///       designated-initializer-clause:
-///         designator brace-or-equal-initializer
-///
-///       designator:
-///         '.' identifier
-///
-/// We allow the C99 syntax extensions in C++20, but do not allow the C++20
-/// extension (a braced-init-list after the designator with no '=') in C99.
-///
-/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
-/// initializer (because it is an expression).  We need to consider this case
-/// when parsing array designators.
-///
-/// \p CodeCompleteCB is called with Designation parsed so far.
 ExprResult Parser::ParseInitializerWithPotentialDesignator(
     DesignatorCompletionInfo DesignatorCompletion) {
   // If this is the old-style GNU extension:
@@ -456,18 +410,6 @@ ExprResult Parser::createEmbedExpr() {
   return Res;
 }
 
-/// ParseBraceInitializer - Called when parsing an initializer that has a
-/// leading open brace.
-///
-///       initializer: [C99 6.7.8]
-///         '{' initializer-list '}'
-///         '{' initializer-list ',' '}'
-/// [C23]   '{' '}'
-///
-///       initializer-list:
-///         designation[opt] initializer ...[opt]
-///         initializer-list ',' designation[opt] initializer ...[opt]
-///
 ExprResult Parser::ParseBraceInitializer() {
   InMessageExpressionRAIIObject InMessage(*this, false);
 
@@ -578,9 +520,6 @@ ExprResult Parser::ParseBraceInitializer() {
   return ExprError(); // an error occurred.
 }
 
-
-// Return true if a comma (or closing brace) is necessary after the
-// __if_exists/if_not_exists statement.
 bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
                                                     bool &InitExprsOk) {
   bool trailingComma = false;
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 6496b4fba54f2..4cb7440649464 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -29,7 +29,6 @@
 
 using namespace clang;
 
-/// Skips attributes after an Objective-C @ directive. Emits a diagnostic.
 void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
   ParsedAttributes attrs(AttrFactory);
   if (Tok.is(tok::kw___attribute)) {
@@ -42,14 +41,6 @@ void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
   }
 }
 
-/// ParseObjCAtDirectives - Handle parts of the external-declaration production:
-///       external-declaration: [C99 6.9]
-/// [OBJC]  objc-class-definition
-/// [OBJC]  objc-class-declaration
-/// [OBJC]  objc-alias-declaration
-/// [OBJC]  objc-protocol-definition
-/// [OBJC]  objc-method-definition
-/// [OBJC]  '@' 'end'
 Parser::DeclGroupPtrTy
 Parser::ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
                               ParsedAttributes &DeclSpecAttrs) {
@@ -115,7 +106,6 @@ Parser::ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
   return Actions.ConvertDeclToDeclGroup(SingleDecl);
 }
 
-/// Class to handle popping type parameters when leaving the scope.
 class Parser::ObjCTypeParamListScope {
   Sema &Actions;
   Scope *S;
@@ -141,13 +131,6 @@ class Parser::ObjCTypeParamListScope {
   }
 };
 
-///
-/// objc-class-declaration:
-///    '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
-///
-/// objc-class-forward-decl:
-///   identifier objc-type-parameter-list[opt]
-///
 Parser::DeclGroupPtrTy
 Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
   ConsumeToken(); // the identifier "class"
@@ -206,35 +189,6 @@ void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
     Diag(Decl->getBeginLoc(), diag::note_objc_container_start) << (int)ock;
 }
 
-///
-///   objc-interface:
-///     objc-class-interface-attributes[opt] objc-class-interface
-///     objc-category-interface
-///
-///   objc-class-interface:
-///     '@' 'interface' identifier objc-type-parameter-list[opt]
-///       objc-superclass[opt] objc-protocol-refs[opt]
-///       objc-class-instance-variables[opt]
-///       objc-interface-decl-list
-///     @end
-///
-///   objc-category-interface:
-///     '@' 'interface' identifier objc-type-parameter-list[opt]
-///       '(' identifier[opt] ')' objc-protocol-refs[opt]
-///       objc-interface-decl-list
-///     @end
-///
-///   objc-superclass:
-///     ':' identifier objc-type-arguments[opt]
-///
-///   objc-class-interface-attributes:
-///     __attribute__((visibility("default")))
-///     __attribute__((visibility("hidden")))
-///     __attribute__((deprecated))
-///     __attribute__((unavailable))
-///     __attribute__((objc_exception)) - used by NSException on 64-bit
-///     __attribute__((objc_root_class))
-///
 Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
                                               ParsedAttributes &attrs) {
   assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
@@ -434,30 +388,6 @@ static void addContextSensitiveTypeNullability(Parser &P,
   }
 }
 
-/// Parse an Objective-C type parameter list, if present, or capture
-/// the locations of the protocol identifiers for a list of protocol
-/// references.
-///
-///   objc-type-parameter-list:
-///     '<' objc-type-parameter (',' objc-type-parameter)* '>'
-///
-///   objc-type-parameter:
-///     objc-type-parameter-variance? identifier objc-type-parameter-bound[opt]
-///
-///   objc-type-parameter-bound:
-///     ':' type-name
-///
-///   objc-type-parameter-variance:
-///     '__covariant'
-///     '__contravariant'
-///
-/// \param lAngleLoc The location of the starting '<'.
-///
-/// \param protocolIdents Will capture the list of identifiers, if the
-/// angle brackets contain a list of protocol references rather than a
-/// type parameter list.
-///
-/// \param rAngleLoc The location of the ending '>'.
 ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
     ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
     SmallVectorImpl<IdentifierLoc> &protocolIdents, SourceLocation &rAngleLoc,
@@ -605,7 +535,6 @@ ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
   return invalid ? nullptr : list;
 }
 
-/// Parse an objc-type-parameter-list.
 ObjCTypeParamList *Parser::parseObjCTypeParamList() {
   SourceLocation lAngleLoc;
   SmallVector<IdentifierLoc, 1> protocolIdents;
@@ -630,18 +559,6 @@ static bool isTopLevelObjCKeyword(tok::ObjCKeywordKind DirectiveKind) {
   }
 }
 
-///   objc-interface-decl-list:
-///     empty
-///     objc-interface-decl-list objc-property-decl [OBJC2]
-///     objc-interface-decl-list objc-method-requirement [OBJC2]
-///     objc-interface-decl-list objc-method-proto ';'
-///     objc-interface-decl-list declaration
-///     objc-interface-decl-list ';'
-///
-///   objc-method-requirement: [OBJC2]
-///     @required
-///     @optional
-///
 void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
                                         Decl *CDecl) {
   SmallVector<Decl *, 32> allMethods;
@@ -870,32 +787,6 @@ static void diagnoseRedundantPropertyNullability(Parser &P,
     << SourceRange(DS.getNullabilityLoc());
 }
 
-///   Parse property attribute declarations.
-///
-///   property-attr-decl: '(' property-attrlist ')'
-///   property-attrlist:
-///     property-attribute
-///     property-attrlist ',' property-attribute
-///   property-attribute:
-///     getter '=' identifier
-///     setter '=' identifier ':'
-///     direct
-///     readonly
-///     readwrite
-///     assign
-///     retain
-///     copy
-///     nonatomic
-///     atomic
-///     strong
-///     weak
-///     unsafe_unretained
-///     nonnull
-///     nullable
-///     null_unspecified
-///     null_resettable
-///     class
-///
 void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
   assert(Tok.getKind() == tok::l_paren);
   BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -1033,16 +924,6 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
   T.consumeClose();
 }
 
-///   objc-method-proto:
-///     objc-instance-method objc-method-decl objc-method-attributes[opt]
-///     objc-class-method objc-method-decl objc-method-attributes[opt]
-///
-///   objc-instance-method: '-'
-///   objc-class-method: '+'
-///
-///   objc-method-attributes:         [OBJC2]
-///     __attribute__((deprecated))
-///
 Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
                                        bool MethodDefinition) {
   assert(Tok.isOneOf(tok::minus, tok::plus) && "expected +/-");
@@ -1056,14 +937,6 @@ Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
   return MDecl;
 }
 
-///   objc-selector:
-///     identifier
-///     one of
-///       enum struct union if else while do for switch case default
-///       break continue return goto asm sizeof typeof __alignof
-///       unsigned long const short volatile signed restrict _Complex
-///       in out inout bycopy byref oneway int char float double void _Bool
-///
 IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
 
   switch (Tok.getKind()) {
@@ -1170,8 +1043,6 @@ IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
   }
 }
 
-///  objc-for-collection-in: 'in'
-///
 bool Parser::isTokIdentifier_in() const {
   // FIXME: May have to do additional look-ahead to only allow for
   // valid tokens following an 'in'; such as an identifier, unary operators,
@@ -1181,25 +1052,6 @@ bool Parser::isTokIdentifier_in() const {
               ObjCTypeQuals[llvm::to_underlying(ObjCTypeQual::in)]);
 }
 
-/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
-/// qualifier list and builds their bitmask representation in the input
-/// argument.
-///
-///   objc-type-qualifiers:
-///     objc-type-qualifier
-///     objc-type-qualifiers objc-type-qualifier
-///
-///   objc-type-qualifier:
-///     'in'
-///     'out'
-///     'inout'
-///     'oneway'
-///     'bycopy'
-///     'byref'
-///     'nonnull'
-///     'nullable'
-///     'null_unspecified'
-///
 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
                                         DeclaratorContext Context) {
   assert(Context == DeclaratorContext::ObjCParameter ||
@@ -1309,10 +1161,6 @@ static void takeDeclAttributes(ParsedAttributes &attrs,
     takeDeclAttributes(attrs, D.getTypeObject(i).getAttrs());
 }
 
-///   objc-type-name:
-///     '(' objc-type-qualifiers[opt] type-name ')'
-///     '(' objc-type-qualifiers[opt] ')'
-///
 ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
                                      DeclaratorContext context,
                                      ParsedAttributes *paramAttrs) {
@@ -1379,34 +1227,6 @@ ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
   return Ty;
 }
 
-///   objc-method-decl:
-///     objc-selector
-///     objc-keyword-selector objc-parmlist[opt]
-///     objc-type-name objc-selector
-///     objc-type-name objc-keyword-selector objc-parmlist[opt]
-///
-///   objc-keyword-selector:
-///     objc-keyword-decl
-///     objc-keyword-selector objc-keyword-decl
-///
-///   objc-keyword-decl:
-///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
-///     objc-selector ':' objc-keyword-attributes[opt] identifier
-///     ':' objc-type-name objc-keyword-attributes[opt] identifier
-///     ':' objc-keyword-attributes[opt] identifier
-///
-///   objc-parmlist:
-///     objc-parms objc-ellipsis[opt]
-///
-///   objc-parms:
-///     objc-parms , parameter-declaration
-///
-///   objc-ellipsis:
-///     , ...
-///
-///   objc-keyword-attributes:         [OBJC2]
-///     __attribute__((unused))
-///
 Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
                                   tok::TokenKind mType,
                                   tok::ObjCKeywordKind MethodImplKind,
@@ -1601,9 +1421,6 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
   return Result;
 }
 
-///   objc-protocol-refs:
-///     '<' identifier-list '>'
-///
 bool Parser::
 ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
                             SmallVectorImpl<SourceLocation> &ProtocolLocs,
@@ -1668,11 +1485,6 @@ TypeResult Parser::parseObjCProtocolQualifierType(SourceLocation &rAngleLoc) {
   return result;
 }
 
-/// Parse Objective-C type arguments or protocol qualifiers.
-///
-///   objc-type-arguments:
-///     '<' type-name '...'[opt] (',' type-name '...'[opt])* '>'
-///
 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
        ParsedType baseType,
        SourceLocation &typeArgsLAngleLoc,
@@ -1950,27 +1762,6 @@ void Parser::HelperActionsForIvarDeclarations(
                       ParsedAttributesView());
 }
 
-///   objc-class-instance-variables:
-///     '{' objc-instance-variable-decl-list[opt] '}'
-///
-///   objc-instance-variable-decl-list:
-///     objc-visibility-spec
-///     objc-instance-variable-decl ';'
-///     ';'
-///     objc-instance-variable-decl-list objc-visibility-spec
-///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
-///     objc-instance-variable-decl-list static_assert-declaration
-///     objc-instance-variable-decl-list ';'
-///
-///   objc-visibility-spec:
-///     @private
-///     @protected
-///     @public
-///     @package [OBJC2]
-///
-///   objc-instance-variable-decl:
-///     struct-declaration
-///
 void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
                                              tok::ObjCKeywordKind visibility,
                                              SourceLocation atLoc) {
@@ -2070,22 +1861,6 @@ void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
                                    T, AllIvarDecls, false);
 }
 
-///   objc-protocol-declaration:
-///     objc-protocol-definition
-///     objc-protocol-forward-reference
-///
-///   objc-protocol-definition:
-///     \@protocol identifier
-///       objc-protocol-refs[opt]
-///       objc-interface-decl-list
-///     \@end
-///
-///   objc-protocol-forward-reference:
-///     \@protocol identifier-list ';'
-///
-///   "\@protocol identifier ;" should be resolved as "\@protocol
-///   identifier-list ;": objc-interface-decl-list may not start with a
-///   semicolon in the first alternative if objc-protocol-refs are omitted.
 Parser::DeclGroupPtrTy
 Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
                                        ParsedAttributes &attrs) {
@@ -2171,16 +1946,6 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
   return Actions.ConvertDeclToDeclGroup(ProtoType);
 }
 
-///   objc-implementation:
-///     objc-class-implementation-prologue
-///     objc-category-implementation-prologue
-///
-///   objc-class-implementation-prologue:
-///     @implementation identifier objc-superclass[opt]
-///       objc-class-instance-variables[opt]
-///
-///   objc-category-implementation-prologue:
-///     @implementation identifier ( identifier )
 Parser::DeclGroupPtrTy
 Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
                                              ParsedAttributes &Attrs) {
@@ -2366,9 +2131,6 @@ void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
   Finished = true;
 }
 
-///   compatibility-alias-decl:
-///     @compatibility_alias alias-name  class-name ';'
-///
 Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
          "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
@@ -2386,17 +2148,6 @@ Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
                                                 classId, classLoc);
 }
 
-///   property-synthesis:
-///     @synthesize property-ivar-list ';'
-///
-///   property-ivar-list:
-///     property-ivar
-///     property-ivar-list ',' property-ivar
-///
-///   property-ivar:
-///     identifier
-///     identifier '=' identifier
-///
 Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
          "ParseObjCPropertySynthesize(): Expected '@synthesize'");
@@ -2445,13 +2196,6 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
   return nullptr;
 }
 
-///   property-dynamic:
-///     @dynamic  property-list
-///
-///   property-list:
-///     identifier
-///     property-list ',' identifier
-///
 Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
          "ParseObjCPropertyDynamic(): Expected '@dynamic'");
@@ -2510,9 +2254,6 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
   return nullptr;
 }
 
-///  objc-throw-statement:
-///    throw expression[opt];
-///
 StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
   ExprResult Res;
   ConsumeToken(); // consume throw
@@ -2528,9 +2269,6 @@ StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
   return Actions.ObjC().ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope());
 }
 
-/// objc-synchronized-statement:
-///   @synchronized '(' expression ')' compound-statement
-///
 StmtResult
 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
   ConsumeToken(); // consume synchronized
@@ -2582,17 +2320,6 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
                                                     body.get());
 }
 
-///  objc-try-catch-statement:
-///    @try compound-statement objc-catch-list[opt]
-///    @try compound-statement objc-catch-list[opt] @finally compound-statement
-///
-///  objc-catch-list:
-///    @catch ( parameter-declaration ) compound-statement
-///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
-///  catch-parameter-declaration:
-///     parameter-declaration
-///     '...' [OBJC2]
-///
 StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
   bool catch_or_finally_seen = false;
 
@@ -2709,9 +2436,6 @@ StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
                                            FinallyStmt.get());
 }
 
-/// objc-autoreleasepool-statement:
-///   @autoreleasepool compound-statement
-///
 StmtResult
 Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
   ConsumeToken(); // consume autoreleasepool
@@ -2732,8 +2456,6 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
                                                      AutoreleasePoolBody.get());
 }
 
-/// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them
-/// for later parsing.
 void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
   if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
       trySkippingFunctionBody()) {
@@ -2776,8 +2498,6 @@ void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
   }
 }
 
-///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
-///
 Decl *Parser::ParseObjCMethodDefinition() {
   Decl *MDecl = ParseObjCMethodPrototype();
 
@@ -2966,28 +2686,6 @@ ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
   }
 }
 
-/// Parse the receiver of an Objective-C++ message send.
-///
-/// This routine parses the receiver of a message send in
-/// Objective-C++ either as a type or as an expression. Note that this
-/// routine must not be called to parse a send to 'super', since it
-/// has no way to return such a result.
-///
-/// \param IsExpr Whether the receiver was parsed as an expression.
-///
-/// \param TypeOrExpr If the receiver was parsed as an expression (\c
-/// IsExpr is true), the parsed expression. If the receiver was parsed
-/// as a type (\c IsExpr is false), the parsed type.
-///
-/// \returns True if an error occurred during parsing or semantic
-/// analysis, in which case the arguments do not have valid
-/// values. Otherwise, returns false for a successful parse.
-///
-///   objc-receiver: [C++]
-///     'super' [not parsed here]
-///     expression
-///     simple-type-specifier
-///     typename-specifier
 bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
   InMessageExpressionRAIIObject InMessage(*this, true);
 
@@ -3057,11 +2755,6 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
   return false;
 }
 
-/// Determine whether the parser is currently referring to a an
-/// Objective-C message send, using a simplified heuristic to avoid overhead.
-///
-/// This routine will only return true for a subset of valid message-send
-/// expressions.
 bool Parser::isSimpleObjCMessageExpression() {
   assert(Tok.is(tok::l_square) && getLangOpts().ObjC &&
          "Incorrect start for isSimpleObjCMessageExpression");
@@ -3098,15 +2791,6 @@ bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
   return false;
 }
 
-///   objc-message-expr:
-///     '[' objc-receiver objc-message-args ']'
-///
-///   objc-receiver: [C]
-///     'super'
-///     expression
-///     class-name
-///     type-name
-///
 ExprResult Parser::ParseObjCMessageExpression() {
   assert(Tok.is(tok::l_square) && "'[' expected");
   SourceLocation LBracLoc = ConsumeBracket(); // consume '['
@@ -3202,44 +2886,6 @@ ExprResult Parser::ParseObjCMessageExpression() {
                                         Res.get());
 }
 
-/// Parse the remainder of an Objective-C message following the
-/// '[' objc-receiver.
-///
-/// This routine handles sends to super, class messages (sent to a
-/// class name), and instance messages (sent to an object), and the
-/// target is represented by \p SuperLoc, \p ReceiverType, or \p
-/// ReceiverExpr, respectively. Only one of these parameters may have
-/// a valid value.
-///
-/// \param LBracLoc The location of the opening '['.
-///
-/// \param SuperLoc If this is a send to 'super', the location of the
-/// 'super' keyword that indicates a send to the superclass.
-///
-/// \param ReceiverType If this is a class message, the type of the
-/// class we are sending a message to.
-///
-/// \param ReceiverExpr If this is an instance message, the expression
-/// used to compute the receiver object.
-///
-///   objc-message-args:
-///     objc-selector
-///     objc-keywordarg-list
-///
-///   objc-keywordarg-list:
-///     objc-keywordarg
-///     objc-keywordarg-list objc-keywordarg
-///
-///   objc-keywordarg:
-///     selector-name[opt] ':' objc-keywordexpr
-///
-///   objc-keywordexpr:
-///     nonempty-expr-list
-///
-///   nonempty-expr-list:
-///     assignment-expression
-///     nonempty-expr-list , assignment-expression
-///
 ExprResult
 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
                                        SourceLocation SuperLoc,
@@ -3437,20 +3083,12 @@ ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
   return Actions.ObjC().ParseObjCStringLiteral(AtLocs.data(), AtStrings);
 }
 
-/// ParseObjCBooleanLiteral -
-/// objc-scalar-literal : '@' boolean-keyword
-///                        ;
-/// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
-///                        ;
 ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc,
                                            bool ArgValue) {
   SourceLocation EndLoc = ConsumeToken();             // consume the keyword.
   return Actions.ObjC().ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
 }
 
-/// ParseObjCCharacterLiteral -
-/// objc-scalar-literal : '@' character-literal
-///                        ;
 ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
   ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
   if (Lit.isInvalid()) {
@@ -3460,11 +3098,6 @@ ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
   return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get());
 }
 
-/// ParseObjCNumericLiteral -
-/// objc-scalar-literal : '@' scalar-literal
-///                        ;
-/// scalar-literal : | numeric-constant			/* any numeric constant. */
-///                    ;
 ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
   ExprResult Lit(Actions.ActOnNumericConstant(Tok));
   if (Lit.isInvalid()) {
@@ -3474,9 +3107,6 @@ ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
   return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get());
 }
 
-/// ParseObjCBoxedExpr -
-/// objc-box-expression:
-///       @( assignment-expression )
 ExprResult
 Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
   if (Tok.isNot(tok::l_paren))
@@ -3608,8 +3238,6 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
                                                    Elements);
 }
 
-///    objc-encode-expression:
-///      \@encode ( type-name )
 ExprResult
 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
@@ -3633,8 +3261,6 @@ Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
       AtLoc, EncLoc, T.getOpenLocation(), Ty.get(), T.getCloseLocation());
 }
 
-///     objc-protocol-expression
-///       \@protocol ( protocol-name )
 ExprResult
 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
   SourceLocation ProtoLoc = ConsumeToken();
@@ -3658,8 +3284,6 @@ Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
       T.getCloseLocation());
 }
 
-///     objc-selector-expression
-///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
 ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
   SourceLocation SelectorLoc = ConsumeToken();
 
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 3843e1ad51cf5..865e78b9164df 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -665,8 +665,6 @@ ExprResult Parser::ParseOpenACCConditionExpr() {
   return R.isInvalid() ? ExprError() : R.get().second;
 }
 
-// Tries to parse the 'modifier-list' for a 'copy', 'copyin', 'copyout', or
-// 'create' clause.
 OpenACCModifierKind Parser::tryParseModifierList(OpenACCClauseKind CK) {
   // Use the tentative parsing to decide whether we are a comma-delmited list of
   // identifers ending in a colon so we can do an actual parse with diagnostics.
@@ -729,11 +727,6 @@ OpenACCModifierKind Parser::tryParseModifierList(OpenACCClauseKind CK) {
   return CurModList;
 }
 
-// OpenACC 3.3, section 1.7:
-// To simplify the specification and convey appropriate constraint information,
-// a pqr-list is a comma-separated list of pdr items. The one exception is a
-// clause-list, which is a list of one or more clauses optionally separated by
-// commas.
 SmallVector<OpenACCClause *>
 Parser::ParseOpenACCClauseList(OpenACCDirectiveKind DirKind) {
   SmallVector<OpenACCClause *> Clauses;
@@ -807,15 +800,6 @@ bool Parser::ParseOpenACCIntExprList(OpenACCDirectiveKind DK,
   return false;
 }
 
-/// OpenACC 3.3 Section 2.4:
-/// The argument to the device_type clause is a comma-separated list of one or
-/// more device architecture name identifiers, or an asterisk.
-///
-/// The syntax of the device_type clause is
-/// device_type( * )
-/// device_type( device-type-list )
-///
-/// The device_type clause may be abbreviated to dtype.
 bool Parser::ParseOpenACCDeviceTypeList(
     llvm::SmallVector<IdentifierLoc> &Archs) {
 
@@ -841,12 +825,6 @@ bool Parser::ParseOpenACCDeviceTypeList(
   return false;
 }
 
-/// OpenACC 3.3 Section 2.9:
-/// size-expr is one of:
-//    *
-//    int-expr
-// Note that this is specified under 'gang-arg-list', but also applies to 'tile'
-// via reference.
 ExprResult Parser::ParseOpenACCSizeExpr(OpenACCClauseKind CK) {
   // The size-expr ends up being ambiguous when only looking at the current
   // token, as it could be a deref of a variable/expression.
@@ -895,12 +873,6 @@ bool Parser::ParseOpenACCSizeExprList(
   return false;
 }
 
-/// OpenACC 3.3 Section 2.9:
-///
-/// where gang-arg is one of:
-/// [num:]int-expr
-/// dim:int-expr
-/// static:size-expr
 Parser::OpenACCGangArgRes Parser::ParseOpenACCGangArg(SourceLocation GangLoc) {
 
   if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Static, getCurToken()) &&
@@ -967,11 +939,6 @@ bool Parser::ParseOpenACCGangArgList(
   return false;
 }
 
-// The OpenACC Clause List is a comma or space-delimited list of clauses (see
-// the comment on ParseOpenACCClauseList).  The concept of a 'clause' doesn't
-// really have its owner grammar and each individual one has its own definition.
-// However, they all are named with a single-identifier (or auto/default!)
-// token, followed in some cases by either braces or parens.
 Parser::OpenACCClauseParseResult
 Parser::ParseOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
                            OpenACCDirectiveKind DirKind) {
@@ -1278,23 +1245,12 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
       Actions.OpenACC().ActOnClause(ExistingClauses, ParsedClause));
 }
 
-/// OpenACC 3.3 section 2.16:
-/// In this section and throughout the specification, the term async-argument
-/// means a nonnegative scalar integer expression (int for C or C++, integer for
-/// Fortran), or one of the special values acc_async_noval or acc_async_sync, as
-/// defined in the C header file and the Fortran openacc module. The special
-/// values are negative values, so as not to conflict with a user-specified
-/// nonnegative async-argument.
 Parser::OpenACCIntExprParseResult
 Parser::ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
                                   SourceLocation Loc) {
   return ParseOpenACCIntExpr(DK, CK, Loc);
 }
 
-/// OpenACC 3.3, section 2.16:
-/// In this section and throughout the specification, the term wait-argument
-/// means:
-/// [ devnum : int-expr : ] [ queues : ] async-argument-list
 Parser::OpenACCWaitParseInfo
 Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) {
   OpenACCWaitParseInfo Result;
@@ -1437,13 +1393,6 @@ Parser::ParseOpenACCBindClauseArgument() {
   return cast<StringLiteral>(Res.get());
 }
 
-/// OpenACC 3.3, section 1.6:
-/// In this spec, a 'var' (in italics) is one of the following:
-/// - a variable name (a scalar, array, or composite variable name)
-/// - a subarray specification with subscript ranges
-/// - an array element
-/// - a member of a composite variable
-/// - a common block name between slashes (fortran only)
 Parser::OpenACCVarParseResult Parser::ParseOpenACCVar(OpenACCDirectiveKind DK,
                                                       OpenACCClauseKind CK) {
   OpenACCArraySectionRAII ArraySections(*this);
@@ -1488,10 +1437,6 @@ llvm::SmallVector<Expr *> Parser::ParseOpenACCVarList(OpenACCDirectiveKind DK,
   return Vars;
 }
 
-/// OpenACC 3.3, section 2.10:
-/// In C and C++, the syntax of the cache directive is:
-///
-/// #pragma acc cache ([readonly:]var-list) new-line
 Parser::OpenACCCacheParseInfo Parser::ParseOpenACCCacheVarList() {
   // If this is the end of the line, just return 'false' and count on the close
   // paren diagnostic to catch the issue.
@@ -1673,7 +1618,6 @@ Parser::ParseOpenACCAfterRoutineStmt(OpenACCDirectiveParseInfo &DirInfo) {
       DirInfo.RParenLoc, DirInfo.Clauses, DirInfo.EndLoc, NextStmt.get());
 }
 
-// Parse OpenACC directive on a declaration.
 Parser::DeclGroupPtrTy
 Parser::ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs,
                                   DeclSpec::TST TagType, Decl *TagDecl) {
@@ -1695,7 +1639,6 @@ Parser::ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs,
       DirInfo.RParenLoc, DirInfo.EndLoc, DirInfo.Clauses));
 }
 
-// Parse OpenACC Directive on a Statement.
 StmtResult Parser::ParseOpenACCDirectiveStmt() {
   assert(Tok.is(tok::annot_pragma_openacc) && "expected OpenACC Start Token");
 
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 8d8698e61216f..b5af23961527c 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -276,16 +276,6 @@ static DeclarationName parseOpenMPReductionId(Parser &P) {
                         : DeclNames.getCXXOperatorName(OOK);
 }
 
-/// Parse 'omp declare reduction' construct.
-///
-///       declare-reduction-directive:
-///        annot_pragma_openmp 'declare' 'reduction'
-///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
-///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
-///        annot_pragma_openmp_end
-/// <reduction_id> is either a base language identifier or one of the following
-/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
-///
 Parser::DeclGroupPtrTy
 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
   // Parse '('.
@@ -529,14 +519,6 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
   }
 }
 
-/// Parses 'omp declare mapper' directive.
-///
-///       declare-mapper-directive:
-///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
-///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
-///         annot_pragma_openmp_end
-/// <mapper-identifier> and <var> are base language identifiers.
-///
 Parser::DeclGroupPtrTy
 Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
   bool IsCorrect = true;
@@ -797,7 +779,6 @@ static bool parseDeclareSimdClauses(
   return IsError;
 }
 
-/// Parse clauses for '#pragma omp declare simd'.
 Parser::DeclGroupPtrTy
 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
                                    CachedTokens &Toks, SourceLocation Loc) {
@@ -1136,9 +1117,6 @@ static ExprResult parseContextScore(Parser &P) {
   return ScoreExpr;
 }
 
-/// Parses an OpenMP context selector.
-///
-/// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
 void Parser::parseOMPContextSelector(
     OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
     llvm::StringMap<SourceLocation> &SeenSelectors) {
@@ -1308,9 +1286,6 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
       << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
 }
 
-/// Parses an OpenMP context selector set.
-///
-/// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
 void Parser::parseOMPContextSelectorSet(
     OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
   auto OuterBC = BraceCount;
@@ -1385,9 +1360,6 @@ void Parser::parseOMPContextSelectorSet(
   }
 }
 
-/// Parse OpenMP context selectors:
-///
-/// <trait-set-selector> [, <trait-set-selector>]*
 bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) {
   llvm::StringMap<SourceLocation> SeenSets;
   do {
@@ -1400,7 +1372,6 @@ bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) {
   return false;
 }
 
-/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
 void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
                                            CachedTokens &Toks,
                                            SourceLocation Loc) {
@@ -1649,13 +1620,6 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
   return false;
 }
 
-/// <clause> [clause[ [,] clause] ... ]
-///
-///  clauses: for error directive
-///     'at' '(' compilation | execution ')'
-///     'severity' '(' fatal | warning ')'
-///     'message' '(' msg-string ')'
-/// ....
 void Parser::ParseOpenMPClauses(OpenMPDirectiveKind DKind,
                                 SmallVectorImpl<OMPClause *> &Clauses,
                                 SourceLocation Loc) {
@@ -1683,19 +1647,6 @@ void Parser::ParseOpenMPClauses(OpenMPDirectiveKind DKind,
   }
 }
 
-/// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
-/// where
-///
-///   clause:
-///     'ext_IMPL_DEFINED'
-///     'absent' '(' directive-name [, directive-name]* ')'
-///     'contains' '(' directive-name [, directive-name]* ')'
-///     'holds' '(' scalar-expression ')'
-///     'no_openmp'
-///     'no_openmp_routines'
-///     'no_openmp_constructs' (OpenMP 6.0)
-///     'no_parallelism'
-///
 void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
                                          SourceLocation Loc) {
   SmallVector<std::string, 4> Assumptions;
@@ -2027,42 +1978,6 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
     ConsumeAnnotationToken();
 }
 
-/// Parsing of declarative OpenMP directives.
-///
-///       threadprivate-directive:
-///         annot_pragma_openmp 'threadprivate' simple-variable-list
-///         annot_pragma_openmp_end
-///
-///       allocate-directive:
-///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
-///         annot_pragma_openmp_end
-///
-///       declare-reduction-directive:
-///        annot_pragma_openmp 'declare' 'reduction' [...]
-///        annot_pragma_openmp_end
-///
-///       declare-mapper-directive:
-///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
-///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
-///         annot_pragma_openmp_end
-///
-///       declare-simd-directive:
-///         annot_pragma_openmp 'declare simd' {<clause> [,]}
-///         annot_pragma_openmp_end
-///         <function declaration/definition>
-///
-///       requires directive:
-///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
-///         annot_pragma_openmp_end
-///
-///       assumes directive:
-///         annot_pragma_openmp 'assumes' <clause> [[[,] <clause>] ... ]
-///         annot_pragma_openmp_end
-///       or
-///         annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
-///         annot_pragma_openmp 'end assumes'
-///         annot_pragma_openmp_end
-///
 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
     AccessSpecifier &AS, ParsedAttributes &Attrs, bool Delayed,
     DeclSpec::TST TagType, Decl *Tag) {
@@ -2657,46 +2572,6 @@ StmtResult Parser::ParseOpenMPInformationalDirective(
   return Directive;
 }
 
-/// Parsing of declarative or executable OpenMP directives.
-///
-///       threadprivate-directive:
-///         annot_pragma_openmp 'threadprivate' simple-variable-list
-///         annot_pragma_openmp_end
-///
-///       allocate-directive:
-///         annot_pragma_openmp 'allocate' simple-variable-list
-///         annot_pragma_openmp_end
-///
-///       declare-reduction-directive:
-///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
-///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
-///         ('omp_priv' '=' <expression>|<function_call>) ')']
-///         annot_pragma_openmp_end
-///
-///       declare-mapper-directive:
-///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
-///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
-///         annot_pragma_openmp_end
-///
-///       executable-directive:
-///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
-///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
-///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
-///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'error'
-///         | 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
-///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
-///         'master taskloop' | 'master taskloop simd' | 'parallel master
-///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
-///         enter data' | 'target exit data' | 'target parallel' | 'target
-///         parallel for' | 'target update' | 'distribute parallel for' |
-///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
-///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
-///         simd' | 'teams distribute parallel for simd' | 'teams distribute
-///         parallel for' | 'target teams' | 'target teams distribute' | 'target
-///         teams distribute parallel for' | 'target teams distribute parallel
-///         for simd' | 'target teams distribute simd' | 'masked' |
-///         'parallel masked' {clause} annot_pragma_openmp_end
-///
 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
     ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective) {
   if (!ReadDirectiveWithinMetadirective)
@@ -3040,10 +2915,6 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
   return Directive;
 }
 
-// Parses simple list:
-//   simple-variable-list:
-//         '(' id-expression {, id-expression} ')'
-//
 bool Parser::ParseOpenMPSimpleVarList(
     OpenMPDirectiveKind Kind,
     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
@@ -3179,26 +3050,6 @@ OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
       Loc, T.getOpenLocation(), T.getCloseLocation(), Data);
 }
 
-/// Parsing of OpenMP clauses.
-///
-///    clause:
-///       if-clause | final-clause | num_threads-clause | safelen-clause |
-///       default-clause | private-clause | firstprivate-clause | shared-clause
-///       | linear-clause | aligned-clause | collapse-clause | bind-clause |
-///       lastprivate-clause | reduction-clause | proc_bind-clause |
-///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
-///       mergeable-clause | flush-clause | read-clause | write-clause |
-///       update-clause | capture-clause | seq_cst-clause | device-clause |
-///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
-///       thread_limit-clause | priority-clause | grainsize-clause |
-///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
-///       from-clause | is_device_ptr-clause | task_reduction-clause |
-///       in_reduction-clause | allocator-clause | allocate-clause |
-///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
-///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
-///       exclusive-clause | uses_allocators-clause | use_device_addr-clause |
-///       has_device_addr
-///
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                      OpenMPClauseKind CKind, bool FirstClause) {
   OMPClauseKind = CKind;
@@ -3576,50 +3427,6 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
   return Val;
 }
 
-/// Parsing of OpenMP clauses with single expressions like 'final',
-/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
-/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
-/// 'detach'.
-///
-///    final-clause:
-///      'final' '(' expression ')'
-///
-///    num_threads-clause:
-///      'num_threads' '(' expression ')'
-///
-///    safelen-clause:
-///      'safelen' '(' expression ')'
-///
-///    simdlen-clause:
-///      'simdlen' '(' expression ')'
-///
-///    collapse-clause:
-///      'collapse' '(' expression ')'
-///
-///    priority-clause:
-///      'priority' '(' expression ')'
-///
-///    grainsize-clause:
-///      'grainsize' '(' expression ')'
-///
-///    num_tasks-clause:
-///      'num_tasks' '(' expression ')'
-///
-///    hint-clause:
-///      'hint' '(' expression ')'
-///
-///    allocator-clause:
-///      'allocator' '(' expression ')'
-///
-///    detach-clause:
-///      'detach' '(' event-handler-expression ')'
-///
-///    align-clause
-///      'align' '(' positive-integer-constant ')'
-///
-///    holds-clause
-///      'holds' '(' expression ')'
-///
 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                                bool ParseOnly) {
   SourceLocation Loc = ConsumeToken();
@@ -3637,10 +3444,6 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                                       LLoc, RLoc);
 }
 
-/// Parse indirect clause for '#pragma omp declare target' directive.
-///  'indirect' '[' '(' invoked-by-fptr ')' ']'
-/// where invoked-by-fptr is a constant boolean expression that evaluates to
-/// true or false at compile time.
 bool Parser::ParseOpenMPIndirectClause(
     SemaOpenMP::DeclareTargetContextInfo &DTCI, bool ParseOnly) {
   SourceLocation Loc = ConsumeToken();
@@ -3678,8 +3481,6 @@ bool Parser::ParseOpenMPIndirectClause(
   return false;
 }
 
-/// Parses a comma-separated list of interop-types and a prefer_type list.
-///
 bool Parser::ParseOMPInteropInfo(OMPInteropInfo &InteropInfo,
                                  OpenMPClauseKind Kind) {
   const Token &Tok = getCurToken();
@@ -3762,29 +3563,6 @@ bool Parser::ParseOMPInteropInfo(OMPInteropInfo &InteropInfo,
   return HasError;
 }
 
-/// Parsing of OpenMP clauses that use an interop-var.
-///
-/// init-clause:
-///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
-///
-/// destroy-clause:
-///   destroy(interop-var)
-///
-/// use-clause:
-///   use(interop-var)
-///
-/// interop-modifier:
-///   prefer_type(preference-list)
-///
-/// preference-list:
-///   foreign-runtime-id [, foreign-runtime-id]...
-///
-/// foreign-runtime-id:
-///   <string-literal> | <constant-integral-expression>
-///
-/// interop-type:
-///   target | targetsync
-///
 OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
                                             bool ParseOnly) {
   SourceLocation Loc = ConsumeToken();
@@ -3888,21 +3666,6 @@ OMPClause *Parser::ParseOpenMPOMPXAttributesClause(bool ParseOnly) {
       Attrs, Loc, T.getOpenLocation(), T.getCloseLocation());
 }
 
-/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
-///
-///    default-clause:
-///         'default' '(' 'none' | 'shared' | 'private' | 'firstprivate' ')'
-///
-///    proc_bind-clause:
-///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
-///
-///    bind-clause:
-///         'bind' '(' 'teams' | 'parallel' | 'thread' ')'
-///
-///    update-clause:
-///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' |
-///         'inoutset' ')'
-///
 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
                                            bool ParseOnly) {
   std::optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
@@ -3924,32 +3687,6 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
       Kind, Val->Type, Val->TypeLoc, Val->LOpen, Val->Loc, Val->RLoc);
 }
 
-/// Parsing of OpenMP clauses like 'ordered'.
-///
-///    ordered-clause:
-///         'ordered'
-///
-///    nowait-clause:
-///         'nowait'
-///
-///    untied-clause:
-///         'untied'
-///
-///    mergeable-clause:
-///         'mergeable'
-///
-///    read-clause:
-///         'read'
-///
-///    threads-clause:
-///         'threads'
-///
-///    simd-clause:
-///         'simd'
-///
-///    nogroup-clause:
-///         'nogroup'
-///
 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
   SourceLocation Loc = Tok.getLocation();
   ConsumeAnyToken();
@@ -3959,22 +3696,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
   return Actions.OpenMP().ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
 }
 
-/// Parsing of OpenMP clauses with single expressions and some additional
-/// argument like 'schedule' or 'dist_schedule'.
-///
-///    schedule-clause:
-///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
-///      ')'
-///
-///    if-clause:
-///      'if' '(' [ directive-name-modifier ':' ] expression ')'
-///
-///    defaultmap:
-///      'defaultmap' '(' modifier [ ':' kind ] ')'
-///
-///    device-clause:
-///      'device' '(' [ device-modifier ':' ] expression ')'
-///
 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
                                                       OpenMPClauseKind Kind,
                                                       bool ParseOnly) {
@@ -4281,7 +4002,6 @@ static OpenMPMapModifierKind isMapModifier(Parser &P) {
   return TypeModifier;
 }
 
-/// Parse the mapper modifier in map, to, and from clauses.
 bool Parser::parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data) {
   // Parse '('.
   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
@@ -4312,11 +4032,6 @@ bool Parser::parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data) {
 
 static OpenMPMapClauseKind isMapType(Parser &P);
 
-/// Parse map-type-modifiers in map clause.
-/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] [map-type] : ] list)
-/// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
-/// present
-/// where, map-type ::= alloc | delete | from | release | to | tofrom
 bool Parser::parseMapTypeModifiers(SemaOpenMP::OpenMPVarListDataTy &Data) {
   bool HasMapType = false;
   SourceLocation PreMapLoc = Tok.getLocation();
@@ -4444,8 +4159,6 @@ static void parseMapType(Parser &P, SemaOpenMP::OpenMPVarListDataTy &Data) {
   P.ConsumeToken();
 }
 
-/// Parses simple expression in parens for single-expression clauses of OpenMP
-/// constructs.
 ExprResult Parser::ParseOpenMPIteratorsExpr() {
   assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
          "Expected 'iterator' token.");
@@ -4683,7 +4396,6 @@ parseOpenMPAllocateClauseModifiers(Parser &P, OpenMPClauseKind Kind,
   return Tail;
 }
 
-/// Parses clauses with list.
 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
                                 OpenMPClauseKind Kind,
                                 SmallVectorImpl<Expr *> &Vars,
@@ -5172,66 +4884,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
          InvalidReductionId || IsInvalidMapperModifier || InvalidIterator;
 }
 
-/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
-/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
-/// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
-///
-///    private-clause:
-///       'private' '(' list ')'
-///    firstprivate-clause:
-///       'firstprivate' '(' list ')'
-///    lastprivate-clause:
-///       'lastprivate' '(' list ')'
-///    shared-clause:
-///       'shared' '(' list ')'
-///    linear-clause:
-///       'linear' '(' linear-list [ ':' linear-step ] ')'
-///    aligned-clause:
-///       'aligned' '(' list [ ':' alignment ] ')'
-///    reduction-clause:
-///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
-///    task_reduction-clause:
-///       'task_reduction' '(' reduction-identifier ':' list ')'
-///    in_reduction-clause:
-///       'in_reduction' '(' reduction-identifier ':' list ')'
-///    copyprivate-clause:
-///       'copyprivate' '(' list ')'
-///    flush-clause:
-///       'flush' '(' list ')'
-///    depend-clause:
-///       'depend' '(' in | out | inout : list | source ')'
-///    map-clause:
-///       'map' '(' [ [ always [,] ] [ close [,] ]
-///          [ mapper '(' mapper-identifier ')' [,] ]
-///          to | from | tofrom | alloc | release | delete ':' ] list ')';
-///    to-clause:
-///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
-///    from-clause:
-///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
-///    use_device_ptr-clause:
-///       'use_device_ptr' '(' list ')'
-///    use_device_addr-clause:
-///       'use_device_addr' '(' list ')'
-///    is_device_ptr-clause:
-///       'is_device_ptr' '(' list ')'
-///    has_device_addr-clause:
-///       'has_device_addr' '(' list ')'
-///    allocate-clause:
-///       'allocate' '(' [ allocator ':' ] list ')'
-///       As of OpenMP 5.1 there's also
-///         'allocate' '(' allocate-modifier: list ')'
-///         where allocate-modifier is: 'allocator' '(' allocator ')'
-///    nontemporal-clause:
-///       'nontemporal' '(' list ')'
-///    inclusive-clause:
-///       'inclusive' '(' list ')'
-///    exclusive-clause:
-///       'exclusive' '(' list ')'
-///
-/// For 'linear' clause linear-list may have the following forms:
-///  list
-///  modifier(list)
-/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
                                             OpenMPClauseKind Kind,
                                             bool ParseOnly) {
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 9f9e4bb92af8c..8dae55c84578a 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -704,11 +704,6 @@ void Parser::resetPragmaHandlers() {
   }
 }
 
-/// Handle the annotation token produced for #pragma unused(...)
-///
-/// Each annot_pragma_unused is followed by the argument token so e.g.
-/// "#pragma unused(x,y)" becomes:
-/// annot_pragma_unused 'x' annot_pragma_unused 'y'
 void Parser::HandlePragmaUnused() {
   assert(Tok.is(tok::annot_pragma_unused));
   SourceLocation UnusedLoc = ConsumeAnnotationToken();
@@ -1226,7 +1221,6 @@ bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
   return true;
 }
 
-// #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
                                    SourceLocation PragmaLocation) {
   if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
@@ -1288,9 +1282,6 @@ bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
   return true;
 }
 
-// #pragma strict_gs_check(pop)
-// #pragma strict_gs_check(push, "on" | "off")
-// #pragma strict_gs_check("on" | "off")
 bool Parser::HandlePragmaMSStrictGuardStackCheck(
     StringRef PragmaName, SourceLocation PragmaLocation) {
   if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
@@ -3857,7 +3848,6 @@ bool Parser::HandlePragmaMSFunction(StringRef PragmaName,
   return true;
 }
 
-// #pragma optimize("gsty", on|off)
 bool Parser::HandlePragmaMSOptimize(StringRef PragmaName,
                                     SourceLocation PragmaLocation) {
   Token FirstTok = Tok;
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 546e524932f5e..696ea837f7702 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -36,8 +36,6 @@ using namespace clang;
 // C99 6.8: Statements and Blocks.
 //===----------------------------------------------------------------------===//
 
-/// Parse a standalone statement (for instance, as the body of an 'if',
-/// 'while', or 'for').
 StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,
                                   ParsedStmtContext StmtCtx) {
   StmtResult Res;
@@ -52,55 +50,6 @@ StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,
   return Res;
 }
 
-/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
-///       StatementOrDeclaration:
-///         statement
-///         declaration
-///
-///       statement:
-///         labeled-statement
-///         compound-statement
-///         expression-statement
-///         selection-statement
-///         iteration-statement
-///         jump-statement
-/// [C++]   declaration-statement
-/// [C++]   try-block
-/// [MS]    seh-try-block
-/// [OBC]   objc-throw-statement
-/// [OBC]   objc-try-catch-statement
-/// [OBC]   objc-synchronized-statement
-/// [GNU]   asm-statement
-/// [OMP]   openmp-construct             [TODO]
-///
-///       labeled-statement:
-///         identifier ':' statement
-///         'case' constant-expression ':' statement
-///         'default' ':' statement
-///
-///       selection-statement:
-///         if-statement
-///         switch-statement
-///
-///       iteration-statement:
-///         while-statement
-///         do-statement
-///         for-statement
-///
-///       expression-statement:
-///         expression[opt] ';'
-///
-///       jump-statement:
-///         'goto' identifier ';'
-///         'continue' ';'
-///         'break' ';'
-///         'return' expression[opt] ';'
-/// [GNU]   'goto' '*' expression ';'
-///
-/// [OBC] objc-throw-statement:
-/// [OBC]   '@' 'throw' expression ';'
-/// [OBC]   '@' 'throw' ';'
-///
 StmtResult
 Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
                                     ParsedStmtContext StmtCtx,
@@ -551,7 +500,6 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
   return Res;
 }
 
-/// Parse an expression statement.
 StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
   // If a case keyword is missing, this is where it should be inserted.
   Token OldToken = Tok;
@@ -596,15 +544,6 @@ StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
   return R;
 }
 
-/// ParseSEHTryBlockCommon
-///
-/// seh-try-block:
-///   '__try' compound-statement seh-handler
-///
-/// seh-handler:
-///   seh-except-block
-///   seh-finally-block
-///
 StmtResult Parser::ParseSEHTryBlock() {
   assert(Tok.is(tok::kw___try) && "Expected '__try'");
   SourceLocation TryLoc = ConsumeToken();
@@ -639,11 +578,6 @@ StmtResult Parser::ParseSEHTryBlock() {
                                   Handler.get());
 }
 
-/// ParseSEHExceptBlock - Handle __except
-///
-/// seh-except-block:
-///   '__except' '(' seh-filter-expression ')' compound-statement
-///
 StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
   PoisonIdentifierRAIIObject raii(Ident__exception_code, false),
     raii2(Ident___exception_code, false),
@@ -691,11 +625,6 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
   return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.get(), Block.get());
 }
 
-/// ParseSEHFinallyBlock - Handle __finally
-///
-/// seh-finally-block:
-///   '__finally' compound-statement
-///
 StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyLoc) {
   PoisonIdentifierRAIIObject raii(Ident__abnormal_termination, false),
     raii2(Ident___abnormal_termination, false),
@@ -738,15 +667,6 @@ static void DiagnoseLabelFollowedByDecl(Parser &P, const Stmt *SubStmt) {
   }
 }
 
-/// ParseLabeledStatement - We have an identifier and a ':' after it.
-///
-///       label:
-///         identifier ':'
-/// [GNU]   identifier ':' attributes[opt]
-///
-///       labeled-statement:
-///         label statement
-///
 StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs,
                                          ParsedStmtContext StmtCtx) {
   assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
@@ -815,11 +735,6 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs,
                                 SubStmt.get());
 }
 
-/// ParseCaseStatement
-///       labeled-statement:
-///         'case' constant-expression ':' statement
-/// [GNU]   'case' constant-expression '...' constant-expression ':' statement
-///
 StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
                                       bool MissingCase, ExprResult Expr) {
   assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
@@ -969,11 +884,6 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
   return TopLevelCase;
 }
 
-/// ParseDefaultStatement
-///       labeled-statement:
-///         'default' ':' statement
-/// Note that this does not parse the 'statement' at the end.
-///
 StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
   assert(Tok.is(tok::kw_default) && "Not a default stmt!");
 
@@ -1024,28 +934,6 @@ StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
                                 Scope::DeclScope | Scope::CompoundStmtScope);
 }
 
-/// ParseCompoundStatement - Parse a "{}" block.
-///
-///       compound-statement: [C99 6.8.2]
-///         { block-item-list[opt] }
-/// [GNU]   { label-declarations block-item-list } [TODO]
-///
-///       block-item-list:
-///         block-item
-///         block-item-list block-item
-///
-///       block-item:
-///         declaration
-/// [GNU]   '__extension__' declaration
-///         statement
-///
-/// [GNU] label-declarations:
-/// [GNU]   label-declaration
-/// [GNU]   label-declarations label-declaration
-///
-/// [GNU] label-declaration:
-/// [GNU]   '__label__' identifier-list ';'
-///
 StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
                                           unsigned ScopeFlags) {
   assert(Tok.is(tok::l_brace) && "Not a compound stmt!");
@@ -1062,9 +950,6 @@ StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
   return R;
 }
 
-/// Parse any pragmas at the start of the compound expression. We handle these
-/// separately since some pragmas (FP_CONTRACT) must appear before any C
-/// statement in the compound, but may be intermingled with other pragmas.
 void Parser::ParseCompoundStatementLeadingPragmas() {
   bool checkForPragmas = true;
   while (checkForPragmas) {
@@ -1144,8 +1029,6 @@ void Parser::DiagnoseLabelAtEndOfCompoundStatement() {
   }
 }
 
-/// Consume any extra semi-colons resulting in null statements,
-/// returning true if any tok::semi were consumed.
 bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
   if (!Tok.is(tok::semi))
     return false;
@@ -1193,10 +1076,6 @@ StmtResult Parser::handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx) {
   return Actions.ActOnExprStmt(E, /*DiscardedValue=*/!IsStmtExprResult);
 }
 
-/// ParseCompoundStatementBody - Parse a sequence of statements optionally
-/// followed by a label and invoke the ActOnCompoundStmt action.  This expects
-/// the '{' to be the current token, and consume the '}' at the end of the
-/// block.  It does not manipulate the scope stack.
 StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
   PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
                                 Tok.getLocation(),
@@ -1350,20 +1229,6 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
                                    Stmts, isStmtExpr);
 }
 
-/// ParseParenExprOrCondition:
-/// [C  ]     '(' expression ')'
-/// [C++]     '(' condition ')'
-/// [C++1z]   '(' init-statement[opt] condition ')'
-///
-/// This function parses and performs error recovery on the specified condition
-/// or expression (depending on whether we're in C++ or C mode).  This function
-/// goes out of its way to recover well.  It returns true if there was a parser
-/// error (the right paren couldn't be found), which indicates that the caller
-/// should try to recover harder.  It returns false if the condition is
-/// successfully parsed.  Note that a successful parse can still have semantic
-/// errors in the condition.
-/// Additionally, it will assign the location of the outer-most '(' and ')',
-/// to LParenLoc and RParenLoc, respectively.
 bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
                                        Sema::ConditionResult &Cond,
                                        SourceLocation Loc,
@@ -1518,15 +1383,6 @@ struct MisleadingIndentationChecker {
 
 }
 
-/// ParseIfStatement
-///       if-statement: [C99 6.8.4.1]
-///         'if' '(' expression ')' statement
-///         'if' '(' expression ')' statement 'else' statement
-/// [C++]   'if' '(' condition ')' statement
-/// [C++]   'if' '(' condition ')' statement 'else' statement
-/// [C++23] 'if' '!' [opt] consteval compound-statement
-/// [C++23] 'if' '!' [opt] consteval compound-statement 'else' statement
-///
 StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
   assert(Tok.is(tok::kw_if) && "Not an if stmt!");
   SourceLocation IfLoc = ConsumeToken();  // eat the 'if'.
@@ -1750,10 +1606,6 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
                              ThenStmt.get(), ElseLoc, ElseStmt.get());
 }
 
-/// ParseSwitchStatement
-///       switch-statement:
-///         'switch' '(' expression ')' statement
-/// [C++]   'switch' '(' condition ')' statement
 StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
   assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
   SourceLocation SwitchLoc = ConsumeToken();  // eat the 'switch'.
@@ -1837,10 +1689,6 @@ StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
   return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
 }
 
-/// ParseWhileStatement
-///       while-statement: [C99 6.8.5.1]
-///         'while' '(' expression ')' statement
-/// [C++]   'while' '(' condition ')' statement
 StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
   assert(Tok.is(tok::kw_while) && "Not a while stmt!");
   SourceLocation WhileLoc = Tok.getLocation();
@@ -1917,10 +1765,6 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
   return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
 }
 
-/// ParseDoStatement
-///       do-statement: [C99 6.8.5.2]
-///         'do' statement 'while' '(' expression ')' ';'
-/// Note: this lets the caller parse the end ';'.
 StmtResult Parser::ParseDoStatement() {
   assert(Tok.is(tok::kw_do) && "Not a do stmt!");
   SourceLocation DoLoc = ConsumeToken();  // eat the 'do'.
@@ -2022,29 +1866,6 @@ bool Parser::isForRangeIdentifier() {
   return false;
 }
 
-/// ParseForStatement
-///       for-statement: [C99 6.8.5.3]
-///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
-///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
-/// [C++]   'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
-/// [C++]       statement
-/// [C++0x] 'for'
-///             'co_await'[opt]    [Coroutines]
-///             '(' for-range-declaration ':' for-range-initializer ')'
-///             statement
-/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
-/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
-///
-/// [C++] for-init-statement:
-/// [C++]   expression-statement
-/// [C++]   simple-declaration
-/// [C++23] alias-declaration
-///
-/// [C++0x] for-range-declaration:
-/// [C++0x]   attribute-specifier-seq[opt] type-specifier-seq declarator
-/// [C++0x] for-range-initializer:
-/// [C++0x]   expression
-/// [C++0x]   braced-init-list            [TODO]
 StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
   assert(Tok.is(tok::kw_for) && "Not a for stmt!");
   SourceLocation ForLoc = ConsumeToken();  // eat the 'for'.
@@ -2431,13 +2252,6 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
                               Body.get());
 }
 
-/// ParseGotoStatement
-///       jump-statement:
-///         'goto' identifier ';'
-/// [GNU]   'goto' '*' expression ';'
-///
-/// Note: this lets the caller parse the end ';'.
-///
 StmtResult Parser::ParseGotoStatement() {
   assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
   SourceLocation GotoLoc = ConsumeToken();  // eat the 'goto'.
@@ -2466,34 +2280,16 @@ StmtResult Parser::ParseGotoStatement() {
   return Res;
 }
 
-/// ParseContinueStatement
-///       jump-statement:
-///         'continue' ';'
-///
-/// Note: this lets the caller parse the end ';'.
-///
 StmtResult Parser::ParseContinueStatement() {
   SourceLocation ContinueLoc = ConsumeToken();  // eat the 'continue'.
   return Actions.ActOnContinueStmt(ContinueLoc, getCurScope());
 }
 
-/// ParseBreakStatement
-///       jump-statement:
-///         'break' ';'
-///
-/// Note: this lets the caller parse the end ';'.
-///
 StmtResult Parser::ParseBreakStatement() {
   SourceLocation BreakLoc = ConsumeToken();  // eat the 'break'.
   return Actions.ActOnBreakStmt(BreakLoc, getCurScope());
 }
 
-/// ParseReturnStatement
-///       jump-statement:
-///         'return' expression[opt] ';'
-///         'return' braced-init-list ';'
-///         'co_return' expression[opt] ';'
-///         'co_return' braced-init-list ';'
 StmtResult Parser::ParseReturnStatement() {
   assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
          "Not a return stmt!");
@@ -2599,11 +2395,6 @@ Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
   return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
 }
 
-/// ParseFunctionTryBlock - Parse a C++ function-try-block.
-///
-///       function-try-block:
-///         'try' ctor-initializer[opt] compound-statement handler-seq
-///
 Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
   assert(Tok.is(tok::kw_try) && "Expected 'try'");
   SourceLocation TryLoc = ConsumeToken();
@@ -2676,11 +2467,6 @@ bool Parser::trySkippingFunctionBody() {
   return true;
 }
 
-/// ParseCXXTryBlock - Parse a C++ try-block.
-///
-///       try-block:
-///         'try' compound-statement handler-seq
-///
 StmtResult Parser::ParseCXXTryBlock() {
   assert(Tok.is(tok::kw_try) && "Expected 'try'");
 
@@ -2688,22 +2474,6 @@ StmtResult Parser::ParseCXXTryBlock() {
   return ParseCXXTryBlockCommon(TryLoc);
 }
 
-/// ParseCXXTryBlockCommon - Parse the common part of try-block and
-/// function-try-block.
-///
-///       try-block:
-///         'try' compound-statement handler-seq
-///
-///       function-try-block:
-///         'try' ctor-initializer[opt] compound-statement handler-seq
-///
-///       handler-seq:
-///         handler handler-seq[opt]
-///
-///       [Borland] try-block:
-///         'try' compound-statement seh-except-block
-///         'try' compound-statement seh-finally-block
-///
 StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
   if (Tok.isNot(tok::l_brace))
     return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
@@ -2761,16 +2531,6 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
   }
 }
 
-/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
-///
-///   handler:
-///     'catch' '(' exception-declaration ')' compound-statement
-///
-///   exception-declaration:
-///     attribute-specifier-seq[opt] type-specifier-seq declarator
-///     attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
-///     '...'
-///
 StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
   assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
 
diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp
index f3415c30dde7a..f088a9850346b 100644
--- a/clang/lib/Parse/ParseStmtAsm.cpp
+++ b/clang/lib/Parse/ParseStmtAsm.cpp
@@ -196,7 +196,6 @@ void ClangAsmParserCallback::handleDiagnostic(const llvm::SMDiagnostic &D) {
   TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
 }
 
-/// Parse an identifier in an MS-style inline assembly block.
 ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
                                         unsigned &NumLineToksConsumed,
                                         bool IsUnevaluatedContext) {
@@ -351,7 +350,6 @@ static bool buildMSAsmString(Preprocessor &PP, SourceLocation AsmLoc,
   return false;
 }
 
-// Determine if this is a GCC-style asm statement.
 bool Parser::isGCCAsmStatement(const Token &TokAfterAsm) const {
   return TokAfterAsm.is(tok::l_paren) || isGNUAsmQualifier(TokAfterAsm);
 }
@@ -360,21 +358,6 @@ bool Parser::isGNUAsmQualifier(const Token &TokAfterAsm) const {
   return getGNUAsmQualifier(TokAfterAsm) != GNUAsmQualifiers::AQ_unspecified;
 }
 
-/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
-/// this routine is called to collect the tokens for an MS asm statement.
-///
-/// [MS]  ms-asm-statement:
-///         ms-asm-block
-///         ms-asm-block ms-asm-statement
-///
-/// [MS]  ms-asm-block:
-///         '__asm' ms-asm-line '\n'
-///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
-///
-/// [MS]  ms-asm-instruction-block
-///         ms-asm-line
-///         ms-asm-line '\n' ms-asm-instruction-block
-///
 StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
   SourceManager &SrcMgr = PP.getSourceManager();
   SourceLocation EndLoc = AsmLoc;
@@ -671,15 +654,6 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
                                 ClobberRefs, Exprs, EndLoc);
 }
 
-/// parseGNUAsmQualifierListOpt - Parse a GNU extended asm qualifier list.
-///       asm-qualifier:
-///         volatile
-///         inline
-///         goto
-///
-///       asm-qualifier-list:
-///         asm-qualifier
-///         asm-qualifier-list asm-qualifier
 bool Parser::parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ) {
   while (true) {
     const GNUAsmQualifiers::AQ A = getGNUAsmQualifier(Tok);
@@ -699,25 +673,6 @@ bool Parser::parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ) {
   return false;
 }
 
-/// ParseAsmStatement - Parse a GNU extended asm statement.
-///       asm-statement:
-///         gnu-asm-statement
-///         ms-asm-statement
-///
-/// [GNU] gnu-asm-statement:
-///         'asm' asm-qualifier-list[opt] '(' asm-argument ')' ';'
-///
-/// [GNU] asm-argument:
-///         asm-string-literal
-///         asm-string-literal ':' asm-operands[opt]
-///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-///                 ':' asm-clobbers
-///
-/// [GNU] asm-clobbers:
-///         asm-string-literal
-///         asm-clobbers ',' asm-string-literal
-///
 StmtResult Parser::ParseAsmStatement(bool &msAsm) {
   assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
   SourceLocation AsmLoc = ConsumeToken();
@@ -868,19 +823,6 @@ StmtResult Parser::ParseAsmStatement(bool &msAsm) {
                                  T.getCloseLocation());
 }
 
-/// ParseAsmOperands - Parse the asm-operands production as used by
-/// asm-statement, assuming the leading ':' token was eaten.
-///
-/// [GNU] asm-operands:
-///         asm-operand
-///         asm-operands ',' asm-operand
-///
-/// [GNU] asm-operand:
-///         asm-string-literal '(' expression ')'
-///         '[' identifier ']' asm-string-literal '(' expression ')'
-///
-//
-// FIXME: Avoid unnecessary std::string trashing.
 bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
                                  SmallVectorImpl<Expr *> &Constraints,
                                  SmallVectorImpl<Expr *> &Exprs) {
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index dbe5e94747c67..88a0079483d9b 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -24,9 +24,6 @@
 #include "llvm/Support/TimeProfiler.h"
 using namespace clang;
 
-/// Re-enter a possible template scope, creating as many template parameter
-/// scopes as necessary.
-/// \return The number of template parameter scopes entered.
 unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) {
   return Actions.ActOnReenterTemplateScope(D, [&] {
     S.Enter(Scope::TemplateParamScope);
@@ -34,8 +31,6 @@ unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) {
   });
 }
 
-/// Parse a template declaration, explicit instantiation, or
-/// explicit specialization.
 Parser::DeclGroupPtrTy
 Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
                                              SourceLocation &DeclEnd,
@@ -51,30 +46,6 @@ Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
                                                   AccessSpecifier::AS_none);
 }
 
-/// Parse a template declaration or an explicit specialization.
-///
-/// Template declarations include one or more template parameter lists
-/// and either the function or class template declaration. Explicit
-/// specializations contain one or more 'template < >' prefixes
-/// followed by a (possibly templated) declaration. Since the
-/// syntactic form of both features is nearly identical, we parse all
-/// of the template headers together and let semantic analysis sort
-/// the declarations from the explicit specializations.
-///
-///       template-declaration: [C++ temp]
-///         'export'[opt] 'template' '<' template-parameter-list '>' declaration
-///
-///       template-declaration: [C++2a]
-///         template-head declaration
-///         template-head concept-definition
-///
-///       TODO: requires-clause
-///       template-head: [C++2a]
-///         'template' '<' template-parameter-list '>'
-///             requires-clause[opt]
-///
-///       explicit-specialization: [ C++ temp.expl.spec]
-///         'template' '<' '>' declaration
 Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(
     DeclaratorContext Context, SourceLocation &DeclEnd,
     ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
@@ -186,16 +157,6 @@ Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(
                                                   AS);
 }
 
-/// Parse a single declaration that declares a template,
-/// template specialization, or explicit instantiation of a template.
-///
-/// \param DeclEnd will receive the source location of the last token
-/// within this declaration.
-///
-/// \param AS the access specifier associated with this
-/// declaration. Will be AS_none for namespace-scope declarations.
-///
-/// \returns the new declaration.
 Parser::DeclGroupPtrTy Parser::ParseDeclarationAfterTemplate(
     DeclaratorContext Context, ParsedTemplateInfo &TemplateInfo,
     ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd,
@@ -269,12 +230,6 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationAfterTemplate(
   return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd);
 }
 
-/// \brief Parse a single declaration that declares a concept.
-///
-/// \param DeclEnd will receive the source location of the last token
-/// within this declaration.
-///
-/// \returns the new declaration.
 Decl *
 Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
                                SourceLocation &DeclEnd) {
@@ -363,15 +318,6 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
                                               Attrs);
 }
 
-/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
-/// angle brackets. Depth is the depth of this template-parameter-list, which
-/// is the number of template headers directly enclosing this template header.
-/// TemplateParams is the current list of template parameters we're building.
-/// The template parameter we parse will be added to this list. LAngleLoc and
-/// RAngleLoc will receive the positions of the '<' and '>', respectively,
-/// that enclose this template parameter list.
-///
-/// \returns true if an error occurred, false otherwise.
 bool Parser::ParseTemplateParameters(
     MultiParseScope &TemplateScopes, unsigned Depth,
     SmallVectorImpl<NamedDecl *> &TemplateParams, SourceLocation &LAngleLoc,
@@ -406,14 +352,6 @@ bool Parser::ParseTemplateParameters(
   return false;
 }
 
-/// ParseTemplateParameterList - Parse a template parameter list. If
-/// the parsing fails badly (i.e., closing bracket was left out), this
-/// will try to put the token stream in a reasonable position (closing
-/// a statement, etc.) and return false.
-///
-///       template-parameter-list:    [C++ temp]
-///         template-parameter
-///         template-parameter-list ',' template-parameter
 bool
 Parser::ParseTemplateParameterList(const unsigned Depth,
                              SmallVectorImpl<NamedDecl*> &TemplateParams) {
@@ -448,8 +386,6 @@ Parser::ParseTemplateParameterList(const unsigned Depth,
   return true;
 }
 
-/// Determine whether the parser is at the start of a template
-/// type parameter.
 Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
   if (Tok.is(tok::kw_class)) {
     // "class" may be the start of an elaborated-type-specifier or a
@@ -531,26 +467,6 @@ Parser::TPResult Parser::isStartOfTemplateTypeParameter() {
   }
 }
 
-/// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
-///
-///       template-parameter: [C++ temp.param]
-///         type-parameter
-///         parameter-declaration
-///
-///       type-parameter: (See below)
-///         type-parameter-key ...[opt] identifier[opt]
-///         type-parameter-key identifier[opt] = type-id
-/// (C++2a) type-constraint ...[opt] identifier[opt]
-/// (C++2a) type-constraint identifier[opt] = type-id
-///         'template' '<' template-parameter-list '>' type-parameter-key
-///               ...[opt] identifier[opt]
-///         'template' '<' template-parameter-list '>' type-parameter-key
-///               identifier[opt] '=' id-expression
-///
-///       type-parameter-key:
-///         class
-///         typename
-///
 NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
 
   switch (isStartOfTemplateTypeParameter()) {
@@ -608,8 +524,6 @@ NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
   return ParseNonTypeTemplateParameter(Depth, Position);
 }
 
-/// Check whether the current token is a template-id annotation denoting a
-/// type-constraint.
 bool Parser::isTypeConstraintAnnotation() {
   const Token &T = Tok.is(tok::annot_cxxscope) ? NextToken() : Tok;
   if (T.isNot(tok::annot_template_id))
@@ -619,14 +533,6 @@ bool Parser::isTypeConstraintAnnotation() {
   return ExistingAnnot->Kind == TNK_Concept_template;
 }
 
-/// Try parsing a type-constraint at the current location.
-///
-///     type-constraint:
-///       nested-name-specifier[opt] concept-name
-///       nested-name-specifier[opt] concept-name
-///           '<' template-argument-list[opt] '>'[opt]
-///
-/// \returns true if an error occurred, and false otherwise.
 bool Parser::TryAnnotateTypeConstraint() {
   if (!getLangOpts().CPlusPlus20)
     return false;
@@ -685,15 +591,6 @@ bool Parser::TryAnnotateTypeConstraint() {
   return false;
 }
 
-/// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]).
-/// Other kinds of template parameters are parsed in
-/// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
-///
-///       type-parameter:     [C++ temp.param]
-///         'class' ...[opt][C++0x] identifier[opt]
-///         'class' identifier[opt] '=' type-id
-///         'typename' ...[opt][C++0x] identifier[opt]
-///         'typename' identifier[opt] '=' type-id
 NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
   assert((Tok.isOneOf(tok::kw_class, tok::kw_typename) ||
           isTypeConstraintAnnotation()) &&
@@ -790,18 +687,6 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
   return NewDecl;
 }
 
-/// ParseTemplateTemplateParameter - Handle the parsing of template
-/// template parameters.
-///
-///       type-parameter:    [C++ temp.param]
-///         template-head type-parameter-key ...[opt] identifier[opt]
-///         template-head type-parameter-key identifier[opt] = id-expression
-///       type-parameter-key:
-///         'class'
-///         'typename'       [C++1z]
-///       template-head:     [C++2a]
-///         'template' '<' template-parameter-list '>'
-///             requires-clause[opt]
 NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,
                                                   unsigned Position) {
   assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
@@ -914,12 +799,6 @@ NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,
       ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);
 }
 
-/// ParseNonTypeTemplateParameter - Handle the parsing of non-type
-/// template parameters (e.g., in "template<int Size> class array;").
-///
-///       template-parameter:
-///         ...
-///         parameter-declaration
 NamedDecl *
 Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
   // Parse the declaration-specifiers (i.e., the type).
@@ -1004,21 +883,6 @@ void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
                             AlreadyHasEllipsis, D.hasName());
 }
 
-/// Parses a '>' at the end of a template list.
-///
-/// If this function encounters '>>', '>>>', '>=', or '>>=', it tries
-/// to determine if these tokens were supposed to be a '>' followed by
-/// '>', '>>', '>=', or '>='. It emits an appropriate diagnostic if necessary.
-///
-/// \param RAngleLoc the location of the consumed '>'.
-///
-/// \param ConsumeLastToken if true, the '>' is consumed.
-///
-/// \param ObjCGenericList if true, this is the '>' closing an Objective-C
-/// type parameter or type argument list, rather than a C++ template parameter
-/// or argument list.
-///
-/// \returns true, if current token does not start with '>', false otherwise.
 bool Parser::ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,
                                             SourceLocation &RAngleLoc,
                                             bool ConsumeLastToken,
@@ -1177,17 +1041,6 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,
   return false;
 }
 
-/// Parses a template-id that after the template name has
-/// already been parsed.
-///
-/// This routine takes care of parsing the enclosed template argument
-/// list ('<' template-parameter-list [opt] '>') and placing the
-/// results into a form that can be transferred to semantic analysis.
-///
-/// \param ConsumeLastToken if true, then we will consume the last
-/// token that forms the template-id. Otherwise, we will leave the
-/// last token in the stream (e.g., so that it can be replaced with an
-/// annotation token).
 bool Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
                                               SourceLocation &LAngleLoc,
                                               TemplateArgList &TemplateArgs,
@@ -1222,47 +1075,6 @@ bool Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
          Invalid;
 }
 
-/// Replace the tokens that form a simple-template-id with an
-/// annotation token containing the complete template-id.
-///
-/// The first token in the stream must be the name of a template that
-/// is followed by a '<'. This routine will parse the complete
-/// simple-template-id and replace the tokens with a single annotation
-/// token with one of two different kinds: if the template-id names a
-/// type (and \p AllowTypeAnnotation is true), the annotation token is
-/// a type annotation that includes the optional nested-name-specifier
-/// (\p SS). Otherwise, the annotation token is a template-id
-/// annotation that does not include the optional
-/// nested-name-specifier.
-///
-/// \param Template  the declaration of the template named by the first
-/// token (an identifier), as returned from \c Action::isTemplateName().
-///
-/// \param TNK the kind of template that \p Template
-/// refers to, as returned from \c Action::isTemplateName().
-///
-/// \param SS if non-NULL, the nested-name-specifier that precedes
-/// this template name.
-///
-/// \param TemplateKWLoc if valid, specifies that this template-id
-/// annotation was preceded by the 'template' keyword and gives the
-/// location of that keyword. If invalid (the default), then this
-/// template-id was not preceded by a 'template' keyword.
-///
-/// \param AllowTypeAnnotation if true (the default), then a
-/// simple-template-id that refers to a class template, template
-/// template parameter, or other template that produces a type will be
-/// replaced with a type annotation token. Otherwise, the
-/// simple-template-id is always replaced with a template-id
-/// annotation token.
-///
-/// \param TypeConstraint if true, then this is actually a type-constraint,
-/// meaning that the template argument list can be omitted (and the template in
-/// question must be a concept).
-///
-/// If an unrecoverable parse error occurs and no annotation token can be
-/// formed, this function returns true.
-///
 bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
                                      CXXScopeSpec &SS,
                                      SourceLocation TemplateKWLoc,
@@ -1350,21 +1162,6 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
   return false;
 }
 
-/// Replaces a template-id annotation token with a type
-/// annotation token.
-///
-/// If there was a failure when forming the type from the template-id,
-/// a type annotation token will still be created, but will have a
-/// NULL type pointer to signify an error.
-///
-/// \param SS The scope specifier appearing before the template-id, if any.
-///
-/// \param AllowImplicitTypename whether this is a context where T::type
-/// denotes a dependent type.
-/// \param IsClassName Is this template-id appearing in a context where we
-/// know it names a class, such as in an elaborated-type-specifier or
-/// base-specifier? ('typename' and 'template' are unneeded and disallowed
-/// in those contexts.)
 void Parser::AnnotateTemplateIdTokenAsType(
     CXXScopeSpec &SS, ImplicitTypenameContext AllowImplicitTypename,
     bool IsClassName) {
@@ -1405,7 +1202,6 @@ static bool isEndOfTemplateArgument(Token Tok) {
                      tok::greatergreatergreater);
 }
 
-/// Parse a C++ template template argument.
 ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
   if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
       !Tok.is(tok::annot_cxxscope))
@@ -1483,14 +1279,6 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
   return Result;
 }
 
-/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
-///
-///       template-argument: [C++ 14.2]
-///         constant-expression
-///         type-id
-///         id-expression
-///         braced-init-list  [C++26, DR]
-///
 ParsedTemplateArgument Parser::ParseTemplateArgument() {
   // C++ [temp.arg]p2:
   //   In a template-argument, an ambiguity between a type-id and an
@@ -1543,14 +1331,6 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() {
                                 ExprArg.get(), Loc);
 }
 
-/// ParseTemplateArgumentList - Parse a C++ template-argument-list
-/// (C++ [temp.names]). Returns true if there was an error.
-///
-///       template-argument-list: [C++ 14.2]
-///         template-argument
-///         template-argument-list ',' template-argument
-///
-/// \param Template is only used for code completion, and may be null.
 bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
                                        TemplateTy Template,
                                        SourceLocation OpenLoc) {
@@ -1588,13 +1368,6 @@ bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
   return false;
 }
 
-/// Parse a C++ explicit template instantiation
-/// (C++ [temp.explicit]).
-///
-///       explicit-instantiation:
-///         'extern' [opt] 'template' declaration
-///
-/// Note that the 'extern' is a GNU extension and C++11 feature.
 Parser::DeclGroupPtrTy Parser::ParseExplicitInstantiation(
     DeclaratorContext Context, SourceLocation ExternLoc,
     SourceLocation TemplateLoc, SourceLocation &DeclEnd,
@@ -1622,7 +1395,6 @@ void Parser::LateTemplateParserCallback(void *P, LateParsedTemplate &LPT) {
   ((Parser *)P)->ParseLateTemplatedFuncDef(LPT);
 }
 
-/// Late parse a C++ function template in Microsoft mode.
 void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
   if (!LPT.D)
      return;
@@ -1706,7 +1478,6 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
   }
 }
 
-/// Lex a delayed template function for late parsing.
 void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
   tok::TokenKind kind = Tok.getKind();
   if (!ConsumeAndStoreFunctionPrologue(Toks)) {
@@ -1723,10 +1494,6 @@ void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
   }
 }
 
-/// We've parsed something that could plausibly be intended to be a template
-/// name (\p LHS) followed by a '<' token, and the following code can't possibly
-/// be an expression. Determine if this is likely to be a template-id and if so,
-/// diagnose it.
 bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {
   TentativeParsingAction TPA(*this);
   // FIXME: We could look at the token sequence in a lot more detail here.
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index fcd76c75c9bfb..cc02ee51618aa 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -16,36 +16,6 @@
 #include "clang/Sema/ParsedTemplate.h"
 using namespace clang;
 
-/// isCXXDeclarationStatement - C++-specialized function that disambiguates
-/// between a declaration or an expression statement, when parsing function
-/// bodies. Returns true for declaration, false for expression.
-///
-///         declaration-statement:
-///           block-declaration
-///
-///         block-declaration:
-///           simple-declaration
-///           asm-definition
-///           namespace-alias-definition
-///           using-declaration
-///           using-directive
-/// [C++0x]   static_assert-declaration
-///
-///         asm-definition:
-///           'asm' '(' string-literal ')' ';'
-///
-///         namespace-alias-definition:
-///           'namespace' identifier = qualified-namespace-specifier ';'
-///
-///         using-declaration:
-///           'using' typename[opt] '::'[opt] nested-name-specifier
-///                 unqualified-id ';'
-///           'using' '::' unqualified-id ;
-///
-///         using-directive:
-///           'using' 'namespace' '::'[opt] nested-name-specifier[opt]
-///                 namespace-name ';'
-///
 bool Parser::isCXXDeclarationStatement(
     bool DisambiguatingWithExpression /*=false*/) {
   assert(getLangOpts().CPlusPlus && "Must be called for C++ only.");
@@ -113,26 +83,6 @@ bool Parser::isCXXDeclarationStatement(
   }
 }
 
-/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
-/// between a simple-declaration or an expression-statement.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-/// Returns false if the statement is disambiguated as expression.
-///
-/// simple-declaration:
-///   decl-specifier-seq init-declarator-list[opt] ';'
-///   decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
-///                      brace-or-equal-initializer ';'    [C++17]
-///
-/// (if AllowForRangeDecl specified)
-/// for ( for-range-declaration : for-range-initializer ) statement
-///
-/// for-range-declaration:
-///    decl-specifier-seq declarator
-///    decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
-///
-/// In any of the above cases there can be a preceding attribute-specifier-seq,
-/// but the caller is expected to handle that.
 bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
   // C++ 6.8p1:
   // There is an ambiguity in the grammar involving expression-statements and
@@ -197,8 +147,6 @@ bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
   return TPR == TPResult::True;
 }
 
-/// Try to consume a token sequence that we've already identified as
-/// (potentially) starting a decl-specifier.
 Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
   switch (Tok.getKind()) {
   case tok::kw__Atomic:
@@ -265,14 +213,6 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
   return TPResult::Ambiguous;
 }
 
-/// simple-declaration:
-///   decl-specifier-seq init-declarator-list[opt] ';'
-///
-/// (if AllowForRangeDecl specified)
-/// for ( for-range-declaration : for-range-initializer ) statement
-/// for-range-declaration:
-///    attribute-specifier-seqopt type-specifier-seq declarator
-///
 Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
   bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);
   if (TryConsumeDeclarationSpecifier() == TPResult::Error)
@@ -301,33 +241,6 @@ Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
   return TPResult::Ambiguous;
 }
 
-/// Tentatively parse an init-declarator-list in order to disambiguate it from
-/// an expression.
-///
-///       init-declarator-list:
-///         init-declarator
-///         init-declarator-list ',' init-declarator
-///
-///       init-declarator:
-///         declarator initializer[opt]
-/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
-///
-///       initializer:
-///         brace-or-equal-initializer
-///         '(' expression-list ')'
-///
-///       brace-or-equal-initializer:
-///         '=' initializer-clause
-/// [C++11] braced-init-list
-///
-///       initializer-clause:
-///         assignment-expression
-///         braced-init-list
-///
-///       braced-init-list:
-///         '{' initializer-list ','[opt] '}'
-///         '{' '}'
-///
 Parser::TPResult
 Parser::TryParseInitDeclaratorList(bool MayHaveTrailingReturnType) {
   while (true) {
@@ -519,23 +432,6 @@ bool Parser::isEnumBase(bool AllowSemi) {
   return R != TPResult::False;
 }
 
-/// Disambiguates between a declaration in a condition, a
-/// simple-declaration in an init-statement, and an expression for
-/// a condition of a if/switch statement.
-///
-///       condition:
-///         expression
-///         type-specifier-seq declarator '=' assignment-expression
-/// [C++11] type-specifier-seq declarator '=' initializer-clause
-/// [C++11] type-specifier-seq declarator braced-init-list
-/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
-///             '=' assignment-expression
-///       simple-declaration:
-///         decl-specifier-seq init-declarator-list[opt] ';'
-///
-/// Note that, unlike isCXXSimpleDeclaration, we must disambiguate all the way
-/// to the ';' to disambiguate cases like 'int(x))' (an expression) from
-/// 'int(x);' (a simple-declaration in an init-statement).
 Parser::ConditionOrInitStatement
 Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,
                                                  bool CanBeForRangeDecl) {
@@ -607,23 +503,6 @@ Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,
     return ConditionOrInitStatement::Expression;
 }
 
-/// Determine whether the next set of tokens contains a type-id.
-///
-/// The context parameter states what context we're parsing right
-/// now, which affects how this routine copes with the token
-/// following the type-id. If the context is
-/// TentativeCXXTypeIdContext::InParens, we have already parsed the '(' and we
-/// will cease lookahead when we hit the corresponding ')'. If the context is
-/// TentativeCXXTypeIdContext::AsTemplateArgument, we've already parsed the '<'
-/// or ',' before this template argument, and will cease lookahead when we hit a
-/// '>', '>>' (in C++0x), or ','; or, in C++0x, an ellipsis immediately
-/// preceding such. Returns true for a type-id and false for an expression.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-///
-/// type-id:
-///   type-specifier-seq abstract-declarator[opt]
-///
 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
 
   isAmbiguous = false;
@@ -704,40 +583,6 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
   return TPR == TPResult::True;
 }
 
-/// Returns true if this is a C++11 attribute-specifier. Per
-/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens
-/// always introduce an attribute. In Objective-C++11, this rule does not
-/// apply if either '[' begins a message-send.
-///
-/// If Disambiguate is true, we try harder to determine whether a '[[' starts
-/// an attribute-specifier, and return
-/// CXX11AttributeKind::InvalidAttributeSpecifier if not.
-///
-/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an
-/// Obj-C message send or the start of an attribute. Otherwise, we assume it
-/// is not an Obj-C message send.
-///
-/// C++11 [dcl.attr.grammar]:
-///
-///     attribute-specifier:
-///         '[' '[' attribute-list ']' ']'
-///         alignment-specifier
-///
-///     attribute-list:
-///         attribute[opt]
-///         attribute-list ',' attribute[opt]
-///         attribute '...'
-///         attribute-list ',' attribute '...'
-///
-///     attribute:
-///         attribute-token attribute-argument-clause[opt]
-///
-///     attribute-token:
-///         identifier
-///         identifier '::' identifier
-///
-///     attribute-argument-clause:
-///         '(' balanced-token-seq ')'
 CXX11AttributeKind
 Parser::isCXX11AttributeSpecifier(bool Disambiguate,
                                   bool OuterMightBeMessageSend) {
@@ -941,24 +786,6 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() {
   }
 }
 
-///         operator-function-id:
-///           'operator' operator
-///
-///         operator: one of
-///           new  delete  new[]  delete[]  +  -  *  /  %  ^  [...]
-///
-///         conversion-function-id:
-///           'operator' conversion-type-id
-///
-///         conversion-type-id:
-///           type-specifier-seq conversion-declarator[opt]
-///
-///         conversion-declarator:
-///           ptr-operator conversion-declarator[opt]
-///
-///         literal-operator-id:
-///           'operator' string-literal identifier
-///           'operator' user-defined-string-literal
 Parser::TPResult Parser::TryParseOperatorId() {
   assert(Tok.is(tok::kw_operator));
   ConsumeToken();
@@ -1035,59 +862,6 @@ Parser::TPResult Parser::TryParseOperatorId() {
   return TryParsePtrOperatorSeq();
 }
 
-///         declarator:
-///           direct-declarator
-///           ptr-operator declarator
-///
-///         direct-declarator:
-///           declarator-id
-///           direct-declarator '(' parameter-declaration-clause ')'
-///                 cv-qualifier-seq[opt] exception-specification[opt]
-///           direct-declarator '[' constant-expression[opt] ']'
-///           '(' declarator ')'
-/// [GNU]     '(' attributes declarator ')'
-///
-///         abstract-declarator:
-///           ptr-operator abstract-declarator[opt]
-///           direct-abstract-declarator
-///
-///         direct-abstract-declarator:
-///           direct-abstract-declarator[opt]
-///                 '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-///                 exception-specification[opt]
-///           direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
-///           '(' abstract-declarator ')'
-/// [C++0x]   ...
-///
-///         ptr-operator:
-///           '*' cv-qualifier-seq[opt]
-///           '&'
-/// [C++0x]   '&&'                                                        [TODO]
-///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
-///
-///         cv-qualifier-seq:
-///           cv-qualifier cv-qualifier-seq[opt]
-///
-///         cv-qualifier:
-///           'const'
-///           'volatile'
-///
-///         declarator-id:
-///           '...'[opt] id-expression
-///
-///         id-expression:
-///           unqualified-id
-///           qualified-id                                                [TODO]
-///
-///         unqualified-id:
-///           identifier
-///           operator-function-id
-///           conversion-function-id
-///           literal-operator-id
-///           '~' class-name                                              [TODO]
-///           '~' decltype-specifier                                      [TODO]
-///           template-id                                                 [TODO]
-///
 Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
                                             bool mayHaveIdentifier,
                                             bool mayHaveDirectInit,
@@ -1222,118 +996,7 @@ class TentativeParseCCC final : public CorrectionCandidateCallback {
   }
 };
 }
-/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
-/// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could
-/// be either a decl-specifier or a function-style cast, and TPResult::Error
-/// if a parsing error was found and reported.
-///
-/// If InvalidAsDeclSpec is not null, some cases that would be ill-formed as
-/// declaration specifiers but possibly valid as some other kind of construct
-/// return TPResult::Ambiguous instead of TPResult::False. When this happens,
-/// the intent is to keep trying to disambiguate, on the basis that we might
-/// find a better reason to treat this construct as a declaration later on.
-/// When this happens and the name could possibly be valid in some other
-/// syntactic context, *InvalidAsDeclSpec is set to 'true'. The current cases
-/// that trigger this are:
-///
-///   * When parsing X::Y (with no 'typename') where X is dependent
-///   * When parsing X<Y> where X is undeclared
-///
-///         decl-specifier:
-///           storage-class-specifier
-///           type-specifier
-///           function-specifier
-///           'friend'
-///           'typedef'
-/// [C++11]   'constexpr'
-/// [C++20]   'consteval'
-/// [GNU]     attributes declaration-specifiers[opt]
-///
-///         storage-class-specifier:
-///           'register'
-///           'static'
-///           'extern'
-///           'mutable'
-///           'auto'
-/// [GNU]     '__thread'
-/// [C++11]   'thread_local'
-/// [C11]     '_Thread_local'
-///
-///         function-specifier:
-///           'inline'
-///           'virtual'
-///           'explicit'
-///
-///         typedef-name:
-///           identifier
-///
-///         type-specifier:
-///           simple-type-specifier
-///           class-specifier
-///           enum-specifier
-///           elaborated-type-specifier
-///           typename-specifier
-///           cv-qualifier
-///
-///         simple-type-specifier:
-///           '::'[opt] nested-name-specifier[opt] type-name
-///           '::'[opt] nested-name-specifier 'template'
-///                 simple-template-id                              [TODO]
-///           'char'
-///           'wchar_t'
-///           'bool'
-///           'short'
-///           'int'
-///           'long'
-///           'signed'
-///           'unsigned'
-///           'float'
-///           'double'
-///           'void'
-/// [GNU]     typeof-specifier
-/// [GNU]     '_Complex'
-/// [C++11]   'auto'
-/// [GNU]     '__auto_type'
-/// [C++11]   'decltype' ( expression )
-/// [C++1y]   'decltype' ( 'auto' )
-///
-///         type-name:
-///           class-name
-///           enum-name
-///           typedef-name
-///
-///         elaborated-type-specifier:
-///           class-key '::'[opt] nested-name-specifier[opt] identifier
-///           class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
-///               simple-template-id
-///           'enum' '::'[opt] nested-name-specifier[opt] identifier
-///
-///         enum-name:
-///           identifier
-///
-///         enum-specifier:
-///           'enum' identifier[opt] '{' enumerator-list[opt] '}'
-///           'enum' identifier[opt] '{' enumerator-list ',' '}'
-///
-///         class-specifier:
-///           class-head '{' member-specification[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]
-///
-///         class-key:
-///           'class'
-///           'struct'
-///           'union'
-///
-///         cv-qualifier:
-///           'const'
-///           'volatile'
-/// [GNU]     restrict
-///
+
 Parser::TPResult
 Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
                                   Parser::TPResult BracedCastResult,
@@ -1956,10 +1619,6 @@ bool Parser::isCXXDeclarationSpecifierAType() {
   }
 }
 
-/// [GNU] typeof-specifier:
-///         'typeof' '(' expressions ')'
-///         'typeof' '(' type-name ')'
-///
 Parser::TPResult Parser::TryParseTypeofSpecifier() {
   assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
   ConsumeToken();
@@ -1973,8 +1632,6 @@ Parser::TPResult Parser::TryParseTypeofSpecifier() {
   return TPResult::Ambiguous;
 }
 
-/// [ObjC] protocol-qualifiers:
-////         '<' identifier-list '>'
 Parser::TPResult Parser::TryParseProtocolQualifiers() {
   assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
   ConsumeToken();
@@ -1997,16 +1654,6 @@ Parser::TPResult Parser::TryParseProtocolQualifiers() {
   return TPResult::Error;
 }
 
-/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
-/// a constructor-style initializer, when parsing declaration statements.
-/// Returns true for function declarator and false for constructor-style
-/// initializer.
-/// If during the disambiguation process a parsing error is encountered,
-/// the function returns true to let the declaration parsing code handle it.
-///
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-///         exception-specification[opt]
-///
 bool Parser::isCXXFunctionDeclarator(
     bool *IsAmbiguous, ImplicitTypenameContext AllowImplicitTypename) {
 
@@ -2052,23 +1699,6 @@ bool Parser::isCXXFunctionDeclarator(
   return TPR != TPResult::False;
 }
 
-/// parameter-declaration-clause:
-///   parameter-declaration-list[opt] '...'[opt]
-///   parameter-declaration-list ',' '...'
-///
-/// parameter-declaration-list:
-///   parameter-declaration
-///   parameter-declaration-list ',' parameter-declaration
-///
-/// parameter-declaration:
-///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
-///   attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
-///     '=' assignment-expression
-///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
-///     attributes[opt]
-///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
-///     attributes[opt] '=' assignment-expression
-///
 Parser::TPResult Parser::TryParseParameterDeclarationClause(
     bool *InvalidAsDeclaration, bool VersusTemplateArgument,
     ImplicitTypenameContext AllowImplicitTypename) {
@@ -2182,18 +1812,6 @@ Parser::TPResult Parser::TryParseParameterDeclarationClause(
   return TPResult::Ambiguous;
 }
 
-/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
-/// parsing as a function declarator.
-/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
-/// return TPResult::Ambiguous, otherwise it will return either False() or
-/// Error().
-///
-/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
-///         exception-specification[opt]
-///
-/// exception-specification:
-///   'throw' '(' type-id-list[opt] ')'
-///
 Parser::TPResult
 Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {
   // The '(' is already parsed.
@@ -2259,10 +1877,6 @@ Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {
   return TPResult::Ambiguous;
 }
 
-// When parsing an identifier after an arrow it may be a member expression,
-// in which case we should not annotate it as an independant expression
-// so we just lookup that name, if it's not a type the construct is not
-// a function declaration.
 bool Parser::NameAfterArrowIsNonType() {
   assert(Tok.is(tok::identifier));
   Token Next = NextToken();
@@ -2286,8 +1900,6 @@ bool Parser::NameAfterArrowIsNonType() {
   return false;
 }
 
-/// '[' constant-expression[opt] ']'
-///
 Parser::TPResult Parser::TryParseBracketDeclarator() {
   ConsumeBracket();
 
@@ -2308,10 +1920,6 @@ Parser::TPResult Parser::TryParseBracketDeclarator() {
   return TPResult::Ambiguous;
 }
 
-/// Determine whether we might be looking at the '<' template-argument-list '>'
-/// of a template-id or simple-template-id, rather than a less-than comparison.
-/// This will often fail and produce an ambiguity, but should never be wrong
-/// if it returns True or False.
 Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {
   if (!TokensToSkip) {
     if (Tok.isNot(tok::less))
@@ -2359,8 +1967,6 @@ Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {
   return TPResult::False;
 }
 
-/// Determine whether we might be looking at the '(' of a C++20 explicit(bool)
-/// in an earlier language mode.
 Parser::TPResult Parser::isExplicitBool() {
   assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token");
 
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index cab0604821c03..48260baf6a090 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -59,8 +59,8 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
       PreferredType(&actions.getASTContext(), pp.isCodeCompletionEnabled()),
       Actions(actions), Diags(PP.getDiagnostics()), StackHandler(Diags),
       GreaterThanIsOperator(true), ColonIsSacred(false),
-      InMessageExpression(false), TemplateParameterDepth(0),
-      ParsingInObjCContainer(false) {
+      InMessageExpression(false), ParsingInObjCContainer(false),
+      TemplateParameterDepth(0) {
   SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
   Tok.startToken();
   Tok.setKind(tok::eof);
@@ -101,12 +101,6 @@ DiagnosticBuilder Parser::DiagCompat(const Token &Tok, unsigned CompatDiagId) {
   return DiagCompat(Tok.getLocation(), CompatDiagId);
 }
 
-/// Emits a diagnostic suggesting parentheses surrounding a
-/// given range.
-///
-/// \param Loc The location where we'll emit the diagnostic.
-/// \param DK The kind of diagnostic to emit.
-/// \param ParenRange Source range enclosing code that should be parenthesized.
 void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK,
                                 SourceRange ParenRange) {
   SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd());
@@ -291,14 +285,6 @@ static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) {
   return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;
 }
 
-/// SkipUntil - Read tokens until we get to the specified token, then consume
-/// it (unless no flag StopBeforeMatch).  Because we cannot guarantee that the
-/// token will ever occur, this skips to the next token, or to some likely
-/// good stopping point.  If StopAtSemi is true, skipping will stop at a ';'
-/// character.
-///
-/// If SkipUntil finds the specified token, it returns true, otherwise it
-/// returns false.
 bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
   // We always want this function to skip at least one token if the first token
   // isn't T and if not at EOF.
@@ -432,7 +418,6 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
 // Scope manipulation
 //===----------------------------------------------------------------------===//
 
-/// EnterScope - Start a new scope.
 void Parser::EnterScope(unsigned ScopeFlags) {
   if (NumCachedScopes) {
     Scope *N = ScopeCache[--NumCachedScopes];
@@ -443,7 +428,6 @@ void Parser::EnterScope(unsigned ScopeFlags) {
   }
 }
 
-/// ExitScope - Pop a scope off the scope stack.
 void Parser::ExitScope() {
   assert(getCurScope() && "Scope imbalance!");
 
@@ -460,8 +444,6 @@ void Parser::ExitScope() {
     ScopeCache[NumCachedScopes++] = OldScope;
 }
 
-/// Set the flags for the current scope to ScopeFlags. If ManageFlags is false,
-/// this object does nothing.
 Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags,
                                  bool ManageFlags)
   : CurScope(ManageFlags ? Self->getCurScope() : nullptr) {
@@ -471,8 +453,6 @@ Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags,
   }
 }
 
-/// Restore the flags for the current scope to what they were before this
-/// object overrode them.
 Parser::ParseScopeFlags::~ParseScopeFlags() {
   if (CurScope)
     CurScope->setFlags(OldFlags);
@@ -501,8 +481,6 @@ Parser::~Parser() {
   DestroyTemplateIds();
 }
 
-/// Initialize - Warm up the parser.
-///
 void Parser::Initialize() {
   // Create the translation unit scope.  Install it as the current scope.
   assert(getCurScope() == nullptr && "A scope is already active?");
@@ -612,16 +590,6 @@ void Parser::DestroyTemplateIds() {
   TemplateIds.clear();
 }
 
-/// Parse the first top-level declaration in a translation unit.
-///
-///   translation-unit:
-/// [C]     external-declaration
-/// [C]     translation-unit external-declaration
-/// [C++]   top-level-declaration-seq[opt]
-/// [C++20] global-module-fragment[opt] module-declaration
-///                 top-level-declaration-seq[opt] private-module-fragment[opt]
-///
-/// Note that in C, it is an error if there is no first declaration.
 bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
                                     Sema::ModuleImportState &ImportState) {
   Actions.ActOnStartOfTranslationUnit();
@@ -643,12 +611,6 @@ bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
   return NoTopLevelDecls;
 }
 
-/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
-/// action tells us to.  This returns true if the EOF was encountered.
-///
-///   top-level-declaration:
-///           declaration
-/// [C++20]   module-import-declaration
 bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
                                Sema::ModuleImportState &ImportState) {
   DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
@@ -797,35 +759,6 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
   return false;
 }
 
-/// ParseExternalDeclaration:
-///
-/// The `Attrs` that are passed in are C++11 attributes and appertain to the
-/// declaration.
-///
-///       external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
-///         function-definition
-///         declaration
-/// [GNU]   asm-definition
-/// [GNU]   __extension__ external-declaration
-/// [OBJC]  objc-class-definition
-/// [OBJC]  objc-class-declaration
-/// [OBJC]  objc-alias-declaration
-/// [OBJC]  objc-protocol-definition
-/// [OBJC]  objc-method-definition
-/// [OBJC]  @end
-/// [C++]   linkage-specification
-/// [GNU] asm-definition:
-///         simple-asm-expr ';'
-/// [C++11] empty-declaration
-/// [C++11] attribute-declaration
-///
-/// [C++11] empty-declaration:
-///           ';'
-///
-/// [C++0x/GNU] 'extern' 'template' declaration
-///
-/// [C++20] module-import-declaration
-///
 Parser::DeclGroupPtrTy
 Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
                                  ParsedAttributes &DeclSpecAttrs,
@@ -1103,8 +1036,6 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
   return Actions.ConvertDeclToDeclGroup(SingleDecl);
 }
 
-/// Determine whether the current token, if it occurs after a
-/// declarator, continues a declaration or declaration list.
 bool Parser::isDeclarationAfterDeclarator() {
   // Check for '= delete' or '= default'
   if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
@@ -1122,8 +1053,6 @@ bool Parser::isDeclarationAfterDeclarator() {
      Tok.is(tok::l_paren));         // int X(0) -> not a function def [C++]
 }
 
-/// Determine whether the current token, if it occurs after a
-/// declarator, indicates the start of a function definition.
 bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
   assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator");
   if (Tok.is(tok::l_brace))   // int X() {}
@@ -1143,22 +1072,6 @@ bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
          Tok.is(tok::kw_try);          // X() try { ... }
 }
 
-/// Parse either a function-definition or a declaration.  We can't tell which
-/// we have until we read up to the compound-statement in function-definition.
-/// TemplateParams, if non-NULL, provides the template parameters when we're
-/// parsing a C++ template-declaration.
-///
-///       function-definition: [C99 6.9.1]
-///         decl-specs      declarator declaration-list[opt] compound-statement
-/// [C90] function-definition: [C99 6.7.1] - implicit int result
-/// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
-///
-///       declaration: [C99 6.7]
-///         declaration-specifiers init-declarator-list[opt] ';'
-/// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode]
-/// [OMP]   threadprivate-directive
-/// [OMP]   allocate-directive                         [TODO]
-///
 Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
     ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,
     ParsingDeclSpec &DS, AccessSpecifier AS) {
@@ -1296,20 +1209,6 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition(
   }
 }
 
-/// ParseFunctionDefinition - We parsed and verified that the specified
-/// Declarator is well formed.  If this is a K&R-style function, read the
-/// parameters declaration-list, then start the compound-statement.
-///
-///       function-definition: [C99 6.9.1]
-///         decl-specs      declarator declaration-list[opt] compound-statement
-/// [C90] function-definition: [C99 6.7.1] - implicit int result
-/// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement
-/// [C++] function-definition: [C++ 8.4]
-///         decl-specifier-seq[opt] declarator ctor-initializer[opt]
-///         function-body
-/// [C++] function-definition: [C++ 8.4]
-///         decl-specifier-seq[opt] declarator function-try-block
-///
 Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
                                       const ParsedTemplateInfo &TemplateInfo,
                                       LateParsedAttrList *LateParsedAttrs) {
@@ -1571,8 +1470,6 @@ void Parser::SkipFunctionBody() {
   }
 }
 
-/// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
-/// types for a function with a K&R-style identifier list for arguments.
 void Parser::ParseKNRParamDeclarations(Declarator &D) {
   // We know that the top-level of this declarator is a function.
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
@@ -1686,16 +1583,6 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
   Actions.ActOnFinishKNRParamDeclarations(getCurScope(), D, Tok.getLocation());
 }
 
-
-/// ParseAsmStringLiteral - This is just a normal string-literal, but is not
-/// allowed to be a wide string, and is not subject to character translation.
-/// Unlike GCC, we also diagnose an empty string literal when parsing for an
-/// asm label as opposed to an asm statement, because such a construct does not
-/// behave well.
-///
-/// [GNU] asm-string-literal:
-///         string-literal
-///
 ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
 
   ExprResult AsmString;
@@ -1733,11 +1620,6 @@ ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
   return Actions.ActOnGCCAsmStmtString(AsmString.get(), ForAsmLabel);
 }
 
-/// ParseSimpleAsm
-///
-/// [GNU] simple-asm-expr:
-///         'asm' '(' asm-string-literal ')'
-///
 ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) {
   assert(Tok.is(tok::kw_asm) && "Not an asm!");
   SourceLocation Loc = ConsumeToken();
@@ -1774,9 +1656,6 @@ ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) {
   return Result;
 }
 
-/// Get the TemplateIdAnnotation from the token and put it in the
-/// cleanup pool so that it gets destroyed when parsing the current top level
-/// declaration is finished.
 TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {
   assert(tok.is(tok::annot_template_id) && "Expected template-id token");
   TemplateIdAnnotation *
@@ -1802,16 +1681,6 @@ void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {
     PP.AnnotateCachedTokens(Tok);
 }
 
-/// Attempt to classify the name at the current token position. This may
-/// form a type, scope or primary expression annotation, or replace the token
-/// with a typo-corrected keyword. This is only appropriate when the current
-/// name must refer to an entity which has already been declared.
-///
-/// \param CCC Indicates how to perform typo-correction for this name. If NULL,
-///        no typo correction will be performed.
-/// \param AllowImplicitTypename Whether we are in a context where a dependent
-///        nested-name-specifier without typename is treated as a type (e.g.
-///        T::type).
 AnnotatedNameKind
 Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,
                         ImplicitTypenameContext AllowImplicitTypename) {
@@ -2014,28 +1883,6 @@ bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
   return true;
 }
 
-/// TryAnnotateTypeOrScopeToken - If the current token position is on a
-/// typename (possibly qualified in C++) or a C++ scope specifier not followed
-/// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
-/// with a single annotation token representing the typename or C++ scope
-/// respectively.
-/// This simplifies handling of C++ scope specifiers and allows efficient
-/// backtracking without the need to re-parse and resolve nested-names and
-/// typenames.
-/// It will mainly be called when we expect to treat identifiers as typenames
-/// (if they are typenames). For example, in C we do not expect identifiers
-/// inside expressions to be treated as typenames so it will not be called
-/// for expressions in C.
-/// The benefit for C/ObjC is that a typename will be annotated and
-/// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
-/// will not be called twice, once to check whether we have a declaration
-/// specifier, and another one to get the actual type inside
-/// ParseDeclarationSpecifiers).
-///
-/// This returns true if an error occurred.
-///
-/// Note that this routine emits an error if you call it with ::new or ::delete
-/// as the current tokens, so only call it in contexts where these are invalid.
 bool Parser::TryAnnotateTypeOrScopeToken(
     ImplicitTypenameContext AllowImplicitTypename) {
   assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
@@ -2162,9 +2009,6 @@ bool Parser::TryAnnotateTypeOrScopeToken(
                                                    AllowImplicitTypename);
 }
 
-/// Try to annotate a type or scope token, having already parsed an
-/// optional scope specifier. \p IsNewScope should be \c true unless the scope
-/// specifier was extracted from an existing tok::annot_cxxscope annotation.
 bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
     CXXScopeSpec &SS, bool IsNewScope,
     ImplicitTypenameContext AllowImplicitTypename) {
@@ -2281,12 +2125,6 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
   return false;
 }
 
-/// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
-/// annotates C++ scope specifiers and template-ids.  This returns
-/// true if there was an error that could not be recovered from.
-///
-/// Note that this routine emits an error if you call it with ::new or ::delete
-/// as the current tokens, so only call it in contexts where these are invalid.
 bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
   assert(getLangOpts().CPlusPlus &&
          "Call sites of this function should be guarded by checking for C++");
@@ -2494,19 +2332,6 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
   Braces.consumeClose();
 }
 
-/// Parse a declaration beginning with the 'module' keyword or C++20
-/// context-sensitive keyword (optionally preceded by 'export').
-///
-///   module-declaration:   [C++20]
-///     'export'[opt] 'module' module-name attribute-specifier-seq[opt] ';'
-///
-///   global-module-fragment:  [C++2a]
-///     'module' ';' top-level-declaration-seq[opt]
-///   module-declaration:      [C++2a]
-///     'export'[opt] 'module' module-name module-partition[opt]
-///            attribute-specifier-seq[opt] ';'
-///   private-module-fragment: [C++2a]
-///     'module' ':' 'private' ';' top-level-declaration-seq[opt]
 Parser::DeclGroupPtrTy
 Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
   SourceLocation StartLoc = Tok.getLocation();
@@ -2588,21 +2413,6 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
                                  ImportState);
 }
 
-/// Parse a module import declaration. This is essentially the same for
-/// Objective-C and C++20 except for the leading '@' (in ObjC) and the
-/// trailing optional attributes (in C++).
-///
-/// [ObjC]  @import declaration:
-///           '@' 'import' module-name ';'
-/// [ModTS] module-import-declaration:
-///           'import' module-name attribute-specifier-seq[opt] ';'
-/// [C++20] module-import-declaration:
-///           'export'[opt] 'import' module-name
-///                   attribute-specifier-seq[opt] ';'
-///           'export'[opt] 'import' module-partition
-///                   attribute-specifier-seq[opt] ';'
-///           'export'[opt] 'import' header-name
-///                   attribute-specifier-seq[opt] ';'
 Decl *Parser::ParseModuleImport(SourceLocation AtLoc,
                                 Sema::ModuleImportState &ImportState) {
   SourceLocation StartLoc = AtLoc.isInvalid() ? Tok.getLocation() : AtLoc;
@@ -2728,13 +2538,6 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc,
   return Import.get();
 }
 
-/// Parse a C++ / Objective-C module name (both forms use the same
-/// grammar).
-///
-///         module-name:
-///           module-name-qualifier[opt] identifier
-///         module-name-qualifier:
-///           module-name-qualifier[opt] identifier '.'
 bool Parser::ParseModuleName(SourceLocation UseLoc,
                              SmallVectorImpl<IdentifierLoc> &Path,
                              bool IsImport) {
@@ -2763,10 +2566,6 @@ bool Parser::ParseModuleName(SourceLocation UseLoc,
   }
 }
 
-/// Try recover parser when module annotation appears where it must not
-/// be found.
-/// \returns false if the recover was successful and parsing may be continued, or
-/// true if parser must bail out to top level and handle the token there.
 bool Parser::parseMisplacedModuleImport() {
   while (true) {
     switch (Tok.getKind()) {

>From e0fdb91966d90d323c24d22c94370e5174c734b1 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 3 May 2025 10:50:11 +0300
Subject: [PATCH 2/5] Remove redundant `private` access specifiers and 2 empty
 groups

---
 clang/include/clang/Parse/Parser.h | 83 ++++++------------------------
 1 file changed, 16 insertions(+), 67 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 59836bcfb6136..c23b93826766d 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -158,23 +158,21 @@ class Parser : public CodeCompletionHandler {
   // Table of Contents
   // -----------------
   // 1. Parsing (Parser.cpp)
-  // 2. Parser Entry Point (ParseAST.cpp)
-  // 3. C++ Class Inline Methods (ParseCXXInlineMethods.cpp)
-  // 4. Declarations (ParseDecl.cpp)
-  // 5. C++ Declarations (ParseDeclCXX.cpp)
-  // 6. Expressions (ParseExpr.cpp)
-  // 7. C++ Expressions (ParseExprCXX.cpp)
-  // 8. HLSL Constructs (ParseHLSL.cpp)
-  // 9. HLSL Root Signature (ParseHLSLRootSignature.cpp)
-  // 10. Initializers (ParseInit.cpp)
-  // 11. Objective-C Constructs (ParseObjc.cpp)
-  // 12. OpenACC Constructs (ParseOpenACC.cpp)
-  // 13. OpenMP Constructs (ParseOpenMP.cpp)
-  // 14. Pragmas (ParsePragma.cpp)
-  // 15. Statements (ParseStmt.cpp)
-  // 16. `inline asm` Statement (ParseStmtAsm.cpp)
-  // 17. C++ Templates (ParseTemplate.cpp)
-  // 18. Tentative Parsing (ParseTentative.cpp)
+  // 2. C++ Class Inline Methods (ParseCXXInlineMethods.cpp)
+  // 3. Declarations (ParseDecl.cpp)
+  // 4. C++ Declarations (ParseDeclCXX.cpp)
+  // 5. Expressions (ParseExpr.cpp)
+  // 6. C++ Expressions (ParseExprCXX.cpp)
+  // 7. HLSL Constructs (ParseHLSL.cpp)
+  // 8. Initializers (ParseInit.cpp)
+  // 9. Objective-C Constructs (ParseObjc.cpp)
+  // 10. OpenACC Constructs (ParseOpenACC.cpp)
+  // 11. OpenMP Constructs (ParseOpenMP.cpp)
+  // 12. Pragmas (ParsePragma.cpp)
+  // 13. Statements (ParseStmt.cpp)
+  // 14. `inline asm` Statement (ParseStmtAsm.cpp)
+  // 15. C++ Templates (ParseTemplate.cpp)
+  // 16. Tentative Parsing (ParseTentative.cpp)
 
   /// \name Parsing
   /// Implementations are in Parser.cpp
@@ -1083,33 +1081,12 @@ class Parser : public CodeCompletionHandler {
   //
   //
 
-  /// \name Parser Entry Point
-  /// Implementations are in ParseAST.cpp
-  ///@{
-
-  public:
-
-  private:
-
-  ///@}
-
-  //
-  //
-  // -------------------------------------------------------------------------
-  //
-  //
-
   /// \name C++ Class Inline Methods
   /// Implementations are in ParseCXXInlineMethods.cpp
   ///@{
 
-  public:
-
   private:
 
-  //===--------------------------------------------------------------------===//
-  // Lexing and parsing of C++ inline methods.
-
   struct ParsingClass;
 
   /// [class.mem]p1: "... the class is regarded as complete within
@@ -2761,8 +2738,6 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseDeclCXX.cpp
   ///@{
 
-  public:
-
   private:
 
   /// Contextual keywords for Microsoft extensions.
@@ -4982,8 +4957,6 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseHLSL.cpp
   ///@{
 
-  public:
-
   private:
 
   bool MaybeParseHLSLAnnotations(Declarator &D,
@@ -5019,28 +4992,10 @@ class Parser : public CodeCompletionHandler {
   //
   //
 
-  /// \name HLSL Root Signature
-  /// Implementations are in ParseHLSLRootSignature.cpp
-  ///@{
-
-  public:
-
-  private:
-
-  ///@}
-
-  //
-  //
-  // -------------------------------------------------------------------------
-  //
-  //
-
   /// \name Initializers
   /// Implementations are in ParseInit.cpp
   ///@{
 
-  public:
-
   private:
 
   //===--------------------------------------------------------------------===//
@@ -6068,12 +6023,10 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseOpenMP.cpp
   ///@{
 
-  public:
+  private:
 
   friend class ParsingOpenMPDirectiveRAII;
 
-  private:
-
   /// Parsing OpenMP directive mode.
   bool OpenMPDirectiveParsing = false;
 
@@ -6716,8 +6669,6 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParsePragma.cpp
   ///@{
 
-  public:
-
   private:
 
   std::unique_ptr<PragmaHandler> AlignHandler;
@@ -7987,8 +7938,6 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseTentative.cpp
   ///@{
 
-  public:
-
   private:
 
   /// TentativeParsingAction - An object that is used as a kind of "tentative

>From 1eefa61a2e3bee84aef25bbd617cfdb4335b809b Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 3 May 2025 11:19:42 +0300
Subject: [PATCH 3/5] Formatting

---
 clang/include/clang/Parse/Parser.h | 1316 ++++++++++++++--------------
 1 file changed, 635 insertions(+), 681 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index c23b93826766d..49227fd173052 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -29,28 +29,28 @@
 #include <stack>
 
 namespace clang {
-  class PragmaHandler;
-  class Scope;
-  class BalancedDelimiterTracker;
-  class CorrectionCandidateCallback;
-  class DeclGroupRef;
-  class DiagnosticBuilder;
-  struct LoopHint;
-  class Parser;
-  class ParsingDeclRAIIObject;
-  class ParsingDeclSpec;
-  class ParsingDeclarator;
-  class ParsingFieldDeclarator;
-  class ColonProtectionRAIIObject;
-  class InMessageExpressionRAIIObject;
-  class PoisonSEHIdentifiersRAIIObject;
-  class OMPClause;
-  class OpenACCClause;
-  class ObjCTypeParamList;
-  struct OMPTraitProperty;
-  struct OMPTraitSelector;
-  struct OMPTraitSet;
-  class OMPTraitInfo;
+class PragmaHandler;
+class Scope;
+class BalancedDelimiterTracker;
+class CorrectionCandidateCallback;
+class DeclGroupRef;
+class DiagnosticBuilder;
+struct LoopHint;
+class Parser;
+class ParsingDeclRAIIObject;
+class ParsingDeclSpec;
+class ParsingDeclarator;
+class ParsingFieldDeclarator;
+class ColonProtectionRAIIObject;
+class InMessageExpressionRAIIObject;
+class PoisonSEHIdentifiersRAIIObject;
+class OMPClause;
+class OpenACCClause;
+class ObjCTypeParamList;
+struct OMPTraitProperty;
+struct OMPTraitSelector;
+struct OMPTraitSet;
+class OMPTraitInfo;
 
 enum class AnnotatedNameKind {
   /// Annotation has failed and emitted an error.
@@ -178,8 +178,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in Parser.cpp
   ///@{
 
-  public:
-
+public:
   friend class ColonProtectionRAIIObject;
   friend class PoisonSEHIdentifiersRAIIObject;
   friend class ParenBraceBracketBalancer;
@@ -221,7 +220,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// Note that in C, it is an error if there is no first declaration.
   bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
-    Sema::ModuleImportState &ImportState);
+                              Sema::ModuleImportState &ImportState);
 
   /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
   /// action tells us to.  This returns true if the EOF was encountered.
@@ -230,11 +229,11 @@ class Parser : public CodeCompletionHandler {
   ///           declaration
   /// [C++20]   module-import-declaration
   bool ParseTopLevelDecl(DeclGroupPtrTy &Result,
-  Sema::ModuleImportState &ImportState);
+                         Sema::ModuleImportState &ImportState);
   bool ParseTopLevelDecl() {
-  DeclGroupPtrTy Result;
-  Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
-  return ParseTopLevelDecl(Result, IS);
+    DeclGroupPtrTy Result;
+    Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
+    return ParseTopLevelDecl(Result, IS);
   }
 
   /// ConsumeToken - Consume the current 'peek token' and lex the next one.
@@ -243,53 +242,52 @@ class Parser : public CodeCompletionHandler {
   /// consume methods.
   /// Returns the location of the consumed token.
   SourceLocation ConsumeToken() {
-  assert(!isTokenSpecial() &&
-  "Should consume special tokens with Consume*Token");
-  PrevTokLocation = Tok.getLocation();
-  PP.Lex(Tok);
-  return PrevTokLocation;
+    assert(!isTokenSpecial() &&
+           "Should consume special tokens with Consume*Token");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
   }
 
   bool TryConsumeToken(tok::TokenKind Expected) {
-  if (Tok.isNot(Expected))
-  return false;
-  assert(!isTokenSpecial() &&
-  "Should consume special tokens with Consume*Token");
-  PrevTokLocation = Tok.getLocation();
-  PP.Lex(Tok);
-  return true;
+    if (Tok.isNot(Expected))
+      return false;
+    assert(!isTokenSpecial() &&
+           "Should consume special tokens with Consume*Token");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return true;
   }
 
   bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
-  if (!TryConsumeToken(Expected))
-  return false;
-  Loc = PrevTokLocation;
-  return true;
+    if (!TryConsumeToken(Expected))
+      return false;
+    Loc = PrevTokLocation;
+    return true;
   }
 
   /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
   /// current token type.  This should only be used in cases where the type of
   /// the token really isn't known, e.g. in error recovery.
   SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
-  if (isTokenParen())
-  return ConsumeParen();
-  if (isTokenBracket())
-  return ConsumeBracket();
-  if (isTokenBrace())
-  return ConsumeBrace();
-  if (isTokenStringLiteral())
-  return ConsumeStringToken();
-  if (Tok.is(tok::code_completion))
-  return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
-                : handleUnexpectedCodeCompletionToken();
-  if (Tok.isAnnotation())
-  return ConsumeAnnotationToken();
-  return ConsumeToken();
+    if (isTokenParen())
+      return ConsumeParen();
+    if (isTokenBracket())
+      return ConsumeBracket();
+    if (isTokenBrace())
+      return ConsumeBrace();
+    if (isTokenStringLiteral())
+      return ConsumeStringToken();
+    if (Tok.is(tok::code_completion))
+      return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
+                                      : handleUnexpectedCodeCompletionToken();
+    if (Tok.isAnnotation())
+      return ConsumeAnnotationToken();
+    return ConsumeToken();
   }
 
-
   SourceLocation getEndOfPreviousToken() {
-  return PP.getLocForEndOfToken(PrevTokLocation);
+    return PP.getLocForEndOfToken(PrevTokLocation);
   }
 
   /// GetLookAheadToken - This peeks ahead N tokens and returns that token
@@ -300,15 +298,14 @@ class Parser : public CodeCompletionHandler {
   /// the Parser always has one token lexed that the preprocessor doesn't.
   ///
   const Token &GetLookAheadToken(unsigned N) {
-    if (N == 0 || Tok.is(tok::eof)) return Tok;
-    return PP.LookAhead(N-1);
+    if (N == 0 || Tok.is(tok::eof))
+      return Tok;
+    return PP.LookAhead(N - 1);
   }
 
   /// NextToken - This peeks ahead one token and returns it without
   /// consuming it.
-  const Token &NextToken() {
-    return PP.LookAhead(0);
-  }
+  const Token &NextToken() { return PP.LookAhead(0); }
 
   /// getTypeAnnotation - Read a parsed type out of an annotation token.
   static TypeResult getTypeAnnotation(const Token &Tok) {
@@ -330,19 +327,20 @@ class Parser : public CodeCompletionHandler {
   /// inside expressions to be treated as typenames so it will not be called
   /// for expressions in C.
   /// The benefit for C/ObjC is that a typename will be annotated and
-  /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
-  /// will not be called twice, once to check whether we have a declaration
-  /// specifier, and another one to get the actual type inside
+  /// Actions.getTypeName will not be needed to be called again (e.g.
+  /// getTypeName will not be called twice, once to check whether we have a
+  /// declaration specifier, and another one to get the actual type inside
   /// ParseDeclarationSpecifiers).
   ///
   /// This returns true if an error occurred.
   ///
-  /// Note that this routine emits an error if you call it with ::new or ::delete
-  /// as the current tokens, so only call it in contexts where these are invalid.
+  /// Note that this routine emits an error if you call it with ::new or
+  /// ::delete as the current tokens, so only call it in contexts where these
+  /// are invalid.
   bool
   TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename =
                                   ImplicitTypenameContext::No);
-  
+
   /// Try to annotate a type or scope token, having already parsed an
   /// optional scope specifier. \p IsNewScope should be \c true unless the scope
   /// specifier was extracted from an existing tok::annot_cxxscope annotation.
@@ -354,8 +352,9 @@ class Parser : public CodeCompletionHandler {
   /// annotates C++ scope specifiers and template-ids.  This returns
   /// true if there was an error that could not be recovered from.
   ///
-  /// Note that this routine emits an error if you call it with ::new or ::delete
-  /// as the current tokens, so only call it in contexts where these are invalid.
+  /// Note that this routine emits an error if you call it with ::new or
+  /// ::delete as the current tokens, so only call it in contexts where these
+  /// are invalid.
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
 
   bool MightBeCXXScopeToken() {
@@ -389,7 +388,7 @@ class Parser : public CodeCompletionHandler {
     // ScopeFlags, but only when we aren't about to enter a compound statement.
     ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
                bool BeforeCompoundStmt = false)
-      : Self(Self) {
+        : Self(Self) {
       if (EnteredScope && !BeforeCompoundStmt)
         Self->EnterScope(ScopeFlags);
       else {
@@ -409,9 +408,7 @@ class Parser : public CodeCompletionHandler {
       }
     }
 
-    ~ParseScope() {
-      Exit();
-    }
+    ~ParseScope() { Exit(); }
   };
 
   /// Introduces zero or more scopes for parsing. The scopes will all be exited
@@ -420,7 +417,7 @@ class Parser : public CodeCompletionHandler {
     Parser &Self;
     unsigned NumScopes = 0;
 
-    MultiParseScope(const MultiParseScope&) = delete;
+    MultiParseScope(const MultiParseScope &) = delete;
 
   public:
     MultiParseScope(Parser &Self) : Self(Self) {}
@@ -434,9 +431,7 @@ class Parser : public CodeCompletionHandler {
         --NumScopes;
       }
     }
-    ~MultiParseScope() {
-      Exit();
-    }
+    ~MultiParseScope() { Exit(); }
   };
 
   /// EnterScope - Start a new scope.
@@ -450,9 +445,7 @@ class Parser : public CodeCompletionHandler {
 
   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
   DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
-  DiagnosticBuilder Diag(unsigned DiagID) {
-    return Diag(Tok, DiagID);
-  }
+  DiagnosticBuilder Diag(unsigned DiagID) { return Diag(Tok, DiagID); }
 
   DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId);
   DiagnosticBuilder DiagCompat(const Token &Tok, unsigned CompatDiagId);
@@ -462,7 +455,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Control flags for SkipUntil functions.
   enum SkipUntilFlags {
-    StopAtSemi = 1 << 0,  ///< Stop skipping at semicolon
+    StopAtSemi = 1 << 0, ///< Stop skipping at semicolon
     /// Stop skipping at specified token, but don't skip the token itself
     StopBeforeMatch = 1 << 1,
     StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
@@ -509,8 +502,7 @@ class Parser : public CodeCompletionHandler {
   bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
                  SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
 
-  private:
-
+private:
   Preprocessor &PP;
 
   /// Tok - The current token we are peeking ahead.  All parsing methods assume
@@ -546,17 +538,14 @@ class Parser : public CodeCompletionHandler {
   /// Identifiers used for SEH handling in Borland. These are only
   /// allowed in particular circumstances
   // __except block
-  IdentifierInfo *Ident__exception_code,
-                 *Ident___exception_code,
-                 *Ident_GetExceptionCode;
+  IdentifierInfo *Ident__exception_code, *Ident___exception_code,
+      *Ident_GetExceptionCode;
   // __except filter expression
-  IdentifierInfo *Ident__exception_info,
-                 *Ident___exception_info,
-                 *Ident_GetExceptionInfo;
+  IdentifierInfo *Ident__exception_info, *Ident___exception_info,
+      *Ident_GetExceptionInfo;
   // __finally
-  IdentifierInfo *Ident__abnormal_termination,
-                 *Ident___abnormal_termination,
-                 *Ident_AbnormalTermination;
+  IdentifierInfo *Ident__abnormal_termination, *Ident___abnormal_termination,
+      *Ident_AbnormalTermination;
 
   /// Contextual keywords for Microsoft extensions.
   IdentifierInfo *Ident__except;
@@ -585,17 +574,13 @@ class Parser : public CodeCompletionHandler {
   //
 
   /// isTokenParen - Return true if the cur token is '(' or ')'.
-  bool isTokenParen() const {
-    return Tok.isOneOf(tok::l_paren, tok::r_paren);
-  }
+  bool isTokenParen() const { return Tok.isOneOf(tok::l_paren, tok::r_paren); }
   /// isTokenBracket - Return true if the cur token is '[' or ']'.
   bool isTokenBracket() const {
     return Tok.isOneOf(tok::l_square, tok::r_square);
   }
   /// isTokenBrace - Return true if the cur token is '{' or '}'.
-  bool isTokenBrace() const {
-    return Tok.isOneOf(tok::l_brace, tok::r_brace);
-  }
+  bool isTokenBrace() const { return Tok.isOneOf(tok::l_brace, tok::r_brace); }
   /// isTokenStringLiteral - True if this token is a string-literal.
   bool isTokenStringLiteral() const {
     return tok::isStringLiteral(Tok.getKind());
@@ -613,10 +598,10 @@ class Parser : public CodeCompletionHandler {
   /// Return the current token to the token stream and make the given
   /// token the current token.
   void UnconsumeToken(Token &Consumed) {
-      Token Next = Tok;
-      PP.EnterToken(Consumed, /*IsReinject*/true);
-      PP.Lex(Tok);
-      PP.EnterToken(Next, /*IsReinject*/true);
+    Token Next = Tok;
+    PP.EnterToken(Consumed, /*IsReinject*/ true);
+    PP.Lex(Tok);
+    PP.EnterToken(Next, /*IsReinject*/ true);
   }
 
   SourceLocation ConsumeAnnotationToken() {
@@ -635,7 +620,7 @@ class Parser : public CodeCompletionHandler {
       ++ParenCount;
     else if (ParenCount) {
       AngleBrackets.clear(*this);
-      --ParenCount;       // Don't let unbalanced )'s drive the count negative.
+      --ParenCount; // Don't let unbalanced )'s drive the count negative.
     }
     PrevTokLocation = Tok.getLocation();
     PP.Lex(Tok);
@@ -650,7 +635,7 @@ class Parser : public CodeCompletionHandler {
       ++BracketCount;
     else if (BracketCount) {
       AngleBrackets.clear(*this);
-      --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
+      --BracketCount; // Don't let unbalanced ]'s drive the count negative.
     }
 
     PrevTokLocation = Tok.getLocation();
@@ -666,7 +651,7 @@ class Parser : public CodeCompletionHandler {
       ++BraceCount;
     else if (BraceCount) {
       AngleBrackets.clear(*this);
-      --BraceCount;     // Don't let unbalanced }'s drive the count negative.
+      --BraceCount; // Don't let unbalanced }'s drive the count negative.
     }
 
     PrevTokLocation = Tok.getLocation();
@@ -730,7 +715,7 @@ class Parser : public CodeCompletionHandler {
   }
 
   static NamedDecl *getNonTypeAnnotation(const Token &Tok) {
-    return static_cast<NamedDecl*>(Tok.getAnnotationValue());
+    return static_cast<NamedDecl *>(Tok.getAnnotationValue());
   }
 
   static void setNonTypeAnnotation(Token &Tok, NamedDecl *ND) {
@@ -738,7 +723,7 @@ class Parser : public CodeCompletionHandler {
   }
 
   static IdentifierInfo *getIdentifierAnnotation(const Token &Tok) {
-    return static_cast<IdentifierInfo*>(Tok.getAnnotationValue());
+    return static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
   }
 
   static void setIdentifierAnnotation(Token &Tok, IdentifierInfo *ND) {
@@ -762,7 +747,8 @@ class Parser : public CodeCompletionHandler {
   /// with a typo-corrected keyword. This is only appropriate when the current
   /// name must refer to an entity which has already been declared.
   ///
-  /// \param CCC Indicates how to perform typo-correction for this name. If NULL,
+  /// \param CCC Indicates how to perform typo-correction for this name. If
+  /// NULL,
   ///        no typo correction will be performed.
   /// \param AllowImplicitTypename Whether we are in a context where a dependent
   ///        nested-name-specifier without typename is treated as a type (e.g.
@@ -804,7 +790,7 @@ class Parser : public CodeCompletionHandler {
   /// If the next token is not a semicolon, this emits the specified diagnostic,
   /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
   /// to the semicolon, consumes that extra token.
-  bool ExpectAndConsumeSemi(unsigned DiagID , StringRef TokenUsed = "");
+  bool ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed = "");
 
   /// Consume any extra semi-colons until the end of the line.
   void ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST T = TST_unspecified);
@@ -846,10 +832,10 @@ class Parser : public CodeCompletionHandler {
     void operator=(const ParseScopeFlags &) = delete;
 
   public:
-    /// Set the flags for the current scope to ScopeFlags. If ManageFlags is false,
-    /// this object does nothing.
+    /// Set the flags for the current scope to ScopeFlags. If ManageFlags is
+    /// false, this object does nothing.
     ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true);
-    
+
     /// Restore the flags for the current scope to what they were before this
     /// object overrode them.
     ~ParseScopeFlags();
@@ -860,13 +846,14 @@ class Parser : public CodeCompletionHandler {
   ///
   /// \param Loc The location where we'll emit the diagnostic.
   /// \param DK The kind of diagnostic to emit.
-  /// \param ParenRange Source range enclosing code that should be parenthesized.
+  /// \param ParenRange Source range enclosing code that should be
+  /// parenthesized.
   void SuggestParentheses(SourceLocation Loc, unsigned DK,
-    SourceRange ParenRange);
+                          SourceRange ParenRange);
 
   //===--------------------------------------------------------------------===//
   // C99 6.9: External Definitions.
-  
+
   /// ParseExternalDeclaration:
   ///
   /// The `Attrs` that are passed in are C++11 attributes and appertain to the
@@ -899,11 +886,11 @@ class Parser : public CodeCompletionHandler {
   DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &DeclAttrs,
                                           ParsedAttributes &DeclSpecAttrs,
                                           ParsingDeclSpec *DS = nullptr);
-  
+
   /// Determine whether the current token, if it occurs after a
   /// declarator, continues a declaration or declaration list.
   bool isDeclarationAfterDeclarator();
-  
+
   /// Determine whether the current token, if it occurs after a
   /// declarator, indicates the start of a function definition.
   bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
@@ -911,7 +898,7 @@ class Parser : public CodeCompletionHandler {
   DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
       ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,
       ParsingDeclSpec *DS = nullptr, AccessSpecifier AS = AS_none);
-  
+
   /// Parse either a function-definition or a declaration.  We can't tell which
   /// we have until we read up to the compound-statement in function-definition.
   /// TemplateParams, if non-NULL, provides the template parameters when we're
@@ -952,9 +939,10 @@ class Parser : public CodeCompletionHandler {
   /// [C++] function-definition: [C++ 8.4]
   ///         decl-specifier-seq[opt] declarator function-try-block
   ///
-  Decl *ParseFunctionDefinition(ParsingDeclarator &D,
-                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
-                 LateParsedAttrList *LateParsedAttrs = nullptr);
+  Decl *ParseFunctionDefinition(
+      ParsingDeclarator &D,
+      const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+      LateParsedAttrList *LateParsedAttrs = nullptr);
 
   /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
   /// types for a function with a K&R-style identifier list for arguments.
@@ -967,12 +955,12 @@ class Parser : public CodeCompletionHandler {
   ///
   /// EndLoc is filled with the location of the last token of the simple-asm.
   ExprResult ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc);
-  
+
   /// ParseAsmStringLiteral - This is just a normal string-literal, but is not
   /// allowed to be a wide string, and is not subject to character translation.
   /// Unlike GCC, we also diagnose an empty string literal when parsing for an
-  /// asm label as opposed to an asm statement, because such a construct does not
-  /// behave well.
+  /// asm label as opposed to an asm statement, because such a construct does
+  /// not behave well.
   ///
   /// [GNU] asm-string-literal:
   ///         string-literal
@@ -999,12 +987,12 @@ class Parser : public CodeCompletionHandler {
     IfExistsBehavior Behavior;
   };
 
-  bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result);
+  bool ParseMicrosoftIfExistsCondition(IfExistsCondition &Result);
   void ParseMicrosoftIfExistsExternalDeclaration();
 
   //===--------------------------------------------------------------------===//
   // Modules
-  
+
   /// Parse a declaration beginning with the 'module' keyword or C++20
   /// context-sensitive keyword (optionally preceded by 'export').
   ///
@@ -1040,8 +1028,8 @@ class Parser : public CodeCompletionHandler {
 
   /// Try recover parser when module annotation appears where it must not
   /// be found.
-  /// \returns false if the recover was successful and parsing may be continued, or
-  /// true if parser must bail out to top level and handle the token there.
+  /// \returns false if the recover was successful and parsing may be continued,
+  /// or true if parser must bail out to top level and handle the token there.
   bool parseMisplacedModuleImport();
 
   bool tryParseMisplacedModuleImport() {
@@ -1085,8 +1073,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseCXXInlineMethods.cpp
   ///@{
 
-  private:
-
+private:
   struct ParsingClass;
 
   /// [class.mem]p1: "... the class is regarded as complete within
@@ -1142,11 +1129,11 @@ class Parser : public CodeCompletionHandler {
     IdentifierInfo &AttrName;
     IdentifierInfo *MacroII = nullptr;
     SourceLocation AttrNameLoc;
-    SmallVector<Decl*, 2> Decls;
+    SmallVector<Decl *, 2> Decls;
 
     explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
                                  SourceLocation Loc)
-      : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
+        : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
 
     void ParseLexedAttributes() override;
 
@@ -1174,7 +1161,7 @@ class Parser : public CodeCompletionHandler {
   };
 
   // A list of late-parsed attributes.  Used by ParseGNUAttributes.
-  class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
+  class LateParsedAttrList : public SmallVector<LateParsedAttribute *, 2> {
   public:
     LateParsedAttrList(bool PSoon = false,
                        bool LateAttrParseExperimentalExtOnly = false)
@@ -1211,9 +1198,9 @@ class Parser : public CodeCompletionHandler {
   /// occurs within a member function declaration inside the class
   /// (C++ [class.mem]p2).
   struct LateParsedDefaultArgument {
-    explicit LateParsedDefaultArgument(Decl *P,
-                                       std::unique_ptr<CachedTokens> Toks = nullptr)
-      : Param(P), Toks(std::move(Toks)) { }
+    explicit LateParsedDefaultArgument(
+        Decl *P, std::unique_ptr<CachedTokens> Toks = nullptr)
+        : Param(P), Toks(std::move(Toks)) {}
 
     /// Param - The parameter declaration for this parameter.
     Decl *Param;
@@ -1256,8 +1243,7 @@ class Parser : public CodeCompletionHandler {
   /// member whose parsing must to be delayed until the class is completely
   /// defined (C++11 [class.mem]p2).
   struct LateParsedMemberInitializer : public LateParsedDeclaration {
-    LateParsedMemberInitializer(Parser *P, Decl *FD)
-      : Self(P), Field(FD) { }
+    LateParsedMemberInitializer(Parser *P, Decl *FD) : Self(P), Field(FD) {}
 
     void ParseLexedMemberInitializers() override;
 
@@ -1277,13 +1263,15 @@ class Parser : public CodeCompletionHandler {
   /// the method declarations and possibly attached inline definitions
   /// will be stored here with the tokens that will be parsed to create those
   /// entities.
-  typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
+  typedef SmallVector<LateParsedDeclaration *, 2>
+      LateParsedDeclarationsContainer;
 
   /// Utility to re-enter a possibly-templated scope while parsing its
   /// late-parsed components.
   struct ReenterTemplateScopeRAII;
-  
-  /// Utility to re-enter a class scope while parsing its late-parsed components.
+
+  /// Utility to re-enter a class scope while parsing its late-parsed
+  /// components.
   struct ReenterClassScopeRAII;
 
   /// ParseCXXInlineMethodDef - We parsed and verified that the specified
@@ -1298,7 +1286,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse the optional ("message") part of a deleted-function-body.
   StringLiteral *ParseCXXDeletedFunctionMessage();
-  
+
   /// If we've encountered '= delete' in a context where it is ill-formed, such
   /// as in the declaration of a non-function, also skip the ("message") part if
   /// it is present to avoid issuing further diagnostics.
@@ -1313,7 +1301,7 @@ class Parser : public CodeCompletionHandler {
   /// Wrapper class which calls ParseLexedAttribute, after setting up the
   /// scope appropriately.
   void ParseLexedAttributes(ParsingClass &Class);
-  
+
   /// Parse all attributes in LAs, and attach them to Decl D.
   void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
                                bool EnterScope, bool OnDefinition);
@@ -1323,8 +1311,8 @@ class Parser : public CodeCompletionHandler {
   /// for each LateParsedAttribute. We consume the saved tokens and
   /// create an attribute with the arguments filled in. We add this
   /// to the Attribute list for the decl.
-  void ParseLexedAttribute(LateParsedAttribute &LA,
-                           bool EnterScope, bool OnDefinition);
+  void ParseLexedAttribute(LateParsedAttribute &LA, bool EnterScope,
+                           bool OnDefinition);
 
   /// ParseLexedMethodDeclarations - We finished parsing the member
   /// specification of a top (non-nested) C++ class. Now go over the
@@ -1332,16 +1320,17 @@ class Parser : public CodeCompletionHandler {
   /// delayed (such as default arguments) and parse them.
   void ParseLexedMethodDeclarations(ParsingClass &Class);
   void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
-  
-  /// ParseLexedMethodDefs - We finished parsing the member specification of a top
-  /// (non-nested) C++ class. Now go over the stack of lexed methods that were
-  /// collected during its parsing and parse them all.
+
+  /// ParseLexedMethodDefs - We finished parsing the member specification of a
+  /// top (non-nested) C++ class. Now go over the stack of lexed methods that
+  /// were collected during its parsing and parse them all.
   void ParseLexedMethodDefs(ParsingClass &Class);
   void ParseLexedMethodDef(LexedMethod &LM);
-  
-  /// ParseLexedMemberInitializers - We finished parsing the member specification
-  /// of a top (non-nested) C++ class. Now go over the stack of lexed data member
-  /// initializers that were collected during its parsing and parse them all.
+
+  /// ParseLexedMemberInitializers - We finished parsing the member
+  /// specification of a top (non-nested) C++ class. Now go over the stack of
+  /// lexed data member initializers that were collected during its parsing and
+  /// parse them all.
   void ParseLexedMemberInitializers(ParsingClass &Class);
   void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
 
@@ -1357,8 +1346,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseDecl.cpp
   ///@{
 
-  public:
-
+public:
   /// SkipMalformedDecl - Read tokens until we get to some likely good stopping
   /// point for skipping past a simple-declaration.
   ///
@@ -1378,8 +1366,7 @@ class Parser : public CodeCompletionHandler {
                 AccessSpecifier AS = AS_none, Decl **OwnedType = nullptr,
                 ParsedAttributes *Attrs = nullptr);
 
-  private:
-
+private:
   /// Ident_vector, Ident_bool, Ident_Bool - cached IdentifierInfos for "vector"
   /// and "bool" fast comparison.  Only present if AltiVec or ZVector are
   /// enabled.
@@ -1417,7 +1404,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Identifiers used by the 'external_source_symbol' attribute.
   IdentifierInfo *Ident_language, *Ident_defined_in,
-  *Ident_generated_declaration, *Ident_USR;
+      *Ident_generated_declaration, *Ident_USR;
 
   /// Factory object for creating ParsedAttr objects.
   AttributeFactory AttrFactory;
@@ -1425,9 +1412,8 @@ class Parser : public CodeCompletionHandler {
   /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
   /// replacing them with the non-context-sensitive keywords.  This returns
   /// true if the token was replaced.
-  bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
-                       const char *&PrevSpec, unsigned &DiagID,
-                       bool &isInvalid) {
+  bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, bool &isInvalid) {
     if (!getLangOpts().AltiVec && !getLangOpts().ZVector)
       return false;
 
@@ -1445,12 +1431,13 @@ class Parser : public CodeCompletionHandler {
   /// This returns true if the token was replaced.
   bool TryAltiVecVectorToken() {
     if ((!getLangOpts().AltiVec && !getLangOpts().ZVector) ||
-        Tok.getIdentifierInfo() != Ident_vector) return false;
+        Tok.getIdentifierInfo() != Ident_vector)
+      return false;
     return TryAltiVecVectorTokenOutOfLine();
   }
 
-  /// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
-  /// from TryAltiVecVectorToken.
+  /// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be
+  /// called from TryAltiVecVectorToken.
   bool TryAltiVecVectorTokenOutOfLine();
   bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
                                 const char *&PrevSpec, unsigned &DiagID,
@@ -1466,31 +1453,31 @@ class Parser : public CodeCompletionHandler {
   /// to the Attribute list for the decl.
   void ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
                             ParsedAttributes *OutAttrs = nullptr);
- 
+
   void ParseLexedPragmas(ParsingClass &Class);
   void ParseLexedPragma(LateParsedPragma &LP);
 
   /// Consume tokens and store them in the passed token container until
-  /// we've passed the try keyword and constructor initializers and have consumed
-  /// the opening brace of the function body. The opening brace will be consumed
-  /// if and only if there was no error.
+  /// we've passed the try keyword and constructor initializers and have
+  /// consumed the opening brace of the function body. The opening brace will be
+  /// consumed if and only if there was no error.
   ///
   /// \return True on error.
   bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
-  
-  /// ConsumeAndStoreInitializer - Consume and store the token at the passed token
-  /// container until the end of the current initializer expression (either a
-  /// default argument or an in-class initializer for a non-static data member).
+
+  /// ConsumeAndStoreInitializer - Consume and store the token at the passed
+  /// token container until the end of the current initializer expression
+  /// (either a default argument or an in-class initializer for a non-static
+  /// data member).
   ///
   /// Returns \c true if we reached the end of something initializer-shaped,
   /// \c false if we bailed out.
   bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK);
-  
+
   /// Consume and store tokens from the '?' to the ':' in a conditional
   /// expression.
   bool ConsumeAndStoreConditional(CachedTokens &Toks);
-  bool ConsumeAndStoreUntil(tok::TokenKind T1,
-                            CachedTokens &Toks,
+  bool ConsumeAndStoreUntil(tok::TokenKind T1, CachedTokens &Toks,
                             bool StopAtSemi = true,
                             bool ConsumeFinalToken = true) {
     return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
@@ -1503,10 +1490,9 @@ class Parser : public CodeCompletionHandler {
   /// Returns true if token 'T1' or 'T2' was found.
   /// NOTE: This is a specialized version of Parser::SkipUntil.
   bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
-                            CachedTokens &Toks,
-                            bool StopAtSemi = true,
+                            CachedTokens &Toks, bool StopAtSemi = true,
                             bool ConsumeFinalToken = true);
- 
+
   //===--------------------------------------------------------------------===//
   // C99 6.7: Declarations.
 
@@ -1713,7 +1699,7 @@ class Parser : public CodeCompletionHandler {
                                   ParsedAttributes &DeclAttrs,
                                   ParsedAttributes &DeclSpecAttrs,
                                   SourceLocation *DeclSpecStart = nullptr);
-  
+
   ///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
   ///         declaration-specifiers init-declarator-list[opt] ';'
   /// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
@@ -1741,7 +1727,7 @@ class Parser : public CodeCompletionHandler {
                          ParsedAttributes &DeclSpecAttrs, bool RequireSemi,
                          ForRangeInit *FRI = nullptr,
                          SourceLocation *DeclSpecStart = nullptr);
-  
+
   /// ParseDeclGroup - Having concluded that this is either a function
   /// definition or a group of object declarations, actually parse the
   /// result.
@@ -1754,7 +1740,7 @@ class Parser : public CodeCompletionHandler {
                                 ParsedTemplateInfo &TemplateInfo,
                                 SourceLocation *DeclEnd = nullptr,
                                 ForRangeInit *FRI = nullptr);
-  
+
   /// Parse 'declaration' after parsing 'declaration-specifiers
   /// declarator'. This method parses the remainder of the declaration
   /// (including any attributes or initializer, among other things) and
@@ -1777,9 +1763,10 @@ class Parser : public CodeCompletionHandler {
   /// According to the standard grammar, =default and =delete are function
   /// definitions, but that definitely doesn't fit with the parser here.
   ///
-  Decl *ParseDeclarationAfterDeclarator(Declarator &D,
-               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
-  
+  Decl *ParseDeclarationAfterDeclarator(
+      Declarator &D,
+      const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+
   /// Parse an optional simple-asm-expr and attributes, and attach them to a
   /// declarator. Returns true on an error.
   bool ParseAsmAttributesAfterDeclarator(Declarator &D);
@@ -1800,7 +1787,7 @@ class Parser : public CodeCompletionHandler {
   bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
                         ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,
                         DeclSpecContext DSC, ParsedAttributes &Attrs);
-  
+
   /// Determine the declaration specifier context from the declarator
   /// context.
   ///
@@ -1911,7 +1898,7 @@ class Parser : public CodeCompletionHandler {
   void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
                           const ParsedTemplateInfo &TemplateInfo,
                           AccessSpecifier AS, DeclSpecContext DSC);
-  
+
   /// ParseEnumBody - Parse a {} enclosed enumerator-list.
   ///       enumerator-list:
   ///         enumerator
@@ -1924,7 +1911,7 @@ class Parser : public CodeCompletionHandler {
   ///
   void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl,
                      SkipBodyInfo *SkipBody = nullptr);
-  
+
   /// ParseStructUnionBody
   ///       struct-contents:
   ///         struct-declaration-list
@@ -1938,8 +1925,8 @@ class Parser : public CodeCompletionHandler {
   void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
                             RecordDecl *TagDecl);
 
-  /// ParseStructDeclaration - Parse a struct declaration without the terminating
-  /// semicolon.
+  /// ParseStructDeclaration - Parse a struct declaration without the
+  /// terminating semicolon.
   ///
   /// Note that a struct declaration refers to a declaration in a struct,
   /// not to the declaration of a struct.
@@ -1975,7 +1962,7 @@ class Parser : public CodeCompletionHandler {
   /// this check is to disambiguate between an expression and a declaration.
   bool isDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
                               bool DisambiguatingWithExpression = false);
-  
+
   /// isTypeSpecifierQualifier - Return true if the current token could be the
   /// start of a specifier-qualifier-list.
   bool isTypeSpecifierQualifier();
@@ -2006,14 +1993,14 @@ class Parser : public CodeCompletionHandler {
     return DiagnoseProhibitedCXX11Attribute();
   }
 
-  /// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
-  /// of a C++11 attribute-specifier in a location where an attribute is not
-  /// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
-  /// situation.
+  /// DiagnoseProhibitedCXX11Attribute - We have found the opening square
+  /// brackets of a C++11 attribute-specifier in a location where an attribute
+  /// is not permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed.
+  /// Diagnose this situation.
   ///
-  /// \return \c true if we skipped an attribute-like chunk of tokens, \c false if
-  /// this doesn't appear to actually be an attribute-specifier, and the caller
-  /// should try to parse it.
+  /// \return \c true if we skipped an attribute-like chunk of tokens, \c false
+  /// if this doesn't appear to actually be an attribute-specifier, and the
+  /// caller should try to parse it.
   bool DiagnoseProhibitedCXX11Attribute();
 
   void CheckMisplacedCXX11Attribute(ParsedAttributes &Attrs,
@@ -2038,7 +2025,8 @@ class Parser : public CodeCompletionHandler {
   // class-key affects the type instead of the variable.
   // Also, Microsoft-style [attributes] seem to affect the type instead of the
   // variable.
-  // This function moves attributes that should apply to the type off DS to Attrs.
+  // This function moves attributes that should apply to the type off DS to
+  // Attrs.
   void stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, DeclSpec &DS,
                                       TagUseKind TUK);
 
@@ -2162,7 +2150,7 @@ class Parser : public CodeCompletionHandler {
   bool ParseSingleGNUAttribute(ParsedAttributes &Attrs, SourceLocation &EndLoc,
                                LateParsedAttrList *LateAttrs = nullptr,
                                Declarator *D = nullptr);
-  
+
   /// ParseGNUAttributes - Parse a non-empty attributes list.
   ///
   /// [GNU] attributes:
@@ -2207,7 +2195,7 @@ class Parser : public CodeCompletionHandler {
   void ParseGNUAttributes(ParsedAttributes &Attrs,
                           LateParsedAttrList *LateAttrs = nullptr,
                           Declarator *D = nullptr);
-  
+
   /// Parse the arguments to a parameterized GNU attribute or
   /// a C++11 attribute in "gnu" namespace.
   void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
@@ -2424,7 +2412,7 @@ class Parser : public CodeCompletionHandler {
   ExprResult ParseAlignArgument(StringRef KWName, SourceLocation Start,
                                 SourceLocation &EllipsisLoc, bool &IsType,
                                 ParsedType &Ty);
-  
+
   /// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
   /// attribute to Attrs.
   ///
@@ -2451,9 +2439,10 @@ class Parser : public CodeCompletionHandler {
     CXXScopeSpec &SS;
     bool EnteredScope;
     bool CreatedScope;
+
   public:
     DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
-      : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
+        : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
 
     void EnterDeclaratorScope() {
       assert(!EnteredScope && "Already entered the scope!");
@@ -2479,15 +2468,15 @@ class Parser : public CodeCompletionHandler {
   /// ParseDeclarator - Parse and verify a newly-initialized declarator.
   void ParseDeclarator(Declarator &D);
   /// A function that parses a variant of direct-declarator.
-  typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
-  
-  /// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator
-  /// is parsed by the function passed to it. Pass null, and the direct-declarator
-  /// isn't parsed at all, making this function effectively parse the C++
-  /// ptr-operator production.
-  ///
-  /// If the grammar of this construct is extended, matching changes must also be
-  /// made to TryParseDeclarator and MightBeDeclarator, and possibly to
+  typedef void (Parser::*DirectDeclParseFunction)(Declarator &);
+
+  /// ParseDeclaratorInternal - Parse a C or C++ declarator. The
+  /// direct-declarator is parsed by the function passed to it. Pass null, and
+  /// the direct-declarator isn't parsed at all, making this function
+  /// effectively parse the C++ ptr-operator production.
+  ///
+  /// If the grammar of this construct is extended, matching changes must also
+  /// be made to TryParseDeclarator and MightBeDeclarator, and possibly to
   /// isConstructorDeclarator.
   ///
   ///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
@@ -2515,11 +2504,10 @@ class Parser : public CodeCompletionHandler {
     AR_GNUAttributesParsed = 1 << 1,
     AR_CXX11AttributesParsed = 1 << 2,
     AR_DeclspecAttributesParsed = 1 << 3,
-    AR_AllAttributesParsed = AR_GNUAttributesParsed |
-                             AR_CXX11AttributesParsed |
+    AR_AllAttributesParsed = AR_GNUAttributesParsed | AR_CXX11AttributesParsed |
                              AR_DeclspecAttributesParsed,
-    AR_VendorAttributesParsed = AR_GNUAttributesParsed |
-                                AR_DeclspecAttributesParsed
+    AR_VendorAttributesParsed =
+        AR_GNUAttributesParsed | AR_DeclspecAttributesParsed
   };
 
   /// ParseTypeQualifierListOpt
@@ -2539,7 +2527,7 @@ class Parser : public CodeCompletionHandler {
       bool AtomicAllowed = true, bool IdentifierRequired = false,
       std::optional<llvm::function_ref<void()>> CodeCompletionHandler =
           std::nullopt);
-  
+
   /// ParseDirectDeclarator
   ///       direct-declarator: [C99 6.7.5]
   /// [C99]   identifier
@@ -2588,11 +2576,12 @@ class Parser : public CodeCompletionHandler {
   /// in isConstructorDeclarator.
   void ParseDirectDeclarator(Declarator &D);
   void ParseDecompositionDeclarator(Declarator &D);
-  
+
   /// ParseParenDeclarator - We parsed the declarator D up to a paren.  This is
   /// only called before the identifier, so these are most likely just grouping
   /// parens for precedence.  If we find that these are actually function
-  /// parameter parens in an abstract-declarator, we call ParseFunctionDeclarator.
+  /// parameter parens in an abstract-declarator, we call
+  /// ParseFunctionDeclarator.
   ///
   ///       direct-declarator:
   ///         '(' declarator ')'
@@ -2603,7 +2592,7 @@ class Parser : public CodeCompletionHandler {
   ///                    parameter-type-list[opt] ')'
   ///
   void ParseParenDeclarator(Declarator &D);
-  
+
   /// ParseFunctionDeclarator - We are after the identifier and have parsed the
   /// declarator D up to a paren, which indicates that we are parsing function
   /// arguments.
@@ -2612,13 +2601,14 @@ class Parser : public CodeCompletionHandler {
   /// immediately after the open paren - they will be applied to the DeclSpec
   /// of the first parameter.
   ///
-  /// If RequiresArg is true, then the first argument of the function is required
-  /// to be present and required to not be an identifier list.
+  /// If RequiresArg is true, then the first argument of the function is
+  /// required to be present and required to not be an identifier list.
   ///
-  /// For C++, after the parameter-list, it also parses the cv-qualifier-seq[opt],
-  /// (C++11) ref-qualifier[opt], exception-specification[opt],
-  /// (C++11) attribute-specifier-seq[opt], (C++11) trailing-return-type[opt] and
-  /// (C++2a) the trailing requires-clause.
+  /// For C++, after the parameter-list, it also parses the
+  /// cv-qualifier-seq[opt], (C++11) ref-qualifier[opt],
+  /// exception-specification[opt], (C++11) attribute-specifier-seq[opt],
+  /// (C++11) trailing-return-type[opt] and (C++2a) the trailing
+  /// requires-clause.
   ///
   /// [C++11] exception-specification:
   ///           dynamic-exception-specification
@@ -2630,21 +2620,22 @@ class Parser : public CodeCompletionHandler {
   void InitCXXThisScopeForDeclaratorIfRelevant(
       const Declarator &D, const DeclSpec &DS,
       std::optional<Sema::CXXThisScopeRAII> &ThisScope);
-  
+
   /// ParseRefQualifier - Parses a member function ref-qualifier. Returns
   /// true if a ref-qualifier is found.
   bool ParseRefQualifier(bool &RefQualifierIsLValueRef,
                          SourceLocation &RefQualifierLoc);
-  
+
   /// isFunctionDeclaratorIdentifierList - This parameter list may have an
   /// identifier list form for a K&R-style function:  void foo(a,b,c)
   ///
-  /// Note that identifier-lists are only allowed for normal declarators, not for
-  /// abstract-declarators.
+  /// Note that identifier-lists are only allowed for normal declarators, not
+  /// for abstract-declarators.
   bool isFunctionDeclaratorIdentifierList();
-  
-  /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
-  /// we found a K&R-style identifier list instead of a typed parameter list.
+
+  /// ParseFunctionDeclaratorIdentifierList - While parsing a function
+  /// declarator we found a K&R-style identifier list instead of a typed
+  /// parameter list.
   ///
   /// After returning, ParamInfo will hold the parsed parameters.
   ///
@@ -2653,8 +2644,7 @@ class Parser : public CodeCompletionHandler {
   ///         identifier-list ',' identifier
   ///
   void ParseFunctionDeclaratorIdentifierList(
-         Declarator &D,
-         SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
+      Declarator &D, SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
   void ParseParameterDeclarationClause(
       Declarator &D, ParsedAttributes &attrs,
       SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
@@ -2669,12 +2659,13 @@ class Parser : public CodeCompletionHandler {
   /// after the opening parenthesis. This function will not parse a K&R-style
   /// identifier list.
   ///
-  /// DeclContext is the context of the declarator being parsed.  If FirstArgAttrs
-  /// is non-null, then the caller parsed those attributes immediately after the
-  /// open paren - they will be applied to the DeclSpec of the first parameter.
+  /// DeclContext is the context of the declarator being parsed.  If
+  /// FirstArgAttrs is non-null, then the caller parsed those attributes
+  /// immediately after the open paren - they will be applied to the DeclSpec of
+  /// the first parameter.
   ///
-  /// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc will
-  /// be the location of the ellipsis, if any was parsed.
+  /// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc
+  /// will be the location of the ellipsis, if any was parsed.
   ///
   ///       parameter-type-list: [C99 6.7.5]
   ///         parameter-list
@@ -2710,7 +2701,7 @@ class Parser : public CodeCompletionHandler {
   /// [C++11] direct-declarator '[' constant-expression[opt] ']'
   ///                           attribute-specifier-seq[opt]
   void ParseBracketDeclarator(Declarator &D);
-  
+
   /// Diagnose brackets before an identifier.
   void ParseMisplacedBracketDeclarator(Declarator &D);
 
@@ -2738,8 +2729,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseDeclCXX.cpp
   ///@{
 
-  private:
-
+private:
   /// Contextual keywords for Microsoft extensions.
   mutable IdentifierInfo *Ident_sealed;
   mutable IdentifierInfo *Ident_abstract;
@@ -2792,8 +2782,8 @@ class Parser : public CodeCompletionHandler {
   public:
     ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass,
                            bool IsInterface)
-      : P(P), Popped(false),
-        State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
+        : P(P), Popped(false),
+          State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
     }
 
     /// Pop this class of the stack.
@@ -2819,12 +2809,10 @@ class Parser : public CodeCompletionHandler {
   ///         'noexcept'
   ///         'noexcept' '(' constant-expression ')'
   ExceptionSpecificationType tryParseExceptionSpecification(
-                    bool Delayed,
-                    SourceRange &SpecificationRange,
-                    SmallVectorImpl<ParsedType> &DynamicExceptions,
-                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
-                    ExprResult &NoexceptExpr,
-                    CachedTokens *&ExceptionSpecTokens);
+      bool Delayed, SourceRange &SpecificationRange,
+      SmallVectorImpl<ParsedType> &DynamicExceptions,
+      SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
+      ExprResult &NoexceptExpr, CachedTokens *&ExceptionSpecTokens);
 
   /// ParseDynamicExceptionSpecification - Parse a C++
   /// dynamic-exception-specification (C++ [except.spec]).
@@ -2838,10 +2826,10 @@ class Parser : public CodeCompletionHandler {
   ///         type-id ... [opt]
   ///         type-id-list ',' type-id ... [opt]
   ///
-  ExceptionSpecificationType ParseDynamicExceptionSpecification(
-                                  SourceRange &SpecificationRange,
-                                  SmallVectorImpl<ParsedType> &Exceptions,
-                                  SmallVectorImpl<SourceRange> &Ranges);
+  ExceptionSpecificationType
+  ParseDynamicExceptionSpecification(SourceRange &SpecificationRange,
+                                     SmallVectorImpl<ParsedType> &Exceptions,
+                                     SmallVectorImpl<SourceRange> &Ranges);
 
   //===--------------------------------------------------------------------===//
   // C++0x 8: Function declaration trailing-return-type
@@ -2920,13 +2908,13 @@ class Parser : public CodeCompletionHandler {
     ParseCXX11AttributeSpecifierInternal(Attrs, OpenMPTokens, EndLoc);
     ReplayOpenMPAttributeTokens(OpenMPTokens);
   }
-  
+
   /// ParseCXX11Attributes - Parse a C++11 or C23 attribute-specifier-seq.
   ///
   /// attribute-specifier-seq:
   ///       attribute-specifier-seq[opt] attribute-specifier
   void ParseCXX11Attributes(ParsedAttributes &attrs);
-  
+
   /// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause.
   /// Parses a C++11 (or C23)-style attribute argument list. Returns true
   /// if this results in adding an attribute to the ParsedAttributes list.
@@ -2950,7 +2938,8 @@ class Parser : public CodeCompletionHandler {
                                SourceLocation ScopeLoc,
                                CachedTokens &OpenMPTokens);
 
-  /// Parse the argument to C++23's [[assume()]] attribute. Returns true on error.
+  /// Parse the argument to C++23's [[assume()]] attribute. Returns true on
+  /// error.
   bool ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
                                   IdentifierInfo *AttrName,
                                   SourceLocation AttrNameLoc,
@@ -2959,8 +2948,8 @@ class Parser : public CodeCompletionHandler {
 
   /// 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.
+  /// \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
@@ -2974,7 +2963,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse uuid() attribute when it appears in a [] Microsoft attribute.
   void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs);
-  
+
   /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr]
   ///
   /// [MS] ms-attribute:
@@ -3021,7 +3010,7 @@ class Parser : public CodeCompletionHandler {
   /// isCXX11FinalKeyword - Determine whether the next token is a C++11
   /// 'final' or Microsoft 'sealed' contextual keyword.
   bool isCXX11FinalKeyword() const;
-  
+
   /// isClassCompatibleKeyword - Determine whether the next token is a C++11
   /// 'final' or Microsoft 'sealed' or 'abstract' contextual keywords.
   bool isClassCompatibleKeyword() const;
@@ -3031,9 +3020,9 @@ class Parser : public CodeCompletionHandler {
 
   void DiagnoseUnexpectedNamespace(NamedDecl *Context);
 
-  /// 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.
+  /// 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
@@ -3075,7 +3064,7 @@ class Parser : public CodeCompletionHandler {
                            unsigned int index, SourceLocation &InlineLoc,
                            ParsedAttributes &attrs,
                            BalancedDelimiterTracker &Tracker);
-  
+
   /// ParseLinkage - We know that the current token is a string_literal
   /// and just before that, that extern was seen.
   ///
@@ -3084,7 +3073,7 @@ class Parser : public CodeCompletionHandler {
   ///         'extern' string-literal declaration
   ///
   Decl *ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context);
-  
+
   /// Parse a standard C++ Modules export-declaration.
   ///
   ///       export-declaration:
@@ -3106,7 +3095,7 @@ class Parser : public CodeCompletionHandler {
   DeclGroupPtrTy 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.
   ///
@@ -3117,10 +3106,8 @@ class Parser : public CodeCompletionHandler {
   ///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
   ///                 namespace-name attributes[opt] ;
   ///
-  Decl *ParseUsingDirective(DeclaratorContext Context,
-                            SourceLocation UsingLoc,
-                            SourceLocation &DeclEnd,
-                            ParsedAttributes &attrs);
+  Decl *ParseUsingDirective(DeclaratorContext Context, SourceLocation UsingLoc,
+                            SourceLocation &DeclEnd, ParsedAttributes &attrs);
 
   struct UsingDeclarator {
     SourceLocation TypenameLoc;
@@ -3141,7 +3128,7 @@ class Parser : public CodeCompletionHandler {
   ///       'typename'[opt] nested-name-specifier unqualified-id
   ///
   bool ParseUsingDeclarator(DeclaratorContext Context, UsingDeclarator &D);
-  
+
   /// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
   /// Assumes that 'using' was already seen.
   ///
@@ -3176,7 +3163,8 @@ class Parser : public CodeCompletionHandler {
       UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
       ParsedAttributes &Attrs, Decl **OwnedType = nullptr);
 
-  /// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
+  /// ParseStaticAssertDeclaration - Parse C++0x or C11
+  /// static_assert-declaration.
   ///
   /// [C++0x] static_assert-declaration:
   ///           static_assert ( constant-expression  ,  string-literal  ) ;
@@ -3185,7 +3173,7 @@ class Parser : public CodeCompletionHandler {
   ///           _Static_assert ( constant-expression  ,  string-literal  ) ;
   ///
   Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
-  
+
   /// ParseNamespaceAlias - Parse the part after the '=' in a namespace
   /// alias definition.
   ///
@@ -3195,12 +3183,12 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // C++ 9: classes [class] and C structs/unions.
-  
+
   /// 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 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
@@ -3246,10 +3234,9 @@ class Parser : public CodeCompletionHandler {
                            AccessSpecifier AS, bool EnteringContext,
                            DeclSpecContext DSC, ParsedAttributes &Attributes);
   void SkipCXXMemberSpecification(SourceLocation StartLoc,
-                                  SourceLocation AttrFixitLoc,
-                                  unsigned TagType,
+                                  SourceLocation AttrFixitLoc, unsigned TagType,
                                   Decl *TagDecl);
-  
+
   /// ParseCXXMemberSpecification - Parse the class definition.
   ///
   ///       member-specification:
@@ -3260,10 +3247,10 @@ class Parser : public CodeCompletionHandler {
                                    SourceLocation AttrFixitLoc,
                                    ParsedAttributes &Attrs, unsigned TagType,
                                    Decl *TagDecl);
-  
+
   /// 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.
+  /// 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.
   ///
@@ -3283,20 +3270,20 @@ class Parser : public CodeCompletionHandler {
   /// be a constant-expression.
   ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
                                        SourceLocation &EqualLoc);
-  
+
   /// Parse a C++ member-declarator up to, but not including, the optional
   /// brace-or-equal-initializer or pure-specifier.
-  bool
-  ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
-                                            VirtSpecifiers &VS,
-                                            ExprResult &BitfieldSize,
-                                            LateParsedAttrList &LateAttrs);
-  
+  bool ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
+                                                 VirtSpecifiers &VS,
+                                                 ExprResult &BitfieldSize,
+                                                 LateParsedAttrList &LateAttrs);
+
   /// Look for declaration specifiers possibly occurring after C++11
   /// virt-specifier-seq and diagnose them.
-  void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D,
-                                                               VirtSpecifiers &VS);
-  
+  void
+  MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D,
+                                                          VirtSpecifiers &VS);
+
   /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
   ///
   ///       member-declaration:
@@ -3355,7 +3342,7 @@ class Parser : public CodeCompletionHandler {
   ParseCXXClassMemberDeclarationWithPragmas(AccessSpecifier &AS,
                                             ParsedAttributes &AccessAttrs,
                                             DeclSpec::TST TagType, Decl *Tag);
-  
+
   /// 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
@@ -3378,7 +3365,7 @@ class Parser : public CodeCompletionHandler {
   ///          mem-initializer ...[opt]
   ///          mem-initializer ...[opt] , mem-initializer-list
   void 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
@@ -3392,17 +3379,17 @@ class Parser : public CodeCompletionHandler {
   ///         '::'[opt] nested-name-specifier[opt] class-name
   ///         identifier
   MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
-  
+
   /// 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 HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
+  void HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo,
                                       Decl *ThisDecl);
 
   //===--------------------------------------------------------------------===//
   // C++ 10: Derived classes [class.derived]
-  
+
   /// 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
@@ -3423,8 +3410,9 @@ class Parser : public CodeCompletionHandler {
   ///         ::[opt] nested-name-specifier[opt] class-name
   TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
                                     SourceLocation &EndLocation);
-  
-  /// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
+
+  /// ParseBaseClause - Parse the base-clause of a C++ class [C++
+  /// class.derived].
   ///
   ///       base-clause : [C++ class.derived]
   ///         ':' base-specifier-list
@@ -3432,7 +3420,7 @@ class Parser : public CodeCompletionHandler {
   ///         base-specifier '...'[opt]
   ///         base-specifier-list ',' base-specifier '...'[opt]
   void 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 {
@@ -3445,7 +3433,7 @@ class Parser : public CodeCompletionHandler {
   ///         attribute-specifier-seq[opt] access-specifier 'virtual'[opt]
   ///                 base-type-specifier
   BaseResult ParseBaseSpecifier(Decl *ClassDecl);
-  
+
   /// getAccessSpecifierIfPresent - Determine whether the next token is
   /// a C++ access-specifier.
   ///
@@ -3467,8 +3455,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseExpr.cpp
   ///@{
 
-  public:
-
+public:
   friend class OffsetOfStateRAIIObject;
 
   typedef Sema::FullExprArg FullExprArg;
@@ -3478,14 +3465,15 @@ class Parser : public CodeCompletionHandler {
 
   /// Simple precedence-based parser for binary/ternary operators.
   ///
-  /// Note: we diverge from the C99 grammar when parsing the assignment-expression
-  /// production.  C99 specifies that the LHS of an assignment operator should be
-  /// parsed as a unary-expression, but consistency dictates that it be a
-  /// conditional-expession.  In practice, the important thing here is that the
-  /// LHS of an assignment has to be an l-value, which productions between
-  /// unary-expression and conditional-expression don't produce.  Because we want
-  /// consistency, we parse the LHS as a conditional-expression, then check for
-  /// l-value-ness in semantic analysis stages.
+  /// Note: we diverge from the C99 grammar when parsing the
+  /// assignment-expression production.  C99 specifies that the LHS of an
+  /// assignment operator should be parsed as a unary-expression, but
+  /// consistency dictates that it be a conditional-expession.  In practice, the
+  /// important thing here is that the LHS of an assignment has to be an
+  /// l-value, which productions between unary-expression and
+  /// conditional-expression don't produce.  Because we want consistency, we
+  /// parse the LHS as a conditional-expression, then check for l-value-ness in
+  /// semantic analysis stages.
   ///
   /// \verbatim
   ///       pm-expression: [C++ 5.5]
@@ -3566,13 +3554,13 @@ class Parser : public CodeCompletionHandler {
   /// \endverbatim
   ExprResult
   ParseExpression(TypeCastState isTypeCast = TypeCastState::NotTypeCast);
-  
+
   ExprResult ParseConstantExpressionInExprEvalContext(
       TypeCastState isTypeCast = TypeCastState::NotTypeCast);
   ExprResult ParseConstantExpression();
   ExprResult ParseArrayBoundExpression();
   ExprResult ParseCaseExpression(SourceLocation CaseLoc);
-  
+
   /// Parse a constraint-expression.
   ///
   /// \verbatim
@@ -3580,7 +3568,7 @@ class Parser : public CodeCompletionHandler {
   ///         logical-or-expression
   /// \endverbatim
   ExprResult ParseConstraintExpression();
-  
+
   /// \brief Parse a constraint-logical-and-expression.
   ///
   /// \verbatim
@@ -3590,9 +3578,8 @@ class Parser : public CodeCompletionHandler {
   ///         constraint-logical-and-expression '&&' primary-expression
   ///
   /// \endverbatim
-  ExprResult
-  ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause);
-  
+  ExprResult ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause);
+
   /// \brief Parse a constraint-logical-or-expression.
   ///
   /// \verbatim
@@ -3604,11 +3591,11 @@ class Parser : public CodeCompletionHandler {
   ///
   /// \endverbatim
   ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause);
-  
+
   /// Parse an expr that doesn't include (top-level) commas.
   ExprResult ParseAssignmentExpression(
       TypeCastState isTypeCast = TypeCastState::NotTypeCast);
-  
+
   ExprResult ParseConditionalExpression();
 
   /// ParseStringLiteralExpression - This handles the various token types that
@@ -3622,8 +3609,7 @@ class Parser : public CodeCompletionHandler {
   ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
   ExprResult ParseUnevaluatedStringLiteralExpression();
 
-  private:
-
+private:
   /// Whether the '>' token acts as an operator or not. This will be
   /// true except when we are parsing an expression within a C++
   /// template argument list, where the '>' closes the template
@@ -3652,11 +3638,11 @@ class Parser : public CodeCompletionHandler {
   /// being parsed.
   Sema::ParsingClassState
   PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
-  
+
   /// Deallocate the given parsed class and all of its nested
   /// classes.
   void DeallocateParsedClasses(ParsingClass *Class);
-  
+
   /// Pop the top class of the stack of classes that are
   /// currently being parsed.
   ///
@@ -3873,8 +3859,7 @@ class Parser : public CodeCompletionHandler {
   /// \endverbatim
   ///
   ExprResult ParseCastExpression(CastParseKind ParseKind,
-                                 bool isAddressOfOperand,
-                                 bool &NotCastExpr,
+                                 bool isAddressOfOperand, bool &NotCastExpr,
                                  TypeCastState isTypeCast,
                                  bool isVectorLiteral = false,
                                  bool *NotPrimaryExpression = nullptr);
@@ -3891,9 +3876,8 @@ class Parser : public CodeCompletionHandler {
   /// suffix.
   bool isPostfixExpressionSuffixStart() {
     tok::TokenKind K = Tok.getKind();
-    return (K == tok::l_square || K == tok::l_paren ||
-            K == tok::period || K == tok::arrow ||
-            K == tok::plusplus || K == tok::minusminus);
+    return (K == tok::l_square || K == tok::l_paren || K == tok::period ||
+            K == tok::arrow || K == tok::plusplus || K == tok::minusminus);
   }
 
   /// Once the leading part of a postfix-expression is parsed, this
@@ -3918,7 +3902,7 @@ class Parser : public CodeCompletionHandler {
   ///         argument-expression-list ',' assignment-expression ...[opt]
   /// \endverbatim
   ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
-  
+
   /// Parse a sizeof or alignof expression.
   ///
   /// \verbatim
@@ -3936,7 +3920,7 @@ class Parser : public CodeCompletionHandler {
   /// [C2y]   '_Countof' '(' type-name ')'
   /// \endverbatim
   ExprResult ParseUnaryExprOrTypeTraitExpression();
-  
+
   /// ParseBuiltinPrimaryExpression
   ///
   /// \verbatim
@@ -3961,9 +3945,9 @@ class Parser : public CodeCompletionHandler {
   /// [GNU]   offsetof-member-designator '[' expression ']'
   /// \endverbatim
   ExprResult ParseBuiltinPrimaryExpression();
-  
-  /// Parse a __builtin_sycl_unique_stable_name expression.  Accepts a type-id as
-  /// a parameter.
+
+  /// Parse a __builtin_sycl_unique_stable_name expression.  Accepts a type-id
+  /// as a parameter.
   ExprResult ParseSYCLUniqueStableNameExpression();
 
   /// ParseExprAfterUnaryExprOrTypeTrait - We parsed a typeof/sizeof/alignof/
@@ -3999,9 +3983,9 @@ class Parser : public CodeCompletionHandler {
   ///           vec_step ( type-name )
   /// \endverbatim
   ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
-                                                     bool &isCastExpr,
-                                                     ParsedType &CastTy,
-                                                     SourceRange &CastRange);
+                                                bool &isCastExpr,
+                                                ParsedType &CastTy,
+                                                SourceRange &CastRange);
 
   /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
   ///
@@ -4043,8 +4027,8 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseParenExpression - This parses the unit that starts with a '(' token,
   /// based on what is allowed by ExprType.  The actual thing parsed is returned
-  /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
-  /// not the parsed cast-expression.
+  /// in ExprType. If stopIfCastExpr is true, it will only return the parsed
+  /// type, not the parsed cast-expression.
   ///
   /// \verbatim
   ///       primary-expression: [C99 6.5.1]
@@ -4069,13 +4053,12 @@ class Parser : public CodeCompletionHandler {
   ///       '(' '[' expression ']' { '[' expression ']' } cast-expression
   /// \endverbatim
   ExprResult ParseParenExpression(ParenParseOption &ExprType,
-                                        bool stopIfCastExpr,
-                                        bool isTypeCast,
-                                        ParsedType &CastTy,
-                                        SourceLocation &RParenLoc);
+                                  bool stopIfCastExpr, bool isTypeCast,
+                                  ParsedType &CastTy,
+                                  SourceLocation &RParenLoc);
 
-  /// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
-  /// and we are at the left brace.
+  /// ParseCompoundLiteralExpression - We have parsed the parenthesized
+  /// type-name and we are at the left brace.
   ///
   /// \verbatim
   ///       postfix-expression: [C99 6.5.2]
@@ -4083,8 +4066,8 @@ class Parser : public CodeCompletionHandler {
   ///         '(' type-name ')' '{' initializer-list ',' '}'
   /// \endverbatim
   ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
-                                                  SourceLocation LParenLoc,
-                                                  SourceLocation RParenLoc);
+                                            SourceLocation LParenLoc,
+                                            SourceLocation RParenLoc);
 
   /// ParseGenericSelectionExpression - Parse a C11 generic-selection
   /// [C11 6.5.1.1].
@@ -4139,7 +4122,7 @@ class Parser : public CodeCompletionHandler {
   /// [clang] block-args:
   /// [clang]   '(' parameter-list ')'
   /// \endverbatim
-  ExprResult ParseBlockLiteralExpression();  // ^{...}
+  ExprResult ParseBlockLiteralExpression(); // ^{...}
 
   /// Parse an assignment expression where part of an Objective-C message
   /// send has already been parsed.
@@ -4151,8 +4134,8 @@ class Parser : public CodeCompletionHandler {
   /// Since this handles full assignment-expression's, it handles postfix
   /// expressions and other binary operators for these expressions as well.
   ExprResult ParseAssignmentExprWithObjCMessageExprStart(
-      SourceLocation LBracloc, SourceLocation SuperLoc,
-      ParsedType ReceiverType, Expr *ReceiverExpr);
+      SourceLocation LBracloc, SourceLocation SuperLoc, ParsedType ReceiverType,
+      Expr *ReceiverExpr);
 
   /// Return true if we know that we are definitely looking at a
   /// decl-specifier, and isn't part of an expression such as a function-style
@@ -4197,7 +4180,7 @@ class Parser : public CodeCompletionHandler {
   /// [clang] block-id:
   /// [clang]   specifier-qualifier-list block-declarator
   /// \endverbatim
-  void ParseBlockId(SourceLocation CaretLoc); 
+  void ParseBlockId(SourceLocation CaretLoc);
 
   /// Parse availability query specification.
   ///
@@ -4225,8 +4208,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseExprCXX.cpp
   ///@{
 
-  public:
-
+public:
   /// Parse a C++ unqualified-id (or a C identifier), which describes the
   /// name of an entity.
   ///
@@ -4247,9 +4229,10 @@ class Parser : public CodeCompletionHandler {
   /// \param ObjectType if this unqualified-id occurs within a member access
   /// expression, the type of the base object whose member is being accessed.
   ///
-  /// \param ObjectHadErrors if this unqualified-id occurs within a member access
-  /// expression, indicates whether the original subexpressions had any errors.
-  /// When true, diagnostics for missing 'template' keyword will be supressed.
+  /// \param ObjectHadErrors if this unqualified-id occurs within a member
+  /// access expression, indicates whether the original subexpressions had any
+  /// errors. When true, diagnostics for missing 'template' keyword will be
+  /// supressed.
   ///
   /// \param EnteringContext whether we are entering the scope of the
   /// nested-name-specifier.
@@ -4258,7 +4241,8 @@ class Parser : public CodeCompletionHandler {
   ///
   /// \param AllowConstructorName whether we allow parsing a constructor name.
   ///
-  /// \param AllowDeductionGuide whether we allow parsing a deduction guide name.
+  /// \param AllowDeductionGuide whether we allow parsing a deduction guide
+  /// name.
   ///
   /// \param Result on a successful parse, contains the parsed unqualified-id.
   ///
@@ -4269,8 +4253,7 @@ class Parser : public CodeCompletionHandler {
                           bool AllowDeductionGuide,
                           SourceLocation *TemplateKWLoc, UnqualifiedId &Result);
 
-  private:
-
+private:
   /// ColonIsSacred - When this is false, we aggressively try to recover from
   /// code like "foo : bar" as if it were a typo for "foo :: bar".  This is not
   /// safe in case statements and a few other things.  This is managed by the
@@ -4278,8 +4261,8 @@ class Parser : public CodeCompletionHandler {
   bool ColonIsSacred;
 
   /// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
-  /// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate
-  /// based on the context past the parens.
+  /// parenthesized ambiguous type-id. This uses tentative parsing to
+  /// disambiguate based on the context past the parens.
   ExprResult ParseCXXAmbiguousParenExpression(
       ParenParseOption &ExprType, ParsedType &CastTy,
       BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
@@ -4330,9 +4313,9 @@ class Parser : public CodeCompletionHandler {
   /// global scope.
   ///
   /// The isAddressOfOperand parameter indicates that this id-expression is a
-  /// direct operand of the address-of operator. This is, besides member contexts,
-  /// the only place where a qualified-id naming a non-static class member may
-  /// appear.
+  /// direct operand of the address-of operator. This is, besides member
+  /// contexts, the only place where a qualified-id naming a non-static class
+  /// member may appear.
   ///
   ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
 
@@ -4368,9 +4351,10 @@ class Parser : public CodeCompletionHandler {
   /// the "." or "->" of a member access expression, this parameter provides the
   /// type of the object whose members are being accessed.
   ///
-  /// \param ObjectHadErrors if this unqualified-id occurs within a member access
-  /// expression, indicates whether the original subexpressions had any errors.
-  /// When true, diagnostics for missing 'template' keyword will be supressed.
+  /// \param ObjectHadErrors if this unqualified-id occurs within a member
+  /// access expression, indicates whether the original subexpressions had any
+  /// errors. When true, diagnostics for missing 'template' keyword will be
+  /// supressed.
   ///
   /// \param EnteringContext whether we will be entering into the context of
   /// the nested-name-specifier after parsing it.
@@ -4464,35 +4448,35 @@ class Parser : public CodeCompletionHandler {
   ///             attribute-specifier-seq[opt] trailing-return-type[opt]
   ///
   ExprResult ParseLambdaExpression();
-  
+
   /// Use lookahead and potentially tentative parsing to determine if we are
   /// looking at a C++11 lambda expression, and parse it if we are.
   ///
   /// If we are not looking at a lambda expression, returns ExprError().
   ExprResult TryParseLambdaExpression();
-  
+
   /// Parse a lambda introducer.
   /// \param Intro A LambdaIntroducer filled in with information about the
   ///        contents of the lambda-introducer.
   /// \param Tentative If non-null, we are disambiguating between a
   ///        lambda-introducer and some other construct. In this mode, we do not
-  ///        produce any diagnostics or take any other irreversible action unless
-  ///        we're sure that this is a lambda-expression.
-  /// \return \c true if parsing (or disambiguation) failed with a diagnostic and
-  ///         the caller should bail out / recover.
+  ///        produce any diagnostics or take any other irreversible action
+  ///        unless we're sure that this is a lambda-expression.
+  /// \return \c true if parsing (or disambiguation) failed with a diagnostic
+  ///         and the caller should bail out / recover.
   bool
   ParseLambdaIntroducer(LambdaIntroducer &Intro,
                         LambdaIntroducerTentativeParse *Tentative = nullptr);
-  
+
   /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda
   /// expression.
   ExprResult ParseLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro);
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2p1: C++ Casts
-  
-  /// ParseCXXCasts - This handles the various ways to cast expressions to another
-  /// type.
+
+  /// ParseCXXCasts - This handles the various ways to cast expressions to
+  /// another type.
   ///
   ///       postfix-expression: [C++ 5.2p1]
   ///         'dynamic_cast' '<' type-name '>' '(' expression ')'
@@ -4509,7 +4493,7 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2p1: C++ Type Identification
-  
+
   /// ParseCXXTypeid - This handles the C++ typeid expression.
   ///
   ///       postfix-expression: [C++ 5.2p1]
@@ -4520,7 +4504,7 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   //  C++ : Microsoft __uuidof Expression
-  
+
   /// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
   ///
   ///         '__uuidof' '(' expression ')'
@@ -4530,7 +4514,7 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2.4: C++ Pseudo-Destructor Expressions
-  
+
   /// Parse a C++ pseudo-destructor expression after the base,
   /// . or -> operator, and nested-name-specifier have already been
   /// parsed. We're handling this fragment of the grammar:
@@ -4563,32 +4547,31 @@ class Parser : public CodeCompletionHandler {
   /// has already been parsed, and the base expression is not of a non-dependent
   /// class type.
   ExprResult ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
-                                            tok::TokenKind OpKind,
-                                            CXXScopeSpec &SS,
-                                            ParsedType ObjectType);
+                                      tok::TokenKind OpKind, CXXScopeSpec &SS,
+                                      ParsedType ObjectType);
 
   //===--------------------------------------------------------------------===//
   // C++ 9.3.2: C++ 'this' pointer
-  
+
   /// ParseCXXThis - This handles the C++ 'this' pointer.
   ///
-  /// C++ 9.3.2: In the body of a non-static member function, the keyword this is
-  /// a non-lvalue expression whose value is the address of the object for which
-  /// the function is called.
+  /// C++ 9.3.2: In the body of a non-static member function, the keyword this
+  /// is a non-lvalue expression whose value is the address of the object for
+  /// which the function is called.
   ExprResult ParseCXXThis();
 
   //===--------------------------------------------------------------------===//
   // C++ 15: C++ Throw Expression
-  
+
   /// ParseThrowExpression - This handles the C++ throw expression.
   ///
   ///       throw-expression: [C++ 15]
   ///         'throw' assignment-expression[opt]
   ExprResult ParseThrowExpression();
-  
+
   //===--------------------------------------------------------------------===//
   // C++ 2.13.5: C++ Boolean Literals
-  
+
   /// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
   ///
   ///       boolean-literal: [C++ 2.13.5]
@@ -4598,7 +4581,7 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // C++ 5.2.3: Explicit type conversion (functional notation)
-  
+
   /// ParseCXXTypeConstructExpression - Parse construction of a specified type.
   /// Can be interpreted either as function-style casting ("int(x)")
   /// or class type construction ("ClassType(x,y,z)")
@@ -4658,9 +4641,9 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // C++ 5.3.4 and 5.3.5: C++ new and delete
-  
-  /// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.
-  /// This ambiguity appears in the syntax of the C++ new operator.
+
+  /// ParseExpressionListOrTypeId - Parse either an expression-list or a
+  /// type-id. This ambiguity appears in the syntax of the C++ new operator.
   ///
   ///        new-expression:
   ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
@@ -4669,9 +4652,9 @@ class Parser : public CodeCompletionHandler {
   ///        new-placement:
   ///                   '(' expression-list ')'
   ///
-  bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr*> &Exprs,
+  bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr *> &Exprs,
                                    Declarator &D);
-  
+
   /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
   /// passed to ParseDeclaratorInternal.
   ///
@@ -4680,13 +4663,14 @@ class Parser : public CodeCompletionHandler {
   ///                   direct-new-declarator '[' constant-expression ']'
   ///
   void ParseDirectNewDeclarator(Declarator &D);
-  
-  /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
-  /// memory in a typesafe manner and call constructors.
+
+  /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to
+  /// allocate memory in a typesafe manner and call constructors.
   ///
-  /// This method is called to parse the new expression after the optional :: has
-  /// been already parsed.  If the :: was present, "UseGlobal" is true and "Start"
-  /// is its location.  Otherwise, "Start" is the location of the 'new' token.
+  /// This method is called to parse the new expression after the optional ::
+  /// has been already parsed.  If the :: was present, "UseGlobal" is true and
+  /// "Start" is its location.  Otherwise, "Start" is the location of the 'new'
+  /// token.
   ///
   ///        new-expression:
   ///                   '::'[opt] 'new' new-placement[opt] new-type-id
@@ -4710,24 +4694,23 @@ class Parser : public CodeCompletionHandler {
   /// [C++0x]           braced-init-list
   ///
   ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
-  
+
   /// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used
   /// to free memory allocated by new.
   ///
   /// This method is called to parse the 'delete' expression after the optional
-  /// '::' has been already parsed.  If the '::' was present, "UseGlobal" is true
-  /// and "Start" is its location.  Otherwise, "Start" is the location of the
-  /// 'delete' token.
+  /// '::' has been already parsed.  If the '::' was present, "UseGlobal" is
+  /// true and "Start" is its location.  Otherwise, "Start" is the location of
+  /// the 'delete' token.
   ///
   ///        delete-expression:
   ///                   '::'[opt] 'delete' cast-expression
   ///                   '::'[opt] 'delete' '[' ']' cast-expression
-  ExprResult ParseCXXDeleteExpression(bool UseGlobal,
-                                            SourceLocation Start);
+  ExprResult ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start);
 
   //===--------------------------------------------------------------------===//
   // C++ if/switch/while/for condition expression.
-  
+
   /// ParseCXXCondition - if/switch/while condition expression.
   ///
   ///       condition:
@@ -4743,8 +4726,8 @@ class Parser : public CodeCompletionHandler {
   /// In C++1z, a condition may in some contexts be preceded by an
   /// optional init-statement. This function will parse that too.
   ///
-  /// \param InitStmt If non-null, an init-statement is permitted, and if present
-  /// will be parsed and stored here.
+  /// \param InitStmt If non-null, an init-statement is permitted, and if
+  /// present will be parsed and stored here.
   ///
   /// \param Loc The location of the start of the statement that requires this
   /// condition, e.g., the "for" in a for loop.
@@ -4753,7 +4736,8 @@ class Parser : public CodeCompletionHandler {
   /// it is considered an error to be recovered from.
   ///
   /// \param FRI If non-null, a for range declaration is permitted, and if
-  /// present will be parsed and stored here, and a null result will be returned.
+  /// present will be parsed and stored here, and a null result will be
+  /// returned.
   ///
   /// \param EnterForConditionScope If true, enter a continue/break scope at the
   /// appropriate moment for a 'for' loop.
@@ -4782,9 +4766,9 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseRequiresExpression - Parse a C++2a requires-expression.
   /// C++2a [expr.prim.req]p1
-  ///     A requires-expression provides a concise way to express requirements on
-  ///     template arguments. A requirement is one that can be checked by name
-  ///     lookup (6.4) or by checking properties of types and expressions.
+  ///     A requires-expression provides a concise way to express requirements
+  ///     on template arguments. A requirement is one that can be checked by
+  ///     name lookup (6.4) or by checking properties of types and expressions.
   ///
   ///     requires-expression:
   ///         'requires' requirement-parameter-list[opt] requirement-body
@@ -4855,16 +4839,14 @@ class Parser : public CodeCompletionHandler {
   /// refers to a template without performing name lookup to verify.
   ///
   /// \returns true if a parse error occurred, false otherwise.
-  bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
-                                    ParsedType ObjectType,
+  bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, ParsedType ObjectType,
                                     bool ObjectHadErrors,
                                     SourceLocation TemplateKWLoc,
                                     IdentifierInfo *Name,
                                     SourceLocation NameLoc,
-                                    bool EnteringContext,
-                                    UnqualifiedId &Id,
+                                    bool EnteringContext, UnqualifiedId &Id,
                                     bool AssumeTemplateId);
-  
+
   /// Parse an operator-function-id or conversion-function-id as part
   /// of a C++ unqualified-id.
   ///
@@ -4906,12 +4888,11 @@ class Parser : public CodeCompletionHandler {
   ///
   /// \returns true if parsing fails, false otherwise.
   bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
-                                  ParsedType ObjectType,
-                                  UnqualifiedId &Result);
+                                  ParsedType ObjectType, UnqualifiedId &Result);
 
   //===--------------------------------------------------------------------===//
   // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
-  
+
   /// Parse the built-in type-trait pseudo-functions that allow
   /// implementation of the TR1/C++11 type traits templates.
   ///
@@ -4927,7 +4908,7 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // Embarcadero: Arary and Expression Traits
-  
+
   /// ParseArrayTypeTrait - Parse the built-in array type-trait
   /// pseudo-functions.
   ///
@@ -4936,7 +4917,7 @@ class Parser : public CodeCompletionHandler {
   /// [Embarcadero]     '__array_extent' '(' type-id ',' expression ')'
   ///
   ExprResult ParseArrayTypeTrait();
-  
+
   /// ParseExpressionTrait - Parse built-in expression-trait
   /// pseudo-functions like __is_lvalue_expr( xxx ).
   ///
@@ -4957,8 +4938,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseHLSL.cpp
   ///@{
 
-  private:
-
+private:
   bool MaybeParseHLSLAnnotations(Declarator &D,
                                  SourceLocation *EndLoc = nullptr,
                                  bool CouldBeBitField = false) {
@@ -4996,8 +4976,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseInit.cpp
   ///@{
 
-  private:
-
+private:
   //===--------------------------------------------------------------------===//
   // C99 6.7.8: Initialization.
 
@@ -5010,12 +4989,12 @@ class Parser : public CodeCompletionHandler {
       return ParseAssignmentExpression();
     return ParseBraceInitializer();
   }
-  
-  /// MayBeDesignationStart - Return true if the current token might be the start
-  /// of a designator.  If we can tell it is impossible that it is a designator,
-  /// return false.
+
+  /// MayBeDesignationStart - Return true if the current token might be the
+  /// start of a designator.  If we can tell it is impossible that it is a
+  /// designator, return false.
   bool MayBeDesignationStart();
-  
+
   /// ParseBraceInitializer - Called when parsing an initializer that has a
   /// leading open brace.
   ///
@@ -5029,14 +5008,14 @@ class Parser : public CodeCompletionHandler {
   ///         initializer-list ',' designation[opt] initializer ...[opt]
   ///
   ExprResult ParseBraceInitializer();
-  
+
   struct DesignatorCompletionInfo {
     SmallVectorImpl<Expr *> &InitExprs;
     QualType PreferredBaseType;
   };
-  
-  /// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
-  /// checking to see if the token stream starts with a designator.
+
+  /// ParseInitializerWithPotentialDesignator - Parse the 'initializer'
+  /// production checking to see if the token stream starts with a designator.
   ///
   /// C99:
   ///
@@ -5078,11 +5057,11 @@ class Parser : public CodeCompletionHandler {
   ///
   /// \p CodeCompleteCB is called with Designation parsed so far.
   ExprResult ParseInitializerWithPotentialDesignator(DesignatorCompletionInfo);
-  
+
   ExprResult createEmbedExpr();
 
   /// A SmallVector of expressions.
-  typedef SmallVector<Expr*, 12> ExprVector;
+  typedef SmallVector<Expr *, 12> ExprVector;
 
   // Return true if a comma (or closing brace) is necessary after the
   // __if_exists/if_not_exists statement.
@@ -5101,8 +5080,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseObjc.cpp
   ///@{
 
-  public:
-
+public:
   friend class InMessageExpressionRAIIObject;
   friend class ObjCDeclContextSwitch;
 
@@ -5116,8 +5094,7 @@ class Parser : public CodeCompletionHandler {
     return Actions.getNullabilityKeyword(nullability);
   }
 
-  private:
-
+private:
   /// Objective-C contextual keywords.
   IdentifierInfo *Ident_instancetype;
 
@@ -5158,10 +5135,11 @@ class Parser : public CodeCompletionHandler {
     Parser &P;
     ObjCContainerDecl *DC;
     SaveAndRestore<bool> WithinObjCContainer;
+
   public:
     explicit ObjCDeclContextSwitch(Parser &p)
-      : P(p), DC(p.getObjCDeclContext()),
-        WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
+        : P(p), DC(p.getObjCDeclContext()),
+          WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
       if (DC)
         P.Actions.ObjC().ActOnObjCTemporaryExitContainerContext(DC);
     }
@@ -5176,11 +5154,12 @@ class Parser : public CodeCompletionHandler {
   void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
 
   // Objective-C External Declarations
-  
+
   /// Skips attributes after an Objective-C @ directive. Emits a diagnostic.
   void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
-  
-  /// ParseObjCAtDirectives - Handle parts of the external-declaration production:
+
+  /// ParseObjCAtDirectives - Handle parts of the external-declaration
+  /// production:
   ///       external-declaration: [C99 6.9]
   /// [OBJC]  objc-class-definition
   /// [OBJC]  objc-class-declaration
@@ -5190,7 +5169,7 @@ class Parser : public CodeCompletionHandler {
   /// [OBJC]  '@' 'end'
   DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
                                        ParsedAttributes &DeclSpecAttrs);
-  
+
   ///
   /// objc-class-declaration:
   ///    '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
@@ -5199,7 +5178,7 @@ class Parser : public CodeCompletionHandler {
   ///   identifier objc-type-parameter-list[opt]
   ///
   DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
-  
+
   ///
   ///   objc-interface:
   ///     objc-class-interface-attributes[opt] objc-class-interface
@@ -5231,13 +5210,13 @@ class Parser : public CodeCompletionHandler {
   ///
   Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
                                         ParsedAttributes &prefixAttrs);
-  
+
   /// Class to handle popping type parameters when leaving the scope.
   class ObjCTypeParamListScope;
-  
+
   /// Parse an objc-type-parameter-list.
   ObjCTypeParamList *parseObjCTypeParamList();
-  
+
   /// Parse an Objective-C type parameter list, if present, or capture
   /// the locations of the protocol identifiers for a list of protocol
   /// references.
@@ -5272,7 +5251,7 @@ class Parser : public CodeCompletionHandler {
                                         BalancedDelimiterTracker &T,
                                         SmallVectorImpl<Decl *> &AllIvarDecls,
                                         bool RBraceMissing);
-  
+
   ///   objc-class-instance-variables:
   ///     '{' objc-instance-variable-decl-list[opt] '}'
   ///
@@ -5297,17 +5276,14 @@ class Parser : public CodeCompletionHandler {
   void ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
                                        tok::ObjCKeywordKind visibility,
                                        SourceLocation atLoc);
-  
+
   ///   objc-protocol-refs:
   ///     '<' identifier-list '>'
   ///
-  bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P,
-                                   SmallVectorImpl<SourceLocation> &PLocs,
-                                   bool WarnOnDeclarations,
-                                   bool ForObjCContainer,
-                                   SourceLocation &LAngleLoc,
-                                   SourceLocation &EndProtoLoc,
-                                   bool consumeLastToken);
+  bool ParseObjCProtocolReferences(
+      SmallVectorImpl<Decl *> &P, SmallVectorImpl<SourceLocation> &PLocs,
+      bool WarnOnDeclarations, bool ForObjCContainer, SourceLocation &LAngleLoc,
+      SourceLocation &EndProtoLoc, bool consumeLastToken);
 
   /// Parse the first angle-bracket-delimited clause for an
   /// Objective-C object or object pointer type, which may be either
@@ -5317,29 +5293,21 @@ class Parser : public CodeCompletionHandler {
   ///     '<' type-name '...'[opt] (',' type-name '...'[opt])* '>'
   ///
   void parseObjCTypeArgsOrProtocolQualifiers(
-         ParsedType baseType,
-         SourceLocation &typeArgsLAngleLoc,
-         SmallVectorImpl<ParsedType> &typeArgs,
-         SourceLocation &typeArgsRAngleLoc,
-         SourceLocation &protocolLAngleLoc,
-         SmallVectorImpl<Decl *> &protocols,
-         SmallVectorImpl<SourceLocation> &protocolLocs,
-         SourceLocation &protocolRAngleLoc,
-         bool consumeLastToken,
-         bool warnOnIncompleteProtocols);
+      ParsedType baseType, SourceLocation &typeArgsLAngleLoc,
+      SmallVectorImpl<ParsedType> &typeArgs, SourceLocation &typeArgsRAngleLoc,
+      SourceLocation &protocolLAngleLoc, SmallVectorImpl<Decl *> &protocols,
+      SmallVectorImpl<SourceLocation> &protocolLocs,
+      SourceLocation &protocolRAngleLoc, bool consumeLastToken,
+      bool warnOnIncompleteProtocols);
 
   /// Parse either Objective-C type arguments or protocol qualifiers; if the
   /// former, also parse protocol qualifiers afterward.
   void parseObjCTypeArgsAndProtocolQualifiers(
-         ParsedType baseType,
-         SourceLocation &typeArgsLAngleLoc,
-         SmallVectorImpl<ParsedType> &typeArgs,
-         SourceLocation &typeArgsRAngleLoc,
-         SourceLocation &protocolLAngleLoc,
-         SmallVectorImpl<Decl *> &protocols,
-         SmallVectorImpl<SourceLocation> &protocolLocs,
-         SourceLocation &protocolRAngleLoc,
-         bool consumeLastToken);
+      ParsedType baseType, SourceLocation &typeArgsLAngleLoc,
+      SmallVectorImpl<ParsedType> &typeArgs, SourceLocation &typeArgsRAngleLoc,
+      SourceLocation &protocolLAngleLoc, SmallVectorImpl<Decl *> &protocols,
+      SmallVectorImpl<SourceLocation> &protocolLocs,
+      SourceLocation &protocolRAngleLoc, bool consumeLastToken);
 
   /// Parse a protocol qualifier type such as '<NSCopying>', which is
   /// an anachronistic way of writing 'id<NSCopying>'.
@@ -5364,8 +5332,7 @@ class Parser : public CodeCompletionHandler {
   ///     @required
   ///     @optional
   ///
-  void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
-                                  Decl *CDecl);
+  void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, Decl *CDecl);
 
   ///   objc-protocol-declaration:
   ///     objc-protocol-definition
@@ -5390,11 +5357,11 @@ class Parser : public CodeCompletionHandler {
     Parser &P;
     Decl *Dcl;
     bool HasCFunction;
-    typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
+    typedef SmallVector<LexedMethod *, 8> LateParsedObjCMethodContainer;
     LateParsedObjCMethodContainer LateParsedObjCMethods;
 
     ObjCImplParsingDataRAII(Parser &parser, Decl *D)
-      : P(parser), Dcl(D), HasCFunction(false) {
+        : P(parser), Dcl(D), HasCFunction(false) {
       P.CurParsedObjCImpl = this;
       Finished = false;
     }
@@ -5407,7 +5374,7 @@ class Parser : public CodeCompletionHandler {
     bool Finished;
   };
   ObjCImplParsingDataRAII *CurParsedObjCImpl;
-  
+
   /// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them
   /// for later parsing.
   void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
@@ -5425,7 +5392,7 @@ class Parser : public CodeCompletionHandler {
   DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
                                                       ParsedAttributes &Attrs);
   DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
-  
+
   ///   compatibility-alias-decl:
   ///     @compatibility_alias alias-name  class-name ';'
   ///
@@ -5475,7 +5442,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx,
                                ParsedAttributes *ParamAttrs);
-  
+
   ///   objc-method-proto:
   ///     objc-instance-method objc-method-decl objc-method-attributes[opt]
   ///     objc-class-method objc-method-decl objc-method-attributes[opt]
@@ -5487,9 +5454,9 @@ class Parser : public CodeCompletionHandler {
   ///     __attribute__((deprecated))
   ///
   Decl *ParseObjCMethodPrototype(
-            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
-            bool MethodDefinition = true);
-  
+      tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+      bool MethodDefinition = true);
+
   ///   objc-method-decl:
   ///     objc-selector
   ///     objc-keyword-selector objc-parmlist[opt]
@@ -5518,10 +5485,11 @@ class Parser : public CodeCompletionHandler {
   ///   objc-keyword-attributes:         [OBJC2]
   ///     __attribute__((unused))
   ///
-  Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
-            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
-            bool MethodDefinition=true);
-  
+  Decl *ParseObjCMethodDecl(
+      SourceLocation mLoc, tok::TokenKind mType,
+      tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+      bool MethodDefinition = true);
+
   ///   Parse property attribute declarations.
   ///
   ///   property-attr-decl: '(' property-attrlist ')'
@@ -5553,58 +5521,58 @@ class Parser : public CodeCompletionHandler {
   ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
   ///
   Decl *ParseObjCMethodDefinition();
-  
+
   //===--------------------------------------------------------------------===//
   // Objective-C Expressions
   ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
   ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
-  
+
   /// ParseObjCCharacterLiteral -
   /// objc-scalar-literal : '@' character-literal
   ///                        ;
   ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
-  
+
   /// ParseObjCNumericLiteral -
   /// objc-scalar-literal : '@' scalar-literal
   ///                        ;
   /// scalar-literal : | numeric-constant			/* any numeric constant. */
   ///                    ;
   ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
-  
+
   /// ParseObjCBooleanLiteral -
   /// objc-scalar-literal : '@' boolean-keyword
   ///                        ;
   /// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
   ///                        ;
   ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
-  
+
   ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
   ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
-  
+
   /// ParseObjCBoxedExpr -
   /// objc-box-expression:
   ///       @( assignment-expression )
   ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
-  
+
   ///    objc-encode-expression:
   ///      \@encode ( type-name )
   ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
-  
+
   ///     objc-selector-expression
   ///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
   ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
-  
+
   ///     objc-protocol-expression
   ///       \@protocol ( protocol-name )
   ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
-  
+
   /// Determine whether the parser is currently referring to a an
   /// Objective-C message send, using a simplified heuristic to avoid overhead.
   ///
   /// This routine will only return true for a subset of valid message-send
   /// expressions.
   bool isSimpleObjCMessageExpression();
-  
+
   ///   objc-message-expr:
   ///     '[' objc-receiver objc-message-args ']'
   ///
@@ -5690,7 +5658,7 @@ class Parser : public CodeCompletionHandler {
 
   StmtResult ParseObjCAtStatement(SourceLocation atLoc,
                                   ParsedStmtContext StmtCtx);
-  
+
   ///  objc-try-catch-statement:
   ///    @try compound-statement objc-catch-list[opt]
   ///    @try compound-statement objc-catch-list[opt] @finally compound-statement
@@ -5703,22 +5671,22 @@ class Parser : public CodeCompletionHandler {
   ///     '...' [OBJC2]
   ///
   StmtResult ParseObjCTryStmt(SourceLocation atLoc);
-  
+
   ///  objc-throw-statement:
   ///    throw expression[opt];
   ///
   StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
-  
+
   /// objc-synchronized-statement:
   ///   @synchronized '(' expression ')' compound-statement
   ///
   StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
-  
+
   /// objc-autoreleasepool-statement:
   ///   @autoreleasepool compound-statement
   ///
   StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc);
-  
+
   /// ParseObjCTypeQualifierList - This routine parses the objective-c's type
   /// qualifier list and builds their bitmask representation in the input
   /// argument.
@@ -5738,8 +5706,7 @@ class Parser : public CodeCompletionHandler {
   ///     'nullable'
   ///     'null_unspecified'
   ///
-  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
-                                  DeclaratorContext Context);
+  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, DeclaratorContext Context);
 
   /// Determine whether we are currently at the start of an Objective-C
   /// class message that appears to be missing the open bracket '['.
@@ -5757,8 +5724,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseOpenACC.cpp
   ///@{
 
-  public:
-
+public:
   friend class ParsingOpenACCDirectiveRAII;
 
   /// Parse OpenACC directive on a declaration.
@@ -5770,12 +5736,11 @@ class Parser : public CodeCompletionHandler {
                                            ParsedAttributes &Attrs,
                                            DeclSpec::TST TagType,
                                            Decl *TagDecl);
-  
+
   // Parse OpenACC Directive on a Statement.
   StmtResult ParseOpenACCDirectiveStmt();
 
-  private:
-
+private:
   /// Parsing OpenACC directive mode.
   bool OpenACCDirectiveParsing = false;
 
@@ -5864,13 +5829,13 @@ class Parser : public CodeCompletionHandler {
   ///
   /// #pragma acc cache ([readonly:]var-list) new-line
   OpenACCCacheParseInfo ParseOpenACCCacheVarList();
-  
+
   /// Tries to parse the 'modifier-list' for a 'copy', 'copyin', 'copyout', or
   /// 'create' clause.
   OpenACCModifierKind tryParseModifierList(OpenACCClauseKind CK);
 
   using OpenACCVarParseResult = std::pair<ExprResult, OpenACCParseCanContinue>;
-  
+
   /// Parses a single variable in a variable list for OpenACC.
   ///
   /// OpenACC 3.3, section 1.6:
@@ -5886,15 +5851,15 @@ class Parser : public CodeCompletionHandler {
   /// Parses the variable list for the variety of places that take a var-list.
   llvm::SmallVector<Expr *> ParseOpenACCVarList(OpenACCDirectiveKind DK,
                                                 OpenACCClauseKind CK);
-  
+
   /// Parses any parameters for an OpenACC Clause, including required/optional
   /// parens.
   ///
   /// The OpenACC Clause List is a comma or space-delimited list of clauses (see
   /// the comment on ParseOpenACCClauseList).  The concept of a 'clause' doesn't
-  /// really have its owner grammar and each individual one has its own definition.
-  /// However, they all are named with a single-identifier (or auto/default!)
-  /// token, followed in some cases by either braces or parens.
+  /// really have its owner grammar and each individual one has its own
+  /// definition. However, they all are named with a single-identifier (or
+  /// auto/default!) token, followed in some cases by either braces or parens.
   OpenACCClauseParseResult
   ParseOpenACCClauseParams(ArrayRef<const OpenACCClause *> ExistingClauses,
                            OpenACCDirectiveKind DirKind, OpenACCClauseKind Kind,
@@ -5905,17 +5870,17 @@ class Parser : public CodeCompletionHandler {
   OpenACCClauseParseResult
   ParseOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
                      OpenACCDirectiveKind DirKind);
-  
+
   /// Parses the clause-list for an OpenACC directive.
   ///
   /// OpenACC 3.3, section 1.7:
-  /// To simplify the specification and convey appropriate constraint information,
-  /// a pqr-list is a comma-separated list of pdr items. The one exception is a
-  /// clause-list, which is a list of one or more clauses optionally separated by
-  /// commas.
+  /// To simplify the specification and convey appropriate constraint
+  /// information, a pqr-list is a comma-separated list of pdr items. The one
+  /// exception is a clause-list, which is a list of one or more clauses
+  /// optionally separated by commas.
   SmallVector<OpenACCClause *>
   ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
-  
+
   /// OpenACC 3.3, section 2.16:
   /// In this section and throughout the specification, the term wait-argument
   /// means:
@@ -5943,7 +5908,7 @@ class Parser : public CodeCompletionHandler {
   bool ParseOpenACCIntExprList(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
                                SourceLocation Loc,
                                llvm::SmallVectorImpl<Expr *> &IntExprs);
-  
+
   /// Parses the 'device-type-list', which is a list of identifiers.
   ///
   /// OpenACC 3.3 Section 2.4:
@@ -5956,17 +5921,17 @@ class Parser : public CodeCompletionHandler {
   ///
   /// The device_type clause may be abbreviated to dtype.
   bool ParseOpenACCDeviceTypeList(llvm::SmallVector<IdentifierLoc> &Archs);
-  
+
   /// Parses the 'async-argument', which is an integral value with two
   /// 'special' values that are likely negative (but come from Macros).
   ///
   /// OpenACC 3.3 section 2.16:
   /// In this section and throughout the specification, the term async-argument
-  /// means a nonnegative scalar integer expression (int for C or C++, integer for
-  /// Fortran), or one of the special values acc_async_noval or acc_async_sync, as
-  /// defined in the C header file and the Fortran openacc module. The special
-  /// values are negative values, so as not to conflict with a user-specified
-  /// nonnegative async-argument.
+  /// means a nonnegative scalar integer expression (int for C or C++, integer
+  /// for Fortran), or one of the special values acc_async_noval or
+  /// acc_async_sync, as defined in the C header file and the Fortran openacc
+  /// module. The special values are negative values, so as not to conflict with
+  /// a user-specified nonnegative async-argument.
   OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
                                                       OpenACCClauseKind CK,
                                                       SourceLocation Loc);
@@ -5978,14 +5943,14 @@ class Parser : public CodeCompletionHandler {
   /// size-expr is one of:
   ///    *
   ///    int-expr
-  /// Note that this is specified under 'gang-arg-list', but also applies to 'tile'
-  /// via reference.
+  /// Note that this is specified under 'gang-arg-list', but also applies to
+  /// 'tile' via reference.
   ExprResult ParseOpenACCSizeExpr(OpenACCClauseKind CK);
-  
+
   /// Parses a comma delimited list of 'size-expr's.
   bool ParseOpenACCSizeExprList(OpenACCClauseKind CK,
                                 llvm::SmallVectorImpl<Expr *> &SizeExprs);
-  
+
   /// Parses a 'gang-arg-list', used for the 'gang' clause.
   ///
   /// OpenACC 3.3 Section 2.9:
@@ -6023,8 +5988,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseOpenMP.cpp
   ///@{
 
-  private:
-
+private:
   friend class ParsingOpenMPDirectiveRAII;
 
   /// Parsing OpenMP directive mode.
@@ -6046,7 +6010,7 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // OpenMP: Directives and clauses.
-  
+
   /// Parse clauses for '#pragma omp declare simd'.
   DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
                                             CachedTokens &Toks,
@@ -6099,7 +6063,8 @@ class Parser : public CodeCompletionHandler {
   bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI,
                                          OMPTraitInfo *ParentTI);
 
-  /// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
+  /// Parse clauses for '#pragma omp declare variant ( variant-func-id )
+  /// clause'.
   void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
                                      SourceLocation Loc);
 
@@ -6160,8 +6125,7 @@ class Parser : public CodeCompletionHandler {
   void parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
                             OpenMPDirectiveKind ExpectedKind,
                             OpenMPDirectiveKind FoundKind,
-                            SourceLocation MatchingLoc,
-                            SourceLocation FoundLoc,
+                            SourceLocation MatchingLoc, SourceLocation FoundLoc,
                             bool SkipUntilOpenMPEnd);
 
   /// Parses declarative OpenMP directives.
@@ -6204,7 +6168,7 @@ class Parser : public CodeCompletionHandler {
       AccessSpecifier &AS, ParsedAttributes &Attrs, bool Delayed = false,
       DeclSpec::TST TagType = DeclSpec::TST_unspecified,
       Decl *TagDecl = nullptr);
-  
+
   /// Parse 'omp declare reduction' construct.
   ///
   ///       declare-reduction-directive:
@@ -6212,11 +6176,11 @@ class Parser : public CodeCompletionHandler {
   ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
   ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
   ///        annot_pragma_openmp_end
-  /// <reduction_id> is either a base language identifier or one of the following
-  /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
+  /// <reduction_id> is either a base language identifier or one of the
+  /// following operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
   ///
   DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
-  
+
   /// Parses initializer for provided omp_priv declaration inside the reduction
   /// initializer.
   void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);
@@ -6248,10 +6212,10 @@ class Parser : public CodeCompletionHandler {
   ///
   bool ParseOpenMPSimpleVarList(
       OpenMPDirectiveKind Kind,
-      const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
-          Callback,
+      const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
+          &Callback,
       bool AllowScopeSpecifier);
-  
+
   /// Parses declarative or executable directive.
   ///
   ///       threadprivate-directive:
@@ -6276,21 +6240,22 @@ class Parser : public CodeCompletionHandler {
   ///       executable-directive:
   ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
   ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
-  ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
-  ///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'error'
-  ///         | 'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
-  ///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
-  ///         'master taskloop' | 'master taskloop simd' | 'parallel master
-  ///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
-  ///         enter data' | 'target exit data' | 'target parallel' | 'target
-  ///         parallel for' | 'target update' | 'distribute parallel for' |
-  ///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
-  ///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
-  ///         simd' | 'teams distribute parallel for simd' | 'teams distribute
-  ///         parallel for' | 'target teams' | 'target teams distribute' | 'target
-  ///         teams distribute parallel for' | 'target teams distribute parallel
-  ///         for simd' | 'target teams distribute simd' | 'masked' |
-  ///         'parallel masked' {clause} annot_pragma_openmp_end
+  ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task'
+  ///         | 'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
+  ///         'error' | 'atomic' | 'for simd' | 'parallel for simd' | 'target' |
+  ///         'target data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop
+  ///         simd' | 'master taskloop' | 'master taskloop simd' | 'parallel
+  ///         master taskloop' | 'parallel master taskloop simd' | 'distribute'
+  ///         | 'target enter data' | 'target exit data' | 'target parallel' |
+  ///         'target parallel for' | 'target update' | 'distribute parallel
+  ///         for' | 'distribute paralle for simd' | 'distribute simd' | 'target
+  ///         parallel for simd' | 'target simd' | 'teams distribute' | 'teams
+  ///         distribute simd' | 'teams distribute parallel for simd' | 'teams
+  ///         distribute parallel for' | 'target teams' | 'target teams
+  ///         distribute' | 'target teams distribute parallel for' | 'target
+  ///         teams distribute parallel for simd' | 'target teams distribute
+  ///         simd' | 'masked' | 'parallel masked' {clause}
+  ///         annot_pragma_openmp_end
   ///
   ///
   /// \param StmtCtx The context in which we're parsing the directive.
@@ -6326,21 +6291,21 @@ class Parser : public CodeCompletionHandler {
   ///
   ///    clause:
   ///       if-clause | final-clause | num_threads-clause | safelen-clause |
-  ///       default-clause | private-clause | firstprivate-clause | shared-clause
-  ///       | linear-clause | aligned-clause | collapse-clause | bind-clause |
-  ///       lastprivate-clause | reduction-clause | proc_bind-clause |
-  ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
-  ///       mergeable-clause | flush-clause | read-clause | write-clause |
-  ///       update-clause | capture-clause | seq_cst-clause | device-clause |
-  ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
-  ///       thread_limit-clause | priority-clause | grainsize-clause |
-  ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
-  ///       from-clause | is_device_ptr-clause | task_reduction-clause |
-  ///       in_reduction-clause | allocator-clause | allocate-clause |
-  ///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
-  ///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
-  ///       exclusive-clause | uses_allocators-clause | use_device_addr-clause |
-  ///       has_device_addr
+  ///       default-clause | private-clause | firstprivate-clause |
+  ///       shared-clause | linear-clause | aligned-clause | collapse-clause |
+  ///       bind-clause | lastprivate-clause | reduction-clause |
+  ///       proc_bind-clause | schedule-clause | copyin-clause |
+  ///       copyprivate-clause | untied-clause | mergeable-clause | flush-clause
+  ///       | read-clause | write-clause | update-clause | capture-clause |
+  ///       seq_cst-clause | device-clause | simdlen-clause | threads-clause |
+  ///       simd-clause | num_teams-clause | thread_limit-clause |
+  ///       priority-clause | grainsize-clause | nogroup-clause |
+  ///       num_tasks-clause | hint-clause | to-clause | from-clause |
+  ///       is_device_ptr-clause | task_reduction-clause | in_reduction-clause |
+  ///       allocator-clause | allocate-clause | acq_rel-clause | acquire-clause
+  ///       | release-clause | relaxed-clause | depobj-clause | destroy-clause |
+  ///       detach-clause | inclusive-clause | exclusive-clause |
+  ///       uses_allocators-clause | use_device_addr-clause | has_device_addr
   ///
   /// \param DKind Kind of current directive.
   /// \param CKind Kind of current clause.
@@ -6349,7 +6314,7 @@ class Parser : public CodeCompletionHandler {
   ///
   OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                OpenMPClauseKind CKind, bool FirstClause);
-  
+
   /// Parses clause with a single expression of a kind \a Kind.
   ///
   /// Parsing of OpenMP clauses with single expressions like 'final',
@@ -6401,8 +6366,7 @@ class Parser : public CodeCompletionHandler {
   /// \param ParseOnly true to skip the clause's semantic actions and return
   /// nullptr.
   ///
-  OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
-                                         bool ParseOnly);
+  OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, bool ParseOnly);
   /// Parses simple clause like 'default' or 'proc_bind' of a kind \a Kind.
   ///
   ///    default-clause:
@@ -6423,7 +6387,7 @@ class Parser : public CodeCompletionHandler {
   /// nullptr.
   ///
   OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind, bool ParseOnly);
-  
+
   /// Parse indirect clause for '#pragma omp declare target' directive.
   ///  'indirect' '[' '(' invoked-by-fptr ')' ']'
   /// where invoked-by-fptr is a constant boolean expression that evaluates to
@@ -6494,7 +6458,7 @@ class Parser : public CodeCompletionHandler {
   /// nullptr.
   ///
   OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly = false);
-  
+
   /// Parses clause with the list of variables of a kind \a Kind:
   /// 'private', 'firstprivate', 'lastprivate',
   /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
@@ -6649,7 +6613,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses the mapper modifier in map, to, and from clauses.
   bool parseMapperModifier(SemaOpenMP::OpenMPVarListDataTy &Data);
-  
+
   /// Parse map-type-modifiers in map clause.
   /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] [map-type] : ] list)
   /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
@@ -6669,8 +6633,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParsePragma.cpp
   ///@{
 
-  private:
-
+private:
   std::unique_ptr<PragmaHandler> AlignHandler;
   std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
   std::unique_ptr<PragmaHandler> OptionsHandler;
@@ -6751,24 +6714,24 @@ class Parser : public CodeCompletionHandler {
 
   void HandlePragmaMSPragma();
   bool HandlePragmaMSSection(StringRef PragmaName,
-                              SourceLocation PragmaLocation);
+                             SourceLocation PragmaLocation);
   bool HandlePragmaMSSegment(StringRef PragmaName,
-                              SourceLocation PragmaLocation);
+                             SourceLocation PragmaLocation);
 
   // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
   bool HandlePragmaMSInitSeg(StringRef PragmaName,
-                              SourceLocation PragmaLocation);
+                             SourceLocation PragmaLocation);
 
   // #pragma strict_gs_check(pop)
   // #pragma strict_gs_check(push, "on" | "off")
   // #pragma strict_gs_check("on" | "off")
   bool HandlePragmaMSStrictGuardStackCheck(StringRef PragmaName,
-                                            SourceLocation PragmaLocation);
+                                           SourceLocation PragmaLocation);
   bool HandlePragmaMSFunction(StringRef PragmaName,
                               SourceLocation PragmaLocation);
   bool HandlePragmaMSAllocText(StringRef PragmaName,
-                                SourceLocation PragmaLocation);
-  
+                               SourceLocation PragmaLocation);
+
   // #pragma optimize("gsty", on|off)
   bool HandlePragmaMSOptimize(StringRef PragmaName,
                               SourceLocation PragmaLocation);
@@ -6847,8 +6810,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseStmt.cpp
   ///@{
 
-  public:
-
+public:
   /// A SmallVector of statements.
   typedef SmallVector<Stmt *, 24> StmtVector;
 
@@ -6940,15 +6902,15 @@ class Parser : public CodeCompletionHandler {
   /// [OBC]   '@' 'throw' expression ';'
   /// [OBC]   '@' 'throw' ';'
   ///
-  StmtResult ParseStatementOrDeclaration(
-      StmtVector &Stmts, ParsedStmtContext StmtCtx,
-      SourceLocation *TrailingElseLoc = nullptr);
+  StmtResult
+  ParseStatementOrDeclaration(StmtVector &Stmts, ParsedStmtContext StmtCtx,
+                              SourceLocation *TrailingElseLoc = nullptr);
 
   StmtResult ParseStatementOrDeclarationAfterAttributes(
       StmtVector &Stmts, ParsedStmtContext StmtCtx,
       SourceLocation *TrailingElseLoc, ParsedAttributes &DeclAttrs,
       ParsedAttributes &DeclSpecAttrs);
-  
+
   /// Parse an expression statement.
   StmtResult ParseExprStatement(ParsedStmtContext StmtCtx);
 
@@ -6972,7 +6934,7 @@ class Parser : public CodeCompletionHandler {
   StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx,
                                 bool MissingCase = false,
                                 ExprResult Expr = ExprResult());
-  
+
   /// ParseDefaultStatement
   ///       labeled-statement:
   ///         'default' ':' statement
@@ -7004,16 +6966,15 @@ class Parser : public CodeCompletionHandler {
   /// [GNU] label-declaration:
   /// [GNU]   '__label__' identifier-list ';'
   ///
-  StmtResult ParseCompoundStatement(bool isStmtExpr,
-                                    unsigned ScopeFlags);
-  
+  StmtResult ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags);
+
   /// Parse any pragmas at the start of the compound expression. We handle these
   /// separately since some pragmas (FP_CONTRACT) must appear before any C
   /// statement in the compound, but may be intermingled with other pragmas.
   void ParseCompoundStatementLeadingPragmas();
 
   void DiagnoseLabelAtEndOfCompoundStatement();
-  
+
   /// Consume any extra semi-colons resulting in null statements,
   /// returning true if any tok::semi were consumed.
   bool ConsumeNullStmt(StmtVector &Stmts);
@@ -7029,15 +6990,15 @@ class Parser : public CodeCompletionHandler {
   /// [C++]     '(' condition ')'
   /// [C++1z]   '(' init-statement[opt] condition ')'
   ///
-  /// This function parses and performs error recovery on the specified condition
-  /// or expression (depending on whether we're in C++ or C mode).  This function
-  /// goes out of its way to recover well.  It returns true if there was a parser
-  /// error (the right paren couldn't be found), which indicates that the caller
-  /// should try to recover harder.  It returns false if the condition is
-  /// successfully parsed.  Note that a successful parse can still have semantic
-  /// errors in the condition.
-  /// Additionally, it will assign the location of the outer-most '(' and ')',
-  /// to LParenLoc and RParenLoc, respectively.
+  /// This function parses and performs error recovery on the specified
+  /// condition or expression (depending on whether we're in C++ or C mode).
+  /// This function goes out of its way to recover well.  It returns true if
+  /// there was a parser error (the right paren couldn't be found), which
+  /// indicates that the caller should try to recover harder.  It returns false
+  /// if the condition is successfully parsed.  Note that a successful parse can
+  /// still have semantic errors in the condition. Additionally, it will assign
+  /// the location of the outer-most '(' and ')', to LParenLoc and RParenLoc,
+  /// respectively.
   bool ParseParenExprOrCondition(StmtResult *InitStmt,
                                  Sema::ConditionResult &CondResult,
                                  SourceLocation Loc, Sema::ConditionKind CK,
@@ -7165,7 +7126,8 @@ class Parser : public CodeCompletionHandler {
   ///
   StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
 
-  /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
+  /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the
+  /// standard
   ///
   ///   handler:
   ///     'catch' '(' exception-declaration ')' compound-statement
@@ -7262,15 +7224,13 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseStmtAsm.cpp
   ///@{
 
-  public:
-
+public:
   /// Parse an identifier in an MS-style inline assembly block.
   ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
                                   unsigned &NumLineToksConsumed,
                                   bool IsUnevaluated);
 
-  private:
-
+private:
   /// ParseAsmStatement - Parse a GNU extended asm statement.
   ///       asm-statement:
   ///         gnu-asm-statement
@@ -7332,9 +7292,9 @@ class Parser : public CodeCompletionHandler {
   public:
     enum AQ {
       AQ_unspecified = 0,
-      AQ_volatile    = 1,
-      AQ_inline      = 2,
-      AQ_goto        = 4,
+      AQ_volatile = 1,
+      AQ_inline = 2,
+      AQ_goto = 4,
     };
     static const char *getQualifierName(AQ Qualifier);
     bool setAsmQualifier(AQ Qualifier);
@@ -7342,7 +7302,7 @@ class Parser : public CodeCompletionHandler {
     inline bool isInline() const { return Qualifiers & AQ_inline; };
     inline bool isGoto() const { return Qualifiers & AQ_goto; }
   };
-  
+
   // Determine if this is a GCC-style asm statement.
   bool isGCCAsmStatement(const Token &TokAfterAsm) const;
 
@@ -7372,8 +7332,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseTemplate.cpp
   ///@{
 
-  public:
-
+public:
   typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
 
   /// Re-enter a possible template scope, creating as many template parameter
@@ -7381,8 +7340,7 @@ class Parser : public CodeCompletionHandler {
   /// \return The number of template parameter scopes entered.
   unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D);
 
-  private:
-
+private:
   /// The "depth" of the template parameters currently being parsed.
   unsigned TemplateParameterDepth;
 
@@ -7390,13 +7348,12 @@ class Parser : public CodeCompletionHandler {
   class TemplateParameterDepthRAII {
     unsigned &Depth;
     unsigned AddedLevels;
+
   public:
     explicit TemplateParameterDepthRAII(unsigned &Depth)
-      : Depth(Depth), AddedLevels(0) {}
+        : Depth(Depth), AddedLevels(0) {}
 
-    ~TemplateParameterDepthRAII() {
-      Depth -= AddedLevels;
-    }
+    ~TemplateParameterDepthRAII() { Depth -= AddedLevels; }
 
     void operator++() {
       ++Depth;
@@ -7522,8 +7479,8 @@ class Parser : public CodeCompletionHandler {
           Locs.back().Priority = Prio;
         }
       } else {
-        Locs.push_back({TemplateName, LessLoc, Prio,
-                        P.ParenCount, P.BracketCount, P.BraceCount});
+        Locs.push_back({TemplateName, LessLoc, Prio, P.ParenCount,
+                        P.BracketCount, P.BraceCount});
       }
     }
 
@@ -7550,20 +7507,22 @@ class Parser : public CodeCompletionHandler {
   /// information that has been parsed prior to parsing declaration
   /// specifiers.
   struct ParsedTemplateInfo {
-    ParsedTemplateInfo() : Kind(ParsedTemplateKind::NonTemplate), TemplateParams(nullptr) {}
+    ParsedTemplateInfo()
+        : Kind(ParsedTemplateKind::NonTemplate), TemplateParams(nullptr) {}
 
     ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
                        bool isSpecialization,
                        bool lastParameterListWasEmpty = false)
-      : Kind(isSpecialization? ParsedTemplateKind::ExplicitSpecialization : ParsedTemplateKind::Template),
-        TemplateParams(TemplateParams),
-        LastParameterListWasEmpty(lastParameterListWasEmpty) { }
+        : Kind(isSpecialization ? ParsedTemplateKind::ExplicitSpecialization
+                                : ParsedTemplateKind::Template),
+          TemplateParams(TemplateParams),
+          LastParameterListWasEmpty(lastParameterListWasEmpty) {}
 
     explicit ParsedTemplateInfo(SourceLocation ExternLoc,
                                 SourceLocation TemplateLoc)
-      : Kind(ParsedTemplateKind::ExplicitInstantiation), TemplateParams(nullptr),
-        ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
-        LastParameterListWasEmpty(false){ }
+        : Kind(ParsedTemplateKind::ExplicitInstantiation),
+          TemplateParams(nullptr), ExternLoc(ExternLoc),
+          TemplateLoc(TemplateLoc), LastParameterListWasEmpty(false) {}
 
     ParsedTemplateKind Kind;
 
@@ -7594,9 +7553,9 @@ class Parser : public CodeCompletionHandler {
   static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
 
   /// We've parsed something that could plausibly be intended to be a template
-  /// name (\p LHS) followed by a '<' token, and the following code can't possibly
-  /// be an expression. Determine if this is likely to be a template-id and if so,
-  /// diagnose it.
+  /// name (\p LHS) followed by a '<' token, and the following code can't
+  /// possibly be an expression. Determine if this is likely to be a template-id
+  /// and if so, diagnose it.
   bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
 
   void checkPotentialAngleBracket(ExprResult &PotentialTemplateName);
@@ -7687,7 +7646,7 @@ class Parser : public CodeCompletionHandler {
   ///         template-parameter
   ///         template-parameter-list ',' template-parameter
   bool ParseTemplateParameterList(unsigned Depth,
-                                  SmallVectorImpl<NamedDecl*> &TemplateParams);
+                                  SmallVectorImpl<NamedDecl *> &TemplateParams);
 
   enum class TPResult;
 
@@ -7792,7 +7751,7 @@ class Parser : public CodeCompletionHandler {
                                       SourceLocation &RAngleLoc,
                                       bool ConsumeLastToken,
                                       bool ObjCGenericList);
-  
+
   /// Parses a template-id that after the template name has
   /// already been parsed.
   ///
@@ -7845,15 +7804,14 @@ class Parser : public CodeCompletionHandler {
   /// annotation token.
   ///
   /// \param TypeConstraint if true, then this is actually a type-constraint,
-  /// meaning that the template argument list can be omitted (and the template in
-  /// question must be a concept).
+  /// meaning that the template argument list can be omitted (and the template
+  /// in question must be a concept).
   ///
   /// If an unrecoverable parse error occurs and no annotation token can be
   /// formed, this function returns true.
   ///
   bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
-                               CXXScopeSpec &SS,
-                               SourceLocation TemplateKWLoc,
+                               CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
                                UnqualifiedId &TemplateName,
                                bool AllowTypeAnnotation = true,
                                bool TypeConstraint = false);
@@ -7915,16 +7873,15 @@ class Parser : public CodeCompletionHandler {
                                             SourceLocation &DeclEnd,
                                             ParsedAttributes &AccessAttrs,
                                             AccessSpecifier AS = AS_none);
-  
+
   /// \brief Parse a single declaration that declares a concept.
   ///
   /// \param DeclEnd will receive the source location of the last token
   /// within this declaration.
   ///
   /// \returns the new declaration.
-  Decl *
-  ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
-                         SourceLocation &DeclEnd);
+  Decl *ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
+                               SourceLocation &DeclEnd);
 
   ///@}
 
@@ -7938,8 +7895,7 @@ class Parser : public CodeCompletionHandler {
   /// Implementations are in ParseTentative.cpp
   ///@{
 
-  private:
-
+private:
   /// TentativeParsingAction - An object that is used as a kind of "tentative
   /// parsing transaction". It gets instantiated to mark the token position and
   /// after the token consumption is done, Commit() or Revert() is called to
@@ -8057,8 +8013,8 @@ class Parser : public CodeCompletionHandler {
   ///    decl-specifier-seq declarator
   ///    decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
   ///
-  /// In any of the above cases there can be a preceding attribute-specifier-seq,
-  /// but the caller is expected to handle that.
+  /// In any of the above cases there can be a preceding
+  /// attribute-specifier-seq, but the caller is expected to handle that.
   bool isCXXSimpleDeclaration(bool AllowForRangeDecl);
 
   /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
@@ -8113,8 +8069,9 @@ class Parser : public CodeCompletionHandler {
   /// following the type-id. If the context is
   /// TentativeCXXTypeIdContext::InParens, we have already parsed the '(' and we
   /// will cease lookahead when we hit the corresponding ')'. If the context is
-  /// TentativeCXXTypeIdContext::AsTemplateArgument, we've already parsed the '<'
-  /// or ',' before this template argument, and will cease lookahead when we hit a
+  /// TentativeCXXTypeIdContext::AsTemplateArgument, we've already parsed the
+  /// '<' or ',' before this template argument, and will cease lookahead when we
+  /// hit a
   /// '>', '>>' (in C++0x), or ','; or, in C++0x, an ellipsis immediately
   /// preceding such. Returns true for a type-id and false for an expression.
   /// If during the disambiguation process a parsing error is encountered,
@@ -8132,9 +8089,7 @@ class Parser : public CodeCompletionHandler {
 
   /// TPResult - Used as the result value for functions whose purpose is to
   /// disambiguate C++ constructs by "tentatively parsing" them.
-  enum class TPResult {
-    True, False, Ambiguous, Error
-  };
+  enum class TPResult { True, False, Ambiguous, Error };
 
   /// Determine whether we could have an enum-base.
   ///
@@ -8269,10 +8224,10 @@ class Parser : public CodeCompletionHandler {
   /// a type-specifier other than a cv-qualifier.
   bool isCXXDeclarationSpecifierAType();
 
-  /// Determine whether we might be looking at the '<' template-argument-list '>'
-  /// of a template-id or simple-template-id, rather than a less-than comparison.
-  /// This will often fail and produce an ambiguity, but should never be wrong
-  /// if it returns True or False.
+  /// Determine whether we might be looking at the '<' template-argument-list
+  /// '>' of a template-id or simple-template-id, rather than a less-than
+  /// comparison. This will often fail and produce an ambiguity, but should
+  /// never be wrong if it returns True or False.
   TPResult isTemplateArgumentList(unsigned TokensToSkip);
 
   /// Determine whether an '(' after an 'explicit' keyword is part of a C++20
@@ -8442,11 +8397,10 @@ class Parser : public CodeCompletionHandler {
       ImplicitTypenameContext AllowImplicitTypename =
           ImplicitTypenameContext::No);
 
-  /// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
-  /// parsing as a function declarator.
-  /// If TryParseFunctionDeclarator fully parsed the function declarator, it will
-  /// return TPResult::Ambiguous, otherwise it will return either False() or
-  /// Error().
+  /// TryParseFunctionDeclarator - We parsed a '(' and we want to try to
+  /// continue parsing as a function declarator. If TryParseFunctionDeclarator
+  /// fully parsed the function declarator, it will return TPResult::Ambiguous,
+  /// otherwise it will return either False() or Error().
   ///
   /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
   ///         exception-specification[opt]
@@ -8518,6 +8472,6 @@ class Parser : public CodeCompletionHandler {
   ///@}
 };
 
-}  // end namespace clang
+} // end namespace clang
 
 #endif

>From 75461ad7a617c65b80a30cb43fe56c871d2ddba7 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 3 May 2025 12:16:21 +0300
Subject: [PATCH 4/5] Put grammar in \verbatim blocks

---
 clang/include/clang/Parse/Parser.h | 427 ++++++++++++++++++++++++++++-
 1 file changed, 418 insertions(+), 9 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 49227fd173052..582dd77944512 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -211,12 +211,14 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse the first top-level declaration in a translation unit.
   ///
+  /// \verbatim
   ///   translation-unit:
   /// [C]     external-declaration
   /// [C]     translation-unit external-declaration
   /// [C++]   top-level-declaration-seq[opt]
   /// [C++20] global-module-fragment[opt] module-declaration
   ///                 top-level-declaration-seq[opt] private-module-fragment[opt]
+  /// \endverbatim
   ///
   /// Note that in C, it is an error if there is no first declaration.
   bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
@@ -225,9 +227,11 @@ class Parser : public CodeCompletionHandler {
   /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
   /// action tells us to.  This returns true if the EOF was encountered.
   ///
+  /// \verbatim
   ///   top-level-declaration:
   ///           declaration
   /// [C++20]   module-import-declaration
+  /// \endverbatim
   bool ParseTopLevelDecl(DeclGroupPtrTy &Result,
                          Sema::ModuleImportState &ImportState);
   bool ParseTopLevelDecl() {
@@ -859,6 +863,7 @@ class Parser : public CodeCompletionHandler {
   /// The `Attrs` that are passed in are C++11 attributes and appertain to the
   /// declaration.
   ///
+  /// \verbatim
   ///       external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
   ///         function-definition
   ///         declaration
@@ -882,6 +887,7 @@ class Parser : public CodeCompletionHandler {
   /// [C++0x/GNU] 'extern' 'template' declaration
   ///
   /// [C++20] module-import-declaration
+  /// \endverbatim
   ///
   DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &DeclAttrs,
                                           ParsedAttributes &DeclSpecAttrs,
@@ -904,6 +910,7 @@ class Parser : public CodeCompletionHandler {
   /// TemplateParams, if non-NULL, provides the template parameters when we're
   /// parsing a C++ template-declaration.
   ///
+  /// \verbatim
   ///       function-definition: [C99 6.9.1]
   ///         decl-specs      declarator declaration-list[opt] compound-statement
   /// [C90] function-definition: [C99 6.7.1] - implicit int result
@@ -914,6 +921,7 @@ class Parser : public CodeCompletionHandler {
   /// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode]
   /// [OMP]   threadprivate-directive
   /// [OMP]   allocate-directive                         [TODO]
+  /// \endverbatim
   ///
   DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributes &Attrs,
                                                 ParsedAttributes &DeclSpecAttrs,
@@ -929,6 +937,7 @@ class Parser : public CodeCompletionHandler {
   /// Declarator is well formed.  If this is a K&R-style function, read the
   /// parameters declaration-list, then start the compound-statement.
   ///
+  /// \verbatim
   ///       function-definition: [C99 6.9.1]
   ///         decl-specs      declarator declaration-list[opt] compound-statement
   /// [C90] function-definition: [C99 6.7.1] - implicit int result
@@ -938,6 +947,7 @@ class Parser : public CodeCompletionHandler {
   ///         function-body
   /// [C++] function-definition: [C++ 8.4]
   ///         decl-specifier-seq[opt] declarator function-try-block
+  /// \endverbatim
   ///
   Decl *ParseFunctionDefinition(
       ParsingDeclarator &D,
@@ -950,8 +960,10 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseSimpleAsm
   ///
+  /// \verbatim
   /// [GNU] simple-asm-expr:
   ///         'asm' '(' asm-string-literal ')'
+  /// \endverbatim
   ///
   /// EndLoc is filled with the location of the last token of the simple-asm.
   ExprResult ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc);
@@ -962,8 +974,10 @@ class Parser : public CodeCompletionHandler {
   /// asm label as opposed to an asm statement, because such a construct does
   /// not behave well.
   ///
+  /// \verbatim
   /// [GNU] asm-string-literal:
   ///         string-literal
+  /// \endverbatim
   ///
   ExprResult ParseAsmStringLiteral(bool ForAsmLabel);
 
@@ -996,6 +1010,7 @@ class Parser : public CodeCompletionHandler {
   /// Parse a declaration beginning with the 'module' keyword or C++20
   /// context-sensitive keyword (optionally preceded by 'export').
   ///
+  /// \verbatim
   ///   module-declaration:   [C++20]
   ///     'export'[opt] 'module' module-name attribute-specifier-seq[opt] ';'
   ///
@@ -1006,12 +1021,14 @@ class Parser : public CodeCompletionHandler {
   ///            attribute-specifier-seq[opt] ';'
   ///   private-module-fragment: [C++2a]
   ///     'module' ':' 'private' ';' top-level-declaration-seq[opt]
+  /// \endverbatim
   DeclGroupPtrTy ParseModuleDecl(Sema::ModuleImportState &ImportState);
 
   /// Parse a module import declaration. This is essentially the same for
   /// Objective-C and C++20 except for the leading '@' (in ObjC) and the
   /// trailing optional attributes (in C++).
   ///
+  /// \verbatim
   /// [ObjC]  @import declaration:
   ///           '@' 'import' module-name ';'
   /// [ModTS] module-import-declaration:
@@ -1023,6 +1040,7 @@ class Parser : public CodeCompletionHandler {
   ///                   attribute-specifier-seq[opt] ';'
   ///           'export'[opt] 'import' header-name
   ///                   attribute-specifier-seq[opt] ';'
+  /// \endverbatim
   Decl *ParseModuleImport(SourceLocation AtLoc,
                           Sema::ModuleImportState &ImportState);
 
@@ -1043,10 +1061,12 @@ class Parser : public CodeCompletionHandler {
   /// Parse a C++ / Objective-C module name (both forms use the same
   /// grammar).
   ///
+  /// \verbatim
   ///         module-name:
   ///           module-name-qualifier[opt] identifier
   ///         module-name-qualifier:
   ///           module-name-qualifier[opt] identifier '.'
+  /// \endverbatim
   bool ParseModuleName(SourceLocation UseLoc,
                        SmallVectorImpl<IdentifierLoc> &Path, bool IsImport);
 
@@ -1356,8 +1376,10 @@ class Parser : public CodeCompletionHandler {
   void SkipMalformedDecl();
 
   /// ParseTypeName
+  /// \verbatim
   ///       type-name: [C99 6.7.6]
   ///         specifier-qualifier-list abstract-declarator[opt]
+  /// \endverbatim
   ///
   /// Called type-id in C++.
   TypeResult
@@ -1683,6 +1705,7 @@ class Parser : public CodeCompletionHandler {
   /// 'Context' should be a DeclaratorContext value.  This returns the
   /// location of the semicolon in DeclEnd.
   ///
+  /// \verbatim
   ///       declaration: [C99 6.7]
   ///         block-declaration ->
   ///           simple-declaration
@@ -1693,6 +1716,7 @@ class Parser : public CodeCompletionHandler {
   /// [C++]   using-declaration
   /// [C++11/C11] static_assert-declaration
   ///         others... [FIXME]
+  /// \endverbatim
   ///
   DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
                                   SourceLocation &DeclEnd,
@@ -1700,6 +1724,7 @@ class Parser : public CodeCompletionHandler {
                                   ParsedAttributes &DeclSpecAttrs,
                                   SourceLocation *DeclSpecStart = nullptr);
 
+  /// \verbatim
   ///       simple-declaration: [C99 6.7: declaration] [C++ 7p1: dcl.dcl]
   ///         declaration-specifiers init-declarator-list[opt] ';'
   /// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
@@ -1710,6 +1735,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///       for-range-declaration: [C++11 6.5p1: stmt.ranged]
   ///         attribute-specifier-seq[opt] type-specifier-seq declarator
+  /// \endverbatim
   ///
   /// If RequireSemi is false, this does not check for a ';' at the end of the
   /// declaration.  If it is true, it checks for and eats it.
@@ -1746,6 +1772,7 @@ class Parser : public CodeCompletionHandler {
   /// (including any attributes or initializer, among other things) and
   /// finalizes the declaration.
   ///
+  /// \verbatim
   ///       init-declarator: [C99 6.7]
   ///         declarator
   ///         declarator '=' initializer
@@ -1759,6 +1786,7 @@ class Parser : public CodeCompletionHandler {
   /// [C++0x] '=' 'default'                                                [TODO]
   /// [C++0x] '=' 'delete'
   /// [C++0x] braced-init-list
+  /// \endverbatim
   ///
   /// According to the standard grammar, =default and =delete are function
   /// definitions, but that definitely doesn't fit with the parser here.
@@ -1805,6 +1833,7 @@ class Parser : public CodeCompletionHandler {
   }
 
   /// ParseDeclarationSpecifiers
+  /// \verbatim
   ///       declaration-specifiers: [C99 6.7]
   ///         storage-class-specifier declaration-specifiers[opt]
   ///         type-specifier declaration-specifiers[opt]
@@ -1831,6 +1860,7 @@ class Parser : public CodeCompletionHandler {
   /// [OpenCL] '__kernel'
   ///       'friend': [C++ dcl.friend]
   ///       'constexpr': [C++0x dcl.constexpr]
+  /// \endverbatim
   void
   ParseDeclarationSpecifiers(DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
                              AccessSpecifier AS, DeclSpecContext DSC,
@@ -1855,10 +1885,12 @@ class Parser : public CodeCompletionHandler {
   }
 
   /// ParseSpecifierQualifierList
+  /// \verbatim
   ///        specifier-qualifier-list:
   ///          type-specifier specifier-qualifier-list[opt]
   ///          type-qualifier specifier-qualifier-list[opt]
   /// [GNU]    attributes     specifier-qualifier-list[opt]
+  /// \endverbatim
   ///
   void ParseSpecifierQualifierList(
       DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,
@@ -1866,6 +1898,7 @@ class Parser : public CodeCompletionHandler {
       DeclSpecContext DSC = DeclSpecContext::DSC_normal);
 
   /// ParseEnumSpecifier
+  /// \verbatim
   ///       enum-specifier: [C99 6.7.2.2]
   ///         'enum' identifier[opt] '{' enumerator-list '}'
   ///[C99/C++]'enum' identifier[opt] '{' enumerator-list ',' '}'
@@ -1894,12 +1927,14 @@ class Parser : public CodeCompletionHandler {
   ///
   /// [C++] elaborated-type-specifier:
   /// [C++]   'enum' nested-name-specifier[opt] identifier
+  /// \endverbatim
   ///
   void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
                           const ParsedTemplateInfo &TemplateInfo,
                           AccessSpecifier AS, DeclSpecContext DSC);
 
   /// ParseEnumBody - Parse a {} enclosed enumerator-list.
+  /// \verbatim
   ///       enumerator-list:
   ///         enumerator
   ///         enumerator-list ',' enumerator
@@ -1908,11 +1943,13 @@ class Parser : public CodeCompletionHandler {
   ///         enumeration-constant attributes[opt] '=' constant-expression
   ///       enumeration-constant:
   ///         identifier
+  /// \endverbatim
   ///
   void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl,
                      SkipBodyInfo *SkipBody = nullptr);
 
   /// ParseStructUnionBody
+  /// \verbatim
   ///       struct-contents:
   ///         struct-declaration-list
   /// [EXT]   empty
@@ -1921,6 +1958,7 @@ class Parser : public CodeCompletionHandler {
   ///         struct-declaration
   ///         struct-declaration-list struct-declaration
   /// [OBC]   '@' 'defs' '(' class-name ')'
+  /// \endverbatim
   ///
   void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
                             RecordDecl *TagDecl);
@@ -1931,6 +1969,7 @@ class Parser : public CodeCompletionHandler {
   /// Note that a struct declaration refers to a declaration in a struct,
   /// not to the declaration of a struct.
   ///
+  /// \verbatim
   ///       struct-declaration:
   /// [C23]   attributes-specifier-seq[opt]
   ///           specifier-qualifier-list struct-declarator-list
@@ -1945,6 +1984,7 @@ class Parser : public CodeCompletionHandler {
   /// [GNU]   declarator attributes[opt]
   ///         declarator[opt] ':' constant-expression
   /// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
+  /// \endverbatim
   ///
   void ParseStructDeclaration(
       ParsingDeclSpec &DS,
@@ -2097,8 +2137,10 @@ class Parser : public CodeCompletionHandler {
   /// There are some attribute parse orderings that should not be allowed in
   /// arbitrary order. e.g.,
   ///
+  /// \verbatim
   ///   [[]] __attribute__(()) int i; // OK
   ///   __attribute__(()) [[]] int i; // Not OK
+  /// \endverbatim
   ///
   /// Such situations should use the specific attribute parsing functionality.
   void ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
@@ -2135,6 +2177,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseSingleGNUAttribute - Parse a single GNU attribute.
   ///
+  /// \verbatim
   /// [GNU]  attrib:
   ///          empty
   ///          attrib-name
@@ -2147,12 +2190,14 @@ class Parser : public CodeCompletionHandler {
   ///          typespec
   ///          typequal
   ///          storageclass
+  /// \endverbatim
   bool ParseSingleGNUAttribute(ParsedAttributes &Attrs, SourceLocation &EndLoc,
                                LateParsedAttrList *LateAttrs = nullptr,
                                Declarator *D = nullptr);
 
   /// ParseGNUAttributes - Parse a non-empty attributes list.
   ///
+  /// \verbatim
   /// [GNU] attributes:
   ///         attribute
   ///         attributes attribute
@@ -2176,6 +2221,7 @@ class Parser : public CodeCompletionHandler {
   ///          typespec
   ///          typequal
   ///          storageclass
+  /// \endverbatim
   ///
   /// Whether an attribute takes an 'identifier' is determined by the
   /// attrib-name. GCC's behavior here is not worth imitating:
@@ -2245,12 +2291,14 @@ class Parser : public CodeCompletionHandler {
     return false;
   }
 
+  /// \verbatim
   /// [MS] decl-specifier:
   ///             __declspec ( extended-decl-modifier-seq )
   ///
   /// [MS] extended-decl-modifier-seq:
   ///             extended-decl-modifier[opt]
   ///             extended-decl-modifier extended-decl-modifier-seq
+  /// \endverbatim
   void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs);
   bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
                                   SourceLocation AttrNameLoc,
@@ -2270,16 +2318,19 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse a version number.
   ///
+  /// \verbatim
   /// version:
   ///   simple-integer
   ///   simple-integer '.' simple-integer
   ///   simple-integer '_' simple-integer
   ///   simple-integer '.' simple-integer '.' simple-integer
   ///   simple-integer '_' simple-integer '_' simple-integer
+  /// \endverbatim
   VersionTuple ParseVersionTuple(SourceRange &Range);
 
   /// Parse the contents of the "availability" attribute.
   ///
+  /// \verbatim
   /// availability-attribute:
   ///   'availability' '(' platform ',' opt-strict version-arg-list,
   ///                      opt-replacement, opt-message')'
@@ -2303,6 +2354,7 @@ class Parser : public CodeCompletionHandler {
   ///   'replacement' '=' <string>
   /// opt-message:
   ///   'message' '=' <string>
+  /// \endverbatim
   void ParseAvailabilityAttribute(IdentifierInfo &Availability,
                                   SourceLocation AvailabilityLoc,
                                   ParsedAttributes &attrs,
@@ -2313,6 +2365,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse the contents of the "external_source_symbol" attribute.
   ///
+  /// \verbatim
   /// external-source-symbol-attribute:
   ///   'external_source_symbol' '(' keyword-arg-list ')'
   ///
@@ -2325,6 +2378,7 @@ class Parser : public CodeCompletionHandler {
   ///   'defined_in' '=' <string>
   ///   'USR' '=' <string>
   ///   'generated_declaration'
+  /// \endverbatim
   void ParseExternalSourceSymbolAttribute(IdentifierInfo &ExternalSourceSymbol,
                                           SourceLocation Loc,
                                           ParsedAttributes &Attrs,
@@ -2334,6 +2388,7 @@ class Parser : public CodeCompletionHandler {
                                           ParsedAttr::Form Form);
 
   /// Parse the contents of the "objc_bridge_related" attribute.
+  /// \verbatim
   /// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
   /// related_class:
   ///     Identifier
@@ -2343,6 +2398,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// opt-instance_method:
   ///     Identifier | <empty>
+  /// \endverbatim
   ///
   void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
                                        SourceLocation ObjCBridgeRelatedLoc,
@@ -2378,12 +2434,15 @@ class Parser : public CodeCompletionHandler {
   void DistributeCLateParsedAttrs(Decl *Dcl, LateParsedAttrList *LateAttrs);
 
   /// Bounds attributes (e.g., counted_by):
+  /// \verbatim
   ///   AttrName '(' expression ')'
+  /// \endverbatim
   void ParseBoundsAttribute(IdentifierInfo &AttrName,
                             SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
                             IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
                             ParsedAttr::Form Form);
 
+  /// \verbatim
   /// [GNU]   typeof-specifier:
   ///           typeof ( expressions )
   ///           typeof ( type-name )
@@ -2395,20 +2454,25 @@ class Parser : public CodeCompletionHandler {
   ///         typeof-specifier-argument:
   ///           expression
   ///           type-name
+  /// \endverbatim
   ///
   void ParseTypeofSpecifier(DeclSpec &DS);
 
+  /// \verbatim
   /// [C11]   atomic-specifier:
   ///           _Atomic ( type-name )
+  /// \endverbatim
   ///
   void ParseAtomicSpecifier(DeclSpec &DS);
 
   /// ParseAlignArgument - Parse the argument to an alignment-specifier.
   ///
+  /// \verbatim
   /// [C11]   type-id
   /// [C11]   constant-expression
   /// [C++0x] type-id ...[opt]
   /// [C++0x] assignment-expression ...[opt]
+  /// \endverbatim
   ExprResult ParseAlignArgument(StringRef KWName, SourceLocation Start,
                                 SourceLocation &EllipsisLoc, bool &IsType,
                                 ParsedType &Ty);
@@ -2416,19 +2480,23 @@ class Parser : public CodeCompletionHandler {
   /// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
   /// attribute to Attrs.
   ///
+  /// \verbatim
   /// alignment-specifier:
   /// [C11]   '_Alignas' '(' type-id ')'
   /// [C11]   '_Alignas' '(' constant-expression ')'
   /// [C++11] 'alignas' '(' type-id ...[opt] ')'
   /// [C++11] 'alignas' '(' assignment-expression ...[opt] ')'
+  /// \endverbatim
   void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
                                SourceLocation *endLoc = nullptr);
   ExprResult ParseExtIntegerArgument();
 
+  /// \verbatim
   /// type-qualifier:
   ///    ('__ptrauth') '(' constant-expression
   ///                   (',' constant-expression)[opt]
   ///                   (',' constant-expression)[opt] ')'
+  /// \endverbatim
   void ParsePtrauthQualifier(ParsedAttributes &Attrs);
 
   /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
@@ -2479,6 +2547,7 @@ class Parser : public CodeCompletionHandler {
   /// be made to TryParseDeclarator and MightBeDeclarator, and possibly to
   /// isConstructorDeclarator.
   ///
+  /// \verbatim
   ///       declarator: [C99 6.7.5] [C++ 8p4, dcl.decl]
   /// [C]     pointer[opt] direct-declarator
   /// [C++]   direct-declarator
@@ -2495,6 +2564,7 @@ class Parser : public CodeCompletionHandler {
   /// [GNU]   '&' restrict[opt] attributes[opt]
   /// [GNU?]  '&&' restrict[opt] attributes[opt]
   ///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
+  /// \endverbatim
   void ParseDeclaratorInternal(Declarator &D,
                                DirectDeclParseFunction DirectDeclParser);
 
@@ -2511,6 +2581,7 @@ class Parser : public CodeCompletionHandler {
   };
 
   /// ParseTypeQualifierListOpt
+  /// \verbatim
   ///          type-qualifier-list: [C99 6.7.5]
   ///            type-qualifier
   /// [vendor]   attributes
@@ -2520,6 +2591,7 @@ class Parser : public CodeCompletionHandler {
   ///              [ only if AttrReqs & AR_VendorAttributesParsed ]
   /// [C++0x]    attribute-specifier[opt] is allowed before cv-qualifier-seq
   ///              [ only if AttReqs & AR_CXX11AttributesParsed ]
+  /// \endverbatim
   /// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
   /// AttrRequirements bitmask values.
   void ParseTypeQualifierListOpt(
@@ -2529,6 +2601,7 @@ class Parser : public CodeCompletionHandler {
           std::nullopt);
 
   /// ParseDirectDeclarator
+  /// \verbatim
   ///       direct-declarator: [C99 6.7.5]
   /// [C99]   identifier
   ///         '(' declarator ')'
@@ -2571,6 +2644,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///       simple-declaration:
   ///         <decl-spec> '[' identifier-list ']' brace-or-equal-initializer ';'
+  /// \endverbatim
   ///
   /// Note, any additional constructs added here may need corresponding changes
   /// in isConstructorDeclarator.
@@ -2583,6 +2657,7 @@ class Parser : public CodeCompletionHandler {
   /// parameter parens in an abstract-declarator, we call
   /// ParseFunctionDeclarator.
   ///
+  /// \verbatim
   ///       direct-declarator:
   ///         '(' declarator ')'
   /// [GNU]   '(' attributes declarator ')'
@@ -2590,6 +2665,7 @@ class Parser : public CodeCompletionHandler {
   ///         direct-declarator '(' identifier-list[opt] ')'
   /// [GNU]   direct-declarator '(' parameter-forward-declarations
   ///                    parameter-type-list[opt] ')'
+  /// \endverbatim
   ///
   void ParseParenDeclarator(Declarator &D);
 
@@ -2610,9 +2686,11 @@ class Parser : public CodeCompletionHandler {
   /// (C++11) trailing-return-type[opt] and (C++2a) the trailing
   /// requires-clause.
   ///
+  /// \verbatim
   /// [C++11] exception-specification:
   ///           dynamic-exception-specification
   ///           noexcept-specification
+  /// \endverbatim
   ///
   void ParseFunctionDeclarator(Declarator &D, ParsedAttributes &FirstArgAttrs,
                                BalancedDelimiterTracker &Tracker,
@@ -2639,9 +2717,11 @@ class Parser : public CodeCompletionHandler {
   ///
   /// After returning, ParamInfo will hold the parsed parameters.
   ///
+  /// \verbatim
   ///       identifier-list: [C99 6.7.5]
   ///         identifier
   ///         identifier-list ',' identifier
+  /// \endverbatim
   ///
   void ParseFunctionDeclaratorIdentifierList(
       Declarator &D, SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
@@ -2667,6 +2747,7 @@ class Parser : public CodeCompletionHandler {
   /// After returning, ParamInfo will hold the parsed parameters. EllipsisLoc
   /// will be the location of the ellipsis, if any was parsed.
   ///
+  /// \verbatim
   ///       parameter-type-list: [C99 6.7.5]
   ///         parameter-list
   ///         parameter-list ',' '...'
@@ -2687,12 +2768,14 @@ class Parser : public CodeCompletionHandler {
   /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
   /// [C++11] attribute-specifier-seq parameter-declaration
   /// [C++2b] attribute-specifier-seq 'this' parameter-declaration
+  /// \endverbatim
   ///
   void ParseParameterDeclarationClause(
       DeclaratorContext DeclaratorContext, ParsedAttributes &attrs,
       SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
       SourceLocation &EllipsisLoc, bool IsACXXFunctionDeclaration = false);
 
+  /// \verbatim
   /// [C90]   direct-declarator '[' constant-expression[opt] ']'
   /// [C99]   direct-declarator '[' type-qual-list[opt] assignment-expr[opt] ']'
   /// [C99]   direct-declarator '[' 'static' type-qual-list[opt] assign-expr ']'
@@ -2700,6 +2783,7 @@ class Parser : public CodeCompletionHandler {
   /// [C99]   direct-declarator '[' type-qual-list[opt] '*' ']'
   /// [C++11] direct-declarator '[' constant-expression[opt] ']'
   ///                           attribute-specifier-seq[opt]
+  /// \endverbatim
   void ParseBracketDeclarator(Declarator &D);
 
   /// Diagnose brackets before an identifier.
@@ -2801,6 +2885,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse a C++ exception-specification if present (C++0x [except.spec]).
   ///
+  /// \verbatim
   ///       exception-specification:
   ///         dynamic-exception-specification
   ///         noexcept-specification
@@ -2808,6 +2893,7 @@ class Parser : public CodeCompletionHandler {
   ///       noexcept-specification:
   ///         'noexcept'
   ///         'noexcept' '(' constant-expression ')'
+  /// \endverbatim
   ExceptionSpecificationType tryParseExceptionSpecification(
       bool Delayed, SourceRange &SpecificationRange,
       SmallVectorImpl<ParsedType> &DynamicExceptions,
@@ -2818,6 +2904,7 @@ class Parser : public CodeCompletionHandler {
   /// dynamic-exception-specification (C++ [except.spec]).
   /// EndLoc is filled with the location of the last token of the specification.
   ///
+  /// \verbatim
   ///       dynamic-exception-specification:
   ///         'throw' '(' type-id-list [opt] ')'
   /// [MS]    'throw' '(' '...' ')'
@@ -2825,6 +2912,7 @@ class Parser : public CodeCompletionHandler {
   ///       type-id-list:
   ///         type-id ... [opt]
   ///         type-id-list ',' type-id ... [opt]
+  /// \endverbatim
   ///
   ExceptionSpecificationType
   ParseDynamicExceptionSpecification(SourceRange &SpecificationRange,
@@ -2877,6 +2965,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse a C++11 or C23 attribute-specifier.
   ///
+  /// \verbatim
   /// [C++11] attribute-specifier:
   ///         '[' '[' attribute-list ']' ']'
   ///         alignment-specifier
@@ -2899,6 +2988,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// [C++11] attribute-namespace:
   ///         identifier
+  /// \endverbatim
   void ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
                                             CachedTokens &OpenMPTokens,
                                             SourceLocation *EndLoc = nullptr);
@@ -2911,14 +3001,17 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXX11Attributes - Parse a C++11 or C23 attribute-specifier-seq.
   ///
+  /// \verbatim
   /// attribute-specifier-seq:
   ///       attribute-specifier-seq[opt] attribute-specifier
+  /// \endverbatim
   void ParseCXX11Attributes(ParsedAttributes &attrs);
 
   /// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause.
   /// Parses a C++11 (or C23)-style attribute argument list. Returns true
   /// if this results in adding an attribute to the ParsedAttributes list.
   ///
+  /// \verbatim
   /// [C++11] attribute-argument-clause:
   ///         '(' balanced-token-seq ')'
   ///
@@ -2931,6 +3024,7 @@ class Parser : public CodeCompletionHandler {
   ///         '[' balanced-token-seq ']'
   ///         '{' balanced-token-seq '}'
   ///         any token but '(', ')', '[', ']', '{', or '}'
+  /// \endverbatim
   bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
                                SourceLocation AttrNameLoc,
                                ParsedAttributes &Attrs, SourceLocation *EndLoc,
@@ -2966,12 +3060,14 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseMicrosoftAttributes - Parse Microsoft attributes [Attr]
   ///
+  /// \verbatim
   /// [MS] ms-attribute:
   ///             '[' token-seq ']'
   ///
   /// [MS] ms-attribute-seq:
   ///             ms-attribute[opt]
   ///             ms-attribute ms-attribute-seq
+  /// \endverbatim
   void ParseMicrosoftAttributes(ParsedAttributes &Attrs);
 
   void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
@@ -2979,8 +3075,10 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseDecltypeSpecifier - Parse a C++11 decltype specifier.
   ///
+  /// \verbatim
   /// 'decltype' ( expression )
   /// 'decltype' ( 'auto' )      [C++1y]
+  /// \endverbatim
   ///
   SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
   void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
@@ -2990,10 +3088,12 @@ class Parser : public CodeCompletionHandler {
   /// isCXX11VirtSpecifier - Determine whether the given token is a C++11
   /// virt-specifier.
   ///
+  /// \verbatim
   ///       virt-specifier:
   ///         override
   ///         final
   ///         __final
+  /// \endverbatim
   VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
   VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
     return isCXX11VirtSpecifier(Tok);
@@ -3001,9 +3101,11 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq.
   ///
+  /// \verbatim
   ///       virt-specifier-seq:
   ///         virt-specifier
   ///         virt-specifier-seq virt-specifier
+  /// \endverbatim
   void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface,
                                           SourceLocation FriendLoc);
 
@@ -3024,6 +3126,7 @@ class Parser : public CodeCompletionHandler {
   /// 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.
   ///
+  /// \verbatim
   ///       namespace-definition: [C++: namespace.def]
   ///         named-namespace-definition
   ///         unnamed-namespace-definition
@@ -3046,6 +3149,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
   ///         'namespace' identifier '=' qualified-namespace-specifier ';'
+  /// \endverbatim
   ///
   DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
                                 SourceLocation &DeclEnd,
@@ -3068,25 +3172,31 @@ class Parser : public CodeCompletionHandler {
   /// ParseLinkage - We know that the current token is a string_literal
   /// and just before that, that extern was seen.
   ///
+  /// \verbatim
   ///       linkage-specification: [C++ 7.5p2: dcl.link]
   ///         'extern' string-literal '{' declaration-seq[opt] '}'
   ///         'extern' string-literal declaration
+  /// \endverbatim
   ///
   Decl *ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context);
 
   /// Parse a standard C++ Modules export-declaration.
   ///
+  /// \verbatim
   ///       export-declaration:
   ///         'export' declaration
   ///         'export' '{' declaration-seq[opt] '}'
+  /// \endverbatim
   ///
   /// HLSL: Parse export function declaration.
   ///
+  /// \verbatim
   ///      export-function-declaration:
   ///         'export' function-declaration
   ///
   ///      export-declaration-group:
   ///         'export' '{' function-declaration-seq[opt] '}'
+  /// \endverbatim
   ///
   Decl *ParseExportDeclaration();
 
@@ -3099,12 +3209,14 @@ class Parser : public CodeCompletionHandler {
   /// ParseUsingDirective - Parse C++ using-directive, assumes
   /// that current token is 'namespace' and 'using' was already parsed.
   ///
+  /// \verbatim
   ///       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] ;
+  /// \endverbatim
   ///
   Decl *ParseUsingDirective(DeclaratorContext Context, SourceLocation UsingLoc,
                             SourceLocation &DeclEnd, ParsedAttributes &attrs);
@@ -3124,14 +3236,17 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse a using-declarator (or the identifier in a C++11 alias-declaration).
   ///
+  /// \verbatim
   ///     using-declarator:
   ///       'typename'[opt] nested-name-specifier unqualified-id
+  /// \endverbatim
   ///
   bool ParseUsingDeclarator(DeclaratorContext Context, UsingDeclarator &D);
 
   /// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
   /// Assumes that 'using' was already seen.
   ///
+  /// \verbatim
   ///     using-declaration: [C++ 7.3.p3: namespace.udecl]
   ///       'using' using-declarator-list[opt] ;
   ///
@@ -3152,6 +3267,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///     elaborated-enum-specifier:
   ///       'enum' nested-name-specifier[opt] identifier
+  /// \endverbatim
   DeclGroupPtrTy ParseUsingDeclaration(DeclaratorContext Context,
                                        const ParsedTemplateInfo &TemplateInfo,
                                        SourceLocation UsingLoc,
@@ -3166,11 +3282,13 @@ class Parser : public CodeCompletionHandler {
   /// ParseStaticAssertDeclaration - Parse C++0x or C11
   /// static_assert-declaration.
   ///
+  /// \verbatim
   /// [C++0x] static_assert-declaration:
   ///           static_assert ( constant-expression  ,  string-literal  ) ;
   ///
   /// [C11]   static_assert-declaration:
   ///           _Static_assert ( constant-expression  ,  string-literal  ) ;
+  /// \endverbatim
   ///
   Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
 
@@ -3194,6 +3312,7 @@ class Parser : public CodeCompletionHandler {
   /// until we reach the start of a definition or see a token that
   /// cannot start a definition.
   ///
+  /// \verbatim
   ///       class-specifier: [C++ class]
   ///         class-head '{' member-specification[opt] '}'
   ///         class-head '{' member-specification[opt] '}' attributes[opt]
@@ -3229,6 +3348,7 @@ class Parser : public CodeCompletionHandler {
   ///       struct-or-union:
   ///         'struct'
   ///         'union'
+  /// \endverbatim
   void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
                            DeclSpec &DS, ParsedTemplateInfo &TemplateInfo,
                            AccessSpecifier AS, bool EnteringContext,
@@ -3239,9 +3359,11 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXMemberSpecification - Parse the class definition.
   ///
+  /// \verbatim
   ///       member-specification:
   ///         member-declaration member-specification[opt]
   ///         access-specifier ':' member-specification[opt]
+  /// \endverbatim
   ///
   void ParseCXXMemberSpecification(SourceLocation StartLoc,
                                    SourceLocation AttrFixitLoc,
@@ -3254,6 +3376,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// This does not check for a pure-specifier; that's handled elsewhere.
   ///
+  /// \verbatim
   ///   brace-or-equal-initializer:
   ///     '=' initializer-expression
   ///     braced-init-list
@@ -3265,6 +3388,7 @@ class Parser : public CodeCompletionHandler {
   ///   defaulted/deleted function-definition:
   ///     '=' 'default'
   ///     '=' 'delete'
+  /// \endverbatim
   ///
   /// Prior to C++0x, the assignment-expression in an initializer-clause must
   /// be a constant-expression.
@@ -3286,6 +3410,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
   ///
+  /// \verbatim
   ///       member-declaration:
   ///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
   ///         function-definition ';'[opt]
@@ -3333,6 +3458,7 @@ class Parser : public CodeCompletionHandler {
   ///         simple-type-specifier
   ///         elaborated-type-specifier
   ///         typename-specifier
+  /// \endverbatim
   ///
   DeclGroupPtrTy ParseCXXClassMemberDeclaration(
       AccessSpecifier AS, ParsedAttributes &Attr,
@@ -3358,12 +3484,14 @@ class Parser : public CodeCompletionHandler {
   /// };
   /// @endcode
   ///
+  /// \verbatim
   /// [C++]  ctor-initializer:
   ///          ':' mem-initializer-list
   ///
   /// [C++]  mem-initializer-list:
   ///          mem-initializer ...[opt]
   ///          mem-initializer ...[opt] , mem-initializer-list
+  /// \endverbatim
   void ParseConstructorInitializer(Decl *ConstructorDecl);
 
   /// ParseMemInitializer - Parse a C++ member initializer, which is
@@ -3371,6 +3499,7 @@ class Parser : public CodeCompletionHandler {
   /// member or base class (C++ [class.base.init]). See
   /// ParseConstructorInitializer for an example.
   ///
+  /// \verbatim
   /// [C++] mem-initializer:
   ///         mem-initializer-id '(' expression-list[opt] ')'
   /// [C++0x] mem-initializer-id braced-init-list
@@ -3378,6 +3507,7 @@ class Parser : public CodeCompletionHandler {
   /// [C++] mem-initializer-id:
   ///         '::'[opt] nested-name-specifier[opt] class-name
   ///         identifier
+  /// \endverbatim
   MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
 
   /// If the given declarator has any parts for which parsing has to be
@@ -3396,6 +3526,7 @@ class Parser : public CodeCompletionHandler {
   /// class. The result is either a type or null, depending on whether a type
   /// name was found.
   ///
+  /// \verbatim
   ///       base-type-specifier: [C++11 class.derived]
   ///         class-or-decltype
   ///       class-or-decltype: [C++11 class.derived]
@@ -3404,21 +3535,26 @@ class Parser : public CodeCompletionHandler {
   ///       class-name: [C++ class.name]
   ///         identifier
   ///         simple-template-id
+  /// \endverbatim
   ///
   /// In C++98, instead of base-type-specifier, we have:
   ///
+  /// \verbatim
   ///         ::[opt] nested-name-specifier[opt] class-name
+  /// \endverbatim
   TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
                                     SourceLocation &EndLocation);
 
   /// ParseBaseClause - Parse the base-clause of a C++ class [C++
   /// class.derived].
   ///
+  /// \verbatim
   ///       base-clause : [C++ class.derived]
   ///         ':' base-specifier-list
   ///       base-specifier-list:
   ///         base-specifier '...'[opt]
   ///         base-specifier-list ',' base-specifier '...'[opt]
+  /// \endverbatim
   void ParseBaseClause(Decl *ClassDecl);
 
   /// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
@@ -3426,21 +3562,25 @@ class Parser : public CodeCompletionHandler {
   ///    class foo : public bar, virtual private baz {
   /// 'public bar' and 'virtual private baz' are each base-specifiers.
   ///
+  /// \verbatim
   ///       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
+  /// \endverbatim
   BaseResult ParseBaseSpecifier(Decl *ClassDecl);
 
   /// getAccessSpecifierIfPresent - Determine whether the next token is
   /// a C++ access-specifier.
   ///
+  /// \verbatim
   ///       access-specifier: [C++ class.derived]
   ///         'private'
   ///         'protected'
   ///         'public'
+  /// \endverbatim
   AccessSpecifier getAccessSpecifierIfPresent() const;
 
   ///@}
@@ -3605,7 +3745,7 @@ class Parser : public CodeCompletionHandler {
   /// \verbatim
   ///       primary-expression: [C99 6.5.1]
   ///         string-literal
-  /// \verbatim
+  /// \endverbatim
   ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
   ExprResult ParseUnevaluatedStringLiteralExpression();
 
@@ -4184,14 +4324,18 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse availability query specification.
   ///
+  /// \verbatim
   ///  availability-spec:
   ///     '*'
   ///     identifier version-tuple
+  /// \endverbatim
   std::optional<AvailabilitySpec> ParseAvailabilitySpec();
   ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
 
   /// Tries to parse cast part of OpenMP array shaping operation:
-  /// '[' expression ']' { '[' expression ']' } ')'.
+  /// \verbatim
+  /// '[' expression ']' { '[' expression ']' } ')'
+  /// \endverbatim
   bool tryParseOpenMPArrayShapingCastPart();
 
   ExprResult ParseBuiltinPtrauthTypeDiscriminator();
@@ -4212,7 +4356,7 @@ class Parser : public CodeCompletionHandler {
   /// Parse a C++ unqualified-id (or a C identifier), which describes the
   /// name of an entity.
   ///
-  /// \code
+  /// \verbatim
   ///       unqualified-id: [C++ expr.prim.general]
   ///         identifier
   ///         operator-function-id
@@ -4220,8 +4364,7 @@ class Parser : public CodeCompletionHandler {
   /// [C++0x] literal-operator-id [TODO]
   ///         ~ class-name
   ///         template-id
-  ///
-  /// \endcode
+  /// \endverbatim
   ///
   /// \param SS The nested-name-specifier that preceded this unqualified-id. If
   /// non-empty, then we are parsing the unqualified-id of a qualified-id.
@@ -4277,6 +4420,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXIdExpression - Handle id-expression.
   ///
+  /// \verbatim
   ///       id-expression:
   ///         unqualified-id
   ///         qualified-id
@@ -4292,6 +4436,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///   '::' conversion-function-id
   ///   '::' '~' class-name
+  /// \endverbatim
   ///
   /// This may cause a slight inconsistency on diagnostics:
   ///
@@ -4305,9 +4450,11 @@ class Parser : public CodeCompletionHandler {
   ///
   /// We simplify the parser a bit and make it work like:
   ///
+  /// \verbatim
   ///       qualified-id:
   ///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
   ///         '::' unqualified-id
+  /// \endverbatim
   ///
   /// That way Sema can handle and report similar errors for namespaces and the
   /// global scope.
@@ -4334,6 +4481,7 @@ class Parser : public CodeCompletionHandler {
   /// may be preceded by '::'). Note that this routine will not parse ::new or
   /// ::delete; it will just leave them in the token stream.
   ///
+  /// \verbatim
   ///       '::'[opt] nested-name-specifier
   ///       '::'
   ///
@@ -4342,6 +4490,7 @@ class Parser : public CodeCompletionHandler {
   ///         namespace-name '::'
   ///         nested-name-specifier identifier '::'
   ///         nested-name-specifier 'template'[opt] simple-template-id '::'
+  /// \endverbatim
   ///
   ///
   /// \param SS the scope specifier that will be set to the parsed
@@ -4404,6 +4553,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseLambdaExpression - Parse a C++11 lambda expression.
   ///
+  /// \verbatim
   ///       lambda-expression:
   ///         lambda-introducer lambda-declarator compound-statement
   ///         lambda-introducer '<' template-parameter-list '>'
@@ -4446,6 +4596,7 @@ class Parser : public CodeCompletionHandler {
   ///       lambda-specifiers:
   ///         decl-specifier-seq[opt] noexcept-specifier[opt]
   ///             attribute-specifier-seq[opt] trailing-return-type[opt]
+  /// \endverbatim
   ///
   ExprResult ParseLambdaExpression();
 
@@ -4478,11 +4629,13 @@ class Parser : public CodeCompletionHandler {
   /// ParseCXXCasts - This handles the various ways to cast expressions to
   /// another type.
   ///
+  /// \verbatim
   ///       postfix-expression: [C++ 5.2p1]
   ///         'dynamic_cast' '<' type-name '>' '(' expression ')'
   ///         'static_cast' '<' type-name '>' '(' expression ')'
   ///         'reinterpret_cast' '<' type-name '>' '(' expression ')'
   ///         'const_cast' '<' type-name '>' '(' expression ')'
+  /// \endverbatim
   ///
   /// C++ for OpenCL s2.3.1 adds:
   ///         'addrspace_cast' '<' type-name '>' '(' expression ')'
@@ -4496,9 +4649,11 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXTypeid - This handles the C++ typeid expression.
   ///
+  /// \verbatim
   ///       postfix-expression: [C++ 5.2p1]
   ///         'typeid' '(' expression ')'
   ///         'typeid' '(' type-id ')'
+  /// \endverbatim
   ///
   ExprResult ParseCXXTypeid();
 
@@ -4507,8 +4662,10 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.
   ///
+  /// \verbatim
   ///         '__uuidof' '(' expression ')'
   ///         '__uuidof' '(' type-id ')'
+  /// \endverbatim
   ///
   ExprResult ParseCXXUuidof();
 
@@ -4519,6 +4676,7 @@ class Parser : public CodeCompletionHandler {
   /// . or -> operator, and nested-name-specifier have already been
   /// parsed. We're handling this fragment of the grammar:
   ///
+  /// \verbatim
   ///       postfix-expression: [C++2a expr.post]
   ///         postfix-expression . template[opt] id-expression
   ///         postfix-expression -> template[opt] id-expression
@@ -4542,6 +4700,7 @@ class Parser : public CodeCompletionHandler {
   ///         ~ type-name
   ///         ~ decltype-specifier
   ///         [...]
+  /// \endverbatim
   ///
   /// ... where the all but the last component of the nested-name-specifier
   /// has already been parsed, and the base expression is not of a non-dependent
@@ -4565,8 +4724,10 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseThrowExpression - This handles the C++ throw expression.
   ///
+  /// \verbatim
   ///       throw-expression: [C++ 15]
   ///         'throw' assignment-expression[opt]
+  /// \endverbatim
   ExprResult ParseThrowExpression();
 
   //===--------------------------------------------------------------------===//
@@ -4574,9 +4735,11 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
   ///
+  /// \verbatim
   ///       boolean-literal: [C++ 2.13.5]
   ///         'true'
   ///         'false'
+  /// \endverbatim
   ExprResult ParseCXXBoolLiteral();
 
   //===--------------------------------------------------------------------===//
@@ -4588,11 +4751,13 @@ class Parser : public CodeCompletionHandler {
   /// or creation of a value-initialized type ("int()").
   /// See [C++ 5.2.3].
   ///
+  /// \verbatim
   ///       postfix-expression: [C++ 5.2p1]
   ///         simple-type-specifier '(' expression-list[opt] ')'
   /// [C++0x] simple-type-specifier braced-init-list
   ///         typename-specifier '(' expression-list[opt] ')'
   /// [C++0x] typename-specifier braced-init-list
+  /// \endverbatim
   ///
   /// In C++1z onwards, the type specifier can also be a template-name.
   ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
@@ -4601,6 +4766,7 @@ class Parser : public CodeCompletionHandler {
   /// This should only be called when the current token is known to be part of
   /// simple-type-specifier.
   ///
+  /// \verbatim
   ///       simple-type-specifier:
   ///         '::'[opt] nested-name-specifier[opt] type-name
   ///         '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]
@@ -4622,6 +4788,7 @@ class Parser : public CodeCompletionHandler {
   ///         class-name
   ///         enum-name
   ///         typedef-name
+  /// \endverbatim
   ///
   void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
 
@@ -4633,8 +4800,10 @@ class Parser : public CodeCompletionHandler {
   /// emits diagnostics if this is not a type-specifier-seq, false
   /// otherwise.
   ///
+  /// \verbatim
   ///   type-specifier-seq: [C++ 8.1]
   ///     type-specifier type-specifier-seq[opt]
+  /// \endverbatim
   ///
   bool ParseCXXTypeSpecifierSeq(
       DeclSpec &DS, DeclaratorContext Context = DeclaratorContext::TypeName);
@@ -4645,12 +4814,14 @@ class Parser : public CodeCompletionHandler {
   /// ParseExpressionListOrTypeId - Parse either an expression-list or a
   /// type-id. This ambiguity appears in the syntax of the C++ new operator.
   ///
+  /// \verbatim
   ///        new-expression:
   ///                   '::'[opt] 'new' new-placement[opt] '(' type-id ')'
   ///                                     new-initializer[opt]
   ///
   ///        new-placement:
   ///                   '(' expression-list ')'
+  /// \endverbatim
   ///
   bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr *> &Exprs,
                                    Declarator &D);
@@ -4658,9 +4829,11 @@ class Parser : public CodeCompletionHandler {
   /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
   /// passed to ParseDeclaratorInternal.
   ///
+  /// \verbatim
   ///        direct-new-declarator:
   ///                   '[' expression[opt] ']'
   ///                   direct-new-declarator '[' constant-expression ']'
+  /// \endverbatim
   ///
   void ParseDirectNewDeclarator(Declarator &D);
 
@@ -4672,6 +4845,7 @@ class Parser : public CodeCompletionHandler {
   /// "Start" is its location.  Otherwise, "Start" is the location of the 'new'
   /// token.
   ///
+  /// \verbatim
   ///        new-expression:
   ///                   '::'[opt] 'new' new-placement[opt] new-type-id
   ///                                     new-initializer[opt]
@@ -4692,6 +4866,7 @@ class Parser : public CodeCompletionHandler {
   ///        new-initializer:
   ///                   '(' expression-list[opt] ')'
   /// [C++0x]           braced-init-list
+  /// \endverbatim
   ///
   ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
 
@@ -4703,9 +4878,11 @@ class Parser : public CodeCompletionHandler {
   /// true and "Start" is its location.  Otherwise, "Start" is the location of
   /// the 'delete' token.
   ///
+  /// \verbatim
   ///        delete-expression:
   ///                   '::'[opt] 'delete' cast-expression
   ///                   '::'[opt] 'delete' '[' ']' cast-expression
+  /// \endverbatim
   ExprResult ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start);
 
   //===--------------------------------------------------------------------===//
@@ -4713,6 +4890,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXCondition - if/switch/while condition expression.
   ///
+  /// \verbatim
   ///       condition:
   ///         expression
   ///         type-specifier-seq declarator '=' assignment-expression
@@ -4722,6 +4900,7 @@ class Parser : public CodeCompletionHandler {
   ///             brace-or-equal-initializer
   /// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
   ///             '=' assignment-expression
+  /// \endverbatim
   ///
   /// In C++1z, a condition may in some contexts be preceded by an
   /// optional init-statement. This function will parse that too.
@@ -4757,8 +4936,10 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse the C++ Coroutines co_yield expression.
   ///
+  /// \verbatim
   ///       co_yield-expression:
   ///         'co_yield' assignment-expression[opt]
+  /// \endverbatim
   ExprResult ParseCoyieldExpression();
 
   //===--------------------------------------------------------------------===//
@@ -4770,6 +4951,7 @@ class Parser : public CodeCompletionHandler {
   ///     on template arguments. A requirement is one that can be checked by
   ///     name lookup (6.4) or by checking properties of types and expressions.
   ///
+  /// \verbatim
   ///     requires-expression:
   ///         'requires' requirement-parameter-list[opt] requirement-body
   ///
@@ -4788,6 +4970,7 @@ class Parser : public CodeCompletionHandler {
   ///         type-requirement
   ///         compound-requirement
   ///         nested-requirement
+  /// \endverbatim
   ExprResult ParseRequiresExpression();
 
   /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
@@ -4853,7 +5036,7 @@ class Parser : public CodeCompletionHandler {
   /// This routine is responsible only for parsing the operator-function-id or
   /// conversion-function-id; it does not handle template arguments in any way.
   ///
-  /// \code
+  /// \verbatim
   ///       operator-function-id: [C++ 13.5]
   ///         'operator' operator
   ///
@@ -4873,7 +5056,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///       conversion-declarator:
   ///         ptr-operator conversion-declarator[opt]
-  /// \endcode
+  /// \endverbatim
   ///
   /// \param SS The nested-name-specifier that preceded this unqualified-id. If
   /// non-empty, then we are parsing the unqualified-id of a qualified-id.
@@ -4896,6 +5079,7 @@ class Parser : public CodeCompletionHandler {
   /// Parse the built-in type-trait pseudo-functions that allow
   /// implementation of the TR1/C++11 type traits templates.
   ///
+  /// \verbatim
   ///       primary-expression:
   ///          unary-type-trait '(' type-id ')'
   ///          binary-type-trait '(' type-id ',' type-id ')'
@@ -4903,6 +5087,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///       type-id-seq:
   ///          type-id ...[opt] type-id-seq[opt]
+  /// \endverbatim
   ///
   ExprResult ParseTypeTrait();
 
@@ -4912,17 +5097,21 @@ class Parser : public CodeCompletionHandler {
   /// ParseArrayTypeTrait - Parse the built-in array type-trait
   /// pseudo-functions.
   ///
+  /// \verbatim
   ///       primary-expression:
   /// [Embarcadero]     '__array_rank' '(' type-id ')'
   /// [Embarcadero]     '__array_extent' '(' type-id ',' expression ')'
+  /// \endverbatim
   ///
   ExprResult ParseArrayTypeTrait();
 
   /// ParseExpressionTrait - Parse built-in expression-trait
   /// pseudo-functions like __is_lvalue_expr( xxx ).
   ///
+  /// \verbatim
   ///       primary-expression:
   /// [Embarcadero]     expression-trait '(' expression ')'
+  /// \endverbatim
   ///
   ExprResult ParseExpressionTrait();
 
@@ -4981,9 +5170,11 @@ class Parser : public CodeCompletionHandler {
   // C99 6.7.8: Initialization.
 
   /// ParseInitializer
+  /// \verbatim
   ///       initializer: [C99 6.7.8]
   ///         assignment-expression
   ///         '{' ...
+  /// \endverbatim
   ExprResult ParseInitializer() {
     if (Tok.isNot(tok::l_brace))
       return ParseAssignmentExpression();
@@ -4998,6 +5189,7 @@ class Parser : public CodeCompletionHandler {
   /// ParseBraceInitializer - Called when parsing an initializer that has a
   /// leading open brace.
   ///
+  /// \verbatim
   ///       initializer: [C99 6.7.8]
   ///         '{' initializer-list '}'
   ///         '{' initializer-list ',' '}'
@@ -5006,6 +5198,7 @@ class Parser : public CodeCompletionHandler {
   ///       initializer-list:
   ///         designation[opt] initializer ...[opt]
   ///         initializer-list ',' designation[opt] initializer ...[opt]
+  /// \endverbatim
   ///
   ExprResult ParseBraceInitializer();
 
@@ -5019,6 +5212,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// C99:
   ///
+  /// \verbatim
   ///       designation:
   ///         designator-list '='
   /// [GNU]   array-designator
@@ -5035,9 +5229,11 @@ class Parser : public CodeCompletionHandler {
   ///       array-designator:
   ///         '[' constant-expression ']'
   /// [GNU]   '[' constant-expression '...' constant-expression ']'
+  /// \endverbatim
   ///
   /// C++20:
   ///
+  /// \verbatim
   ///       designated-initializer-list:
   ///         designated-initializer-clause
   ///         designated-initializer-list ',' designated-initializer-clause
@@ -5047,6 +5243,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///       designator:
   ///         '.' identifier
+  /// \endverbatim
   ///
   /// We allow the C99 syntax extensions in C++20, but do not allow the C++20
   /// extension (a braced-init-list after the designator with no '=') in C99.
@@ -5160,6 +5357,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseObjCAtDirectives - Handle parts of the external-declaration
   /// production:
+  /// \verbatim
   ///       external-declaration: [C99 6.9]
   /// [OBJC]  objc-class-definition
   /// [OBJC]  objc-class-declaration
@@ -5167,19 +5365,23 @@ class Parser : public CodeCompletionHandler {
   /// [OBJC]  objc-protocol-definition
   /// [OBJC]  objc-method-definition
   /// [OBJC]  '@' 'end'
+  /// \endverbatim
   DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
                                        ParsedAttributes &DeclSpecAttrs);
 
   ///
+  /// \verbatim
   /// objc-class-declaration:
   ///    '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
   ///
   /// objc-class-forward-decl:
   ///   identifier objc-type-parameter-list[opt]
+  /// \endverbatim
   ///
   DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
 
   ///
+  /// \verbatim
   ///   objc-interface:
   ///     objc-class-interface-attributes[opt] objc-class-interface
   ///     objc-category-interface
@@ -5207,6 +5409,7 @@ class Parser : public CodeCompletionHandler {
   ///     __attribute__((unavailable))
   ///     __attribute__((objc_exception)) - used by NSException on 64-bit
   ///     __attribute__((objc_root_class))
+  /// \endverbatim
   ///
   Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
                                         ParsedAttributes &prefixAttrs);
@@ -5221,6 +5424,7 @@ class Parser : public CodeCompletionHandler {
   /// the locations of the protocol identifiers for a list of protocol
   /// references.
   ///
+  /// \verbatim
   ///   objc-type-parameter-list:
   ///     '<' objc-type-parameter (',' objc-type-parameter)* '>'
   ///
@@ -5233,6 +5437,7 @@ class Parser : public CodeCompletionHandler {
   ///   objc-type-parameter-variance:
   ///     '__covariant'
   ///     '__contravariant'
+  /// \endverbatim
   ///
   /// \param lAngleLoc The location of the starting '<'.
   ///
@@ -5252,6 +5457,7 @@ class Parser : public CodeCompletionHandler {
                                         SmallVectorImpl<Decl *> &AllIvarDecls,
                                         bool RBraceMissing);
 
+  /// \verbatim
   ///   objc-class-instance-variables:
   ///     '{' objc-instance-variable-decl-list[opt] '}'
   ///
@@ -5272,13 +5478,16 @@ class Parser : public CodeCompletionHandler {
   ///
   ///   objc-instance-variable-decl:
   ///     struct-declaration
+  /// \endverbatim
   ///
   void ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
                                        tok::ObjCKeywordKind visibility,
                                        SourceLocation atLoc);
 
+  /// \verbatim
   ///   objc-protocol-refs:
   ///     '<' identifier-list '>'
+  /// \endverbatim
   ///
   bool ParseObjCProtocolReferences(
       SmallVectorImpl<Decl *> &P, SmallVectorImpl<SourceLocation> &PLocs,
@@ -5289,8 +5498,10 @@ class Parser : public CodeCompletionHandler {
   /// Objective-C object or object pointer type, which may be either
   /// type arguments or protocol qualifiers.
   ///
+  /// \verbatim
   ///   objc-type-arguments:
   ///     '<' type-name '...'[opt] (',' type-name '...'[opt])* '>'
+  /// \endverbatim
   ///
   void parseObjCTypeArgsOrProtocolQualifiers(
       ParsedType baseType, SourceLocation &typeArgsLAngleLoc,
@@ -5320,6 +5531,7 @@ class Parser : public CodeCompletionHandler {
                                                     bool consumeLastToken,
                                                     SourceLocation &endLoc);
 
+  /// \verbatim
   ///   objc-interface-decl-list:
   ///     empty
   ///     objc-interface-decl-list objc-property-decl [OBJC2]
@@ -5331,9 +5543,11 @@ class Parser : public CodeCompletionHandler {
   ///   objc-method-requirement: [OBJC2]
   ///     @required
   ///     @optional
+  /// \endverbatim
   ///
   void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, Decl *CDecl);
 
+  /// \verbatim
   ///   objc-protocol-declaration:
   ///     objc-protocol-definition
   ///     objc-protocol-forward-reference
@@ -5346,6 +5560,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///   objc-protocol-forward-reference:
   ///     \@protocol identifier-list ';'
+  /// \endverbatim
   ///
   ///   "\@protocol identifier ;" should be resolved as "\@protocol
   ///   identifier-list ;": objc-interface-decl-list may not start with a
@@ -5379,6 +5594,7 @@ class Parser : public CodeCompletionHandler {
   /// for later parsing.
   void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
 
+  /// \verbatim
   ///   objc-implementation:
   ///     objc-class-implementation-prologue
   ///     objc-category-implementation-prologue
@@ -5389,15 +5605,19 @@ class Parser : public CodeCompletionHandler {
   ///
   ///   objc-category-implementation-prologue:
   ///     @implementation identifier ( identifier )
+  /// \endverbatim
   DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
                                                       ParsedAttributes &Attrs);
   DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
 
+  /// \verbatim
   ///   compatibility-alias-decl:
   ///     @compatibility_alias alias-name  class-name ';'
+  /// \endverbatim
   ///
   Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
 
+  /// \verbatim
   ///   property-synthesis:
   ///     @synthesize property-ivar-list ';'
   ///
@@ -5408,18 +5628,22 @@ class Parser : public CodeCompletionHandler {
   ///   property-ivar:
   ///     identifier
   ///     identifier '=' identifier
+  /// \endverbatim
   ///
   Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
 
+  /// \verbatim
   ///   property-dynamic:
   ///     @dynamic  property-list
   ///
   ///   property-list:
   ///     identifier
   ///     property-list ',' identifier
+  /// \endverbatim
   ///
   Decl *ParseObjCPropertyDynamic(SourceLocation atLoc);
 
+  /// \verbatim
   ///   objc-selector:
   ///     identifier
   ///     one of
@@ -5427,22 +5651,28 @@ class Parser : public CodeCompletionHandler {
   ///       break continue return goto asm sizeof typeof __alignof
   ///       unsigned long const short volatile signed restrict _Complex
   ///       in out inout bycopy byref oneway int char float double void _Bool
+  /// \endverbatim
   ///
   IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
 
   IdentifierInfo *ObjCTypeQuals[llvm::to_underlying(ObjCTypeQual::NumQuals)];
 
+  /// \verbatim
   ///  objc-for-collection-in: 'in'
+  /// \endverbatim
   ///
   bool isTokIdentifier_in() const;
 
+  /// \verbatim
   ///   objc-type-name:
   ///     '(' objc-type-qualifiers[opt] type-name ')'
   ///     '(' objc-type-qualifiers[opt] ')'
+  /// \endverbatim
   ///
   ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx,
                                ParsedAttributes *ParamAttrs);
 
+  /// \verbatim
   ///   objc-method-proto:
   ///     objc-instance-method objc-method-decl objc-method-attributes[opt]
   ///     objc-class-method objc-method-decl objc-method-attributes[opt]
@@ -5452,11 +5682,13 @@ class Parser : public CodeCompletionHandler {
   ///
   ///   objc-method-attributes:         [OBJC2]
   ///     __attribute__((deprecated))
+  /// \endverbatim
   ///
   Decl *ParseObjCMethodPrototype(
       tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
       bool MethodDefinition = true);
 
+  /// \verbatim
   ///   objc-method-decl:
   ///     objc-selector
   ///     objc-keyword-selector objc-parmlist[opt]
@@ -5484,6 +5716,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///   objc-keyword-attributes:         [OBJC2]
   ///     __attribute__((unused))
+  /// \endverbatim
   ///
   Decl *ParseObjCMethodDecl(
       SourceLocation mLoc, tok::TokenKind mType,
@@ -5492,6 +5725,7 @@ class Parser : public CodeCompletionHandler {
 
   ///   Parse property attribute declarations.
   ///
+  /// \verbatim
   ///   property-attr-decl: '(' property-attrlist ')'
   ///   property-attrlist:
   ///     property-attribute
@@ -5515,10 +5749,13 @@ class Parser : public CodeCompletionHandler {
   ///     null_unspecified
   ///     null_resettable
   ///     class
+  /// \endverbatim
   ///
   void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
 
+  /// \verbatim
   ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
+  /// \endverbatim
   ///
   Decl *ParseObjCMethodDefinition();
 
@@ -5528,42 +5765,56 @@ class Parser : public CodeCompletionHandler {
   ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
 
   /// ParseObjCCharacterLiteral -
+  /// \verbatim
   /// objc-scalar-literal : '@' character-literal
   ///                        ;
+  /// \endverbatim
   ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
 
   /// ParseObjCNumericLiteral -
+  /// \verbatim
   /// objc-scalar-literal : '@' scalar-literal
   ///                        ;
   /// scalar-literal : | numeric-constant			/* any numeric constant. */
   ///                    ;
+  /// \endverbatim
   ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
 
   /// ParseObjCBooleanLiteral -
+  /// \verbatim
   /// objc-scalar-literal : '@' boolean-keyword
   ///                        ;
   /// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
   ///                        ;
+  /// \endverbatim
   ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
 
   ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
   ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
 
   /// ParseObjCBoxedExpr -
+  /// \verbatim
   /// objc-box-expression:
   ///       @( assignment-expression )
+  /// \endverbatim
   ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
 
+  /// \verbatim
   ///    objc-encode-expression:
   ///      \@encode ( type-name )
+  /// \endverbatim
   ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
 
+  /// \verbatim
   ///     objc-selector-expression
   ///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
+  /// \endverbatim
   ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
 
+  /// \verbatim
   ///     objc-protocol-expression
   ///       \@protocol ( protocol-name )
+  /// \endverbatim
   ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
 
   /// Determine whether the parser is currently referring to a an
@@ -5573,6 +5824,7 @@ class Parser : public CodeCompletionHandler {
   /// expressions.
   bool isSimpleObjCMessageExpression();
 
+  /// \verbatim
   ///   objc-message-expr:
   ///     '[' objc-receiver objc-message-args ']'
   ///
@@ -5581,6 +5833,7 @@ class Parser : public CodeCompletionHandler {
   ///     expression
   ///     class-name
   ///     type-name
+  /// \endverbatim
   ///
   ExprResult ParseObjCMessageExpression();
 
@@ -5604,6 +5857,7 @@ class Parser : public CodeCompletionHandler {
   /// \param ReceiverExpr If this is an instance message, the expression
   /// used to compute the receiver object.
   ///
+  /// \verbatim
   ///   objc-message-args:
   ///     objc-selector
   ///     objc-keywordarg-list
@@ -5621,6 +5875,7 @@ class Parser : public CodeCompletionHandler {
   ///   nonempty-expr-list:
   ///     assignment-expression
   ///     nonempty-expr-list , assignment-expression
+  /// \endverbatim
   ///
   ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
                                             SourceLocation SuperLoc,
@@ -5644,11 +5899,13 @@ class Parser : public CodeCompletionHandler {
   /// analysis, in which case the arguments do not have valid
   /// values. Otherwise, returns false for a successful parse.
   ///
+  /// \verbatim
   ///   objc-receiver: [C++]
   ///     'super' [not parsed here]
   ///     expression
   ///     simple-type-specifier
   ///     typename-specifier
+  /// \endverbatim
   bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
 
   //===--------------------------------------------------------------------===//
@@ -5659,6 +5916,7 @@ class Parser : public CodeCompletionHandler {
   StmtResult ParseObjCAtStatement(SourceLocation atLoc,
                                   ParsedStmtContext StmtCtx);
 
+  /// \verbatim
   ///  objc-try-catch-statement:
   ///    @try compound-statement objc-catch-list[opt]
   ///    @try compound-statement objc-catch-list[opt] @finally compound-statement
@@ -5669,21 +5927,28 @@ class Parser : public CodeCompletionHandler {
   ///  catch-parameter-declaration:
   ///     parameter-declaration
   ///     '...' [OBJC2]
+  /// \endverbatim
   ///
   StmtResult ParseObjCTryStmt(SourceLocation atLoc);
 
+  /// \verbatim
   ///  objc-throw-statement:
   ///    throw expression[opt];
+  /// \endverbatim
   ///
   StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
 
+  /// \verbatim
   /// objc-synchronized-statement:
   ///   @synchronized '(' expression ')' compound-statement
+  /// \endverbatim
   ///
   StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
 
+  /// \verbatim
   /// objc-autoreleasepool-statement:
   ///   @autoreleasepool compound-statement
+  /// \endverbatim
   ///
   StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc);
 
@@ -5691,6 +5956,7 @@ class Parser : public CodeCompletionHandler {
   /// qualifier list and builds their bitmask representation in the input
   /// argument.
   ///
+  /// \verbatim
   ///   objc-type-qualifiers:
   ///     objc-type-qualifier
   ///     objc-type-qualifiers objc-type-qualifier
@@ -5705,6 +5971,7 @@ class Parser : public CodeCompletionHandler {
   ///     'nonnull'
   ///     'nullable'
   ///     'null_unspecified'
+  /// \endverbatim
   ///
   void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, DeclaratorContext Context);
 
@@ -5884,7 +6151,9 @@ class Parser : public CodeCompletionHandler {
   /// OpenACC 3.3, section 2.16:
   /// In this section and throughout the specification, the term wait-argument
   /// means:
+  /// \verbatim
   /// [ devnum : int-expr : ] [ queues : ] async-argument-list
+  /// \endverbatim
   OpenACCWaitParseInfo ParseOpenACCWaitArgument(SourceLocation Loc,
                                                 bool IsDirective);
 
@@ -5956,9 +6225,11 @@ class Parser : public CodeCompletionHandler {
   /// OpenACC 3.3 Section 2.9:
   ///
   /// where gang-arg is one of:
+  /// \verbatim
   /// [num:]int-expr
   /// dim:int-expr
   /// static:size-expr
+  /// \endverbatim
   bool ParseOpenACCGangArgList(SourceLocation GangLoc,
                                llvm::SmallVectorImpl<OpenACCGangKind> &GKs,
                                llvm::SmallVectorImpl<Expr *> &IntExprs);
@@ -6039,20 +6310,26 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses an OpenMP context selector.
   ///
+  /// \verbatim
   /// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
+  /// \endverbatim
   void parseOMPContextSelector(OMPTraitSelector &TISelector,
                                llvm::omp::TraitSet Set,
                                llvm::StringMap<SourceLocation> &SeenSelectors);
 
   /// Parses an OpenMP context selector set.
   ///
+  /// \verbatim
   /// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
+  /// \endverbatim
   void parseOMPContextSelectorSet(OMPTraitSet &TISet,
                                   llvm::StringMap<SourceLocation> &SeenSets);
 
   /// Parse OpenMP context selectors:
   ///
+  /// \verbatim
   /// <trait-set-selector> [, <trait-set-selector>]*
+  /// \endverbatim
   bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI);
 
   /// Parse an 'append_args' clause for '#pragma omp declare variant'.
@@ -6073,6 +6350,7 @@ class Parser : public CodeCompletionHandler {
   /// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
   /// where
   ///
+  /// \verbatim
   ///   clause:
   ///     'ext_IMPL_DEFINED'
   ///     'absent' '(' directive-name [, directive-name]* ')'
@@ -6082,6 +6360,7 @@ class Parser : public CodeCompletionHandler {
   ///     'no_openmp_routines'
   ///     'no_openmp_constructs' (OpenMP 6.0)
   ///     'no_parallelism'
+  /// \endverbatim
   ///
   void ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
                                    SourceLocation Loc);
@@ -6091,6 +6370,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses clauses for directive.
   ///
+  /// \verbatim
   /// <clause> [clause[ [,] clause] ... ]
   ///
   ///  clauses: for error directive
@@ -6098,6 +6378,7 @@ class Parser : public CodeCompletionHandler {
   ///     'severity' '(' fatal | warning ')'
   ///     'message' '(' msg-string ')'
   /// ....
+  /// \endverbatim
   ///
   /// \param DKind Kind of current directive.
   /// \param clauses for current directive.
@@ -6130,6 +6411,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses declarative OpenMP directives.
   ///
+  /// \verbatim
   ///       threadprivate-directive:
   ///         annot_pragma_openmp 'threadprivate' simple-variable-list
   ///         annot_pragma_openmp_end
@@ -6163,6 +6445,7 @@ class Parser : public CodeCompletionHandler {
   ///         annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
   ///         annot_pragma_openmp 'end assumes'
   ///         annot_pragma_openmp_end
+  /// \endverbatim
   ///
   DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
       AccessSpecifier &AS, ParsedAttributes &Attrs, bool Delayed = false,
@@ -6171,11 +6454,13 @@ class Parser : public CodeCompletionHandler {
 
   /// Parse 'omp declare reduction' construct.
   ///
+  /// \verbatim
   ///       declare-reduction-directive:
   ///        annot_pragma_openmp 'declare' 'reduction'
   ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
   ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
   ///        annot_pragma_openmp_end
+  /// \endverbatim
   /// <reduction_id> is either a base language identifier or one of the
   /// following operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
   ///
@@ -6187,10 +6472,12 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses 'omp declare mapper' directive.
   ///
+  /// \verbatim
   ///       declare-mapper-directive:
   ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
   ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
   ///         annot_pragma_openmp_end
+  /// \endverbatim
   /// <mapper-identifier> and <var> are base language identifiers.
   ///
   DeclGroupPtrTy ParseOpenMPDeclareMapperDirective(AccessSpecifier AS);
@@ -6202,8 +6489,10 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses simple list of variables.
   ///
+  /// \verbatim
   ///   simple-variable-list:
   ///         '(' id-expression {, id-expression} ')'
+  /// \endverbatim
   ///
   /// \param Kind Kind of the directive.
   /// \param Callback Callback function to be called for the list elements.
@@ -6218,6 +6507,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses declarative or executable directive.
   ///
+  /// \verbatim
   ///       threadprivate-directive:
   ///         annot_pragma_openmp 'threadprivate' simple-variable-list
   ///         annot_pragma_openmp_end
@@ -6256,6 +6546,7 @@ class Parser : public CodeCompletionHandler {
   ///         teams distribute parallel for simd' | 'target teams distribute
   ///         simd' | 'masked' | 'parallel masked' {clause}
   ///         annot_pragma_openmp_end
+  /// \endverbatim
   ///
   ///
   /// \param StmtCtx The context in which we're parsing the directive.
@@ -6289,6 +6580,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses clause of kind \a CKind for directive of a kind \a Kind.
   ///
+  /// \verbatim
   ///    clause:
   ///       if-clause | final-clause | num_threads-clause | safelen-clause |
   ///       default-clause | private-clause | firstprivate-clause |
@@ -6306,6 +6598,7 @@ class Parser : public CodeCompletionHandler {
   ///       | release-clause | relaxed-clause | depobj-clause | destroy-clause |
   ///       detach-clause | inclusive-clause | exclusive-clause |
   ///       uses_allocators-clause | use_device_addr-clause | has_device_addr
+  /// \endverbatim
   ///
   /// \param DKind Kind of current directive.
   /// \param CKind Kind of current clause.
@@ -6322,6 +6615,7 @@ class Parser : public CodeCompletionHandler {
   /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
   /// 'detach'.
   ///
+  /// \verbatim
   ///    final-clause:
   ///      'final' '(' expression ')'
   ///
@@ -6360,7 +6654,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///    holds-clause
   ///      'holds' '(' expression ')'
-  ///
+  /// \endverbatim
   ///
   /// \param Kind Kind of current clause.
   /// \param ParseOnly true to skip the clause's semantic actions and return
@@ -6369,6 +6663,7 @@ class Parser : public CodeCompletionHandler {
   OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, bool ParseOnly);
   /// Parses simple clause like 'default' or 'proc_bind' of a kind \a Kind.
   ///
+  /// \verbatim
   ///    default-clause:
   ///         'default' '(' 'none' | 'shared' | 'private' | 'firstprivate' ')'
   ///
@@ -6381,6 +6676,7 @@ class Parser : public CodeCompletionHandler {
   ///    update-clause:
   ///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' |
   ///         'inoutset' ')'
+  /// \endverbatim
   ///
   /// \param Kind Kind of current clause.
   /// \param ParseOnly true to skip the clause's semantic actions and return
@@ -6399,6 +6695,7 @@ class Parser : public CodeCompletionHandler {
   /// Parses clause with a single expression and an additional argument
   /// of a kind \a Kind like 'schedule' or 'dist_schedule'.
   ///
+  /// \verbatim
   ///    schedule-clause:
   ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
   ///      ')'
@@ -6411,6 +6708,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///    device-clause:
   ///      'device' '(' [ device-modifier ':' ] expression ')'
+  /// \endverbatim
   ///
   /// \param DKind Directive kind.
   /// \param Kind Kind of current clause.
@@ -6429,6 +6727,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses clause without any additional arguments like 'ordered'.
   ///
+  /// \verbatim
   ///    ordered-clause:
   ///         'ordered'
   ///
@@ -6452,6 +6751,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///    nogroup-clause:
   ///         'nogroup'
+  /// \endverbatim
   ///
   /// \param Kind Kind of current clause.
   /// \param ParseOnly true to skip the clause's semantic actions and return
@@ -6464,6 +6764,7 @@ class Parser : public CodeCompletionHandler {
   /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
   /// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
   ///
+  /// \verbatim
   ///    private-clause:
   ///       'private' '(' list ')'
   ///    firstprivate-clause:
@@ -6515,6 +6816,7 @@ class Parser : public CodeCompletionHandler {
   ///       'inclusive' '(' list ')'
   ///    exclusive-clause:
   ///       'exclusive' '(' list ')'
+  /// \endverbatim
   ///
   /// For 'linear' clause linear-list may have the following forms:
   ///  list
@@ -6547,13 +6849,17 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses simple expression in parens for single-expression clauses of OpenMP
   /// constructs.
+  /// \verbatim
   /// <iterators> = 'iterator' '(' { [ <iterator-type> ] identifier =
   /// <range-specification> }+ ')'
+  /// \endverbatim
   ExprResult ParseOpenMPIteratorsExpr();
 
   /// Parses allocators and traits in the context of the uses_allocator clause.
   /// Expected format:
+  /// \verbatim
   /// '(' { <allocator> [ '(' <allocator_traits> ')' ] }+ ')'
+  /// \endverbatim
   OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind);
 
   /// Parses the 'interop' parts of the 'append_args' and 'init' clauses.
@@ -6561,6 +6867,7 @@ class Parser : public CodeCompletionHandler {
 
   /// Parses clause with an interop variable of kind \a Kind.
   ///
+  /// \verbatim
   /// init-clause:
   ///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
   ///
@@ -6581,6 +6888,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// interop-type:
   ///   target | targetsync
+  /// \endverbatim
   ///
   /// \param Kind Kind of current clause.
   /// \param ParseOnly true to skip the clause's semantic actions and return
@@ -6854,6 +7162,7 @@ class Parser : public CodeCompletionHandler {
                  ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt);
 
   /// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
+  /// \verbatim
   ///       StatementOrDeclaration:
   ///         statement
   ///         declaration
@@ -6901,6 +7210,7 @@ class Parser : public CodeCompletionHandler {
   /// [OBC] objc-throw-statement:
   /// [OBC]   '@' 'throw' expression ';'
   /// [OBC]   '@' 'throw' ';'
+  /// \endverbatim
   ///
   StmtResult
   ParseStatementOrDeclaration(StmtVector &Stmts, ParsedStmtContext StmtCtx,
@@ -6916,28 +7226,34 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseLabeledStatement - We have an identifier and a ':' after it.
   ///
+  /// \verbatim
   ///       label:
   ///         identifier ':'
   /// [GNU]   identifier ':' attributes[opt]
   ///
   ///       labeled-statement:
   ///         label statement
+  /// \endverbatim
   ///
   StmtResult ParseLabeledStatement(ParsedAttributes &Attrs,
                                    ParsedStmtContext StmtCtx);
 
   /// ParseCaseStatement
+  /// \verbatim
   ///       labeled-statement:
   ///         'case' constant-expression ':' statement
   /// [GNU]   'case' constant-expression '...' constant-expression ':' statement
+  /// \endverbatim
   ///
   StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx,
                                 bool MissingCase = false,
                                 ExprResult Expr = ExprResult());
 
   /// ParseDefaultStatement
+  /// \verbatim
   ///       labeled-statement:
   ///         'default' ':' statement
+  /// \endverbatim
   /// Note that this does not parse the 'statement' at the end.
   ///
   StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx);
@@ -6946,6 +7262,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCompoundStatement - Parse a "{}" block.
   ///
+  /// \verbatim
   ///       compound-statement: [C99 6.8.2]
   ///         { block-item-list[opt] }
   /// [GNU]   { label-declarations block-item-list } [TODO]
@@ -6965,6 +7282,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// [GNU] label-declaration:
   /// [GNU]   '__label__' identifier-list ';'
+  /// \endverbatim
   ///
   StmtResult ParseCompoundStatement(bool isStmtExpr, unsigned ScopeFlags);
 
@@ -6986,9 +7304,11 @@ class Parser : public CodeCompletionHandler {
   StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
 
   /// ParseParenExprOrCondition:
+  /// \verbatim
   /// [C  ]     '(' expression ')'
   /// [C++]     '(' condition ')'
   /// [C++1z]   '(' init-statement[opt] condition ')'
+  /// \endverbatim
   ///
   /// This function parses and performs error recovery on the specified
   /// condition or expression (depending on whether we're in C++ or C mode).
@@ -7006,6 +7326,7 @@ class Parser : public CodeCompletionHandler {
                                  SourceLocation &RParenLoc);
 
   /// ParseIfStatement
+  /// \verbatim
   ///       if-statement: [C99 6.8.4.1]
   ///         'if' '(' expression ')' statement
   ///         'if' '(' expression ')' statement 'else' statement
@@ -7013,28 +7334,36 @@ class Parser : public CodeCompletionHandler {
   /// [C++]   'if' '(' condition ')' statement 'else' statement
   /// [C++23] 'if' '!' [opt] consteval compound-statement
   /// [C++23] 'if' '!' [opt] consteval compound-statement 'else' statement
+  /// \endverbatim
   ///
   StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
 
   /// ParseSwitchStatement
+  /// \verbatim
   ///       switch-statement:
   ///         'switch' '(' expression ')' statement
   /// [C++]   'switch' '(' condition ')' statement
+  /// \endverbatim
   StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
 
   /// ParseWhileStatement
+  /// \verbatim
   ///       while-statement: [C99 6.8.5.1]
   ///         'while' '(' expression ')' statement
   /// [C++]   'while' '(' condition ')' statement
+  /// \endverbatim
   StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
 
   /// ParseDoStatement
+  /// \verbatim
   ///       do-statement: [C99 6.8.5.2]
   ///         'do' statement 'while' '(' expression ')' ';'
+  /// \endverbatim
   /// Note: this lets the caller parse the end ';'.
   StmtResult ParseDoStatement();
 
   /// ParseForStatement
+  /// \verbatim
   ///       for-statement: [C99 6.8.5.3]
   ///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
   ///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
@@ -7057,39 +7386,48 @@ class Parser : public CodeCompletionHandler {
   /// [C++0x] for-range-initializer:
   /// [C++0x]   expression
   /// [C++0x]   braced-init-list            [TODO]
+  /// \endverbatim
   StmtResult ParseForStatement(SourceLocation *TrailingElseLoc);
 
   /// ParseGotoStatement
+  /// \verbatim
   ///       jump-statement:
   ///         'goto' identifier ';'
   /// [GNU]   'goto' '*' expression ';'
+  /// \endverbatim
   ///
   /// Note: this lets the caller parse the end ';'.
   ///
   StmtResult ParseGotoStatement();
 
   /// ParseContinueStatement
+  /// \verbatim
   ///       jump-statement:
   ///         'continue' ';'
+  /// \endverbatim
   ///
   /// Note: this lets the caller parse the end ';'.
   ///
   StmtResult ParseContinueStatement();
 
   /// ParseBreakStatement
+  /// \verbatim
   ///       jump-statement:
   ///         'break' ';'
+  /// \endverbatim
   ///
   /// Note: this lets the caller parse the end ';'.
   ///
   StmtResult ParseBreakStatement();
 
   /// ParseReturnStatement
+  /// \verbatim
   ///       jump-statement:
   ///         'return' expression[opt] ';'
   ///         'return' braced-init-list ';'
   ///         'co_return' expression[opt] ';'
   ///         'co_return' braced-init-list ';'
+  /// \endverbatim
   StmtResult ParseReturnStatement();
 
   StmtResult ParsePragmaLoopHint(StmtVector &Stmts, ParsedStmtContext StmtCtx,
@@ -7103,14 +7441,17 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseCXXTryBlock - Parse a C++ try-block.
   ///
+  /// \verbatim
   ///       try-block:
   ///         'try' compound-statement handler-seq
+  /// \endverbatim
   ///
   StmtResult ParseCXXTryBlock();
 
   /// ParseCXXTryBlockCommon - Parse the common part of try-block and
   /// function-try-block.
   ///
+  /// \verbatim
   ///       try-block:
   ///         'try' compound-statement handler-seq
   ///
@@ -7123,12 +7464,14 @@ class Parser : public CodeCompletionHandler {
   ///       [Borland] try-block:
   ///         'try' compound-statement seh-except-block
   ///         'try' compound-statement seh-finally-block
+  /// \endverbatim
   ///
   StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
 
   /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the
   /// standard
   ///
+  /// \verbatim
   ///   handler:
   ///     'catch' '(' exception-declaration ')' compound-statement
   ///
@@ -7136,6 +7479,7 @@ class Parser : public CodeCompletionHandler {
   ///     attribute-specifier-seq[opt] type-specifier-seq declarator
   ///     attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
   ///     '...'
+  /// \endverbatim
   ///
   StmtResult ParseCXXCatchBlock(bool FnCatch = false);
 
@@ -7144,26 +7488,32 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseSEHTryBlockCommon
   ///
+  /// \verbatim
   /// seh-try-block:
   ///   '__try' compound-statement seh-handler
   ///
   /// seh-handler:
   ///   seh-except-block
   ///   seh-finally-block
+  /// \endverbatim
   ///
   StmtResult ParseSEHTryBlock();
 
   /// ParseSEHExceptBlock - Handle __except
   ///
+  /// \verbatim
   /// seh-except-block:
   ///   '__except' '(' seh-filter-expression ')' compound-statement
+  /// \endverbatim
   ///
   StmtResult ParseSEHExceptBlock(SourceLocation Loc);
 
   /// ParseSEHFinallyBlock - Handle __finally
   ///
+  /// \verbatim
   /// seh-finally-block:
   ///   '__finally' compound-statement
+  /// \endverbatim
   ///
   StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
 
@@ -7173,8 +7523,10 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseFunctionTryBlock - Parse a C++ function-try-block.
   ///
+  /// \verbatim
   ///       function-try-block:
   ///         'try' ctor-initializer[opt] compound-statement handler-seq
+  /// \endverbatim
   ///
   Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
 
@@ -7232,6 +7584,7 @@ class Parser : public CodeCompletionHandler {
 
 private:
   /// ParseAsmStatement - Parse a GNU extended asm statement.
+  /// \verbatim
   ///       asm-statement:
   ///         gnu-asm-statement
   ///         ms-asm-statement
@@ -7249,12 +7602,14 @@ class Parser : public CodeCompletionHandler {
   /// [GNU] asm-clobbers:
   ///         asm-string-literal
   ///         asm-clobbers ',' asm-string-literal
+  /// \endverbatim 
   ///
   StmtResult ParseAsmStatement(bool &msAsm);
 
   /// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
   /// this routine is called to collect the tokens for an MS asm statement.
   ///
+  /// \verbatim
   /// [MS]  ms-asm-statement:
   ///         ms-asm-block
   ///         ms-asm-block ms-asm-statement
@@ -7266,12 +7621,14 @@ class Parser : public CodeCompletionHandler {
   /// [MS]  ms-asm-instruction-block
   ///         ms-asm-line
   ///         ms-asm-line '\n' ms-asm-instruction-block
+  /// \endverbatim
   ///
   StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
 
   /// ParseAsmOperands - Parse the asm-operands production as used by
   /// asm-statement, assuming the leading ':' token was eaten.
   ///
+  /// \verbatim
   /// [GNU] asm-operands:
   ///         asm-operand
   ///         asm-operands ',' asm-operand
@@ -7279,8 +7636,8 @@ class Parser : public CodeCompletionHandler {
   /// [GNU] asm-operand:
   ///         asm-string-literal '(' expression ')'
   ///         '[' identifier ']' asm-string-literal '(' expression ')'
+  /// \endverbatim
   ///
-  //
   // FIXME: Avoid unnecessary std::string trashing.
   bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
                            SmallVectorImpl<Expr *> &Constraints,
@@ -7310,6 +7667,7 @@ class Parser : public CodeCompletionHandler {
   GNUAsmQualifiers::AQ getGNUAsmQualifier(const Token &Tok) const;
 
   /// parseGNUAsmQualifierListOpt - Parse a GNU extended asm qualifier list.
+  /// \verbatim
   ///       asm-qualifier:
   ///         volatile
   ///         inline
@@ -7318,6 +7676,7 @@ class Parser : public CodeCompletionHandler {
   ///       asm-qualifier-list:
   ///         asm-qualifier
   ///         asm-qualifier-list asm-qualifier
+  /// \endverbatim
   bool parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ);
 
   ///@}
@@ -7587,6 +7946,7 @@ class Parser : public CodeCompletionHandler {
   /// of the template headers together and let semantic analysis sort
   /// the declarations from the explicit specializations.
   ///
+  /// \verbatim
   ///       template-declaration: [C++ temp]
   ///         'export'[opt] 'template' '<' template-parameter-list '>' declaration
   ///
@@ -7601,6 +7961,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///       explicit-specialization: [ C++ temp.expl.spec]
   ///         'template' '<' '>' declaration
+  /// \endverbatim
   DeclGroupPtrTy ParseTemplateDeclarationOrSpecialization(
       DeclaratorContext Context, SourceLocation &DeclEnd,
       ParsedAttributes &AccessAttrs, AccessSpecifier AS);
@@ -7642,9 +8003,11 @@ class Parser : public CodeCompletionHandler {
   /// will try to put the token stream in a reasonable position (closing
   /// a statement, etc.) and return false.
   ///
+  /// \verbatim
   ///       template-parameter-list:    [C++ temp]
   ///         template-parameter
   ///         template-parameter-list ',' template-parameter
+  /// \endverbatim
   bool ParseTemplateParameterList(unsigned Depth,
                                   SmallVectorImpl<NamedDecl *> &TemplateParams);
 
@@ -7656,6 +8019,7 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
   ///
+  /// \verbatim
   ///       template-parameter: [C++ temp.param]
   ///         type-parameter
   ///         parameter-declaration
@@ -7673,6 +8037,7 @@ class Parser : public CodeCompletionHandler {
   ///       type-parameter-key:
   ///         class
   ///         typename
+  /// \endverbatim
   ///
   NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position);
 
@@ -7680,16 +8045,19 @@ class Parser : public CodeCompletionHandler {
   /// Other kinds of template parameters are parsed in
   /// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
   ///
+  /// \verbatim
   ///       type-parameter:     [C++ temp.param]
   ///         'class' ...[opt][C++0x] identifier[opt]
   ///         'class' identifier[opt] '=' type-id
   ///         'typename' ...[opt][C++0x] identifier[opt]
   ///         'typename' identifier[opt] '=' type-id
+  /// \endverbatim
   NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position);
 
   /// ParseTemplateTemplateParameter - Handle the parsing of template
   /// template parameters.
   ///
+  /// \verbatim
   ///       type-parameter:    [C++ temp.param]
   ///         template-head type-parameter-key ...[opt] identifier[opt]
   ///         template-head type-parameter-key identifier[opt] = id-expression
@@ -7699,14 +8067,17 @@ class Parser : public CodeCompletionHandler {
   ///       template-head:     [C++2a]
   ///         'template' '<' template-parameter-list '>'
   ///             requires-clause[opt]
+  /// \endverbatim
   NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
 
   /// ParseNonTypeTemplateParameter - Handle the parsing of non-type
   /// template parameters (e.g., in "template<int Size> class array;").
   ///
+  /// \verbatim
   ///       template-parameter:
   ///         ...
   ///         parameter-declaration
+  /// \endverbatim
   NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
 
   /// Check whether the current token is a template-id annotation denoting a
@@ -7715,10 +8086,12 @@ class Parser : public CodeCompletionHandler {
 
   /// Try parsing a type-constraint at the current location.
   ///
+  /// \verbatim
   ///     type-constraint:
   ///       nested-name-specifier[opt] concept-name
   ///       nested-name-specifier[opt] concept-name
   ///           '<' template-argument-list[opt] '>'[opt]
+  /// \endverbatim
   ///
   /// \returns true if an error occurred, and false otherwise.
   bool TryAnnotateTypeConstraint();
@@ -7839,9 +8212,11 @@ class Parser : public CodeCompletionHandler {
   /// ParseTemplateArgumentList - Parse a C++ template-argument-list
   /// (C++ [temp.names]). Returns true if there was an error.
   ///
+  /// \verbatim
   ///       template-argument-list: [C++ 14.2]
   ///         template-argument
   ///         template-argument-list ',' template-argument
+  /// \endverbatim
   ///
   /// \param Template is only used for code completion, and may be null.
   bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
@@ -7852,19 +8227,23 @@ class Parser : public CodeCompletionHandler {
 
   /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
   ///
+  /// \verbatim
   ///       template-argument: [C++ 14.2]
   ///         constant-expression
   ///         type-id
   ///         id-expression
   ///         braced-init-list  [C++26, DR]
+  /// \endverbatim
   ///
   ParsedTemplateArgument ParseTemplateArgument();
 
   /// Parse a C++ explicit template instantiation
   /// (C++ [temp.explicit]).
   ///
+  /// \verbatim
   ///       explicit-instantiation:
   ///         'extern' [opt] 'template' declaration
+  /// \endverbatim
   ///
   /// Note that the 'extern' is a GNU extension and C++11 feature.
   DeclGroupPtrTy ParseExplicitInstantiation(DeclaratorContext Context,
@@ -7967,6 +8346,7 @@ class Parser : public CodeCompletionHandler {
   /// between a declaration or an expression statement, when parsing function
   /// bodies. Returns true for declaration, false for expression.
   ///
+  /// \verbatim
   ///         declaration-statement:
   ///           block-declaration
   ///
@@ -7992,6 +8372,7 @@ class Parser : public CodeCompletionHandler {
   ///         using-directive:
   ///           'using' 'namespace' '::'[opt] nested-name-specifier[opt]
   ///                 namespace-name ';'
+  /// \endverbatim
   ///
   bool isCXXDeclarationStatement(bool DisambiguatingWithExpression = false);
 
@@ -8001,17 +8382,21 @@ class Parser : public CodeCompletionHandler {
   /// the function returns true to let the declaration parsing code handle it.
   /// Returns false if the statement is disambiguated as expression.
   ///
+  /// \verbatim
   /// simple-declaration:
   ///   decl-specifier-seq init-declarator-list[opt] ';'
   ///   decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
   ///                      brace-or-equal-initializer ';'    [C++17]
+  /// \endverbatim
   ///
   /// (if AllowForRangeDecl specified)
   /// for ( for-range-declaration : for-range-initializer ) statement
   ///
+  /// \verbatim
   /// for-range-declaration:
   ///    decl-specifier-seq declarator
   ///    decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
+  /// \endverbatim
   ///
   /// In any of the above cases there can be a preceding
   /// attribute-specifier-seq, but the caller is expected to handle that.
@@ -8045,6 +8430,7 @@ class Parser : public CodeCompletionHandler {
   /// simple-declaration in an init-statement, and an expression for
   /// a condition of a if/switch statement.
   ///
+  /// \verbatim
   ///       condition:
   ///         expression
   ///         type-specifier-seq declarator '=' assignment-expression
@@ -8054,6 +8440,7 @@ class Parser : public CodeCompletionHandler {
   ///             '=' assignment-expression
   ///       simple-declaration:
   ///         decl-specifier-seq init-declarator-list[opt] ';'
+  /// \endverbatim
   ///
   /// Note that, unlike isCXXSimpleDeclaration, we must disambiguate all the way
   /// to the ';' to disambiguate cases like 'int(x))' (an expression) from
@@ -8077,8 +8464,10 @@ class Parser : public CodeCompletionHandler {
   /// If during the disambiguation process a parsing error is encountered,
   /// the function returns true to let the declaration parsing code handle it.
   ///
+  /// \verbatim
   /// type-id:
   ///   type-specifier-seq abstract-declarator[opt]
+  /// \endverbatim
   ///
   bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
 
@@ -8119,6 +8508,7 @@ class Parser : public CodeCompletionHandler {
   ///   * When parsing X::Y (with no 'typename') where X is dependent
   ///   * When parsing X<Y> where X is undeclared
   ///
+  /// \verbatim
   ///         decl-specifier:
   ///           storage-class-specifier
   ///           type-specifier
@@ -8213,6 +8603,7 @@ class Parser : public CodeCompletionHandler {
   ///           'const'
   ///           'volatile'
   /// [GNU]     restrict
+  /// \endverbatim
   ///
   TPResult
   isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
@@ -8247,6 +8638,7 @@ class Parser : public CodeCompletionHandler {
   // that more tentative parsing is necessary for disambiguation.
   // They all consume tokens, so backtracking should be used after calling them.
 
+  /// \verbatim
   /// simple-declaration:
   ///   decl-specifier-seq init-declarator-list[opt] ';'
   ///
@@ -8254,12 +8646,15 @@ class Parser : public CodeCompletionHandler {
   /// for ( for-range-declaration : for-range-initializer ) statement
   /// for-range-declaration:
   ///    attribute-specifier-seqopt type-specifier-seq declarator
+  /// \endverbatim
   ///
   TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl);
 
+  /// \verbatim
   /// [GNU] typeof-specifier:
   ///         'typeof' '(' expressions ')'
   ///         'typeof' '(' type-name ')'
+  /// \endverbatim
   ///
   TPResult TryParseTypeofSpecifier();
 
@@ -8269,6 +8664,7 @@ class Parser : public CodeCompletionHandler {
 
   TPResult TryParsePtrOperatorSeq();
 
+  /// \verbatim
   ///         operator-function-id:
   ///           'operator' operator
   ///
@@ -8287,11 +8683,13 @@ class Parser : public CodeCompletionHandler {
   ///         literal-operator-id:
   ///           'operator' string-literal identifier
   ///           'operator' user-defined-string-literal
+  /// \endverbatim
   TPResult TryParseOperatorId();
 
   /// Tentatively parse an init-declarator-list in order to disambiguate it from
   /// an expression.
   ///
+  /// \verbatim
   ///       init-declarator-list:
   ///         init-declarator
   ///         init-declarator-list ',' init-declarator
@@ -8315,9 +8713,11 @@ class Parser : public CodeCompletionHandler {
   ///       braced-init-list:
   ///         '{' initializer-list ','[opt] '}'
   ///         '{' '}'
+  /// \endverbatim
   ///
   TPResult TryParseInitDeclaratorList(bool MayHaveTrailingReturnType = false);
 
+  /// \verbatim
   ///         declarator:
   ///           direct-declarator
   ///           ptr-operator declarator
@@ -8370,11 +8770,13 @@ class Parser : public CodeCompletionHandler {
   ///           '~' class-name                                              [TODO]
   ///           '~' decltype-specifier                                      [TODO]
   ///           template-id                                                 [TODO]
+  /// \endverbatim
   ///
   TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
                               bool mayHaveDirectInit = false,
                               bool mayHaveTrailingReturnType = false);
 
+  /// \verbatim
   /// parameter-declaration-clause:
   ///   parameter-declaration-list[opt] '...'[opt]
   ///   parameter-declaration-list ',' '...'
@@ -8391,6 +8793,7 @@ class Parser : public CodeCompletionHandler {
   ///     attributes[opt]
   ///   attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
   ///     attributes[opt] '=' assignment-expression
+  /// \endverbatim
   ///
   TPResult TryParseParameterDeclarationClause(
       bool *InvalidAsDeclaration = nullptr, bool VersusTemplateArg = false,
@@ -8402,11 +8805,13 @@ class Parser : public CodeCompletionHandler {
   /// fully parsed the function declarator, it will return TPResult::Ambiguous,
   /// otherwise it will return either False() or Error().
   ///
+  /// \verbatim
   /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
   ///         exception-specification[opt]
   ///
   /// exception-specification:
   ///   'throw' '(' type-id-list[opt] ')'
+  /// \endverbatim
   ///
   TPResult TryParseFunctionDeclarator(bool MayHaveTrailingReturnType = false);
 
@@ -8416,7 +8821,9 @@ class Parser : public CodeCompletionHandler {
   // a function declaration.
   bool NameAfterArrowIsNonType();
 
+  /// \verbatim
   /// '[' constant-expression[opt] ']'
+  /// \endverbatim
   ///
   TPResult TryParseBracketDeclarator();
 
@@ -8446,6 +8853,7 @@ class Parser : public CodeCompletionHandler {
   ///
   /// C++11 [dcl.attr.grammar]:
   ///
+  /// \verbatim
   ///     attribute-specifier:
   ///         '[' '[' attribute-list ']' ']'
   ///         alignment-specifier
@@ -8465,6 +8873,7 @@ class Parser : public CodeCompletionHandler {
   ///
   ///     attribute-argument-clause:
   ///         '(' balanced-token-seq ')'
+  /// \endverbatim
   CXX11AttributeKind
   isCXX11AttributeSpecifier(bool Disambiguate = false,
                             bool OuterMightBeMessageSend = false);

>From ec29f83a02841bb61df88f5fede0054f18c1b367 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 4 May 2025 06:35:51 +0300
Subject: [PATCH 5/5] Bring updates from main branch

---
 clang/include/clang/Parse/Parser.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 582dd77944512..ab6927130bc2b 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2596,7 +2596,7 @@ class Parser : public CodeCompletionHandler {
   /// AttrRequirements bitmask values.
   void ParseTypeQualifierListOpt(
       DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
-      bool AtomicAllowed = true, bool IdentifierRequired = false,
+      bool AtomicOrPtrauthAllowed = true, bool IdentifierRequired = false,
       std::optional<llvm::function_ref<void()>> CodeCompletionHandler =
           std::nullopt);
 



More information about the cfe-commits mailing list