[Lldb-commits] [clang] [clang-tools-extra] [flang] [lldb] Reapply "[clang] Refactor to remove clangDriver dependency from clangFrontend and flangFrontend (#165277)" (PR #169597)
Naveen Seth Hanig via lldb-commits
lldb-commits at lists.llvm.org
Tue Nov 25 18:57:56 PST 2025
https://github.com/naveen-seth created https://github.com/llvm/llvm-project/pull/169597
This reapplies 3773bbe by reverting a96ec1c.
The original revert was due to a report of a broken build, which was later resolved by fully clearing the build directory.
>From 80f888bd1ea32f9c9cb2a1c9daa6874fc2bedc9b Mon Sep 17 00:00:00 2001
From: Naveen Seth Hanig <naveen.hanig at outlook.com>
Date: Wed, 26 Nov 2025 03:31:28 +0100
Subject: [PATCH] =?UTF-8?q?Revert=20"Revert=20"=20[clang]=20Refactor=20to?=
=?UTF-8?q?=20remove=20clangDriver=20dependency=20from=20clang=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit dea330b38d9c18b68219abdb52baaa72c9f1103d.
---
clang-tools-extra/clangd/CompileCommands.cpp | 3 +-
clang-tools-extra/clangd/Compiler.cpp | 1 +
clang/docs/ReleaseNotes.rst | 2 +
clang/include/clang/Driver/CommonArgs.h | 10 -
.../clang/Driver/CreateASTUnitFromArgs.h | 80 ++++
.../clang/Driver/CreateInvocationFromArgs.h | 76 ++++
clang/include/clang/Driver/Driver.h | 4 -
clang/include/clang/Frontend/ASTUnit.h | 144 ++++----
.../clang/Frontend/CompilerInvocation.h | 10 -
.../clang/Frontend/StandaloneDiagnostic.h | 82 +++++
clang/include/clang/Frontend/Utils.h | 45 ---
clang/include/clang/Options/OptionUtils.h | 24 ++
clang/lib/CrossTU/CMakeLists.txt | 1 +
clang/lib/CrossTU/CrossTranslationUnit.cpp | 3 +-
clang/lib/Driver/CMakeLists.txt | 4 +
clang/lib/Driver/CreateASTUnitFromArgs.cpp | 166 +++++++++
.../CreateInvocationFromArgs.cpp} | 13 +-
clang/lib/Driver/Driver.cpp | 35 +-
clang/lib/Driver/ToolChains/Clang.cpp | 1 +
clang/lib/Driver/ToolChains/CommonArgs.cpp | 163 ---------
clang/lib/Driver/ToolChains/Flang.cpp | 1 +
clang/lib/Frontend/ASTUnit.cpp | 343 +++---------------
clang/lib/Frontend/CMakeLists.txt | 3 +-
clang/lib/Frontend/CompilerInvocation.cpp | 8 -
clang/lib/Frontend/StandaloneDiagnostic.cpp | 117 ++++++
clang/lib/Interpreter/CMakeLists.txt | 1 +
clang/lib/Interpreter/Interpreter.cpp | 3 +-
clang/lib/Options/OptionUtils.cpp | 215 ++++++++++-
clang/lib/Tooling/Tooling.cpp | 4 +-
clang/tools/c-index-test/CMakeLists.txt | 1 +
clang/tools/c-index-test/core_main.cpp | 1 +
clang/tools/diagtool/CMakeLists.txt | 1 +
clang/tools/diagtool/ShowEnabledWarnings.cpp | 1 +
clang/tools/driver/cc1_main.cpp | 3 +-
clang/tools/libclang/CIndex.cpp | 3 +-
clang/tools/libclang/CIndexer.cpp | 3 +-
clang/tools/libclang/CMakeLists.txt | 1 +
clang/tools/libclang/Indexing.cpp | 1 +
clang/unittests/Driver/DXCModeTest.cpp | 1 +
clang/unittests/Driver/ToolChainTest.cpp | 1 +
clang/unittests/Frontend/ASTUnitTest.cpp | 6 +-
.../Frontend/CompilerInstanceTest.cpp | 1 +
clang/unittests/Frontend/UtilsTest.cpp | 1 +
clang/unittests/Sema/CMakeLists.txt | 1 +
clang/unittests/Sema/SemaNoloadLookupTest.cpp | 1 +
.../Serialization/ForceCheckFileInputTest.cpp | 1 +
.../Serialization/LoadSpecLazilyTest.cpp | 1 +
.../Serialization/ModuleCacheTest.cpp | 1 +
.../Serialization/NoCommentsTest.cpp | 1 +
.../PreambleInNamedModulesTest.cpp | 1 +
.../Serialization/VarDeclConstantInitTest.cpp | 1 +
clang/unittests/Tooling/Syntax/TokensTest.cpp | 1 +
.../unittests/Tooling/Syntax/TreeTestBase.cpp | 1 +
flang/lib/Frontend/CMakeLists.txt | 1 -
flang/lib/Frontend/CompilerInvocation.cpp | 5 +-
lldb/source/Commands/CommandObjectTarget.cpp | 1 +
.../ExpressionParser/Clang/CMakeLists.txt | 2 +-
.../ExpressionParser/Clang/ClangHost.cpp | 4 +-
.../Clang/ClangModulesDeclVendor.cpp | 1 +
lldb/unittests/Expression/ClangParserTest.cpp | 4 +-
60 files changed, 934 insertions(+), 681 deletions(-)
create mode 100644 clang/include/clang/Driver/CreateASTUnitFromArgs.h
create mode 100644 clang/include/clang/Driver/CreateInvocationFromArgs.h
create mode 100644 clang/include/clang/Frontend/StandaloneDiagnostic.h
create mode 100644 clang/lib/Driver/CreateASTUnitFromArgs.cpp
rename clang/lib/{Frontend/CreateInvocationFromCommandLine.cpp => Driver/CreateInvocationFromArgs.cpp} (93%)
create mode 100644 clang/lib/Frontend/StandaloneDiagnostic.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 c6a79ed71ca2f..c4d968bd01b65 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 83bcb7cab550f..76a6c5a128efb 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -406,10 +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 e585933a5c8be..341460e1962cb 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -23,11 +23,13 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/PrecompiledPreamble.h"
+#include "clang/Frontend/StandaloneDiagnostic.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Serialization/ASTWriter.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -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/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 e54e83151ad1e..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;
@@ -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 different hashes, for example).
-
- // Dir is bin/ or lib/, depending on where BinaryPath is.
- StringRef Dir = llvm::sys::path::parent_path(BinaryPath);
- SmallString<128> P(Dir);
-
- StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
- if (!ConfiguredResourceDir.empty()) {
- // FIXME: We should fix the behavior of llvm::sys::path::append so we don't
- // need to check for absolute paths here.
- if (llvm::sys::path::is_absolute(ConfiguredResourceDir))
- P = ConfiguredResourceDir;
- else
- llvm::sys::path::append(P, ConfiguredResourceDir);
- } else {
- // On Windows, libclang.dll is in bin/.
- // On non-Windows, libclang.so/.dylib is in lib/.
- // With a static-library build of libclang, LibClangPath will contain the
- // path of the embedding binary, which for LLVM binaries will be in bin/.
- // ../lib gets us to lib/ in both cases.
- P = llvm::sys::path::parent_path(Dir);
- // This search path is also created in the COFF driver of lld, so any
- // changes here also needs to happen in lld/COFF/Driver.cpp
- llvm::sys::path::append(P, CLANG_INSTALL_LIBDIR_BASENAME, "clang",
- CLANG_VERSION_MAJOR_STRING);
- }
-
- return std::string(P);
-}
-
CUIDOptions::CUIDOptions(llvm::opt::DerivedArgList &Args, const Driver &D)
: UseCUID(Kind::Hash) {
if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
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 1de779ccbf141..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,114 +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) {
@@ -2406,64 +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 c7c29a91721c0..5f1c7afdc80a3 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -27,7 +27,6 @@
#include "clang/Basic/Version.h"
#include "clang/Basic/XRayInstr.h"
#include "clang/Config/config.h"
-#include "clang/Driver/Driver.h"
#include "clang/Frontend/CommandLineSourceLoc.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendOptions.h"
@@ -3273,13 +3272,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::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 different hashes, for example).
+
+ // Dir is bin/ or lib/, depending on where BinaryPath is.
+ StringRef Dir = llvm::sys::path::parent_path(BinaryPath);
+ SmallString<128> P(Dir);
+
+ StringRef ConfiguredResourceDir(CLANG_RESOURCE_DIR);
+ if (!ConfiguredResourceDir.empty()) {
+ // FIXME: We should fix the behavior of llvm::sys::path::append so we don't
+ // need to check for absolute paths here.
+ if (llvm::sys::path::is_absolute(ConfiguredResourceDir))
+ P = ConfiguredResourceDir;
+ else
+ llvm::sys::path::append(P, ConfiguredResourceDir);
+ } else {
+ // On Windows, libclang.dll is in bin/.
+ // On non-Windows, libclang.so/.dylib is in lib/.
+ // With a static-library build of libclang, LibClangPath will contain the
+ // path of the embedding binary, which for LLVM binaries will be in bin/.
+ // ../lib gets us to lib/ in both cases.
+ P = llvm::sys::path::parent_path(Dir);
+ // This search path is also created in the COFF driver of lld, so any
+ // changes here also needs to happen in lld/COFF/Driver.cpp
+ llvm::sys::path::append(P, CLANG_INSTALL_LIBDIR_BASENAME, "clang",
+ CLANG_VERSION_MAJOR_STRING);
+ }
+
+ return std::string(P);
+}
+
+std::string clang::GetResourcesPath(const char *Argv0, void *MainAddr) {
+ const std::string ClangExecutable =
+ llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
+ return GetResourcesPath(ClangExecutable);
+}
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 300d59df1bf7b..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