llvm/clang/lib/Parse/Parser.cpp

//===--- Parser.cpp - C Language Family Parser ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements the Parser interfaces.
//
//===----------------------------------------------------------------------===//

#include "clang/Parse/Parser.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/FileManager.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TimeProfiler.h"
usingnamespaceclang;


namespace {
/// A comment handler that passes comments found by the preprocessor
/// to the parser action.
class ActionCommentHandler : public CommentHandler {};
} // end anonymous namespace

IdentifierInfo *Parser::getSEHExceptKeyword() {}

Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
    :{}

DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {}

DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {}

/// 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) {}

static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok) {}

bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
                              StringRef Msg) {}

bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed) {}

void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) {}

bool Parser::expectIdentifier() {}

void Parser::checkCompoundToken(SourceLocation FirstTokLoc,
                                tok::TokenKind FirstTokKind, CompoundToken Op) {}

//===----------------------------------------------------------------------===//
// Error recovery.
//===----------------------------------------------------------------------===//

static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) {}

/// 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) {}

//===----------------------------------------------------------------------===//
// Scope manipulation
//===----------------------------------------------------------------------===//

/// EnterScope - Start a new scope.
void Parser::EnterScope(unsigned ScopeFlags) {}

/// ExitScope - Pop a scope off the scope stack.
void Parser::ExitScope() {}

/// 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)
  :{}

/// Restore the flags for the current scope to what they were before this
/// object overrode them.
Parser::ParseScopeFlags::~ParseScopeFlags() {}


//===----------------------------------------------------------------------===//
// C99 6.9: External Definitions.
//===----------------------------------------------------------------------===//

Parser::~Parser() {}

/// Initialize - Warm up the parser.
///
void Parser::Initialize() {}

void Parser::DestroyTemplateIds() {}

/// 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) {}

/// 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) {}

/// 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,
                                 ParsingDeclSpec *DS) {}

/// Determine whether the current token, if it occurs after a
/// declarator, continues a declaration or declaration list.
bool Parser::isDeclarationAfterDeclarator() {}

/// Determine whether the current token, if it occurs after a
/// declarator, indicates the start of a function definition.
bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {}

/// 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) {}

Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition(
    ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,
    ParsingDeclSpec *DS, AccessSpecifier AS) {}

/// 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) {}

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) {}


/// 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) {}

/// ParseSimpleAsm
///
/// [GNU] simple-asm-expr:
///         'asm' '(' asm-string-literal ')'
///
ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) {}

/// 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) {}

void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {}

/// 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).
Parser::AnnotatedNameKind
Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,
                        ImplicitTypenameContext AllowImplicitTypename) {}

bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {}

/// 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) {}

/// 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) {}

/// 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) {}

bool Parser::isTokenEqualOrEqualTypo() {}

SourceLocation Parser::handleUnexpectedCodeCompletionToken() {}

// Code-completion pass-through functions

void Parser::CodeCompleteDirective(bool InConditional) {}

void Parser::CodeCompleteInConditionalExclusion() {}

void Parser::CodeCompleteMacroName(bool IsDefinition) {}

void Parser::CodeCompletePreprocessorExpression() {}

void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,
                                       MacroInfo *MacroInfo,
                                       unsigned ArgumentIndex) {}

void Parser::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) {}

void Parser::CodeCompleteNaturalLanguage() {}

bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {}

void Parser::ParseMicrosoftIfExistsExternalDeclaration() {}

/// 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) {}

/// 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) {}

/// 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<std::pair<IdentifierInfo *, SourceLocation>> &Path,
    bool IsImport) {}

/// 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() {}

void Parser::diagnoseUseOfC11Keyword(const Token &Tok) {}

bool BalancedDelimiterTracker::diagnoseOverflow() {}

bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
                                                const char *Msg,
                                                tok::TokenKind SkipToTok) {}

bool BalancedDelimiterTracker::diagnoseMissingClose() {}

void BalancedDelimiterTracker::skipToEnd() {}