diff options
| author | Vlad Serebrennikov <serebrennikov.vladislav@gmail.com> | 2025-05-14 10:37:06 +0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-14 10:37:06 +0400 |
| commit | 301340ace64b7c741f14101ec84b3d8448b85cec (patch) | |
| tree | 5f78f1495a30140cd4d9e55f53619e9d8ca2a9dd /clang/lib/Parse/ParseTentative.cpp | |
| parent | bdf8c9984ae325b9934ec6051a853a29830af9e2 (diff) | |
| download | llvm-301340ace64b7c741f14101ec84b3d8448b85cec.zip llvm-301340ace64b7c741f14101ec84b3d8448b85cec.tar.gz llvm-301340ace64b7c741f14101ec84b3d8448b85cec.tar.bz2 | |
[clang][NFC] Regroup declarations in `Parser` (#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.
Diffstat (limited to 'clang/lib/Parse/ParseTentative.cpp')
| -rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 396 |
1 files changed, 1 insertions, 395 deletions
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index fcd76c7..cc02ee5 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 @@ public: } }; } -/// 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"); |
