Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[clang][NFC] Regroup declarations in Parser #138511

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Endilll
Copy link
Contributor

@Endilll Endilll commented May 5, 2025

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.

@Endilll Endilll added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label May 5, 2025
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:openmp OpenMP related changes to Clang labels May 5, 2025
@llvmbot
Copy link
Member

llvmbot commented May 5, 2025

@llvm/pr-subscribers-clang

Author: Vlad Serebrennikov (Endilll)

Changes

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.

Patch is 731.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138511.diff

16 Files Affected:

  • (modified) clang/include/clang/Parse/Parser.h (+7898-3021)
  • (modified) clang/lib/Parse/ParseCXXInlineMethods.cpp (-52)
  • (modified) clang/lib/Parse/ParseDecl.cpp (-566)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (-419)
  • (modified) clang/lib/Parse/ParseExpr.cpp (-543)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (-526)
  • (modified) clang/lib/Parse/ParseInit.cpp (-61)
  • (modified) clang/lib/Parse/ParseObjc.cpp (-376)
  • (modified) clang/lib/Parse/ParseOpenACC.cpp (-57)
  • (modified) clang/lib/Parse/ParseOpenMP.cpp (-348)
  • (modified) clang/lib/Parse/ParsePragma.cpp (-10)
  • (modified) clang/lib/Parse/ParseStmt.cpp (-240)
  • (modified) clang/lib/Parse/ParseStmtAsm.cpp (-58)
  • (modified) clang/lib/Parse/ParseTemplate.cpp (-233)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+1-395)
  • (modified) clang/lib/Parse/Parser.cpp (+2-203)
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 00e4b980bf44a..ab6927130bc2b 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.
@@ -153,571 +153,438 @@ 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. 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
+  ///@{
+
+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;
 
-  Preprocessor &PP;
+  Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
+  ~Parser() override;
 
-  /// Tok - The current token we are peeking ahead.  All parsing methods assume
-  /// that this is valid.
-  Token Tok;
+  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; }
 
-  // PrevTokLocation - The location of the token we previously
-  // consumed. This token is used for diagnostics where we expected to
-  // see a token following another token (e.g., the ';' at the end of
-  // a statement).
-  SourceLocation PrevTokLocation;
+  const Token &getCurToken() const { return Tok; }
+  Scope *getCurScope() const { return Actions.getCurScope(); }
 
-  /// Tracks an expected type for the current token when parsing an expression.
-  /// Used by code completion for ranking.
-  PreferredTypeBuilder PreferredType;
+  void incrementMSManglingNumber() const {
+    return Actions.incrementMSManglingNumber();
+  }
 
-  unsigned short ParenCount = 0, BracketCount = 0, BraceCount = 0;
-  unsigned short MisplacedModuleBeginCount = 0;
+  // 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;
 
-  /// Actions - These are the callbacks we invoke as we parse various constructs
-  /// in the file.
-  Sema &Actions;
+  /// Initialize - Warm up the parser.
+  ///
+  void Initialize();
 
-  DiagnosticsEngine &Diags;
+  /// 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,
+                              Sema::ModuleImportState &ImportState);
 
-  StackExhaustionHandler StackHandler;
+  /// 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() {
+    DeclGroupPtrTy Result;
+    Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
+    return ParseTopLevelDecl(Result, IS);
+  }
 
-  /// ScopeCache - Cache scopes to reduce malloc traffic.
-  static constexpr int ScopeCacheSize = 16;
-  unsigned NumCachedScopes;
-  Scope *ScopeCache[ScopeCacheSize];
+  /// 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;
+  }
 
-  /// 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;
-  // __except filter expression
-  IdentifierInfo *Ident__exception_info,
-                 *Ident___exception_info,
-                 *Ident_GetExceptionInfo;
-  // __finally
-  IdentifierInfo *Ident__abnormal_termination,
-                 *Ident___abnormal_termination,
-                 *Ident_AbnormalTermination;
+  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;
+  }
 
