[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