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

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


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vlad Serebrennikov (Endilll)

<details>
<summary>Changes</summary>

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
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]

``````````

</details>


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


More information about the cfe-commits mailing list