-  /// Contextual keywords for Microsoft extensions.
-  IdentifierInfo *Ident__except;
-  mutable IdentifierInfo *Ident_sealed;
-  mutable IdentifierInfo *Ident_abstract;
+  bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
+    if (!TryConsumeToken(Expected))
+      return false;
+    Loc = PrevTokLocation;
+    return true;
+  }
 
-  /// 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;
+  /// 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();
+  }
 
-  /// Objective-C contextual keywords.
-  IdentifierInfo *Ident_instancetype;
+  SourceLocation getEndOfPreviousToken() {
+    return PP.getLocForEndOfToken(PrevTokLocation);
+  }
 
-  /// Identifier for "introduced".
-  IdentifierInfo *Ident_introduced;
+  /// 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);
+  }
 
-  /// Identifier for "deprecated".
-  IdentifierInfo *Ident_deprecated;
+  /// NextToken - This peeks ahead one token and returns it without
+  /// consuming it.
+  const Token &NextToken() { return PP.LookAhead(0); }
 
-  /// Identifier for "obsoleted".
-  IdentifierInfo *Ident_obsoleted;
+  /// 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());
+  }
 
-  /// Identifier for "unavailable".
-  IdentifierInfo *Ident_unavailable;
+  /// 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);
 
-  /// Identifier for "message".
-  IdentifierInfo *Ident_message;
+  /// 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);
 
-  /// Identifier for "strict".
-  IdentifierInfo *Ident_strict;
+  /// 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);
 
-  /// 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;
+  //===--------------------------------------------------------------------===//
+  // Scope manipulation
 
-  /// Identifiers used by the 'external_source_symbol' attribute.
-  IdentifierInfo *Ident_language, *Ident_defined_in,
-      *Ident_generated_declaration, *Ident_USR;
+  /// 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;
 
-  /// C++11 contextual keywords.
-  mutable IdentifierInfo *Ident_final;
-  mutable IdentifierInfo *Ident_GNU_final;
-  mutable IdentifierInfo *Ident_override;
+  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();
 
-  // C++2a contextual keywords.
-  mutable IdentifierInfo *Ident_import;
-  mutable IdentifierInfo *Ident_module;
+        this->Self = nullptr;
+      }
+    }
 
-  // C++ type trait keywords that can be reverted to identifiers and still be
-  // used as type traits.
-  llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
+    // 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;
+      }
+    }
 
-  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;
+    ~ParseScope() { Exit(); }
+  };
 
-  std::unique_ptr<CommentHandler> CommentSemaHandler;
+  /// 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;
 
-  /// 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;
+    MultiParseScope(const MultiParseScope &) = delete;
 
-  /// 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;
+  public:
+    MultiParseScope(Parser &Self) : Self(Self) {}
+    void Enter(unsigned ScopeFlags) {
+      Self.EnterScope(ScopeFlags);
+      ++NumScopes;
+    }
+    void Exit() {
+      while (NumScopes) {
+        Self.ExitScope();
+        --NumScopes;
+      }
+    }
+    ~MultiParseScope() { Exit(); }
+  };
 
-  /// Parsing OpenMP directive mode.
-  bool OpenMPDirectiveParsing = false;
+  /// EnterScope - Start a new scope.
+  void EnterScope(unsigned ScopeFlags);
 
-  /// Parsing OpenACC directive mode.
-  bool OpenACCDirectiveParsing = false;
+  /// ExitScope - Pop a scope off the scope stack.
+  void ExitScope();
 
-  /// Currently parsing a situation where an OpenACC array section could be
-  /// legal, such as a 'var-list'.
-  bool AllowOpenACCArraySections = false;
+  //===--------------------------------------------------------------------===//
+  // Diagnostic Emission and Error recovery.
 
