Revert " [clang] Refactor to remove clangDriver dependency from clangFrontend and flangFrontend (#165277)" (#169397)
This reverts commit 3773bbe and relands the last revert attempt 40334b8. 3773bbe broke the build for the build configuration described in here: https://github.com/llvm/llvm-project/pull/165277#issuecomment-3572432250
This commit is contained in:
parent
5c15f57923
commit
dea330b38d
@ -132,7 +132,8 @@ std::optional<std::string> detectSysroot() {
|
||||
|
||||
std::string detectStandardResourceDir() {
|
||||
static int StaticForMainAddr; // Just an address in this process.
|
||||
return GetResourcesPath("clangd", (void *)&StaticForMainAddr);
|
||||
return CompilerInvocation::GetResourcesPath("clangd",
|
||||
(void *)&StaticForMainAddr);
|
||||
}
|
||||
|
||||
// The path passed to argv[0] is important:
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "Compiler.h"
|
||||
#include "support/Logger.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "clang/Serialization/PCHContainerOperations.h"
|
||||
|
||||
@ -84,8 +84,6 @@ Potentially Breaking Changes
|
||||
- Downstream projects that previously linked only against ``clangDriver`` may
|
||||
now (also) need to link against the new ``clangOptions`` library, since
|
||||
options-related code has been moved out of the Driver into a separate library.
|
||||
- The ``clangFrontend`` library no longer depends on ``clangDriver``, which may
|
||||
break downstream projects that relied on this transitive dependency.
|
||||
|
||||
C/C++ Language Potentially Breaking Changes
|
||||
-------------------------------------------
|
||||
|
||||
@ -291,6 +291,16 @@ void handleVectorizeLoopsArgs(const llvm::opt::ArgList &Args,
|
||||
void handleVectorizeSLPArgs(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs);
|
||||
|
||||
// Parse -mprefer-vector-width=. Return the Value string if well-formed.
|
||||
// Otherwise, return an empty string and issue a diagnosic message if needed.
|
||||
StringRef parseMPreferVectorWidthOption(clang::DiagnosticsEngine &Diags,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
||||
// Parse -mrecip. Return the Value string if well-formed.
|
||||
// Otherwise, return an empty string and issue a diagnosic message if needed.
|
||||
StringRef parseMRecipOption(clang::DiagnosticsEngine &Diags,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
||||
// Convert ComplexRangeKind to a string that can be passed as a frontend option.
|
||||
std::string complexRangeKindToStr(LangOptions::ComplexRangeKind Range);
|
||||
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
//===-- CreateInvocationFromArgs.h - Create an ASTUnit from Args-*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Utility for creating an ASTUnit from a vector of command line arguments.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H
|
||||
#define LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H
|
||||
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// Create an ASTUnit from a vector of command line arguments, which must
|
||||
/// specify exactly one source file.
|
||||
///
|
||||
/// \param ArgBegin - The beginning of the argument vector.
|
||||
///
|
||||
/// \param ArgEnd - The end of the argument vector.
|
||||
///
|
||||
/// \param PCHContainerOps - The PCHContainerOperations to use for loading and
|
||||
/// creating modules.
|
||||
///
|
||||
/// \param Diags - The diagnostics engine to use for reporting errors; its
|
||||
/// lifetime is expected to extend past that of the returned ASTUnit.
|
||||
///
|
||||
/// \param ResourceFilesPath - The path to the compiler resource files.
|
||||
///
|
||||
/// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
|
||||
/// PCH are stored in temporary files.
|
||||
///
|
||||
/// \param PreambleStoragePath - The path to a directory, in which to create
|
||||
/// temporary PCH files. If empty, the default system temporary directory is
|
||||
/// used. This parameter is ignored if \p StorePreamblesInMemory is true.
|
||||
///
|
||||
/// \param ModuleFormat - If provided, uses the specific module format.
|
||||
///
|
||||
/// \param ErrAST - If non-null and parsing failed without any AST to return
|
||||
/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
|
||||
/// mainly to allow the caller to see the diagnostics.
|
||||
///
|
||||
/// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
|
||||
/// Note that preamble is saved to a temporary directory on a RealFileSystem,
|
||||
/// so in order for it to be loaded correctly, VFS should have access to
|
||||
/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
|
||||
/// if \p VFS is nullptr.
|
||||
///
|
||||
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
|
||||
// shouldn't need to specify them at construction time.
|
||||
std::unique_ptr<ASTUnit> CreateASTUnitFromCommandLine(
|
||||
const char **ArgBegin, const char **ArgEnd,
|
||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
std::shared_ptr<DiagnosticOptions> DiagOpts,
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
|
||||
bool StorePreamblesInMemory = false,
|
||||
StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false,
|
||||
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
|
||||
ArrayRef<ASTUnit::RemappedFile> RemappedFiles = {},
|
||||
bool RemappedFilesKeepOriginalName = true,
|
||||
unsigned PrecompilePreambleAfterNParses = 0,
|
||||
TranslationUnitKind TUKind = TU_Complete,
|
||||
bool CacheCodeCompletionResults = false,
|
||||
bool IncludeBriefCommentsInCodeCompletion = false,
|
||||
bool AllowPCHWithCompilerErrors = false,
|
||||
SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None,
|
||||
bool SingleFileParse = false, bool UserFilesAreVolatile = false,
|
||||
bool ForSerialization = false, bool RetainExcludedConditionalBlocks = false,
|
||||
std::optional<StringRef> ModuleFormat = std::nullopt,
|
||||
std::unique_ptr<ASTUnit> *ErrAST = nullptr,
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H
|
||||
@ -1,76 +0,0 @@
|
||||
//===--- CreateInvocationFromArgs.h - CompilerInvocation from Args --------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Utility for creating a CompilerInvocation from command-line arguments, for
|
||||
// tools to use in preparation to parse a file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H
|
||||
#define LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CompilerInvocation;
|
||||
class DiagnosticsEngine;
|
||||
|
||||
/// Optional inputs to createInvocation.
|
||||
struct CreateInvocationOptions {
|
||||
/// Receives diagnostics encountered while parsing command-line flags.
|
||||
/// If not provided, these are printed to stderr.
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags = nullptr;
|
||||
/// Used e.g. to probe for system headers locations.
|
||||
/// If not provided, the real filesystem is used.
|
||||
/// FIXME: the driver does perform some non-virtualized IO.
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr;
|
||||
/// Whether to attempt to produce a non-null (possibly incorrect) invocation
|
||||
/// if any errors were encountered.
|
||||
/// By default, always return null on errors.
|
||||
bool RecoverOnError = false;
|
||||
/// Allow the driver to probe the filesystem for PCH files.
|
||||
/// This is used to replace -include with -include-pch in the cc1 args.
|
||||
/// FIXME: ProbePrecompiled=true is a poor, historical default.
|
||||
/// It misbehaves if the PCH file is from GCC, has the wrong version, etc.
|
||||
bool ProbePrecompiled = false;
|
||||
/// If set, the target is populated with the cc1 args produced by the driver.
|
||||
/// This may be populated even if createInvocation returns nullptr.
|
||||
std::vector<std::string> *CC1Args = nullptr;
|
||||
};
|
||||
|
||||
/// Interpret clang arguments in preparation to parse a file.
|
||||
///
|
||||
/// This simulates a number of steps Clang takes when its driver is invoked:
|
||||
/// - choosing actions (e.g compile + link) to run
|
||||
/// - probing the system for settings like standard library locations
|
||||
/// - spawning a cc1 subprocess to compile code, with more explicit arguments
|
||||
/// - in the cc1 process, assembling those arguments into a CompilerInvocation
|
||||
/// which is used to configure the parser
|
||||
///
|
||||
/// This simulation is lossy, e.g. in some situations one driver run would
|
||||
/// result in multiple parses. (Multi-arch, CUDA, ...).
|
||||
/// This function tries to select a reasonable invocation that tools should use.
|
||||
///
|
||||
/// Args[0] should be the driver name, such as "clang" or "/usr/bin/g++".
|
||||
/// Absolute path is preferred - this affects searching for system headers.
|
||||
///
|
||||
/// May return nullptr if an invocation could not be determined.
|
||||
/// See CreateInvocationOptions::RecoverOnError to try harder!
|
||||
std::unique_ptr<CompilerInvocation>
|
||||
createInvocation(ArrayRef<const char *> Args,
|
||||
CreateInvocationOptions Opts = {});
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H
|
||||
@ -406,6 +406,10 @@ private:
|
||||
SmallString<128> &CrashDiagDir);
|
||||
|
||||
public:
|
||||
/// Takes the path to a binary that's either in bin/ or lib/ and returns
|
||||
/// the path to clang's resource directory.
|
||||
static std::string GetResourcesPath(StringRef BinaryPath);
|
||||
|
||||
Driver(StringRef ClangExecutable, StringRef TargetTriple,
|
||||
DiagnosticsEngine &Diags, std::string Title = "clang LLVM compiler",
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
|
||||
|
||||
@ -23,13 +23,11 @@
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
#include "clang/Frontend/PrecompiledPreamble.h"
|
||||
#include "clang/Frontend/StandaloneDiagnostic.h"
|
||||
#include "clang/Lex/HeaderSearchOptions.h"
|
||||
#include "clang/Lex/ModuleLoader.h"
|
||||
#include "clang/Lex/PreprocessingRecord.h"
|
||||
#include "clang/Sema/CodeCompleteConsumer.h"
|
||||
#include "clang/Serialization/ASTBitCodes.h"
|
||||
#include "clang/Serialization/ASTWriter.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
@ -38,7 +36,6 @@
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Bitstream/BitstreamWriter.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@ -91,6 +88,25 @@ enum class CaptureDiagsKind { None, All, AllWithoutNonErrorsFromIncludes };
|
||||
|
||||
/// Utility class for loading a ASTContext from an AST file.
|
||||
class ASTUnit {
|
||||
public:
|
||||
struct StandaloneFixIt {
|
||||
std::pair<unsigned, unsigned> RemoveRange;
|
||||
std::pair<unsigned, unsigned> InsertFromRange;
|
||||
std::string CodeToInsert;
|
||||
bool BeforePreviousInsertions;
|
||||
};
|
||||
|
||||
struct StandaloneDiagnostic {
|
||||
unsigned ID;
|
||||
DiagnosticsEngine::Level Level;
|
||||
std::string Message;
|
||||
std::string Filename;
|
||||
unsigned LocOffset;
|
||||
std::vector<std::pair<unsigned, unsigned>> Ranges;
|
||||
std::vector<StandaloneFixIt> FixIts;
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<LangOptions> LangOpts;
|
||||
std::unique_ptr<CodeGenOptions> CodeGenOpts;
|
||||
// FIXME: The documentation on \c LoadFrom* member functions states that the
|
||||
@ -113,15 +129,7 @@ class ASTUnit {
|
||||
bool HadModuleLoaderFatalFailure = false;
|
||||
bool StorePreamblesInMemory = false;
|
||||
|
||||
/// Utility struct for managing ASTWriter and its associated data streams.
|
||||
struct ASTWriterData {
|
||||
SmallString<128> Buffer;
|
||||
llvm::BitstreamWriter Stream;
|
||||
ASTWriter Writer;
|
||||
|
||||
ASTWriterData(ModuleCache &ModCache, const CodeGenOptions &CGOpts)
|
||||
: Stream(Buffer), Writer(Stream, Buffer, ModCache, CGOpts, {}) {}
|
||||
};
|
||||
struct ASTWriterData;
|
||||
std::unique_ptr<ASTWriterData> WriterData;
|
||||
|
||||
FileSystemOptions FileSystemOpts;
|
||||
@ -263,6 +271,11 @@ class ASTUnit {
|
||||
static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
|
||||
ASTUnit &AST, CaptureDiagsKind CaptureDiagnostics);
|
||||
|
||||
void
|
||||
TranslateStoredDiagnostics(FileManager &FileMgr, SourceManager &SrcMan,
|
||||
const SmallVectorImpl<StandaloneDiagnostic> &Diags,
|
||||
SmallVectorImpl<StoredDiagnostic> &Out);
|
||||
|
||||
void clearFileLevelDecls();
|
||||
|
||||
public:
|
||||
@ -821,24 +834,65 @@ public:
|
||||
bool IncludeBriefCommentsInCodeCompletion = false,
|
||||
bool UserFilesAreVolatile = false);
|
||||
|
||||
friend std::unique_ptr<ASTUnit> CreateASTUnitFromCommandLine(
|
||||
/// LoadFromCommandLine - Create an ASTUnit from a vector of command line
|
||||
/// arguments, which must specify exactly one source file.
|
||||
///
|
||||
/// \param ArgBegin - The beginning of the argument vector.
|
||||
///
|
||||
/// \param ArgEnd - The end of the argument vector.
|
||||
///
|
||||
/// \param PCHContainerOps - The PCHContainerOperations to use for loading and
|
||||
/// creating modules.
|
||||
///
|
||||
/// \param Diags - The diagnostics engine to use for reporting errors; its
|
||||
/// lifetime is expected to extend past that of the returned ASTUnit.
|
||||
///
|
||||
/// \param ResourceFilesPath - The path to the compiler resource files.
|
||||
///
|
||||
/// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
|
||||
/// PCH are stored in temporary files.
|
||||
///
|
||||
/// \param PreambleStoragePath - The path to a directory, in which to create
|
||||
/// temporary PCH files. If empty, the default system temporary directory is
|
||||
/// used. This parameter is ignored if \p StorePreamblesInMemory is true.
|
||||
///
|
||||
/// \param ModuleFormat - If provided, uses the specific module format.
|
||||
///
|
||||
/// \param ErrAST - If non-null and parsing failed without any AST to return
|
||||
/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
|
||||
/// mainly to allow the caller to see the diagnostics.
|
||||
///
|
||||
/// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
|
||||
/// Note that preamble is saved to a temporary directory on a RealFileSystem,
|
||||
/// so in order for it to be loaded correctly, VFS should have access to
|
||||
/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
|
||||
/// if \p VFS is nullptr.
|
||||
///
|
||||
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
|
||||
// shouldn't need to specify them at construction time.
|
||||
static std::unique_ptr<ASTUnit> LoadFromCommandLine(
|
||||
const char **ArgBegin, const char **ArgEnd,
|
||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
std::shared_ptr<DiagnosticOptions> DiagOpts,
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
|
||||
bool StorePreamblesInMemory, StringRef PreambleStoragePath,
|
||||
bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
|
||||
ArrayRef<ASTUnit::RemappedFile> RemappedFiles,
|
||||
bool RemappedFilesKeepOriginalName,
|
||||
unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
|
||||
bool CacheCodeCompletionResults,
|
||||
bool IncludeBriefCommentsInCodeCompletion,
|
||||
bool AllowPCHWithCompilerErrors,
|
||||
SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse,
|
||||
bool UserFilesAreVolatile, bool ForSerialization,
|
||||
bool RetainExcludedConditionalBlocks,
|
||||
std::optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST,
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS);
|
||||
bool StorePreamblesInMemory = false,
|
||||
StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false,
|
||||
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
|
||||
ArrayRef<RemappedFile> RemappedFiles = {},
|
||||
bool RemappedFilesKeepOriginalName = true,
|
||||
unsigned PrecompilePreambleAfterNParses = 0,
|
||||
TranslationUnitKind TUKind = TU_Complete,
|
||||
bool CacheCodeCompletionResults = false,
|
||||
bool IncludeBriefCommentsInCodeCompletion = false,
|
||||
bool AllowPCHWithCompilerErrors = false,
|
||||
SkipFunctionBodiesScope SkipFunctionBodies =
|
||||
SkipFunctionBodiesScope::None,
|
||||
bool SingleFileParse = false, bool UserFilesAreVolatile = false,
|
||||
bool ForSerialization = false,
|
||||
bool RetainExcludedConditionalBlocks = false,
|
||||
std::optional<StringRef> ModuleFormat = std::nullopt,
|
||||
std::unique_ptr<ASTUnit> *ErrAST = nullptr,
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
|
||||
|
||||
/// Reparse the source files using the same command-line options that
|
||||
/// were originally used to produce this translation unit.
|
||||
@ -909,44 +963,6 @@ public:
|
||||
bool serialize(raw_ostream &OS);
|
||||
};
|
||||
|
||||
/// Diagnostic consumer that saves each diagnostic it is given.
|
||||
class FilterAndStoreDiagnosticConsumer : public DiagnosticConsumer {
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags;
|
||||
SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags;
|
||||
bool CaptureNonErrorsFromIncludes = true;
|
||||
const LangOptions *LangOpts = nullptr;
|
||||
SourceManager *SourceMgr = nullptr;
|
||||
|
||||
public:
|
||||
FilterAndStoreDiagnosticConsumer(
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags,
|
||||
SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags,
|
||||
bool CaptureNonErrorsFromIncludes);
|
||||
|
||||
void BeginSourceFile(const LangOptions &LangOpts,
|
||||
const Preprocessor *PP = nullptr) override;
|
||||
|
||||
void HandleDiagnostic(DiagnosticsEngine::Level Level,
|
||||
const Diagnostic &Info) override;
|
||||
};
|
||||
|
||||
/// RAII object that optionally captures and filters diagnostics, if
|
||||
/// there is no diagnostic client to capture them already.
|
||||
class CaptureDroppedDiagnostics {
|
||||
DiagnosticsEngine &Diags;
|
||||
FilterAndStoreDiagnosticConsumer Client;
|
||||
DiagnosticConsumer *PreviousClient = nullptr;
|
||||
std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
|
||||
|
||||
public:
|
||||
CaptureDroppedDiagnostics(
|
||||
CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags,
|
||||
SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags);
|
||||
|
||||
~CaptureDroppedDiagnostics();
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_FRONTEND_ASTUNIT_H
|
||||
|
||||
@ -299,6 +299,16 @@ public:
|
||||
DiagnosticsEngine &Diags,
|
||||
const char *Argv0 = nullptr);
|
||||
|
||||
/// Get the directory where the compiler headers
|
||||
/// reside, relative to the compiler binary (found by the passed in
|
||||
/// arguments).
|
||||
///
|
||||
/// \param Argv0 - The program path (from argv[0]), for finding the builtin
|
||||
/// compiler path.
|
||||
/// \param MainAddr - The address of main (or some other function in the main
|
||||
/// executable), for finding the builtin compiler path.
|
||||
static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
|
||||
|
||||
/// Populate \p Opts with the default set of pointer authentication-related
|
||||
/// options given \p LangOpts and \p Triple.
|
||||
///
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
//===--- StandaloneDiagnostic.h - Serializable Diagnostic -------*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// A serializable diagnostic representation to retain diagnostics after their
|
||||
// SourceManager has been destroyed.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_STANDALONEDIAGNOSTICS_H
|
||||
#define LLVM_CLANG_FRONTEND_STANDALONEDIAGNOSTICS_H
|
||||
|
||||
#include "clang/Basic/DiagnosticIDs.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// Represents a StoredDiagnostic in a form that can be retained until after its
|
||||
/// SourceManager has been destroyed.
|
||||
///
|
||||
/// Source locations are stored as a combination of filename and offsets into
|
||||
/// that file.
|
||||
/// To report the diagnostic, it must first be translated back into a
|
||||
/// StoredDiagnostic with a new associated SourceManager.
|
||||
struct StandaloneDiagnostic {
|
||||
/// Represents a CharSourceRange within a StandaloneDiagnostic.
|
||||
struct SourceOffsetRange {
|
||||
SourceOffsetRange(CharSourceRange Range, const SourceManager &SrcMgr,
|
||||
const LangOptions &LangOpts);
|
||||
|
||||
unsigned Begin = 0;
|
||||
unsigned End = 0;
|
||||
};
|
||||
|
||||
/// Represents a FixItHint within a StandaloneDiagnostic.
|
||||
struct StandaloneFixIt {
|
||||
StandaloneFixIt(const SourceManager &SrcMgr, const LangOptions &LangOpts,
|
||||
const FixItHint &FixIt);
|
||||
|
||||
SourceOffsetRange RemoveRange;
|
||||
SourceOffsetRange InsertFromRange;
|
||||
std::string CodeToInsert;
|
||||
bool BeforePreviousInsertions;
|
||||
};
|
||||
|
||||
StandaloneDiagnostic(const LangOptions &LangOpts,
|
||||
const StoredDiagnostic &InDiag);
|
||||
|
||||
DiagnosticsEngine::Level Level;
|
||||
SrcMgr::CharacteristicKind FileKind;
|
||||
unsigned ID = 0;
|
||||
unsigned FileOffset = 0;
|
||||
std::string Message;
|
||||
std::string Filename;
|
||||
std::vector<SourceOffsetRange> Ranges;
|
||||
std::vector<StandaloneFixIt> FixIts;
|
||||
};
|
||||
|
||||
/// Translates \c StandaloneDiag into a StoredDiagnostic, associating it with
|
||||
/// the provided FileManager and SourceManager.
|
||||
///
|
||||
/// This allows the diagnostic to be emitted using the diagnostics engine, since
|
||||
/// StandaloneDiagnostics themselfs cannot be emitted directly.
|
||||
StoredDiagnostic
|
||||
translateStandaloneDiag(FileManager &FileMgr, SourceManager &SrcMgr,
|
||||
const StandaloneDiagnostic &StandaloneDiag,
|
||||
llvm::StringMap<SourceLocation> &SrcLocCache);
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // STANDALONEDIAGNOSTICS
|
||||
@ -192,6 +192,51 @@ IntrusiveRefCntPtr<ExternalSemaSource>
|
||||
createChainedIncludesSource(CompilerInstance &CI,
|
||||
IntrusiveRefCntPtr<ASTReader> &OutReader);
|
||||
|
||||
/// Optional inputs to createInvocation.
|
||||
struct CreateInvocationOptions {
|
||||
/// Receives diagnostics encountered while parsing command-line flags.
|
||||
/// If not provided, these are printed to stderr.
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags = nullptr;
|
||||
/// Used e.g. to probe for system headers locations.
|
||||
/// If not provided, the real filesystem is used.
|
||||
/// FIXME: the driver does perform some non-virtualized IO.
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr;
|
||||
/// Whether to attempt to produce a non-null (possibly incorrect) invocation
|
||||
/// if any errors were encountered.
|
||||
/// By default, always return null on errors.
|
||||
bool RecoverOnError = false;
|
||||
/// Allow the driver to probe the filesystem for PCH files.
|
||||
/// This is used to replace -include with -include-pch in the cc1 args.
|
||||
/// FIXME: ProbePrecompiled=true is a poor, historical default.
|
||||
/// It misbehaves if the PCH file is from GCC, has the wrong version, etc.
|
||||
bool ProbePrecompiled = false;
|
||||
/// If set, the target is populated with the cc1 args produced by the driver.
|
||||
/// This may be populated even if createInvocation returns nullptr.
|
||||
std::vector<std::string> *CC1Args = nullptr;
|
||||
};
|
||||
|
||||
/// Interpret clang arguments in preparation to parse a file.
|
||||
///
|
||||
/// This simulates a number of steps Clang takes when its driver is invoked:
|
||||
/// - choosing actions (e.g compile + link) to run
|
||||
/// - probing the system for settings like standard library locations
|
||||
/// - spawning a cc1 subprocess to compile code, with more explicit arguments
|
||||
/// - in the cc1 process, assembling those arguments into a CompilerInvocation
|
||||
/// which is used to configure the parser
|
||||
///
|
||||
/// This simulation is lossy, e.g. in some situations one driver run would
|
||||
/// result in multiple parses. (Multi-arch, CUDA, ...).
|
||||
/// This function tries to select a reasonable invocation that tools should use.
|
||||
///
|
||||
/// Args[0] should be the driver name, such as "clang" or "/usr/bin/g++".
|
||||
/// Absolute path is preferred - this affects searching for system headers.
|
||||
///
|
||||
/// May return nullptr if an invocation could not be determined.
|
||||
/// See CreateInvocationOptions::ShouldRecoverOnErrors to try harder!
|
||||
std::unique_ptr<CompilerInvocation>
|
||||
createInvocation(ArrayRef<const char *> Args,
|
||||
CreateInvocationOptions Opts = {});
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_FRONTEND_UTILS_H
|
||||
|
||||
@ -28,7 +28,6 @@ class ArgList;
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// Return the value of the last argument as an integer, or a default. If Diags
|
||||
/// is non-null, emits an error if the argument is given, but non-integral.
|
||||
int getLastArgIntValue(const llvm::opt::ArgList &Args,
|
||||
@ -54,29 +53,6 @@ inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
|
||||
return getLastArgUInt64Value(Args, Id, Default, &Diags, Base);
|
||||
}
|
||||
|
||||
// Parse -mprefer-vector-width=. Return the Value string if well-formed.
|
||||
// Otherwise, return an empty string and issue a diagnosic message if needed.
|
||||
StringRef parseMPreferVectorWidthOption(clang::DiagnosticsEngine &Diags,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
||||
// Parse -mrecip. Return the Value string if well-formed.
|
||||
// Otherwise, return an empty string and issue a diagnosic message if needed.
|
||||
StringRef parseMRecipOption(clang::DiagnosticsEngine &Diags,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
||||
/// Get the directory where the compiler headers reside, relative to the
|
||||
/// compiler binary path \p BinaryPath.
|
||||
std::string GetResourcesPath(StringRef BinaryPath);
|
||||
|
||||
/// Get the directory where the compiler headers reside, relative to the
|
||||
/// compiler binary path (found by the passed in arguments).
|
||||
///
|
||||
/// \param Argv0 The program path (from argv[0]), for finding the builtin
|
||||
/// compiler path.
|
||||
/// \param MainAddr The address of main (or some other function in the main
|
||||
/// executable), for finding the builtin compiler path.
|
||||
std::string GetResourcesPath(const char *Argv0, void *MainAddr);
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_OPTIONS_OPTIONUTILS_H
|
||||
|
||||
@ -9,7 +9,6 @@ add_clang_library(clangCrossTU
|
||||
LINK_LIBS
|
||||
clangAST
|
||||
clangBasic
|
||||
clangDriver
|
||||
clangFrontend
|
||||
clangIndex
|
||||
)
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include "clang/Basic/DiagnosticDriver.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/CrossTU/CrossTUDiagnostic.h"
|
||||
#include "clang/Driver/CreateASTUnitFromArgs.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
@ -620,7 +619,7 @@ CrossTranslationUnitContext::ASTLoader::loadFromSource(
|
||||
auto Diags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(DiagID, *DiagOpts,
|
||||
DiagClient);
|
||||
|
||||
return CreateASTUnitFromCommandLine(
|
||||
return ASTUnit::LoadFromCommandLine(
|
||||
CommandLineArgs.begin(), (CommandLineArgs.end()),
|
||||
CI.getPCHContainerOperations(), DiagOpts, Diags,
|
||||
CI.getHeaderSearchOpts().ResourceDir);
|
||||
|
||||
@ -17,8 +17,6 @@ endif()
|
||||
add_clang_library(clangDriver
|
||||
Action.cpp
|
||||
Compilation.cpp
|
||||
CreateASTUnitFromArgs.cpp
|
||||
CreateInvocationFromArgs.cpp
|
||||
Distro.cpp
|
||||
Driver.cpp
|
||||
Job.cpp
|
||||
@ -98,8 +96,6 @@ add_clang_library(clangDriver
|
||||
|
||||
LINK_LIBS
|
||||
clangBasic
|
||||
clangFrontend
|
||||
clangSerialization
|
||||
clangLex
|
||||
clangOptions
|
||||
${system_libs}
|
||||
|
||||
@ -1,166 +0,0 @@
|
||||
//===--- CreateASTUnitFromArgs.h - Create an ASTUnit from Args ------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Utility for creating an ASTUnit from a vector of command line arguments.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/CreateASTUnitFromArgs.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "clang/Serialization/ModuleCache.h"
|
||||
#include "llvm/Support/CrashRecoveryContext.h"
|
||||
|
||||
using namespace clang;
|
||||
|
||||
/// Create an ASTUnit from a vector of command line arguments, which must
|
||||
/// specify exactly one source file.
|
||||
///
|
||||
/// \param ArgBegin - The beginning of the argument vector.
|
||||
///
|
||||
/// \param ArgEnd - The end of the argument vector.
|
||||
///
|
||||
/// \param PCHContainerOps - The PCHContainerOperations to use for loading and
|
||||
/// creating modules.
|
||||
///
|
||||
/// \param Diags - The diagnostics engine to use for reporting errors; its
|
||||
/// lifetime is expected to extend past that of the returned ASTUnit.
|
||||
///
|
||||
/// \param ResourceFilesPath - The path to the compiler resource files.
|
||||
///
|
||||
/// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
|
||||
/// PCH are stored in temporary files.
|
||||
///
|
||||
/// \param PreambleStoragePath - The path to a directory, in which to create
|
||||
/// temporary PCH files. If empty, the default system temporary directory is
|
||||
/// used. This parameter is ignored if \p StorePreamblesInMemory is true.
|
||||
///
|
||||
/// \param ModuleFormat - If provided, uses the specific module format.
|
||||
///
|
||||
/// \param ErrAST - If non-null and parsing failed without any AST to return
|
||||
/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
|
||||
/// mainly to allow the caller to see the diagnostics.
|
||||
///
|
||||
/// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
|
||||
/// Note that preamble is saved to a temporary directory on a RealFileSystem,
|
||||
/// so in order for it to be loaded correctly, VFS should have access to
|
||||
/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
|
||||
/// if \p VFS is nullptr.
|
||||
///
|
||||
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
|
||||
// shouldn't need to specify them at construction time.
|
||||
std::unique_ptr<ASTUnit> clang::CreateASTUnitFromCommandLine(
|
||||
const char **ArgBegin, const char **ArgEnd,
|
||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
std::shared_ptr<DiagnosticOptions> DiagOpts,
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
|
||||
bool StorePreamblesInMemory, StringRef PreambleStoragePath,
|
||||
bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
|
||||
ArrayRef<ASTUnit::RemappedFile> RemappedFiles,
|
||||
bool RemappedFilesKeepOriginalName, unsigned PrecompilePreambleAfterNParses,
|
||||
TranslationUnitKind TUKind, bool CacheCodeCompletionResults,
|
||||
bool IncludeBriefCommentsInCodeCompletion, bool AllowPCHWithCompilerErrors,
|
||||
SkipFunctionBodiesScope SkipFunctionBodies, bool SingleFileParse,
|
||||
bool UserFilesAreVolatile, bool ForSerialization,
|
||||
bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
|
||||
std::unique_ptr<ASTUnit> *ErrAST,
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
|
||||
assert(Diags.get() && "no DiagnosticsEngine was provided");
|
||||
|
||||
// If no VFS was provided, create one that tracks the physical file system.
|
||||
// If '-working-directory' was passed as an argument, 'createInvocation' will
|
||||
// set this as the current working directory of the VFS.
|
||||
if (!VFS)
|
||||
VFS = llvm::vfs::createPhysicalFileSystem();
|
||||
|
||||
SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
|
||||
|
||||
std::shared_ptr<CompilerInvocation> CI;
|
||||
|
||||
{
|
||||
CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
|
||||
&StoredDiagnostics, nullptr);
|
||||
|
||||
CreateInvocationOptions CIOpts;
|
||||
CIOpts.VFS = VFS;
|
||||
CIOpts.Diags = Diags;
|
||||
CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
|
||||
CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts));
|
||||
if (!CI)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Override any files that need remapping
|
||||
for (const auto &RemappedFile : RemappedFiles) {
|
||||
CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
|
||||
RemappedFile.second);
|
||||
}
|
||||
PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
|
||||
PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
|
||||
PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
|
||||
PPOpts.SingleFileParseMode = SingleFileParse;
|
||||
PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
|
||||
|
||||
// Override the resources path.
|
||||
CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
|
||||
|
||||
CI->getFrontendOpts().SkipFunctionBodies =
|
||||
SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile;
|
||||
|
||||
if (ModuleFormat)
|
||||
CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
|
||||
|
||||
// Create the AST unit.
|
||||
std::unique_ptr<ASTUnit> AST;
|
||||
AST.reset(new ASTUnit(false));
|
||||
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
|
||||
AST->StoredDiagnostics.swap(StoredDiagnostics);
|
||||
ASTUnit::ConfigureDiags(Diags, *AST, CaptureDiagnostics);
|
||||
AST->DiagOpts = DiagOpts;
|
||||
AST->Diagnostics = Diags;
|
||||
AST->FileSystemOpts = CI->getFileSystemOpts();
|
||||
AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());
|
||||
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
|
||||
AST->FileMgr =
|
||||
llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
|
||||
AST->StorePreamblesInMemory = StorePreamblesInMemory;
|
||||
AST->PreambleStoragePath = PreambleStoragePath;
|
||||
AST->ModCache = createCrossProcessModuleCache();
|
||||
AST->OnlyLocalDecls = OnlyLocalDecls;
|
||||
AST->CaptureDiagnostics = CaptureDiagnostics;
|
||||
AST->TUKind = TUKind;
|
||||
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
|
||||
AST->IncludeBriefCommentsInCodeCompletion =
|
||||
IncludeBriefCommentsInCodeCompletion;
|
||||
AST->UserFilesAreVolatile = UserFilesAreVolatile;
|
||||
AST->Invocation = CI;
|
||||
AST->SkipFunctionBodies = SkipFunctionBodies;
|
||||
if (ForSerialization)
|
||||
AST->WriterData.reset(
|
||||
new ASTUnit::ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));
|
||||
// Zero out now to ease cleanup during crash recovery.
|
||||
CI = nullptr;
|
||||
Diags = nullptr;
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get());
|
||||
|
||||
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
|
||||
PrecompilePreambleAfterNParses, VFS)) {
|
||||
// Some error occurred, if caller wants to examine diagnostics, pass it the
|
||||
// ASTUnit.
|
||||
if (ErrAST) {
|
||||
AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
|
||||
ErrAST->swap(AST);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return AST;
|
||||
}
|
||||
@ -66,7 +66,6 @@
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
#include "clang/Driver/Types.h"
|
||||
#include "clang/Lex/DependencyDirectivesScanner.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Options/Options.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
@ -126,6 +125,40 @@ template <typename F> static bool usesInput(const ArgList &Args, F &&Fn) {
|
||||
});
|
||||
}
|
||||
|
||||
// static
|
||||
std::string Driver::GetResourcesPath(StringRef BinaryPath) {
|
||||
// Since the resource directory is embedded in the module hash, it's important
|
||||
// that all places that need it call this function, so that they get the
|
||||
// exact same string ("a/../b/" and "b/" get different hashes, for example).
|
||||
|
||||
// Dir is bin/ or lib/, depending on where BinaryPath is.
|
||||
StringRef Dir = llvm::sys::path::parent_path(BinaryPath);
|
||||
SmallString<128> P(Dir);
|
||||
|
||||
StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
|
||||
if (!ConfiguredResourceDir.empty()) {
|
||||
// FIXME: We should fix the behavior of llvm::sys::path::append so we don't
|
||||
// need to check for absolute paths here.
|
||||
if (llvm::sys::path::is_absolute(ConfiguredResourceDir))
|
||||
P = ConfiguredResourceDir;
|
||||
else
|
||||
llvm::sys::path::append(P, ConfiguredResourceDir);
|
||||
} else {
|
||||
// On Windows, libclang.dll is in bin/.
|
||||
// On non-Windows, libclang.so/.dylib is in lib/.
|
||||
// With a static-library build of libclang, LibClangPath will contain the
|
||||
// path of the embedding binary, which for LLVM binaries will be in bin/.
|
||||
// ../lib gets us to lib/ in both cases.
|
||||
P = llvm::sys::path::parent_path(Dir);
|
||||
// This search path is also created in the COFF driver of lld, so any
|
||||
// changes here also needs to happen in lld/COFF/Driver.cpp
|
||||
llvm::sys::path::append(P, CLANG_INSTALL_LIBDIR_BASENAME, "clang",
|
||||
CLANG_VERSION_MAJOR_STRING);
|
||||
}
|
||||
|
||||
return std::string(P);
|
||||
}
|
||||
|
||||
CUIDOptions::CUIDOptions(llvm::opt::DerivedArgList &Args, const Driver &D)
|
||||
: UseCUID(Kind::Hash) {
|
||||
if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
|
||||
|
||||
@ -32,7 +32,6 @@
|
||||
#include "clang/Driver/SanitizerArgs.h"
|
||||
#include "clang/Driver/Types.h"
|
||||
#include "clang/Driver/XRayArgs.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Options/Options.h"
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
|
||||
@ -3398,6 +3398,169 @@ void tools::handleInterchangeLoopsArgs(const ArgList &Args,
|
||||
CmdArgs.push_back("-floop-interchange");
|
||||
}
|
||||
|
||||
// Parse -mprefer-vector-width=. Return the Value string if well-formed.
|
||||
// Otherwise, return an empty string and issue a diagnosic message if needed.
|
||||
StringRef tools::parseMPreferVectorWidthOption(clang::DiagnosticsEngine &Diags,
|
||||
const llvm::opt::ArgList &Args) {
|
||||
Arg *A = Args.getLastArg(options::OPT_mprefer_vector_width_EQ);
|
||||
if (!A)
|
||||
return "";
|
||||
|
||||
StringRef Value = A->getValue();
|
||||
unsigned Width LLVM_ATTRIBUTE_UNINITIALIZED;
|
||||
|
||||
// Only "none" and Integer values are accepted by
|
||||
// -mprefer-vector-width=<value>.
|
||||
if (Value != "none" && Value.getAsInteger(10, Width)) {
|
||||
Diags.Report(clang::diag::err_drv_invalid_value)
|
||||
<< A->getOption().getName() << Value;
|
||||
return "";
|
||||
}
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
// This is a helper function for validating the optional refinement step
|
||||
// parameter in reciprocal argument strings. Return false if there is an error
|
||||
// parsing the refinement step. Otherwise, return true and set the Position
|
||||
// of the refinement step in the input string.
|
||||
static bool getRefinementStep(StringRef In, clang::DiagnosticsEngine &Diags,
|
||||
const Arg &A, size_t &Position) {
|
||||
const char RefinementStepToken = ':';
|
||||
Position = In.find(RefinementStepToken);
|
||||
if (Position != StringRef::npos) {
|
||||
StringRef Option = A.getOption().getName();
|
||||
StringRef RefStep = In.substr(Position + 1);
|
||||
// Allow exactly one numeric character for the additional refinement
|
||||
// step parameter. This is reasonable for all currently-supported
|
||||
// operations and architectures because we would expect that a larger value
|
||||
// of refinement steps would cause the estimate "optimization" to
|
||||
// under-perform the native operation. Also, if the estimate does not
|
||||
// converge quickly, it probably will not ever converge, so further
|
||||
// refinement steps will not produce a better answer.
|
||||
if (RefStep.size() != 1) {
|
||||
Diags.Report(diag::err_drv_invalid_value) << Option << RefStep;
|
||||
return false;
|
||||
}
|
||||
char RefStepChar = RefStep[0];
|
||||
if (RefStepChar < '0' || RefStepChar > '9') {
|
||||
Diags.Report(diag::err_drv_invalid_value) << Option << RefStep;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Parse -mrecip. Return the Value string if well-formed.
|
||||
// Otherwise, return an empty string and issue a diagnosic message if needed.
|
||||
StringRef tools::parseMRecipOption(clang::DiagnosticsEngine &Diags,
|
||||
const ArgList &Args) {
|
||||
StringRef DisabledPrefixIn = "!";
|
||||
StringRef DisabledPrefixOut = "!";
|
||||
StringRef EnabledPrefixOut = "";
|
||||
StringRef Out = "";
|
||||
|
||||
Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
|
||||
if (!A)
|
||||
return "";
|
||||
|
||||
unsigned NumOptions = A->getNumValues();
|
||||
if (NumOptions == 0) {
|
||||
// No option is the same as "all".
|
||||
return "all";
|
||||
}
|
||||
|
||||
// Pass through "all", "none", or "default" with an optional refinement step.
|
||||
if (NumOptions == 1) {
|
||||
StringRef Val = A->getValue(0);
|
||||
size_t RefStepLoc;
|
||||
if (!getRefinementStep(Val, Diags, *A, RefStepLoc))
|
||||
return "";
|
||||
StringRef ValBase = Val.slice(0, RefStepLoc);
|
||||
if (ValBase == "all" || ValBase == "none" || ValBase == "default") {
|
||||
return Val;
|
||||
}
|
||||
}
|
||||
|
||||
// Each reciprocal type may be enabled or disabled individually.
|
||||
// Check each input value for validity, concatenate them all back together,
|
||||
// and pass through.
|
||||
|
||||
llvm::StringMap<bool> OptionStrings;
|
||||
OptionStrings.insert(std::make_pair("divd", false));
|
||||
OptionStrings.insert(std::make_pair("divf", false));
|
||||
OptionStrings.insert(std::make_pair("divh", false));
|
||||
OptionStrings.insert(std::make_pair("vec-divd", false));
|
||||
OptionStrings.insert(std::make_pair("vec-divf", false));
|
||||
OptionStrings.insert(std::make_pair("vec-divh", false));
|
||||
OptionStrings.insert(std::make_pair("sqrtd", false));
|
||||
OptionStrings.insert(std::make_pair("sqrtf", false));
|
||||
OptionStrings.insert(std::make_pair("sqrth", false));
|
||||
OptionStrings.insert(std::make_pair("vec-sqrtd", false));
|
||||
OptionStrings.insert(std::make_pair("vec-sqrtf", false));
|
||||
OptionStrings.insert(std::make_pair("vec-sqrth", false));
|
||||
|
||||
for (unsigned i = 0; i != NumOptions; ++i) {
|
||||
StringRef Val = A->getValue(i);
|
||||
|
||||
bool IsDisabled = Val.starts_with(DisabledPrefixIn);
|
||||
// Ignore the disablement token for string matching.
|
||||
if (IsDisabled)
|
||||
Val = Val.substr(1);
|
||||
|
||||
size_t RefStep;
|
||||
if (!getRefinementStep(Val, Diags, *A, RefStep))
|
||||
return "";
|
||||
|
||||
StringRef ValBase = Val.slice(0, RefStep);
|
||||
llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(ValBase);
|
||||
if (OptionIter == OptionStrings.end()) {
|
||||
// Try again specifying float suffix.
|
||||
OptionIter = OptionStrings.find(ValBase.str() + 'f');
|
||||
if (OptionIter == OptionStrings.end()) {
|
||||
// The input name did not match any known option string.
|
||||
Diags.Report(diag::err_drv_unknown_argument) << Val;
|
||||
return "";
|
||||
}
|
||||
// The option was specified without a half or float or double suffix.
|
||||
// Make sure that the double or half entry was not already specified.
|
||||
// The float entry will be checked below.
|
||||
if (OptionStrings[ValBase.str() + 'd'] ||
|
||||
OptionStrings[ValBase.str() + 'h']) {
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getOption().getName() << Val;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
if (OptionIter->second == true) {
|
||||
// Duplicate option specified.
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getOption().getName() << Val;
|
||||
return "";
|
||||
}
|
||||
|
||||
// Mark the matched option as found. Do not allow duplicate specifiers.
|
||||
OptionIter->second = true;
|
||||
|
||||
// If the precision was not specified, also mark the double and half entry
|
||||
// as found.
|
||||
if (ValBase.back() != 'f' && ValBase.back() != 'd' &&
|
||||
ValBase.back() != 'h') {
|
||||
OptionStrings[ValBase.str() + 'd'] = true;
|
||||
OptionStrings[ValBase.str() + 'h'] = true;
|
||||
}
|
||||
|
||||
// Build the output string.
|
||||
StringRef Prefix = IsDisabled ? DisabledPrefixOut : EnabledPrefixOut;
|
||||
Out = Args.MakeArgString(Out + Prefix + Val);
|
||||
if (i != NumOptions - 1)
|
||||
Out = Args.MakeArgString(Out + ",");
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
std::string tools::complexRangeKindToStr(LangOptions::ComplexRangeKind Range) {
|
||||
switch (Range) {
|
||||
case LangOptions::ComplexRangeKind::CX_Full:
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
|
||||
#include "clang/Basic/CodeGenOptions.h"
|
||||
#include "clang/Driver/CommonArgs.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Options/Options.h"
|
||||
#include "llvm/Frontend/Debug/Options.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
@ -44,7 +44,6 @@
|
||||
#include "clang/Frontend/FrontendOptions.h"
|
||||
#include "clang/Frontend/MultiplexConsumer.h"
|
||||
#include "clang/Frontend/PrecompiledPreamble.h"
|
||||
#include "clang/Frontend/StandaloneDiagnostic.h"
|
||||
#include "clang/Frontend/Utils.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
#include "clang/Lex/HeaderSearchOptions.h"
|
||||
@ -211,6 +210,15 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
|
||||
return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
|
||||
}
|
||||
|
||||
struct ASTUnit::ASTWriterData {
|
||||
SmallString<128> Buffer;
|
||||
llvm::BitstreamWriter Stream;
|
||||
ASTWriter Writer;
|
||||
|
||||
ASTWriterData(ModuleCache &ModCache, const CodeGenOptions &CGOpts)
|
||||
: Stream(Buffer), Writer(Stream, Buffer, ModCache, CGOpts, {}) {}
|
||||
};
|
||||
|
||||
void ASTUnit::clearFileLevelDecls() {
|
||||
FileDecls.clear();
|
||||
}
|
||||
@ -573,24 +581,73 @@ public:
|
||||
Counter = NewCounter;
|
||||
}
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
FilterAndStoreDiagnosticConsumer::FilterAndStoreDiagnosticConsumer(
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags,
|
||||
SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags,
|
||||
bool CaptureNonErrorsFromIncludes)
|
||||
: StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
|
||||
CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
|
||||
assert((StoredDiags || StandaloneDiags) &&
|
||||
"No output collections were passed to StoredDiagnosticConsumer.");
|
||||
}
|
||||
/// Diagnostic consumer that saves each diagnostic it is given.
|
||||
class FilterAndStoreDiagnosticConsumer : public DiagnosticConsumer {
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags;
|
||||
SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags;
|
||||
bool CaptureNonErrorsFromIncludes = true;
|
||||
const LangOptions *LangOpts = nullptr;
|
||||
SourceManager *SourceMgr = nullptr;
|
||||
|
||||
void FilterAndStoreDiagnosticConsumer::BeginSourceFile(
|
||||
const LangOptions &LangOpts, const Preprocessor *PP) {
|
||||
this->LangOpts = &LangOpts;
|
||||
if (PP)
|
||||
SourceMgr = &PP->getSourceManager();
|
||||
}
|
||||
public:
|
||||
FilterAndStoreDiagnosticConsumer(
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags,
|
||||
SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags,
|
||||
bool CaptureNonErrorsFromIncludes)
|
||||
: StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
|
||||
CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
|
||||
assert((StoredDiags || StandaloneDiags) &&
|
||||
"No output collections were passed to StoredDiagnosticConsumer.");
|
||||
}
|
||||
|
||||
void BeginSourceFile(const LangOptions &LangOpts,
|
||||
const Preprocessor *PP = nullptr) override {
|
||||
this->LangOpts = &LangOpts;
|
||||
if (PP)
|
||||
SourceMgr = &PP->getSourceManager();
|
||||
}
|
||||
|
||||
void HandleDiagnostic(DiagnosticsEngine::Level Level,
|
||||
const Diagnostic &Info) override;
|
||||
};
|
||||
|
||||
/// RAII object that optionally captures and filters diagnostics, if
|
||||
/// there is no diagnostic client to capture them already.
|
||||
class CaptureDroppedDiagnostics {
|
||||
DiagnosticsEngine &Diags;
|
||||
FilterAndStoreDiagnosticConsumer Client;
|
||||
DiagnosticConsumer *PreviousClient = nullptr;
|
||||
std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
|
||||
|
||||
public:
|
||||
CaptureDroppedDiagnostics(
|
||||
CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags,
|
||||
SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
|
||||
: Diags(Diags),
|
||||
Client(StoredDiags, StandaloneDiags,
|
||||
CaptureDiagnostics !=
|
||||
CaptureDiagsKind::AllWithoutNonErrorsFromIncludes) {
|
||||
if (CaptureDiagnostics != CaptureDiagsKind::None ||
|
||||
Diags.getClient() == nullptr) {
|
||||
OwningPreviousClient = Diags.takeClient();
|
||||
PreviousClient = Diags.getClient();
|
||||
Diags.setClient(&Client, false);
|
||||
}
|
||||
}
|
||||
|
||||
~CaptureDroppedDiagnostics() {
|
||||
if (Diags.getClient() == &Client)
|
||||
Diags.setClient(PreviousClient, !!OwningPreviousClient.release());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static ASTUnit::StandaloneDiagnostic
|
||||
makeStandaloneDiagnostic(const LangOptions &LangOpts,
|
||||
const StoredDiagnostic &InDiag);
|
||||
|
||||
static bool isInMainFile(const clang::Diagnostic &D) {
|
||||
if (!D.hasSourceManager() || !D.getLocation().isValid())
|
||||
@ -626,32 +683,12 @@ void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
|
||||
StoredDiag.emplace(Level, Info);
|
||||
ResultDiag = &*StoredDiag;
|
||||
}
|
||||
StandaloneDiags->emplace_back(*LangOpts, *ResultDiag);
|
||||
StandaloneDiags->push_back(
|
||||
makeStandaloneDiagnostic(*LangOpts, *ResultDiag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CaptureDroppedDiagnostics::CaptureDroppedDiagnostics(
|
||||
CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,
|
||||
SmallVectorImpl<StoredDiagnostic> *StoredDiags,
|
||||
SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags)
|
||||
: Diags(Diags),
|
||||
Client(StoredDiags, StandaloneDiags,
|
||||
CaptureDiagnostics !=
|
||||
CaptureDiagsKind::AllWithoutNonErrorsFromIncludes) {
|
||||
if (CaptureDiagnostics != CaptureDiagsKind::None ||
|
||||
Diags.getClient() == nullptr) {
|
||||
OwningPreviousClient = Diags.takeClient();
|
||||
PreviousClient = Diags.getClient();
|
||||
Diags.setClient(&Client, false);
|
||||
}
|
||||
}
|
||||
|
||||
CaptureDroppedDiagnostics::~CaptureDroppedDiagnostics() {
|
||||
if (Diags.getClient() == &Client)
|
||||
Diags.setClient(PreviousClient, !!OwningPreviousClient.release());
|
||||
}
|
||||
|
||||
IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {
|
||||
return Reader;
|
||||
}
|
||||
@ -1073,7 +1110,7 @@ private:
|
||||
unsigned Hash = 0;
|
||||
std::vector<Decl *> TopLevelDecls;
|
||||
std::vector<LocalDeclID> TopLevelDeclIDs;
|
||||
llvm::SmallVector<StandaloneDiagnostic, 4> PreambleDiags;
|
||||
llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@ -1222,17 +1259,10 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
|
||||
return true;
|
||||
|
||||
if (SavedMainFileBuffer) {
|
||||
StoredDiagnostics.clear();
|
||||
StoredDiagnostics.reserve(PreambleDiagnostics.size());
|
||||
llvm::transform(std::move(PreambleDiagnostics),
|
||||
std::back_inserter(StoredDiagnostics),
|
||||
[&](auto &&StandaloneDiag) {
|
||||
return translateStandaloneDiag(
|
||||
getFileManager(), getSourceManager(),
|
||||
std::move(StandaloneDiag), PreambleSrcLocCache);
|
||||
});
|
||||
} else
|
||||
if (SavedMainFileBuffer)
|
||||
TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
|
||||
PreambleDiagnostics, StoredDiagnostics);
|
||||
else
|
||||
PreambleSrcLocCache.clear();
|
||||
|
||||
if (llvm::Error Err = Act->Execute()) {
|
||||
@ -1251,6 +1281,51 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::pair<unsigned, unsigned>
|
||||
makeStandaloneRange(CharSourceRange Range, const SourceManager &SM,
|
||||
const LangOptions &LangOpts) {
|
||||
CharSourceRange FileRange = Lexer::makeFileCharRange(Range, SM, LangOpts);
|
||||
unsigned Offset = SM.getFileOffset(FileRange.getBegin());
|
||||
unsigned EndOffset = SM.getFileOffset(FileRange.getEnd());
|
||||
return std::make_pair(Offset, EndOffset);
|
||||
}
|
||||
|
||||
static ASTUnit::StandaloneFixIt makeStandaloneFixIt(const SourceManager &SM,
|
||||
const LangOptions &LangOpts,
|
||||
const FixItHint &InFix) {
|
||||
ASTUnit::StandaloneFixIt OutFix;
|
||||
OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts);
|
||||
OutFix.InsertFromRange =
|
||||
makeStandaloneRange(InFix.InsertFromRange, SM, LangOpts);
|
||||
OutFix.CodeToInsert = InFix.CodeToInsert;
|
||||
OutFix.BeforePreviousInsertions = InFix.BeforePreviousInsertions;
|
||||
return OutFix;
|
||||
}
|
||||
|
||||
static ASTUnit::StandaloneDiagnostic
|
||||
makeStandaloneDiagnostic(const LangOptions &LangOpts,
|
||||
const StoredDiagnostic &InDiag) {
|
||||
ASTUnit::StandaloneDiagnostic OutDiag;
|
||||
OutDiag.ID = InDiag.getID();
|
||||
OutDiag.Level = InDiag.getLevel();
|
||||
OutDiag.Message = std::string(InDiag.getMessage());
|
||||
OutDiag.LocOffset = 0;
|
||||
if (InDiag.getLocation().isInvalid())
|
||||
return OutDiag;
|
||||
const SourceManager &SM = InDiag.getLocation().getManager();
|
||||
SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation());
|
||||
OutDiag.Filename = std::string(SM.getFilename(FileLoc));
|
||||
if (OutDiag.Filename.empty())
|
||||
return OutDiag;
|
||||
OutDiag.LocOffset = SM.getFileOffset(FileLoc);
|
||||
for (const auto &Range : InDiag.getRanges())
|
||||
OutDiag.Ranges.push_back(makeStandaloneRange(Range, SM, LangOpts));
|
||||
for (const auto &FixIt : InDiag.getFixIts())
|
||||
OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, FixIt));
|
||||
|
||||
return OutDiag;
|
||||
}
|
||||
|
||||
/// Attempt to build or re-use a precompiled preamble when (re-)parsing
|
||||
/// the source file.
|
||||
///
|
||||
@ -1705,6 +1780,114 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
|
||||
return AST;
|
||||
}
|
||||
|
||||
std::unique_ptr<ASTUnit> ASTUnit::LoadFromCommandLine(
|
||||
const char **ArgBegin, const char **ArgEnd,
|
||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
std::shared_ptr<DiagnosticOptions> DiagOpts,
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
|
||||
bool StorePreamblesInMemory, StringRef PreambleStoragePath,
|
||||
bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
|
||||
ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
|
||||
unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
|
||||
bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
|
||||
bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
|
||||
bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
|
||||
bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
|
||||
std::unique_ptr<ASTUnit> *ErrAST,
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
|
||||
assert(Diags.get() && "no DiagnosticsEngine was provided");
|
||||
|
||||
// If no VFS was provided, create one that tracks the physical file system.
|
||||
// If '-working-directory' was passed as an argument, 'createInvocation' will
|
||||
// set this as the current working directory of the VFS.
|
||||
if (!VFS)
|
||||
VFS = llvm::vfs::createPhysicalFileSystem();
|
||||
|
||||
SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
|
||||
|
||||
std::shared_ptr<CompilerInvocation> CI;
|
||||
|
||||
{
|
||||
CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
|
||||
&StoredDiagnostics, nullptr);
|
||||
|
||||
CreateInvocationOptions CIOpts;
|
||||
CIOpts.VFS = VFS;
|
||||
CIOpts.Diags = Diags;
|
||||
CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
|
||||
CI = createInvocation(llvm::ArrayRef(ArgBegin, ArgEnd), std::move(CIOpts));
|
||||
if (!CI)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Override any files that need remapping
|
||||
for (const auto &RemappedFile : RemappedFiles) {
|
||||
CI->getPreprocessorOpts().addRemappedFile(RemappedFile.first,
|
||||
RemappedFile.second);
|
||||
}
|
||||
PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
|
||||
PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
|
||||
PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
|
||||
PPOpts.SingleFileParseMode = SingleFileParse;
|
||||
PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
|
||||
|
||||
// Override the resources path.
|
||||
CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
|
||||
|
||||
CI->getFrontendOpts().SkipFunctionBodies =
|
||||
SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile;
|
||||
|
||||
if (ModuleFormat)
|
||||
CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
|
||||
|
||||
// Create the AST unit.
|
||||
std::unique_ptr<ASTUnit> AST;
|
||||
AST.reset(new ASTUnit(false));
|
||||
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
|
||||
AST->StoredDiagnostics.swap(StoredDiagnostics);
|
||||
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
|
||||
AST->DiagOpts = DiagOpts;
|
||||
AST->Diagnostics = Diags;
|
||||
AST->FileSystemOpts = CI->getFileSystemOpts();
|
||||
AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());
|
||||
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
|
||||
AST->FileMgr =
|
||||
llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
|
||||
AST->StorePreamblesInMemory = StorePreamblesInMemory;
|
||||
AST->PreambleStoragePath = PreambleStoragePath;
|
||||
AST->ModCache = createCrossProcessModuleCache();
|
||||
AST->OnlyLocalDecls = OnlyLocalDecls;
|
||||
AST->CaptureDiagnostics = CaptureDiagnostics;
|
||||
AST->TUKind = TUKind;
|
||||
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
|
||||
AST->IncludeBriefCommentsInCodeCompletion =
|
||||
IncludeBriefCommentsInCodeCompletion;
|
||||
AST->UserFilesAreVolatile = UserFilesAreVolatile;
|
||||
AST->Invocation = CI;
|
||||
AST->SkipFunctionBodies = SkipFunctionBodies;
|
||||
if (ForSerialization)
|
||||
AST->WriterData.reset(new ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));
|
||||
// Zero out now to ease cleanup during crash recovery.
|
||||
CI = nullptr;
|
||||
Diags = nullptr;
|
||||
|
||||
// Recover resources if we crash before exiting this method.
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> ASTUnitCleanup(AST.get());
|
||||
|
||||
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
|
||||
PrecompilePreambleAfterNParses, VFS)) {
|
||||
// Some error occurred, if caller wants to examine diagnostics, pass it the
|
||||
// ASTUnit.
|
||||
if (ErrAST) {
|
||||
AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
|
||||
ErrAST->swap(AST);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return AST;
|
||||
}
|
||||
|
||||
bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
ArrayRef<RemappedFile> RemappedFiles,
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
|
||||
@ -2223,6 +2406,64 @@ bool ASTUnit::serialize(raw_ostream &OS) {
|
||||
return serializeUnit(Writer, Buffer, getSema(), OS);
|
||||
}
|
||||
|
||||
void ASTUnit::TranslateStoredDiagnostics(
|
||||
FileManager &FileMgr, SourceManager &SrcMgr,
|
||||
const SmallVectorImpl<StandaloneDiagnostic> &Diags,
|
||||
SmallVectorImpl<StoredDiagnostic> &Out) {
|
||||
// Map the standalone diagnostic into the new source manager. We also need to
|
||||
// remap all the locations to the new view. This includes the diag location,
|
||||
// any associated source ranges, and the source ranges of associated fix-its.
|
||||
// FIXME: There should be a cleaner way to do this.
|
||||
SmallVector<StoredDiagnostic, 4> Result;
|
||||
Result.reserve(Diags.size());
|
||||
|
||||
for (const auto &SD : Diags) {
|
||||
// Rebuild the StoredDiagnostic.
|
||||
if (SD.Filename.empty())
|
||||
continue;
|
||||
auto FE = FileMgr.getOptionalFileRef(SD.Filename);
|
||||
if (!FE)
|
||||
continue;
|
||||
SourceLocation FileLoc;
|
||||
auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
|
||||
if (ItFileID == PreambleSrcLocCache.end()) {
|
||||
FileID FID = SrcMgr.translateFile(*FE);
|
||||
FileLoc = SrcMgr.getLocForStartOfFile(FID);
|
||||
PreambleSrcLocCache[SD.Filename] = FileLoc;
|
||||
} else {
|
||||
FileLoc = ItFileID->getValue();
|
||||
}
|
||||
|
||||
if (FileLoc.isInvalid())
|
||||
continue;
|
||||
SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);
|
||||
FullSourceLoc Loc(L, SrcMgr);
|
||||
|
||||
SmallVector<CharSourceRange, 4> Ranges;
|
||||
Ranges.reserve(SD.Ranges.size());
|
||||
for (const auto &Range : SD.Ranges) {
|
||||
SourceLocation BL = FileLoc.getLocWithOffset(Range.first);
|
||||
SourceLocation EL = FileLoc.getLocWithOffset(Range.second);
|
||||
Ranges.push_back(CharSourceRange::getCharRange(BL, EL));
|
||||
}
|
||||
|
||||
SmallVector<FixItHint, 2> FixIts;
|
||||
FixIts.reserve(SD.FixIts.size());
|
||||
for (const auto &FixIt : SD.FixIts) {
|
||||
FixIts.push_back(FixItHint());
|
||||
FixItHint &FH = FixIts.back();
|
||||
FH.CodeToInsert = FixIt.CodeToInsert;
|
||||
SourceLocation BL = FileLoc.getLocWithOffset(FixIt.RemoveRange.first);
|
||||
SourceLocation EL = FileLoc.getLocWithOffset(FixIt.RemoveRange.second);
|
||||
FH.RemoveRange = CharSourceRange::getCharRange(BL, EL);
|
||||
}
|
||||
|
||||
Result.push_back(
|
||||
StoredDiagnostic(SD.Level, SD.ID, SD.Message, Loc, Ranges, FixIts));
|
||||
}
|
||||
Result.swap(Out);
|
||||
}
|
||||
|
||||
void ASTUnit::addFileLevelDecl(Decl *D) {
|
||||
assert(D);
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ add_clang_library(clangFrontend
|
||||
ChainedIncludesSource.cpp
|
||||
CompilerInstance.cpp
|
||||
CompilerInvocation.cpp
|
||||
CreateInvocationFromCommandLine.cpp
|
||||
DependencyFile.cpp
|
||||
DependencyGraph.cpp
|
||||
DiagnosticRenderer.cpp
|
||||
@ -35,7 +36,6 @@ add_clang_library(clangFrontend
|
||||
SARIFDiagnosticPrinter.cpp
|
||||
SerializedDiagnosticPrinter.cpp
|
||||
SerializedDiagnosticReader.cpp
|
||||
StandaloneDiagnostic.cpp
|
||||
TestModuleFileExtension.cpp
|
||||
TextDiagnostic.cpp
|
||||
TextDiagnosticBuffer.cpp
|
||||
@ -51,6 +51,7 @@ add_clang_library(clangFrontend
|
||||
clangAPINotes
|
||||
clangAST
|
||||
clangBasic
|
||||
clangDriver
|
||||
clangOptions
|
||||
clangEdit
|
||||
clangLex
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Basic/XRayInstr.h"
|
||||
#include "clang/Config/config.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Frontend/CommandLineSourceLoc.h"
|
||||
#include "clang/Frontend/DependencyOutputOptions.h"
|
||||
#include "clang/Frontend/FrontendOptions.h"
|
||||
@ -3272,6 +3273,13 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
||||
return Diags.getNumErrors() == NumErrorsBefore;
|
||||
}
|
||||
|
||||
std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
|
||||
void *MainAddr) {
|
||||
std::string ClangExecutable =
|
||||
llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
|
||||
return driver::Driver::GetResourcesPath(ClangExecutable);
|
||||
}
|
||||
|
||||
static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts,
|
||||
ArgumentConsumer Consumer) {
|
||||
const HeaderSearchOptions *HeaderSearchOpts = &Opts;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//===--- CreateInvocationFromArgs.h - CompilerInvocation from Args --------===//
|
||||
//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -10,9 +10,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Driver/Action.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
@ -24,13 +24,12 @@
|
||||
#include "llvm/Option/ArgList.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#include "llvm/TargetParser/Host.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace llvm::opt;
|
||||
|
||||
namespace clang {
|
||||
|
||||
std::unique_ptr<CompilerInvocation>
|
||||
createInvocation(ArrayRef<const char *> ArgList, CreateInvocationOptions Opts) {
|
||||
clang::createInvocation(ArrayRef<const char *> ArgList,
|
||||
CreateInvocationOptions Opts) {
|
||||
assert(!ArgList.empty());
|
||||
std::optional<DiagnosticOptions> LocalDiagOpts;
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
|
||||
@ -115,5 +114,3 @@ createInvocation(ArrayRef<const char *> ArgList, CreateInvocationOptions Opts) {
|
||||
return nullptr;
|
||||
return CI;
|
||||
}
|
||||
|
||||
} // namespace clang
|
||||
@ -1,117 +0,0 @@
|
||||
//===--- StandaloneDiagnostic.h - Serializable Diagnostic ------------- ---===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Frontend/StandaloneDiagnostic.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
StandaloneDiagnostic::SourceOffsetRange::SourceOffsetRange(
|
||||
CharSourceRange Range, const SourceManager &SrcMgr,
|
||||
const LangOptions &LangOpts) {
|
||||
const auto FileRange = Lexer::makeFileCharRange(Range, SrcMgr, LangOpts);
|
||||
Begin = SrcMgr.getFileOffset(FileRange.getBegin());
|
||||
End = SrcMgr.getFileOffset(FileRange.getEnd());
|
||||
}
|
||||
|
||||
StandaloneDiagnostic::StandaloneFixIt::StandaloneFixIt(
|
||||
const SourceManager &SrcMgr, const LangOptions &LangOpts,
|
||||
const FixItHint &FixIt)
|
||||
: RemoveRange(FixIt.RemoveRange, SrcMgr, LangOpts),
|
||||
InsertFromRange(FixIt.InsertFromRange, SrcMgr, LangOpts),
|
||||
CodeToInsert(FixIt.CodeToInsert),
|
||||
BeforePreviousInsertions(FixIt.BeforePreviousInsertions) {}
|
||||
|
||||
StandaloneDiagnostic::StandaloneDiagnostic(const LangOptions &LangOpts,
|
||||
const StoredDiagnostic &InDiag)
|
||||
: Level(InDiag.getLevel()), ID(InDiag.getID()),
|
||||
Message(InDiag.getMessage()) {
|
||||
const FullSourceLoc &FullLoc = InDiag.getLocation();
|
||||
// This is not an invalid diagnostic; invalid SourceLocations are used to
|
||||
// represent diagnostics without a specific SourceLocation.
|
||||
if (FullLoc.isInvalid())
|
||||
return;
|
||||
|
||||
const auto &SrcMgr = FullLoc.getManager();
|
||||
FileKind = SrcMgr.getFileCharacteristic(static_cast<SourceLocation>(FullLoc));
|
||||
const auto FileLoc = SrcMgr.getFileLoc(static_cast<SourceLocation>(FullLoc));
|
||||
FileOffset = SrcMgr.getFileOffset(FileLoc);
|
||||
Filename = SrcMgr.getFilename(FileLoc);
|
||||
assert(!Filename.empty() && "diagnostic with location has no source file?");
|
||||
|
||||
Ranges.reserve(InDiag.getRanges().size());
|
||||
for (const auto &Range : InDiag.getRanges())
|
||||
Ranges.emplace_back(Range, SrcMgr, LangOpts);
|
||||
|
||||
FixIts.reserve(InDiag.getFixIts().size());
|
||||
for (const auto &FixIt : InDiag.getFixIts())
|
||||
FixIts.emplace_back(SrcMgr, LangOpts, FixIt);
|
||||
}
|
||||
|
||||
StoredDiagnostic
|
||||
translateStandaloneDiag(FileManager &FileMgr, SourceManager &SrcMgr,
|
||||
const StandaloneDiagnostic &StandaloneDiag,
|
||||
llvm::StringMap<SourceLocation> &SrcLocCache) {
|
||||
const auto FileRef = FileMgr.getOptionalFileRef(StandaloneDiag.Filename);
|
||||
if (!FileRef)
|
||||
return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,
|
||||
StandaloneDiag.Message);
|
||||
|
||||
// Try to get FileLoc from cache first
|
||||
SourceLocation FileLoc;
|
||||
auto It = SrcLocCache.find(StandaloneDiag.Filename);
|
||||
if (It != SrcLocCache.end()) {
|
||||
FileLoc = It->getValue();
|
||||
}
|
||||
|
||||
// Cache miss - compute and cache the location
|
||||
if (FileLoc.isInvalid()) {
|
||||
const auto FileID =
|
||||
SrcMgr.getOrCreateFileID(*FileRef, StandaloneDiag.FileKind);
|
||||
FileLoc = SrcMgr.getLocForStartOfFile(FileID);
|
||||
|
||||
if (FileLoc.isInvalid())
|
||||
return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,
|
||||
StandaloneDiag.Message);
|
||||
|
||||
SrcLocCache[StandaloneDiag.Filename] = FileLoc;
|
||||
}
|
||||
|
||||
const auto DiagLoc = FileLoc.getLocWithOffset(StandaloneDiag.FileOffset);
|
||||
const FullSourceLoc Loc(DiagLoc, SrcMgr);
|
||||
|
||||
auto ConvertOffsetRange =
|
||||
[&](const StandaloneDiagnostic::SourceOffsetRange &Range) {
|
||||
return CharSourceRange(
|
||||
SourceRange(FileLoc.getLocWithOffset(Range.Begin),
|
||||
FileLoc.getLocWithOffset(Range.End)),
|
||||
/*IsTokenRange*/ false);
|
||||
};
|
||||
|
||||
SmallVector<CharSourceRange, 4> TranslatedRanges;
|
||||
TranslatedRanges.reserve(StandaloneDiag.Ranges.size());
|
||||
transform(StandaloneDiag.Ranges, std::back_inserter(TranslatedRanges),
|
||||
ConvertOffsetRange);
|
||||
|
||||
SmallVector<FixItHint, 2> TranslatedFixIts;
|
||||
TranslatedFixIts.reserve(StandaloneDiag.FixIts.size());
|
||||
for (const auto &FixIt : StandaloneDiag.FixIts) {
|
||||
FixItHint TranslatedFixIt;
|
||||
TranslatedFixIt.CodeToInsert = FixIt.CodeToInsert;
|
||||
TranslatedFixIt.RemoveRange = ConvertOffsetRange(FixIt.RemoveRange);
|
||||
TranslatedFixIt.InsertFromRange = ConvertOffsetRange(FixIt.InsertFromRange);
|
||||
TranslatedFixIt.BeforePreviousInsertions = FixIt.BeforePreviousInsertions;
|
||||
TranslatedFixIts.push_back(std::move(TranslatedFixIt));
|
||||
}
|
||||
|
||||
return StoredDiagnostic(StandaloneDiag.Level, StandaloneDiag.ID,
|
||||
StandaloneDiag.Message, Loc, TranslatedRanges,
|
||||
TranslatedFixIts);
|
||||
}
|
||||
|
||||
} // namespace clang
|
||||
@ -46,7 +46,6 @@ add_clang_library(clangInterpreter
|
||||
clangFrontend
|
||||
clangFrontendTool
|
||||
clangLex
|
||||
clangOptions
|
||||
clangParse
|
||||
clangSema
|
||||
clangSerialization
|
||||
|
||||
@ -42,7 +42,6 @@
|
||||
#include "clang/Interpreter/Interpreter.h"
|
||||
#include "clang/Interpreter/Value.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Options/Options.h"
|
||||
#include "clang/Sema/Lookup.h"
|
||||
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
|
||||
@ -106,7 +105,7 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
|
||||
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
|
||||
Clang->getHeaderSearchOpts().ResourceDir.empty())
|
||||
Clang->getHeaderSearchOpts().ResourceDir =
|
||||
GetResourcesPath(Argv[0], nullptr);
|
||||
CompilerInvocation::GetResourcesPath(Argv[0], nullptr);
|
||||
|
||||
Clang->createVirtualFileSystem();
|
||||
|
||||
|
||||
@ -9,12 +9,7 @@
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticDriver.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Config/config.h"
|
||||
#include "clang/Options/Options.h"
|
||||
#include "llvm/Option/ArgList.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace llvm::opt;
|
||||
@ -36,211 +31,17 @@ IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int clang::getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
|
||||
DiagnosticsEngine *Diags, unsigned Base) {
|
||||
namespace clang {
|
||||
|
||||
int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
|
||||
DiagnosticsEngine *Diags, unsigned Base) {
|
||||
return getLastArgIntValueImpl<int>(Args, Id, Default, Diags, Base);
|
||||
}
|
||||
|
||||
uint64_t clang::getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
|
||||
uint64_t Default,
|
||||
DiagnosticsEngine *Diags, unsigned Base) {
|
||||
uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
|
||||
uint64_t Default, DiagnosticsEngine *Diags,
|
||||
unsigned Base) {
|
||||
return getLastArgIntValueImpl<uint64_t>(Args, Id, Default, Diags, Base);
|
||||
}
|
||||
|
||||
StringRef clang::parseMPreferVectorWidthOption(clang::DiagnosticsEngine &Diags,
|
||||
const llvm::opt::ArgList &Args) {
|
||||
const Arg *A = Args.getLastArg(options::OPT_mprefer_vector_width_EQ);
|
||||
if (!A)
|
||||
return "";
|
||||
|
||||
StringRef Value = A->getValue();
|
||||
unsigned Width LLVM_ATTRIBUTE_UNINITIALIZED;
|
||||
|
||||
// Only "none" and Integer values are accepted by
|
||||
// -mprefer-vector-width=<value>.
|
||||
if (Value != "none" && Value.getAsInteger(10, Width)) {
|
||||
Diags.Report(clang::diag::err_drv_invalid_value)
|
||||
<< A->getOption().getName() << Value;
|
||||
return "";
|
||||
}
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
// This is a helper function for validating the optional refinement step
|
||||
// parameter in reciprocal argument strings. Return false if there is an error
|
||||
// parsing the refinement step. Otherwise, return true and set the Position
|
||||
// of the refinement step in the input string.
|
||||
static bool getRefinementStep(StringRef In, clang::DiagnosticsEngine &Diags,
|
||||
const Arg &A, size_t &Position) {
|
||||
const char RefinementStepToken = ':';
|
||||
Position = In.find(RefinementStepToken);
|
||||
if (Position != StringRef::npos) {
|
||||
StringRef Option = A.getOption().getName();
|
||||
StringRef RefStep = In.substr(Position + 1);
|
||||
// Allow exactly one numeric character for the additional refinement
|
||||
// step parameter. This is reasonable for all currently-supported
|
||||
// operations and architectures because we would expect that a larger value
|
||||
// of refinement steps would cause the estimate "optimization" to
|
||||
// under-perform the native operation. Also, if the estimate does not
|
||||
// converge quickly, it probably will not ever converge, so further
|
||||
// refinement steps will not produce a better answer.
|
||||
if (RefStep.size() != 1) {
|
||||
Diags.Report(diag::err_drv_invalid_value) << Option << RefStep;
|
||||
return false;
|
||||
}
|
||||
char RefStepChar = RefStep[0];
|
||||
if (RefStepChar < '0' || RefStepChar > '9') {
|
||||
Diags.Report(diag::err_drv_invalid_value) << Option << RefStep;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
StringRef clang::parseMRecipOption(clang::DiagnosticsEngine &Diags,
|
||||
const ArgList &Args) {
|
||||
StringRef DisabledPrefixIn = "!";
|
||||
StringRef DisabledPrefixOut = "!";
|
||||
StringRef EnabledPrefixOut = "";
|
||||
StringRef Out = "";
|
||||
|
||||
const Arg *A = Args.getLastArg(options::OPT_mrecip, options::OPT_mrecip_EQ);
|
||||
if (!A)
|
||||
return "";
|
||||
|
||||
const unsigned NumOptions = A->getNumValues();
|
||||
if (NumOptions == 0) {
|
||||
// No option is the same as "all".
|
||||
return "all";
|
||||
}
|
||||
|
||||
// Pass through "all", "none", or "default" with an optional refinement step.
|
||||
if (NumOptions == 1) {
|
||||
StringRef Val = A->getValue(0);
|
||||
size_t RefStepLoc;
|
||||
if (!getRefinementStep(Val, Diags, *A, RefStepLoc))
|
||||
return "";
|
||||
StringRef ValBase = Val.slice(0, RefStepLoc);
|
||||
if (ValBase == "all" || ValBase == "none" || ValBase == "default") {
|
||||
return Val;
|
||||
}
|
||||
}
|
||||
|
||||
// Each reciprocal type may be enabled or disabled individually.
|
||||
// Check each input value for validity, concatenate them all back together,
|
||||
// and pass through.
|
||||
|
||||
llvm::StringMap<bool> OptionStrings;
|
||||
OptionStrings.insert(std::make_pair("divd", false));
|
||||
OptionStrings.insert(std::make_pair("divf", false));
|
||||
OptionStrings.insert(std::make_pair("divh", false));
|
||||
OptionStrings.insert(std::make_pair("vec-divd", false));
|
||||
OptionStrings.insert(std::make_pair("vec-divf", false));
|
||||
OptionStrings.insert(std::make_pair("vec-divh", false));
|
||||
OptionStrings.insert(std::make_pair("sqrtd", false));
|
||||
OptionStrings.insert(std::make_pair("sqrtf", false));
|
||||
OptionStrings.insert(std::make_pair("sqrth", false));
|
||||
OptionStrings.insert(std::make_pair("vec-sqrtd", false));
|
||||
OptionStrings.insert(std::make_pair("vec-sqrtf", false));
|
||||
OptionStrings.insert(std::make_pair("vec-sqrth", false));
|
||||
|
||||
for (unsigned i = 0; i != NumOptions; ++i) {
|
||||
StringRef Val = A->getValue(i);
|
||||
|
||||
bool IsDisabled = Val.starts_with(DisabledPrefixIn);
|
||||
// Ignore the disablement token for string matching.
|
||||
if (IsDisabled)
|
||||
Val = Val.substr(1);
|
||||
|
||||
size_t RefStep;
|
||||
if (!getRefinementStep(Val, Diags, *A, RefStep))
|
||||
return "";
|
||||
|
||||
StringRef ValBase = Val.slice(0, RefStep);
|
||||
llvm::StringMap<bool>::iterator OptionIter = OptionStrings.find(ValBase);
|
||||
if (OptionIter == OptionStrings.end()) {
|
||||
// Try again specifying float suffix.
|
||||
OptionIter = OptionStrings.find(ValBase.str() + 'f');
|
||||
if (OptionIter == OptionStrings.end()) {
|
||||
// The input name did not match any known option string.
|
||||
Diags.Report(diag::err_drv_unknown_argument) << Val;
|
||||
return "";
|
||||
}
|
||||
// The option was specified without a half or float or double suffix.
|
||||
// Make sure that the double or half entry was not already specified.
|
||||
// The float entry will be checked below.
|
||||
if (OptionStrings[ValBase.str() + 'd'] ||
|
||||
OptionStrings[ValBase.str() + 'h']) {
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getOption().getName() << Val;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
if (OptionIter->second == true) {
|
||||
// Duplicate option specified.
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getOption().getName() << Val;
|
||||
return "";
|
||||
}
|
||||
|
||||
// Mark the matched option as found. Do not allow duplicate specifiers.
|
||||
OptionIter->second = true;
|
||||
|
||||
// If the precision was not specified, also mark the double and half entry
|
||||
// as found.
|
||||
if (ValBase.back() != 'f' && ValBase.back() != 'd' &&
|
||||
ValBase.back() != 'h') {
|
||||
OptionStrings[ValBase.str() + 'd'] = true;
|
||||
OptionStrings[ValBase.str() + 'h'] = true;
|
||||
}
|
||||
|
||||
// Build the output string.
|
||||
StringRef Prefix = IsDisabled ? DisabledPrefixOut : EnabledPrefixOut;
|
||||
Out = Args.MakeArgString(Out + Prefix + Val);
|
||||
if (i != NumOptions - 1)
|
||||
Out = Args.MakeArgString(Out + ",");
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
std::string clang::GetResourcesPath(StringRef BinaryPath) {
|
||||
// Since the resource directory is embedded in the module hash, it's important
|
||||
// that all places that need it call this function, so that they get the
|
||||
// exact same string ("a/../b/" and "b/" get different hashes, for example).
|
||||
|
||||
// Dir is bin/ or lib/, depending on where BinaryPath is.
|
||||
StringRef Dir = llvm::sys::path::parent_path(BinaryPath);
|
||||
SmallString<128> P(Dir);
|
||||
|
||||
StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
|
||||
if (!ConfiguredResourceDir.empty()) {
|
||||
// FIXME: We should fix the behavior of llvm::sys::path::append so we don't
|
||||
// need to check for absolute paths here.
|
||||
if (llvm::sys::path::is_absolute(ConfiguredResourceDir))
|
||||
P = ConfiguredResourceDir;
|
||||
else
|
||||
llvm::sys::path::append(P, ConfiguredResourceDir);
|
||||
} else {
|
||||
// On Windows, libclang.dll is in bin/.
|
||||
// On non-Windows, libclang.so/.dylib is in lib/.
|
||||
// With a static-library build of libclang, LibClangPath will contain the
|
||||
// path of the embedding binary, which for LLVM binaries will be in bin/.
|
||||
// ../lib gets us to lib/ in both cases.
|
||||
P = llvm::sys::path::parent_path(Dir);
|
||||
// This search path is also created in the COFF driver of lld, so any
|
||||
// changes here also needs to happen in lld/COFF/Driver.cpp
|
||||
llvm::sys::path::append(P, CLANG_INSTALL_LIBDIR_BASENAME, "clang",
|
||||
CLANG_VERSION_MAJOR_STRING);
|
||||
}
|
||||
|
||||
return std::string(P);
|
||||
}
|
||||
|
||||
std::string clang::GetResourcesPath(const char *Argv0, void *MainAddr) {
|
||||
const std::string ClangExecutable =
|
||||
llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
|
||||
return GetResourcesPath(ClangExecutable);
|
||||
}
|
||||
} // namespace clang
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
#include "clang/Lex/HeaderSearchOptions.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Options/Options.h"
|
||||
#include "clang/Tooling/ArgumentsAdjusters.h"
|
||||
#include "clang/Tooling/CompilationDatabase.h"
|
||||
@ -511,7 +510,8 @@ static void injectResourceDir(CommandLineArguments &Args, const char *Argv0,
|
||||
|
||||
// If there's no override in place add our resource dir.
|
||||
Args = getInsertArgumentAdjuster(
|
||||
("-resource-dir=" + GetResourcesPath(Argv0, MainAddr)).c_str())(Args, "");
|
||||
("-resource-dir=" + CompilerInvocation::GetResourcesPath(Argv0, MainAddr))
|
||||
.c_str())(Args, "");
|
||||
}
|
||||
|
||||
int ClangTool::run(ToolAction *Action) {
|
||||
|
||||
@ -27,7 +27,6 @@ else()
|
||||
libclang
|
||||
clangAST
|
||||
clangBasic
|
||||
clangDriver
|
||||
clangFrontend
|
||||
clangIndex
|
||||
clangSerialization
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
|
||||
@ -15,6 +15,5 @@ add_clang_tool(diagtool
|
||||
clang_target_link_libraries(diagtool
|
||||
PRIVATE
|
||||
clangBasic
|
||||
clangDriver
|
||||
clangFrontend
|
||||
)
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "DiagTool.h"
|
||||
#include "DiagnosticNames.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/TextDiagnosticBuffer.h"
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
#include "clang/CodeGen/ObjectFilePCHContainerWriter.h"
|
||||
#include "clang/Config/config.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
@ -270,7 +269,7 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
|
||||
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
|
||||
Clang->getHeaderSearchOpts().ResourceDir.empty())
|
||||
Clang->getHeaderSearchOpts().ResourceDir =
|
||||
GetResourcesPath(Argv0, MainAddr);
|
||||
CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
|
||||
|
||||
/// Create the actual file system.
|
||||
Clang->createVirtualFileSystem(llvm::vfs::getRealFileSystem(), DiagsBuffer);
|
||||
|
||||
@ -38,7 +38,6 @@
|
||||
#include "clang/Basic/Stack.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Driver/CreateASTUnitFromArgs.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Index/CommentToXML.h"
|
||||
@ -4362,7 +4361,7 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
|
||||
LibclangInvocationReporter InvocationReporter(
|
||||
*CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
|
||||
options, llvm::ArrayRef(*Args), /*InvocationArgs=*/{}, unsaved_files);
|
||||
std::unique_ptr<ASTUnit> Unit = CreateASTUnitFromCommandLine(
|
||||
std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromCommandLine(
|
||||
Args->data(), Args->data() + Args->size(),
|
||||
CXXIdx->getPCHContainerOperations(), DiagOpts, Diags,
|
||||
CXXIdx->getClangResourcesPath(), CXXIdx->getStorePreamblesInMemory(),
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Config/config.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
@ -138,7 +137,7 @@ const std::string &CIndexer::getClangResourcesPath() {
|
||||
#endif
|
||||
|
||||
// Cache our result.
|
||||
ResourcesPath = GetResourcesPath(LibClangPath);
|
||||
ResourcesPath = driver::Driver::GetResourcesPath(LibClangPath);
|
||||
return ResourcesPath;
|
||||
}
|
||||
|
||||
|
||||
@ -65,7 +65,6 @@ set(LIBS
|
||||
clangFrontend
|
||||
clangIndex
|
||||
clangLex
|
||||
clangOptions
|
||||
clangRewrite
|
||||
clangSema
|
||||
clangSerialization
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
#include "CXString.h"
|
||||
#include "CXTranslationUnit.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
@ -9,8 +9,6 @@
|
||||
#include <fstream>
|
||||
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Driver/CreateASTUnitFromArgs.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
@ -175,7 +173,7 @@ TEST_F(ASTUnitTest, LoadFromCommandLineEarlyError) {
|
||||
auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
|
||||
std::unique_ptr<clang::ASTUnit> ErrUnit;
|
||||
|
||||
std::unique_ptr<ASTUnit> AST = CreateASTUnitFromCommandLine(
|
||||
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
|
||||
&Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "",
|
||||
false, CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false,
|
||||
false, SkipFunctionBodiesScope::None, false, true, false, false,
|
||||
@ -203,7 +201,7 @@ TEST_F(ASTUnitTest, LoadFromCommandLineWorkingDirectory) {
|
||||
auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
|
||||
std::unique_ptr<clang::ASTUnit> ErrUnit;
|
||||
|
||||
std::unique_ptr<ASTUnit> AST = CreateASTUnitFromCommandLine(
|
||||
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
|
||||
&Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "",
|
||||
false, CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false,
|
||||
false, SkipFunctionBodiesScope::None, false, true, false, false,
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "clang/Frontend/Utils.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
|
||||
@ -13,7 +13,6 @@ add_distinct_clang_unittest(SemaTests
|
||||
clangAST
|
||||
clangASTMatchers
|
||||
clangBasic
|
||||
clangDriver
|
||||
clangFrontend
|
||||
clangParse
|
||||
clangSema
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TokenKinds.def"
|
||||
#include "clang/Basic/TokenKinds.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
#include "clang/Frontend/Utils.h"
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
#include "TreeTestBase.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
|
||||
@ -75,6 +75,7 @@ add_flang_library(flangFrontend
|
||||
|
||||
CLANG_LIBS
|
||||
clangBasic
|
||||
clangDriver
|
||||
clangOptions
|
||||
)
|
||||
|
||||
|
||||
@ -325,9 +325,10 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
|
||||
for (auto *a : args.filtered(clang::options::OPT_fpass_plugin_EQ))
|
||||
opts.LLVMPassPlugins.push_back(a->getValue());
|
||||
|
||||
opts.Reciprocals = clang::parseMRecipOption(diags, args);
|
||||
opts.Reciprocals = clang::driver::tools::parseMRecipOption(diags, args);
|
||||
|
||||
opts.PreferVectorWidth = clang::parseMPreferVectorWidthOption(diags, args);
|
||||
opts.PreferVectorWidth =
|
||||
clang::driver::tools::parseMPreferVectorWidthOption(diags, args);
|
||||
|
||||
// -fembed-offload-object option
|
||||
for (auto *a : args.filtered(clang::options::OPT_fembed_offload_object_EQ))
|
||||
|
||||
@ -60,7 +60,6 @@
|
||||
#include "lldb/lldb-forward.h"
|
||||
#include "lldb/lldb-private-enumerations.h"
|
||||
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
||||
@ -51,10 +51,10 @@ add_lldb_library(lldbPluginExpressionParserClang
|
||||
CLANG_LIBS
|
||||
clangAST
|
||||
clangCodeGen
|
||||
clangDriver
|
||||
clangEdit
|
||||
clangFrontend
|
||||
clangLex
|
||||
clangOptions
|
||||
clangParse
|
||||
clangRewrite
|
||||
clangRewriteFrontend
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Config/config.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
@ -53,7 +53,7 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
|
||||
std::string raw_path = lldb_shlib_spec.GetPath();
|
||||
llvm::StringRef parent_dir = llvm::sys::path::parent_path(raw_path);
|
||||
static const std::string clang_resource_path =
|
||||
clang::GetResourcesPath("bin/lldb");
|
||||
clang::driver::Driver::GetResourcesPath("bin/lldb");
|
||||
|
||||
static const llvm::StringRef kResourceDirSuffixes[] = {
|
||||
// LLVM.org's build of LLDB uses the clang resource directory placed
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Driver/CreateInvocationFromArgs.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Config/config.h"
|
||||
#include "clang/Options/OptionUtils.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
|
||||
#include "Plugins/ExpressionParser/Clang/ClangHost.h"
|
||||
#include "TestingSupport/SubsystemRAII.h"
|
||||
@ -43,7 +43,7 @@ TEST_F(ClangHostTest, ComputeClangResourceDirectory) {
|
||||
std::string path_to_liblldb = "C:\\foo\\bar\\lib\\";
|
||||
#endif
|
||||
std::string path_to_clang_dir =
|
||||
clang::GetResourcesPath(path_to_liblldb + "liblldb");
|
||||
clang::driver::Driver::GetResourcesPath(path_to_liblldb + "liblldb");
|
||||
llvm::SmallString<256> path_to_clang_lib_dir_real;
|
||||
llvm::sys::fs::real_path(path_to_clang_dir, path_to_clang_lib_dir_real);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user