[Lldb-commits] [lldb] 3773bbe - [clang] Refactor to remove clangDriver dependency from clangFrontend and flangFrontend (#165277)
via lldb-commits
lldb-commits at lists.llvm.org
Sun Nov 23 08:55:41 PST 2025
Author: Naveen Seth Hanig
Date: 2025-11-23T17:55:36+01:00
New Revision: 3773bbe9e7916ec89fb3e3cd02e29c54cabac82b
URL: https://github.com/llvm/llvm-project/commit/3773bbe9e7916ec89fb3e3cd02e29c54cabac82b
DIFF: https://github.com/llvm/llvm-project/commit/3773bbe9e7916ec89fb3e3cd02e29c54cabac82b.diff
LOG: [clang] Refactor to remove clangDriver dependency from clangFrontend and flangFrontend (#165277)
This removes the dependency on clangDriver from clangFrontend and
flangFrontend.
This refactoring is part of a broader effort to support driver-managed
builds for compilations using C++ named modules and/or Clang modules.
It is required for linking the dependency scanning tooling against the
driver without introducing cyclic dependencies, which would otherwise
cause build failures when dynamic linking is enabled.
In particular, clangFrontend must no longer depend on clangDriver
for this to be possible.
This change was discussed in the following RFC:
https://discourse.llvm.org/t/rfc-new-clangoptions-library-remove-dependency-on-clangdriver-from-clangfrontend-and-flangfrontend/88773
Added:
clang/include/clang/Driver/CreateASTUnitFromArgs.h
clang/include/clang/Driver/CreateInvocationFromArgs.h
clang/include/clang/Frontend/StandaloneDiagnostic.h
clang/lib/Driver/CreateASTUnitFromArgs.cpp
clang/lib/Driver/CreateInvocationFromArgs.cpp
clang/lib/Frontend/StandaloneDiagnostic.cpp
Modified:
clang-tools-extra/clangd/CompileCommands.cpp
clang-tools-extra/clangd/Compiler.cpp
clang/docs/ReleaseNotes.rst
clang/include/clang/Driver/CommonArgs.h
clang/include/clang/Driver/Driver.h
clang/include/clang/Frontend/ASTUnit.h
clang/include/clang/Frontend/ChainedDiagnosticConsumer.h
clang/include/clang/Frontend/CompilerInvocation.h
clang/include/clang/Frontend/Utils.h
clang/include/clang/Options/OptionUtils.h
clang/lib/CrossTU/CMakeLists.txt
clang/lib/CrossTU/CrossTranslationUnit.cpp
clang/lib/Driver/CMakeLists.txt
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/Flang.cpp
clang/lib/Frontend/ASTUnit.cpp
clang/lib/Frontend/CMakeLists.txt
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Interpreter/CMakeLists.txt
clang/lib/Interpreter/Interpreter.cpp
clang/lib/Options/OptionUtils.cpp
clang/lib/Tooling/Tooling.cpp
clang/tools/c-index-test/CMakeLists.txt
clang/tools/c-index-test/core_main.cpp
clang/tools/diagtool/CMakeLists.txt
clang/tools/diagtool/ShowEnabledWarnings.cpp
clang/tools/driver/cc1_main.cpp
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CIndexer.cpp
clang/tools/libclang/CMakeLists.txt
clang/tools/libclang/Indexing.cpp
clang/unittests/Driver/DXCModeTest.cpp
clang/unittests/Driver/ToolChainTest.cpp
clang/unittests/Frontend/ASTUnitTest.cpp
clang/unittests/Frontend/CompilerInstanceTest.cpp
clang/unittests/Frontend/UtilsTest.cpp
clang/unittests/Sema/CMakeLists.txt
clang/unittests/Sema/SemaNoloadLookupTest.cpp
clang/unittests/Serialization/ForceCheckFileInputTest.cpp
clang/unittests/Serialization/LoadSpecLazilyTest.cpp
clang/unittests/Serialization/ModuleCacheTest.cpp
clang/unittests/Serialization/NoCommentsTest.cpp
clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
clang/unittests/Serialization/VarDeclConstantInitTest.cpp
clang/unittests/Tooling/Syntax/TokensTest.cpp
clang/unittests/Tooling/Syntax/TreeTestBase.cpp
flang/lib/Frontend/CMakeLists.txt
flang/lib/Frontend/CompilerInvocation.cpp
lldb/source/Commands/CommandObjectTarget.cpp
lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
lldb/unittests/Expression/ClangParserTest.cpp
Removed:
clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
################################################################################
diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index 7990f2719e9a0..4eda330716f21 100644
--- a/clang-tools-extra/clangd/CompileCommands.cpp
+++ b/clang-tools-extra/clangd/CompileCommands.cpp
@@ -132,8 +132,7 @@ std::optional<std::string> detectSysroot() {
std::string detectStandardResourceDir() {
static int StaticForMainAddr; // Just an address in this process.
- return CompilerInvocation::GetResourcesPath("clangd",
- (void *)&StaticForMainAddr);
+ return GetResourcesPath("clangd", (void *)&StaticForMainAddr);
}
// The path passed to argv[0] is important:
diff --git a/clang-tools-extra/clangd/Compiler.cpp b/clang-tools-extra/clangd/Compiler.cpp
index 6ebc2eac25745..9ea7df139382a 100644
--- a/clang-tools-extra/clangd/Compiler.cpp
+++ b/clang-tools-extra/clangd/Compiler.cpp
@@ -9,6 +9,7 @@
#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"
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8161ccdffca82..439e47b209b2f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -84,6 +84,8 @@ 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
-------------------------------------------
diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h
index ac17d6211d882..264bd4965f9ad 100644
--- a/clang/include/clang/Driver/CommonArgs.h
+++ b/clang/include/clang/Driver/CommonArgs.h
@@ -291,16 +291,6 @@ 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);
diff --git a/clang/include/clang/Driver/CreateASTUnitFromArgs.h b/clang/include/clang/Driver/CreateASTUnitFromArgs.h
new file mode 100644
index 0000000000000..30575cc04ca7c
--- /dev/null
+++ b/clang/include/clang/Driver/CreateASTUnitFromArgs.h
@@ -0,0 +1,80 @@
+//===-- 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
diff --git a/clang/include/clang/Driver/CreateInvocationFromArgs.h b/clang/include/clang/Driver/CreateInvocationFromArgs.h
new file mode 100644
index 0000000000000..0e0f67373ce87
--- /dev/null
+++ b/clang/include/clang/Driver/CreateInvocationFromArgs.h
@@ -0,0 +1,76 @@
+//===--- 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
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index aa86bffb802a4..76a6c5a128efb 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -406,11 +406,6 @@ class Driver {
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);
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 3cea159afa33c..341460e1962cb 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -22,12 +22,14 @@
#include "clang/Basic/SourceLocation.h"
#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/Frontend/PrecompiledPreamble.h"
+#include "clang/Serialization/ASTWriter.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -36,6 +38,7 @@
#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>
@@ -88,25 +91,6 @@ 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
@@ -129,7 +113,15 @@ class ASTUnit {
bool HadModuleLoaderFatalFailure = false;
bool StorePreamblesInMemory = false;
- struct ASTWriterData;
+ /// 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, {}) {}
+ };
std::unique_ptr<ASTWriterData> WriterData;
FileSystemOptions FileSystemOpts;
@@ -271,11 +263,6 @@ 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:
@@ -834,65 +821,24 @@ class ASTUnit {
bool IncludeBriefCommentsInCodeCompletion = false,
bool UserFilesAreVolatile = false);
- /// 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(
+ friend 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<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);
+ 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);
/// Reparse the source files using the same command-line options that
/// were originally used to produce this translation unit.
@@ -963,6 +909,44 @@ class ASTUnit {
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
diff --git a/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h b/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h
index ca284560754fd..839b5e7fa0a3e 100644
--- a/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ b/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -66,6 +66,6 @@ class ChainedDiagnosticConsumer : public DiagnosticConsumer {
}
};
-} // end namspace clang
+} // namespace clang
#endif
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h
index b19a6e1a8acc3..4977ddb307d21 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -299,16 +299,6 @@ class CompilerInvocation : public CompilerInvocationBase {
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.
///
diff --git a/clang/include/clang/Frontend/StandaloneDiagnostic.h b/clang/include/clang/Frontend/StandaloneDiagnostic.h
new file mode 100644
index 0000000000000..c23d5f95e0c2f
--- /dev/null
+++ b/clang/include/clang/Frontend/StandaloneDiagnostic.h
@@ -0,0 +1,82 @@
+//===--- 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
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index ed2703c76f18d..1c561b47b5c47 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -192,51 +192,6 @@ 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
diff --git a/clang/include/clang/Options/OptionUtils.h b/clang/include/clang/Options/OptionUtils.h
index 83c48bd7d6843..02c9c27554db1 100644
--- a/clang/include/clang/Options/OptionUtils.h
+++ b/clang/include/clang/Options/OptionUtils.h
@@ -28,6 +28,7 @@ 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,
@@ -53,6 +54,29 @@ 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
diff --git a/clang/lib/CrossTU/CMakeLists.txt b/clang/lib/CrossTU/CMakeLists.txt
index 3349fc283925d..eef7a892701fb 100644
--- a/clang/lib/CrossTU/CMakeLists.txt
+++ b/clang/lib/CrossTU/CMakeLists.txt
@@ -9,6 +9,7 @@ add_clang_library(clangCrossTU
LINK_LIBS
clangAST
clangBasic
+ clangDriver
clangFrontend
clangIndex
)
diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index 0287845a741ed..a3fc2cf6bfb3c 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -16,6 +16,7 @@
#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"
@@ -619,7 +620,7 @@ CrossTranslationUnitContext::ASTLoader::loadFromSource(
auto Diags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(DiagID, *DiagOpts,
DiagClient);
- return ASTUnit::LoadFromCommandLine(
+ return CreateASTUnitFromCommandLine(
CommandLineArgs.begin(), (CommandLineArgs.end()),
CI.getPCHContainerOperations(), DiagOpts, Diags,
CI.getHeaderSearchOpts().ResourceDir);
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 8052659e9836b..d987111827597 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -17,6 +17,8 @@ endif()
add_clang_library(clangDriver
Action.cpp
Compilation.cpp
+ CreateASTUnitFromArgs.cpp
+ CreateInvocationFromArgs.cpp
Distro.cpp
Driver.cpp
Job.cpp
@@ -96,6 +98,8 @@ add_clang_library(clangDriver
LINK_LIBS
clangBasic
+ clangFrontend
+ clangSerialization
clangLex
clangOptions
${system_libs}
diff --git a/clang/lib/Driver/CreateASTUnitFromArgs.cpp b/clang/lib/Driver/CreateASTUnitFromArgs.cpp
new file mode 100644
index 0000000000000..ea31a8ed07c5f
--- /dev/null
+++ b/clang/lib/Driver/CreateASTUnitFromArgs.cpp
@@ -0,0 +1,166 @@
+//===--- 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;
+}
diff --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Driver/CreateInvocationFromArgs.cpp
similarity index 93%
rename from clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
rename to clang/lib/Driver/CreateInvocationFromArgs.cpp
index 9db594bed1538..516d61f1a1159 100644
--- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/clang/lib/Driver/CreateInvocationFromArgs.cpp
@@ -1,4 +1,4 @@
-//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
+//===--- 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.
@@ -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,12 +24,13 @@
#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>
-clang::createInvocation(ArrayRef<const char *> ArgList,
- CreateInvocationOptions Opts) {
+createInvocation(ArrayRef<const char *> ArgList, CreateInvocationOptions Opts) {
assert(!ArgList.empty());
std::optional<DiagnosticOptions> LocalDiagOpts;
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
@@ -78,7 +79,7 @@ clang::createInvocation(ArrayRef<const char *> ArgList,
const driver::JobList &Jobs = C->getJobs();
bool OffloadCompilation = false;
if (Jobs.size() > 1) {
- for (auto &A : C->getActions()){
+ for (auto &A : C->getActions()) {
// On MacOSX real actions may end up being wrapped in BindArchAction
if (isa<driver::BindArchAction>(A))
A = *A->input_begin();
@@ -114,3 +115,5 @@ clang::createInvocation(ArrayRef<const char *> ArgList,
return nullptr;
return CI;
}
+
+} // namespace clang
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index de8d4601210ae..c6dd66d9efef3 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -66,6 +66,7 @@
#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"
@@ -125,40 +126,6 @@ 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
diff erent 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)) {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c5d40c9825fab..2f0aec3ec3c37 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -32,6 +32,7 @@
#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"
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 4c036f0f8dee3..d3539a594df11 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -3398,169 +3398,6 @@ 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:
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index cc4755cd6a9b0..438de23be0103 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -11,6 +11,7 @@
#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"
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index db13086bcb470..e72317da64596 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -44,6 +44,7 @@
#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"
@@ -210,15 +211,6 @@ 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();
}
@@ -581,73 +573,24 @@ class ASTInfoCollector : public ASTReaderListener {
Counter = NewCounter;
}
};
+} // anonymous namespace
-/// 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;
-
-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
+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.");
+}
-static ASTUnit::StandaloneDiagnostic
-makeStandaloneDiagnostic(const LangOptions &LangOpts,
- const StoredDiagnostic &InDiag);
+void FilterAndStoreDiagnosticConsumer::BeginSourceFile(
+ const LangOptions &LangOpts, const Preprocessor *PP) {
+ this->LangOpts = &LangOpts;
+ if (PP)
+ SourceMgr = &PP->getSourceManager();
+}
static bool isInMainFile(const clang::Diagnostic &D) {
if (!D.hasSourceManager() || !D.getLocation().isValid())
@@ -683,12 +626,32 @@ void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
StoredDiag.emplace(Level, Info);
ResultDiag = &*StoredDiag;
}
- StandaloneDiags->push_back(
- makeStandaloneDiagnostic(*LangOpts, *ResultDiag));
+ StandaloneDiags->emplace_back(*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;
}
@@ -1110,7 +1073,7 @@ class ASTUnitPreambleCallbacks : public PreambleCallbacks {
unsigned Hash = 0;
std::vector<Decl *> TopLevelDecls;
std::vector<LocalDeclID> TopLevelDeclIDs;
- llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
+ llvm::SmallVector<StandaloneDiagnostic, 4> PreambleDiags;
};
} // namespace
@@ -1259,10 +1222,17 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
return true;
- if (SavedMainFileBuffer)
- TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
- PreambleDiagnostics, StoredDiagnostics);
- else
+ 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
PreambleSrcLocCache.clear();
if (llvm::Error Err = Act->Execute()) {
@@ -1281,51 +1251,6 @@ 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.
///
@@ -1780,116 +1705,6 @@ 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) {
@@ -2408,65 +2223,6 @@ 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);
diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt
index dac9e0d26f393..634f239933605 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -17,7 +17,6 @@ add_clang_library(clangFrontend
ChainedIncludesSource.cpp
CompilerInstance.cpp
CompilerInvocation.cpp
- CreateInvocationFromCommandLine.cpp
DependencyFile.cpp
DependencyGraph.cpp
DiagnosticRenderer.cpp
@@ -36,6 +35,7 @@ add_clang_library(clangFrontend
SARIFDiagnosticPrinter.cpp
SerializedDiagnosticPrinter.cpp
SerializedDiagnosticReader.cpp
+ StandaloneDiagnostic.cpp
TestModuleFileExtension.cpp
TextDiagnostic.cpp
TextDiagnosticBuffer.cpp
@@ -51,7 +51,6 @@ add_clang_library(clangFrontend
clangAPINotes
clangAST
clangBasic
- clangDriver
clangOptions
clangEdit
clangLex
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index be7239da55cce..c081ed7215b54 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3274,13 +3274,6 @@ 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::GetResourcesPath(ClangExecutable);
-}
-
static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts,
ArgumentConsumer Consumer) {
const HeaderSearchOptions *HeaderSearchOpts = &Opts;
diff --git a/clang/lib/Frontend/StandaloneDiagnostic.cpp b/clang/lib/Frontend/StandaloneDiagnostic.cpp
new file mode 100644
index 0000000000000..4f19c91b7d266
--- /dev/null
+++ b/clang/lib/Frontend/StandaloneDiagnostic.cpp
@@ -0,0 +1,117 @@
+//===--- 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
diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt
index 37faa0302caaa..9a597146b2fc4 100644
--- a/clang/lib/Interpreter/CMakeLists.txt
+++ b/clang/lib/Interpreter/CMakeLists.txt
@@ -46,6 +46,7 @@ add_clang_library(clangInterpreter
clangFrontend
clangFrontendTool
clangLex
+ clangOptions
clangParse
clangSema
clangSerialization
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index 7764fa7dc92b9..6cbc5e9910bcc 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -42,6 +42,7 @@
#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"
@@ -105,7 +106,7 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
Clang->getHeaderSearchOpts().ResourceDir.empty())
Clang->getHeaderSearchOpts().ResourceDir =
- CompilerInvocation::GetResourcesPath(Argv[0], nullptr);
+ GetResourcesPath(Argv[0], nullptr);
Clang->createVirtualFileSystem();
diff --git a/clang/lib/Options/OptionUtils.cpp b/clang/lib/Options/OptionUtils.cpp
index fcafd3c83c6b3..e5aefa012f679 100644
--- a/clang/lib/Options/OptionUtils.cpp
+++ b/clang/lib/Options/OptionUtils.cpp
@@ -9,7 +9,12 @@
#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;
@@ -31,17 +36,211 @@ IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
}
} // namespace
-namespace clang {
-
-int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
- DiagnosticsEngine *Diags, unsigned Base) {
+int clang::getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
+ DiagnosticsEngine *Diags, unsigned Base) {
return getLastArgIntValueImpl<int>(Args, Id, Default, Diags, Base);
}
-uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
- uint64_t Default, DiagnosticsEngine *Diags,
- unsigned Base) {
+uint64_t clang::getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
+ uint64_t Default,
+ DiagnosticsEngine *Diags, unsigned Base) {
return getLastArgIntValueImpl<uint64_t>(Args, Id, Default, Diags, Base);
}
-} // namespace clang
+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
diff erent 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);
+}
diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index 9bae12454d2dc..1d55f615de8a9 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -31,6 +31,7 @@
#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"
@@ -510,8 +511,7 @@ static void injectResourceDir(CommandLineArguments &Args, const char *Argv0,
// If there's no override in place add our resource dir.
Args = getInsertArgumentAdjuster(
- ("-resource-dir=" + CompilerInvocation::GetResourcesPath(Argv0, MainAddr))
- .c_str())(Args, "");
+ ("-resource-dir=" + GetResourcesPath(Argv0, MainAddr)).c_str())(Args, "");
}
int ClangTool::run(ToolAction *Action) {
diff --git a/clang/tools/c-index-test/CMakeLists.txt b/clang/tools/c-index-test/CMakeLists.txt
index 24e7c9692ca56..41e80e66ffa7a 100644
--- a/clang/tools/c-index-test/CMakeLists.txt
+++ b/clang/tools/c-index-test/CMakeLists.txt
@@ -27,6 +27,7 @@ else()
libclang
clangAST
clangBasic
+ clangDriver
clangFrontend
clangIndex
clangSerialization
diff --git a/clang/tools/c-index-test/core_main.cpp b/clang/tools/c-index-test/core_main.cpp
index 5a3086a7fc08f..c67479fd130ca 100644
--- a/clang/tools/c-index-test/core_main.cpp
+++ b/clang/tools/c-index-test/core_main.cpp
@@ -8,6 +8,7 @@
#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"
diff --git a/clang/tools/diagtool/CMakeLists.txt b/clang/tools/diagtool/CMakeLists.txt
index b49619c075c73..09b2a81790f87 100644
--- a/clang/tools/diagtool/CMakeLists.txt
+++ b/clang/tools/diagtool/CMakeLists.txt
@@ -15,5 +15,6 @@ add_clang_tool(diagtool
clang_target_link_libraries(diagtool
PRIVATE
clangBasic
+ clangDriver
clangFrontend
)
diff --git a/clang/tools/diagtool/ShowEnabledWarnings.cpp b/clang/tools/diagtool/ShowEnabledWarnings.cpp
index bea0288c09358..5b25e656dafa4 100644
--- a/clang/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/clang/tools/diagtool/ShowEnabledWarnings.cpp
@@ -9,6 +9,7 @@
#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"
diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp
index 92357487865ce..cc757039cafd0 100644
--- a/clang/tools/driver/cc1_main.cpp
+++ b/clang/tools/driver/cc1_main.cpp
@@ -17,6 +17,7 @@
#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"
@@ -269,7 +270,7 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
Clang->getHeaderSearchOpts().ResourceDir.empty())
Clang->getHeaderSearchOpts().ResourceDir =
- CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
+ GetResourcesPath(Argv0, MainAddr);
/// Create the actual file system.
Clang->createVirtualFileSystem(llvm::vfs::getRealFileSystem(), DiagsBuffer);
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index f4d6fa72a1dfe..32e84248c1b27 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -38,6 +38,7 @@
#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"
@@ -4361,7 +4362,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 = ASTUnit::LoadFromCommandLine(
+ std::unique_ptr<ASTUnit> Unit = CreateASTUnitFromCommandLine(
Args->data(), Args->data() + Args->size(),
CXXIdx->getPCHContainerOperations(), DiagOpts, Diags,
CXXIdx->getClangResourcesPath(), CXXIdx->getStorePreamblesInMemory(),
diff --git a/clang/tools/libclang/CIndexer.cpp b/clang/tools/libclang/CIndexer.cpp
index 11d9312b64849..853a936b43e37 100644
--- a/clang/tools/libclang/CIndexer.cpp
+++ b/clang/tools/libclang/CIndexer.cpp
@@ -16,6 +16,7 @@
#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"
@@ -137,7 +138,7 @@ const std::string &CIndexer::getClangResourcesPath() {
#endif
// Cache our result.
- ResourcesPath = driver::Driver::GetResourcesPath(LibClangPath);
+ ResourcesPath = GetResourcesPath(LibClangPath);
return ResourcesPath;
}
diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt
index e0ff7605b68b8..b0105f5a5f79f 100644
--- a/clang/tools/libclang/CMakeLists.txt
+++ b/clang/tools/libclang/CMakeLists.txt
@@ -65,6 +65,7 @@ set(LIBS
clangFrontend
clangIndex
clangLex
+ clangOptions
clangRewrite
clangSema
clangSerialization
diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index c142f142d5071..75323d70afcfe 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -15,6 +15,7 @@
#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"
diff --git a/clang/unittests/Driver/DXCModeTest.cpp b/clang/unittests/Driver/DXCModeTest.cpp
index e0454f190b35a..130da620b40b5 100644
--- a/clang/unittests/Driver/DXCModeTest.cpp
+++ b/clang/unittests/Driver/DXCModeTest.cpp
@@ -15,6 +15,7 @@
#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"
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index afa17ff219be2..8f533790ec501 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -17,6 +17,7 @@
#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"
diff --git a/clang/unittests/Frontend/ASTUnitTest.cpp b/clang/unittests/Frontend/ASTUnitTest.cpp
index dfdbe90e72f1f..bf9e4e184b5db 100644
--- a/clang/unittests/Frontend/ASTUnitTest.cpp
+++ b/clang/unittests/Frontend/ASTUnitTest.cpp
@@ -9,6 +9,8 @@
#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"
@@ -173,7 +175,7 @@ TEST_F(ASTUnitTest, LoadFromCommandLineEarlyError) {
auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
std::unique_ptr<clang::ASTUnit> ErrUnit;
- std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
+ std::unique_ptr<ASTUnit> AST = CreateASTUnitFromCommandLine(
&Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "",
false, CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false,
false, SkipFunctionBodiesScope::None, false, true, false, false,
@@ -201,7 +203,7 @@ TEST_F(ASTUnitTest, LoadFromCommandLineWorkingDirectory) {
auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
std::unique_ptr<clang::ASTUnit> ErrUnit;
- std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCommandLine(
+ std::unique_ptr<ASTUnit> AST = CreateASTUnitFromCommandLine(
&Args[0], &Args[4], PCHContainerOps, DiagOpts, Diags, "", false, "",
false, CaptureDiagsKind::All, {}, true, 0, TU_Complete, false, false,
false, SkipFunctionBodiesScope::None, false, true, false, false,
diff --git a/clang/unittests/Frontend/CompilerInstanceTest.cpp b/clang/unittests/Frontend/CompilerInstanceTest.cpp
index cd3fefa1ea994..39d35b48f394a 100644
--- a/clang/unittests/Frontend/CompilerInstanceTest.cpp
+++ b/clang/unittests/Frontend/CompilerInstanceTest.cpp
@@ -8,6 +8,7 @@
#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"
diff --git a/clang/unittests/Frontend/UtilsTest.cpp b/clang/unittests/Frontend/UtilsTest.cpp
index fc411e4af705f..a82733d57714a 100644
--- a/clang/unittests/Frontend/UtilsTest.cpp
+++ b/clang/unittests/Frontend/UtilsTest.cpp
@@ -9,6 +9,7 @@
#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"
diff --git a/clang/unittests/Sema/CMakeLists.txt b/clang/unittests/Sema/CMakeLists.txt
index b61ed8c457635..188f6135a60ac 100644
--- a/clang/unittests/Sema/CMakeLists.txt
+++ b/clang/unittests/Sema/CMakeLists.txt
@@ -13,6 +13,7 @@ add_distinct_clang_unittest(SemaTests
clangAST
clangASTMatchers
clangBasic
+ clangDriver
clangFrontend
clangParse
clangSema
diff --git a/clang/unittests/Sema/SemaNoloadLookupTest.cpp b/clang/unittests/Sema/SemaNoloadLookupTest.cpp
index e565372698e5e..3944269eff502 100644
--- a/clang/unittests/Sema/SemaNoloadLookupTest.cpp
+++ b/clang/unittests/Sema/SemaNoloadLookupTest.cpp
@@ -10,6 +10,7 @@
#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"
diff --git a/clang/unittests/Serialization/ForceCheckFileInputTest.cpp b/clang/unittests/Serialization/ForceCheckFileInputTest.cpp
index edf33ae04230b..b76dcfec96063 100644
--- a/clang/unittests/Serialization/ForceCheckFileInputTest.cpp
+++ b/clang/unittests/Serialization/ForceCheckFileInputTest.cpp
@@ -9,6 +9,7 @@
#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"
diff --git a/clang/unittests/Serialization/LoadSpecLazilyTest.cpp b/clang/unittests/Serialization/LoadSpecLazilyTest.cpp
index d7b55491fddac..f55925aeae1f2 100644
--- a/clang/unittests/Serialization/LoadSpecLazilyTest.cpp
+++ b/clang/unittests/Serialization/LoadSpecLazilyTest.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Driver/CreateInvocationFromArgs.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp
index e9b8da3dba6af..df26e54588b9e 100644
--- a/clang/unittests/Serialization/ModuleCacheTest.cpp
+++ b/clang/unittests/Serialization/ModuleCacheTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#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"
diff --git a/clang/unittests/Serialization/NoCommentsTest.cpp b/clang/unittests/Serialization/NoCommentsTest.cpp
index 01bb6999a7c90..444a082bba907 100644
--- a/clang/unittests/Serialization/NoCommentsTest.cpp
+++ b/clang/unittests/Serialization/NoCommentsTest.cpp
@@ -9,6 +9,7 @@
#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"
diff --git a/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp b/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
index 55ee72875ead2..b826f20ce4d70 100644
--- a/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
+++ b/clang/unittests/Serialization/PreambleInNamedModulesTest.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Driver/CreateInvocationFromArgs.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
index 743f851fc5fe1..2be01def49809 100644
--- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
+++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp
@@ -9,6 +9,7 @@
#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"
diff --git a/clang/unittests/Tooling/Syntax/TokensTest.cpp b/clang/unittests/Tooling/Syntax/TokensTest.cpp
index 47184cbf5d768..468ca5ddd2c75 100644
--- a/clang/unittests/Tooling/Syntax/TokensTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TokensTest.cpp
@@ -20,6 +20,7 @@
#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"
diff --git a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
index b2be64fc08f3d..dad75854240ef 100644
--- a/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTestBase.cpp
@@ -13,6 +13,7 @@
#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"
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index bb0b4a39cec9b..fb74b3dcb280e 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -75,7 +75,6 @@ add_flang_library(flangFrontend
CLANG_LIBS
clangBasic
- clangDriver
clangOptions
)
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 0c32f3914e04b..b6c4e6303cdac 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -325,10 +325,9 @@ 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::driver::tools::parseMRecipOption(diags, args);
+ opts.Reciprocals = clang::parseMRecipOption(diags, args);
- opts.PreferVectorWidth =
- clang::driver::tools::parseMPreferVectorWidthOption(diags, args);
+ opts.PreferVectorWidth = clang::parseMPreferVectorWidthOption(diags, args);
// -fembed-offload-object option
for (auto *a : args.filtered(clang::options::OPT_fembed_offload_object_EQ))
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 30bca639060e6..7f880d223d6c3 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -60,6 +60,7 @@
#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"
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt b/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
index 01d588ff6a78b..759a7c4dd14fb 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CMakeLists.txt
@@ -51,10 +51,10 @@ add_lldb_library(lldbPluginExpressionParserClang
CLANG_LIBS
clangAST
clangCodeGen
- clangDriver
clangEdit
clangFrontend
clangLex
+ clangOptions
clangParse
clangRewrite
clangRewriteFrontend
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 6de851081598f..660a21e3c6a8d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -10,7 +10,7 @@
#include "clang/Basic/Version.h"
#include "clang/Config/config.h"
-#include "clang/Driver/Driver.h"
+#include "clang/Options/OptionUtils.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::driver::Driver::GetResourcesPath("bin/lldb");
+ clang::GetResourcesPath("bin/lldb");
static const llvm::StringRef kResourceDirSuffixes[] = {
// LLVM.org's build of LLDB uses the clang resource directory placed
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index e37c84efefdc9..ce8dc50b84a31 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -10,6 +10,7 @@
#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"
diff --git a/lldb/unittests/Expression/ClangParserTest.cpp b/lldb/unittests/Expression/ClangParserTest.cpp
index fab4487c73719..c949026e87cd8 100644
--- a/lldb/unittests/Expression/ClangParserTest.cpp
+++ b/lldb/unittests/Expression/ClangParserTest.cpp
@@ -8,7 +8,7 @@
#include "clang/Basic/Version.h"
#include "clang/Config/config.h"
-#include "clang/Driver/Driver.h"
+#include "clang/Options/OptionUtils.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::driver::Driver::GetResourcesPath(path_to_liblldb + "liblldb");
+ clang::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);
More information about the lldb-commits
mailing list