-  /// RAII object to set reset OpenACC parsing a context where Array Sections
-  /// are allowed.
-  class OpenACCArraySectionRAII {
-    Parser &P;
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+  DiagnosticBuilder Diag(const Token...
[truncated]

Copy link

github-actions bot commented May 5, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- clang/include/clang/Parse/Parser.h clang/lib/Parse/ParseCXXInlineMethods.cpp clang/lib/Parse/ParseDecl.cpp clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Parse/ParseExprCXX.cpp clang/lib/Parse/ParseInit.cpp clang/lib/Parse/ParseObjc.cpp clang/lib/Parse/ParseOpenACC.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Parse/ParsePragma.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/ParseStmtAsm.cpp clang/lib/Parse/ParseTemplate.cpp clang/lib/Parse/ParseTentative.cpp clang/lib/Parse/Parser.cpp
View the diff from clang-format here.
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index ab6927130..2702fd299 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -217,7 +217,8 @@ public:
   /// [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]
+  ///                 top-level-declaration-seq[opt]
+  ///                 private-module-fragment[opt]
   /// \endverbatim
   ///
   /// Note that in C, it is an error if there is no first declaration.
@@ -912,15 +913,16 @@ private:
   ///
   /// \verbatim
   ///       function-definition: [C99 6.9.1]
-  ///         decl-specs      declarator declaration-list[opt] compound-statement
+  ///         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
+  /// [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]
+  /// [!C99]  init-declarator-list ';'                   [TODO: warn in c99
+  /// mode] [OMP]   threadprivate-directive [OMP]   allocate-directive [TODO]
   /// \endverbatim
   ///
   DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributes &Attrs,
@@ -939,10 +941,11 @@ private:
   ///
   /// \verbatim
   ///       function-definition: [C99 6.9.1]
-  ///         decl-specs      declarator declaration-list[opt] compound-statement
+  ///         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]
+  /// [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]
@@ -1783,9 +1786,7 @@ private:
   /// [C++] initializer:
   /// [C++]   '=' initializer-clause
   /// [C++]   '(' expression-list ')'
-  /// [C++0x] '=' 'default'                                                [TODO]
-  /// [C++0x] '=' 'delete'
-  /// [C++0x] braced-init-list
+  /// [C++0x] '=' 'default' [TODO] [C++0x] '=' 'delete' [C++0x] braced-init-list
   /// \endverbatim
   ///
   /// According to the standard grammar, =default and =delete are function
@@ -1902,9 +1903,11 @@ private:
   ///       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]
+  /// [GNU]   'enum' attributes[opt] identifier[opt] '{' enumerator-list ','
+  /// [opt]
   ///                                                 '}' attributes[opt]
-  /// [MS]    'enum' __declspec[opt] identifier[opt] '{' enumerator-list ',' [opt]
+  /// [MS]    'enum' __declspec[opt] identifier[opt] '{' enumerator-list ','
+  /// [opt]
   ///                                                 '}'
   ///         'enum' identifier
   /// [GNU]   'enum' attributes[opt] identifier
@@ -1913,8 +1916,9 @@ private:
   /// [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
+  ///         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]
@@ -2389,8 +2393,8 @@ private:
 
   /// Parse the contents of the "objc_bridge_related" attribute.
   /// \verbatim
-  /// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
-  /// related_class:
+  /// objc_bridge_related '(' related_class ',' opt-class_method ','
+  /// opt-instance_method ')' related_class:
   ///     Identifier
   ///
   /// opt-class_method:
@@ -3342,8 +3346,10 @@ private:
   ///       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[opt] '{'
+  /// struct-contents
+  ///                                                         '}'
+  ///                                                         attributes[opt]
   /// [GNU]   struct-or-union attributes[opt] identifier
   ///       struct-or-union:
   ///         'struct'
@@ -3415,8 +3421,8 @@ private:
   ///         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]
+  ///         ::[opt] nested-name-specifier template[opt] unqualified-id
+  ///         ';'[TODO] using-declaration [TODO]
   /// [C++0x] static_assert-declaration
   ///         template-declaration
   /// [GNU]   '__extension__' member-declaration
@@ -3870,8 +3876,9 @@ private:
   /// [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 ','
+  /// [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' '(' ')'
@@ -3887,21 +3894,19 @@ private:
   /// [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
+  /// [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
@@ -4066,8 +4071,9 @@ private:
   /// \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 ','
+  /// [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' '(' ')'
@@ -4769,16 +4775,8 @@ private:
   /// \verbatim
   ///       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
+  ///         '::'[opt] nested-name-specifier 'template' simple-template-id
+  ///         [TODO] char wchar_t bool short int long signed unsigned float
   ///         double
   ///         void
   /// [GNU]   typeof-specifier
@@ -5429,7 +5427,8 @@ private:
   ///     '<' objc-type-parameter (',' objc-type-parameter)* '>'
   ///
   ///   objc-type-parameter:
-  ///     objc-type-parameter-variance? identifier objc-type-parameter-bound[opt]
+  ///     objc-type-parameter-variance? identifier
+  ///     objc-type-parameter-bound[opt]
   ///
   ///   objc-type-parameter-bound:
   ///     ':' type-name
@@ -5700,8 +5699,8 @@ private:
   ///     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-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
   ///
@@ -5775,7 +5774,8 @@ private:
   /// \verbatim
   /// objc-scalar-literal : '@' scalar-literal
   ///                        ;
-  /// scalar-literal : | numeric-constant			/* any numeric constant. */
+  /// scalar-literal : | numeric-constant			/* any numeric
+  /// constant. */
   ///                    ;
   /// \endverbatim
   ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
@@ -5919,11 +5919,13 @@ private:
   /// \verbatim
   ///  objc-try-catch-statement:
   ///    @try compound-statement objc-catch-list[opt]
-  ///    @try compound-statement objc-catch-list[opt] @finally compound-statement
+  ///    @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
+  ///    objc-catch-list @catch ( catch-parameter-declaration )
+  ///    compound-statement
   ///  catch-parameter-declaration:
   ///     parameter-declaration
   ///     '...' [OBJC2]
@@ -6320,7 +6322,8 @@ private:
   /// Parses an OpenMP context selector set.
   ///
   /// \verbatim
-  /// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
+  /// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]*
+  /// '}'
   /// \endverbatim
   void parseOMPContextSelectorSet(OMPTraitSet &TISet,
                                   llvm::StringMap<SourceLocation> &SeenSets);
@@ -6425,8 +6428,8 @@ private:
   ///        annot_pragma_openmp_end
   ///
   ///       declare-mapper-directive:
-  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
-  ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
+  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer>
+  ///         ':'] <type> <var> ')' [<clause>[[,] <clause>] ... ]
   ///         annot_pragma_openmp_end
   ///
   ///       declare-simd-directive:
@@ -6458,8 +6461,8 @@ private:
   ///       declare-reduction-directive:
   ///        annot_pragma_openmp 'declare' 'reduction'
   ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
-  ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
-  ///        annot_pragma_openmp_end
+  ///        ['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 '||'.
@@ -6474,8 +6477,8 @@ private:
   ///
   /// \verbatim
   ///       declare-mapper-directive:
-  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
-  ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
+  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier>
+  ///         ':'] <type> <var> ')' [<clause>[[,] <clause>] ... ]
   ///         annot_pragma_openmp_end
   /// \endverbatim
   /// <mapper-identifier> and <var> are base language identifiers.
@@ -6523,8 +6526,8 @@ private:
   ///         annot_pragma_openmp_end
   ///
   ///       declare-mapper-directive:
-  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
-  ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
+  ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer>
+  ///         ':'] <type> <var> ')' [<clause>[[,] <clause>] ... ]
   ///         annot_pragma_openmp_end
   ///
   ///       executable-directive:
@@ -6697,7 +6700,8 @@ private:
   ///
   /// \verbatim
   ///    schedule-clause:
-  ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
+  ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression
+  ///      ]
   ///      ')'
   ///
   ///    if-clause:
@@ -6869,7 +6873,8 @@ private:
   ///
   /// \verbatim
   /// init-clause:
-  ///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
+  ///   init([interop-modifier, ]interop-type[[, interop-type] ...
+  ///   ]:interop-var)
   ///
   /// destroy-clause:
   ///   destroy(interop-var)
@@ -6923,10 +6928,10 @@ public:
   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
+  /// 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);
 
   ///@}
@@ -7127,8 +7132,7 @@ public:
   /// MisleadingIndentationChecker on an else active, this location is invalid.
   SourceLocation MisleadingIndentationElseLoc;
 
-  private:
-
+private:
   /// Flags describing a context in which we're parsing a statement.
   enum class ParsedStmtContext {
     /// This context permits declarations in language modes where declarations
@@ -7367,9 +7371,8 @@ public:
   ///       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'
+  /// [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
@@ -7477,7 +7480,8 @@ public:
   ///
   ///   exception-declaration:
   ///     attribute-specifier-seq[opt] type-specifier-seq declarator
-  ///     attribute-specifier-seq[opt] type-specifier-seq abstract-declarator[opt]
+  ///     attribute-specifier-seq[opt] type-specifier-seq
+  ///     abstract-declarator[opt]
   ///     '...'
   /// \endverbatim
   ///
@@ -7602,7 +7606,7 @@ private:
   /// [GNU] asm-clobbers:
   ///         asm-string-literal
   ///         asm-clobbers ',' asm-string-literal
-  /// \endverbatim 
+  /// \endverbatim
   ///
   StmtResult ParseAsmStatement(bool &msAsm);
 
@@ -7948,7 +7952,8 @@ private:
   ///
   /// \verbatim
   ///       template-declaration: [C++ temp]
-  ///         'export'[opt] 'template' '<' template-parameter-list '>' declaration
+  ///         'export'[opt] 'template' '<' template-parameter-list '>'
+  ///         declaration
   ///
   ///       template-declaration: [C++2a]
   ///         template-head declaration
@@ -8745,7 +8750,7 @@ private:
   ///         ptr-operator:
   ///           '*' cv-qualifier-seq[opt]
   ///           '&'
-  /// [C++0x]   '&&'                                                        [TODO]
+  /// [C++0x]   '&&' [TODO]
   ///           '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
   ///
   ///         cv-qualifier-seq:
@@ -8760,16 +8765,15 @@ private:
   ///
   ///         id-expression:
   ///           unqualified-id
-  ///           qualified-id                                                [TODO]
+  ///           qualified-id [TODO]
   ///
   ///         unqualified-id:
   ///           identifier
   ///           operator-function-id
   ///           conversion-function-id
   ///           literal-operator-id
-  ///           '~' class-name                                              [TODO]
-  ///           '~' decltype-specifier                                      [TODO]
-  ///           template-id                                                 [TODO]
+  ///           '~' class-name [TODO]
+  ///           '~' decltype-specifier [TODO] template-id [TODO]
   /// \endverbatim
   ///
   TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
@@ -8786,8 +8790,9 @@ private:
   ///   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]
+  ///   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]

@AaronBallman
Copy link
Collaborator

3. File has been formatted with clang-format, except for the grammar, because clang-format butchers it.

Yeah, this problem comes up rather frequently, I wonder if clang-format can get some additional smarts to make that less of a challenge? CC @mydeveloperday @owenca

@AaronBallman
Copy link
Collaborator

I think downstreams need some kind of notification that this large of a change is coming; can you post something to Discourse to alert them and encourage them to mention any major hardships on this PR?

@Endilll
Copy link
Contributor Author

Endilll commented May 5, 2025

  1. File has been formatted with clang-format, except for the grammar, because clang-format butchers it.

Yeah, this problem comes up rather frequently, I wonder if clang-format can get some additional smarts to make that less of a challenge? CC @mydeveloperday @owenca

To be more specific, generally clang-format leaves grammar alone, but when it exceeds column limit, the result looks unacceptable for me.

@Endilll
Copy link
Contributor Author

Endilll commented May 5, 2025

I think downstreams need some kind of notification that this large of a change is coming; can you post something to Discourse to alert them and encourage them to mention any major hardships on this PR?

https://discourse.llvm.org/t/parser-h-reorganization-pr/86178

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick scroll through most of it, but I believe this is, besides the churn, non-problematic once it passes the discourse notice-thing.

@owenca
Copy link
Contributor

owenca commented May 6, 2025

  1. File has been formatted with clang-format, except for the grammar, because clang-format butchers it.

Yeah, this problem comes up rather frequently, I wonder if clang-format can get some additional smarts to make that less of a challenge? CC @mydeveloperday @owenca

Maybe the CommentPragmas option can be of help here?

@AaronBallman
Copy link
Collaborator

CC @llvm/clang-vendors

Copy link
Member

@Sirraide Sirraide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice. Thanks!

Documentation has been moved from .cpp files to the header. Grammar was consistently put in \verbatim blocks to render nicely in Doxygen.

Especially this part; this has bothered me in the past. ;Þ

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Assuming we don't get push-back by Friday from downstreams on the Discourse post or here on the PR, I think it's fine to land. (I think downstreams need more than ~2 days to determine impacts, but ~5 days is a bit more reasonable.)

InMessageExpression(false), TemplateParameterDepth(0),
ParsingInObjCContainer(false) {
InMessageExpression(false), ParsingInObjCContainer(false),
TemplateParameterDepth(0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are dedicated sections for Objective-C and templates, where the latter lexically comes after the former, so I was reminded by Clang that the actual initialization order is different from what was written here

@Sirraide
Copy link
Member

Sirraide commented May 7, 2025

  1. File has been formatted with clang-format, except for the grammar, because clang-format butchers it.

Yeah, this problem comes up rather frequently, I wonder if clang-format can get some additional smarts to make that less of a challenge? CC @mydeveloperday @owenca

Maybe the CommentPragmas option can be of help here?

I think it might be nice to maybe add EnableFormatComments/DisableFormatComments as options to clang-format where users can list custom comment strings that enable/disable formatting. We could make use of that to disable formatting between \verbatim/\endverbatim, and it might also be useful for people coming from other formatters (e.g. CLion’s formatter uses @formatter:off and @formatter:on and also lets you define custom markers).

I could work on adding options for that if there is in any interest in this—though before I do, any other suggestions as to what the name of those options should be? Because renaming an option after it’s been added is a bit tedious iirc ;Þ

@Sirraide
Copy link
Member

Sirraide commented May 7, 2025

We could make use of that to disable formatting between \verbatim/\endverbatim

(to be clear, this wouldn’t immediately ‘solve’ the problem of grammar comments not being formatted properly because people will most likely still be using older clang-format versions locally, but I think it would be a useful option to have irrespective of this pr)

@Endilll
Copy link
Contributor Author

Endilll commented May 7, 2025

  1. File has been formatted with clang-format, except for the grammar, because clang-format butchers it.

Yeah, this problem comes up rather frequently, I wonder if clang-format can get some additional smarts to make that less of a challenge? CC @mydeveloperday @owenca

Maybe the CommentPragmas option can be of help here?

I think it might be nice to maybe add EnableFormatComments/DisableFormatComments as options to clang-format where users can list custom comment strings that enable/disable formatting. We could make use of that to disable formatting between \verbatim/\endverbatim, and it might also be useful for people coming from other formatters (e.g. CLion’s formatter uses @formatter:off and @formatter:on and also lets you define custom markers).

I could work on adding options for that if there is in any interest in this—though before I do, any other suggestions as to what the name of those options should be? Because renaming an option after it’s been added is a bit tedious iirc ;Þ

I think I prefer clang-format to understand what \verbatim is if one big EnableFormatComments: true is specified in the config, without manually listing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants