llvm/clang/lib/Lex/Pragma.cpp

//===- Pragma.cpp - Pragma registration and handling ----------------------===//
//
// 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 PragmaHandler/PragmaTable interfaces and implements
// pragma related methods of the Preprocessor class.
//
//===----------------------------------------------------------------------===//

#include "clang/Lex/Pragma.h"
#include "clang/Basic/CLWarnings.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorLexer.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/Token.h"
#include "clang/Lex/TokenLexer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Timer.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <optional>
#include <string>
#include <utility>
#include <vector>

usingnamespaceclang;

// Out-of-line destructor to provide a home for the class.
PragmaHandler::~PragmaHandler() = default;

//===----------------------------------------------------------------------===//
// EmptyPragmaHandler Implementation.
//===----------------------------------------------------------------------===//

EmptyPragmaHandler::EmptyPragmaHandler(StringRef Name) :{}

void EmptyPragmaHandler::HandlePragma(Preprocessor &PP,
                                      PragmaIntroducer Introducer,
                                      Token &FirstToken) {}

//===----------------------------------------------------------------------===//
// PragmaNamespace Implementation.
//===----------------------------------------------------------------------===//

/// FindHandler - Check to see if there is already a handler for the
/// specified name.  If not, return the handler for the null identifier if it
/// exists, otherwise return null.  If IgnoreNull is true (the default) then
/// the null handler isn't returned on failure to match.
PragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
                                            bool IgnoreNull) const {}

void PragmaNamespace::AddPragma(PragmaHandler *Handler) {}

void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {}

void PragmaNamespace::HandlePragma(Preprocessor &PP,
                                   PragmaIntroducer Introducer, Token &Tok) {}

//===----------------------------------------------------------------------===//
// Preprocessor Pragma Directive Handling.
//===----------------------------------------------------------------------===//

namespace {
// TokenCollector provides the option to collect tokens that were "read"
// and return them to the stream to be read later.
// Currently used when reading _Pragma/__pragma directives.
struct TokenCollector {};
} // namespace

/// HandlePragmaDirective - The "\#pragma" directive has been parsed.  Lex the
/// rest of the pragma, passing it to the registered pragma handlers.
void Preprocessor::HandlePragmaDirective(PragmaIntroducer Introducer) {}

/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
/// return the first token after the directive.  The _Pragma token has just
/// been read into 'Tok'.
void Preprocessor::Handle_Pragma(Token &Tok) {}

void clang::prepare_PragmaString(SmallVectorImpl<char> &StrVal) {}

/// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
/// is not enclosed within a string literal.
void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {}

/// HandlePragmaOnce - Handle \#pragma once.  OnceTok is the 'once'.
void Preprocessor::HandlePragmaOnce(Token &OnceTok) {}

void Preprocessor::HandlePragmaMark(Token &MarkTok) {}

/// HandlePragmaPoison - Handle \#pragma GCC poison.  PoisonTok is the 'poison'.
void Preprocessor::HandlePragmaPoison() {}

/// HandlePragmaSystemHeader - Implement \#pragma GCC system_header.  We know
/// that the whole directive has been parsed.
void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {}

/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {}

/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
/// Return the IdentifierInfo* associated with the macro to push or pop.
IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {}

/// Handle \#pragma push_macro.
///
/// The syntax is:
/// \code
///   #pragma push_macro("macro")
/// \endcode
void Preprocessor::HandlePragmaPushMacro(Token &PushMacroTok) {}

/// Handle \#pragma pop_macro.
///
/// The syntax is:
/// \code
///   #pragma pop_macro("macro")
/// \endcode
void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {}

void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {}

// Lex a component of a module name: either an identifier or a string literal;
// for components that can be expressed both ways, the two forms are equivalent.
static bool LexModuleNameComponent(
    Preprocessor &PP, Token &Tok,
    std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
    bool First) {}

static bool LexModuleName(
    Preprocessor &PP, Token &Tok,
    llvm::SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>>
        &ModuleName) {}

void Preprocessor::HandlePragmaModuleBuild(Token &Tok) {}

void Preprocessor::HandlePragmaHdrstop(Token &Tok) {}

/// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
/// If 'Namespace' is non-null, then it is a token required to exist on the
/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
void Preprocessor::AddPragmaHandler(StringRef Namespace,
                                    PragmaHandler *Handler) {}

/// RemovePragmaHandler - Remove the specific pragma handler from the
/// preprocessor. If \arg Namespace is non-null, then it should be the
/// namespace that \arg Handler was added to. It is an error to remove
/// a handler that has not been registered.
void Preprocessor::RemovePragmaHandler(StringRef Namespace,
                                       PragmaHandler *Handler) {}

bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {}

namespace {

/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
struct PragmaOnceHandler : public PragmaHandler {};

/// PragmaMarkHandler - "\#pragma mark ..." is ignored by the compiler, and the
/// rest of the line is not lexed.
struct PragmaMarkHandler : public PragmaHandler {};

/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
struct PragmaPoisonHandler : public PragmaHandler {};

/// PragmaSystemHeaderHandler - "\#pragma system_header" marks the current file
/// as a system header, which silences warnings in it.
struct PragmaSystemHeaderHandler : public PragmaHandler {};

struct PragmaDependencyHandler : public PragmaHandler {};

struct PragmaDebugHandler : public PragmaHandler {};

struct PragmaUnsafeBufferUsageHandler : public PragmaHandler {};

/// PragmaDiagnosticHandler - e.g. '\#pragma GCC diagnostic ignored "-Wformat"'
struct PragmaDiagnosticHandler : public PragmaHandler {};

/// "\#pragma hdrstop [<header-name-string>]"
struct PragmaHdrstopHandler : public PragmaHandler {};

/// "\#pragma warning(...)".  MSVC's diagnostics do not map cleanly to clang's
/// diagnostics, so we don't really implement this pragma.  We parse it and
/// ignore it to avoid -Wunknown-pragma warnings.
struct PragmaWarningHandler : public PragmaHandler {};

/// "\#pragma execution_character_set(...)". MSVC supports this pragma only
/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn
/// otherwise to avoid -Wunknown-pragma warnings.
struct PragmaExecCharsetHandler : public PragmaHandler {};

/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
struct PragmaIncludeAliasHandler : public PragmaHandler {};

/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
/// extension.  The syntax is:
/// \code
///   #pragma message(string)
/// \endcode
/// OR, in GCC mode:
/// \code
///   #pragma message string
/// \endcode
/// string is a string, which is fully macro expanded, and permits string
/// concatenation, embedded escape characters, etc... See MSDN for more details.
/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
/// form as \#pragma message.
struct PragmaMessageHandler : public PragmaHandler {};

/// Handle the clang \#pragma module import extension. The syntax is:
/// \code
///   #pragma clang module import some.module.name
/// \endcode
struct PragmaModuleImportHandler : public PragmaHandler {};

/// Handle the clang \#pragma module begin extension. The syntax is:
/// \code
///   #pragma clang module begin some.module.name
///   ...
///   #pragma clang module end
/// \endcode
struct PragmaModuleBeginHandler : public PragmaHandler {};

/// Handle the clang \#pragma module end extension.
struct PragmaModuleEndHandler : public PragmaHandler {};

/// Handle the clang \#pragma module build extension.
struct PragmaModuleBuildHandler : public PragmaHandler {};

/// Handle the clang \#pragma module load extension.
struct PragmaModuleLoadHandler : public PragmaHandler {};

/// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
/// macro on the top of the stack.
struct PragmaPushMacroHandler : public PragmaHandler {};

/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
/// macro to the value on the top of the stack.
struct PragmaPopMacroHandler : public PragmaHandler {};

/// PragmaARCCFCodeAuditedHandler -
///   \#pragma clang arc_cf_code_audited begin/end
struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {};

/// PragmaAssumeNonNullHandler -
///   \#pragma clang assume_nonnull begin/end
struct PragmaAssumeNonNullHandler : public PragmaHandler {};

/// Handle "\#pragma region [...]"
///
/// The syntax is
/// \code
///   #pragma region [optional name]
///   #pragma endregion [optional comment]
/// \endcode
///
/// \note This is
/// <a href="http://msdn.microsoft.com/en-us/library/b6xkz944(v=vs.80).aspx">editor-only</a>
/// pragma, just skipped by compiler.
struct PragmaRegionHandler : public PragmaHandler {};

/// "\#pragma managed"
/// "\#pragma managed(...)"
/// "\#pragma unmanaged"
/// MSVC ignores this pragma when not compiling using /clr, which clang doesn't
/// support. We parse it and ignore it to avoid -Wunknown-pragma warnings.
struct PragmaManagedHandler : public EmptyPragmaHandler {};

/// This handles parsing pragmas that take a macro name and optional message
static IdentifierInfo *HandleMacroAnnotationPragma(Preprocessor &PP, Token &Tok,
                                                   const char *Pragma,
                                                   std::string &MessageString) {}

/// "\#pragma clang deprecated(...)"
///
/// The syntax is
/// \code
///   #pragma clang deprecate(MACRO_NAME [, Message])
/// \endcode
struct PragmaDeprecatedHandler : public PragmaHandler {};

/// "\#pragma clang restrict_expansion(...)"
///
/// The syntax is
/// \code
///   #pragma clang restrict_expansion(MACRO_NAME [, Message])
/// \endcode
struct PragmaRestrictExpansionHandler : public PragmaHandler {};

/// "\#pragma clang final(...)"
///
/// The syntax is
/// \code
///   #pragma clang final(MACRO_NAME)
/// \endcode
struct PragmaFinalHandler : public PragmaHandler {};

} // namespace

/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
/// \#pragma GCC poison/system_header/dependency and \#pragma once.
void Preprocessor::RegisterBuiltinPragmas() {}

/// Ignore all pragmas, useful for modes such as -Eonly which would otherwise
/// warn about those pragmas being unknown.
void Preprocessor::IgnorePragmas() {}