Skip to content

Commit 3773bbe

Browse files
authored
[clang] Refactor to remove clangDriver dependency from clangFrontend and flangFrontend (llvm#165277)
This removes the dependency on clangDriver from clangFrontend and flangFrontend. This refactoring is part of a broader effort to support driver-managed builds for compilations using C++ named modules and/or Clang modules. It is required for linking the dependency scanning tooling against the driver without introducing cyclic dependencies, which would otherwise cause build failures when dynamic linking is enabled. In particular, clangFrontend must no longer depend on clangDriver for this to be possible. This change was discussed in the following RFC: https://discourse.llvm.org/t/rfc-new-clangoptions-library-remove-dependency-on-clangdriver-from-clangfrontend-and-flangfrontend/88773
1 parent 8b7401f commit 3773bbe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+937
-687
lines changed

clang-tools-extra/clangd/CompileCommands.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,7 @@ std::optional<std::string> detectSysroot() {
132132

133133
std::string detectStandardResourceDir() {
134134
static int StaticForMainAddr; // Just an address in this process.
135-
return CompilerInvocation::GetResourcesPath("clangd",
136-
(void *)&StaticForMainAddr);
135+
return GetResourcesPath("clangd", (void *)&StaticForMainAddr);
137136
}
138137

139138
// The path passed to argv[0] is important:

clang-tools-extra/clangd/Compiler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Compiler.h"
1010
#include "support/Logger.h"
1111
#include "clang/Basic/TargetInfo.h"
12+
#include "clang/Driver/CreateInvocationFromArgs.h"
1213
#include "clang/Frontend/CompilerInvocation.h"
1314
#include "clang/Lex/PreprocessorOptions.h"
1415
#include "clang/Serialization/PCHContainerOperations.h"

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ Potentially Breaking Changes
8484
- Downstream projects that previously linked only against ``clangDriver`` may
8585
now (also) need to link against the new ``clangOptions`` library, since
8686
options-related code has been moved out of the Driver into a separate library.
87+
- The ``clangFrontend`` library no longer depends on ``clangDriver``, which may
88+
break downstream projects that relied on this transitive dependency.
8789

8890
C/C++ Language Potentially Breaking Changes
8991
-------------------------------------------

clang/include/clang/Driver/CommonArgs.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,6 @@ void handleVectorizeLoopsArgs(const llvm::opt::ArgList &Args,
291291
void handleVectorizeSLPArgs(const llvm::opt::ArgList &Args,
292292
llvm::opt::ArgStringList &CmdArgs);
293293

294-
// Parse -mprefer-vector-width=. Return the Value string if well-formed.
295-
// Otherwise, return an empty string and issue a diagnosic message if needed.
296-
StringRef parseMPreferVectorWidthOption(clang::DiagnosticsEngine &Diags,
297-
const llvm::opt::ArgList &Args);
298-
299-
// Parse -mrecip. Return the Value string if well-formed.
300-
// Otherwise, return an empty string and issue a diagnosic message if needed.
301-
StringRef parseMRecipOption(clang::DiagnosticsEngine &Diags,
302-
const llvm::opt::ArgList &Args);
303-
304294
// Convert ComplexRangeKind to a string that can be passed as a frontend option.
305295
std::string complexRangeKindToStr(LangOptions::ComplexRangeKind Range);
306296

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//===-- CreateInvocationFromArgs.h - Create an ASTUnit from Args-*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Utility for creating an ASTUnit from a vector of command line arguments.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H
14+
#define LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H
15+
16+
#include "clang/Frontend/ASTUnit.h"
17+
18+
namespace clang {
19+
20+
/// Create an ASTUnit from a vector of command line arguments, which must
21+
/// specify exactly one source file.
22+
///
23+
/// \param ArgBegin - The beginning of the argument vector.
24+
///
25+
/// \param ArgEnd - The end of the argument vector.
26+
///
27+
/// \param PCHContainerOps - The PCHContainerOperations to use for loading and
28+
/// creating modules.
29+
///
30+
/// \param Diags - The diagnostics engine to use for reporting errors; its
31+
/// lifetime is expected to extend past that of the returned ASTUnit.
32+
///
33+
/// \param ResourceFilesPath - The path to the compiler resource files.
34+
///
35+
/// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
36+
/// PCH are stored in temporary files.
37+
///
38+
/// \param PreambleStoragePath - The path to a directory, in which to create
39+
/// temporary PCH files. If empty, the default system temporary directory is
40+
/// used. This parameter is ignored if \p StorePreamblesInMemory is true.
41+
///
42+
/// \param ModuleFormat - If provided, uses the specific module format.
43+
///
44+
/// \param ErrAST - If non-null and parsing failed without any AST to return
45+
/// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
46+
/// mainly to allow the caller to see the diagnostics.
47+
///
48+
/// \param VFS - A llvm::vfs::FileSystem to be used for all file accesses.
49+
/// Note that preamble is saved to a temporary directory on a RealFileSystem,
50+
/// so in order for it to be loaded correctly, VFS should have access to
51+
/// it(i.e., be an overlay over RealFileSystem). RealFileSystem will be used
52+
/// if \p VFS is nullptr.
53+
///
54+
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
55+
// shouldn't need to specify them at construction time.
56+
std::unique_ptr<ASTUnit> CreateASTUnitFromCommandLine(
57+
const char **ArgBegin, const char **ArgEnd,
58+
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
59+
std::shared_ptr<DiagnosticOptions> DiagOpts,
60+
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
61+
bool StorePreamblesInMemory = false,
62+
StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false,
63+
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
64+
ArrayRef<ASTUnit::RemappedFile> RemappedFiles = {},
65+
bool RemappedFilesKeepOriginalName = true,
66+
unsigned PrecompilePreambleAfterNParses = 0,
67+
TranslationUnitKind TUKind = TU_Complete,
68+
bool CacheCodeCompletionResults = false,
69+
bool IncludeBriefCommentsInCodeCompletion = false,
70+
bool AllowPCHWithCompilerErrors = false,
71+
SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None,
72+
bool SingleFileParse = false, bool UserFilesAreVolatile = false,
73+
bool ForSerialization = false, bool RetainExcludedConditionalBlocks = false,
74+
std::optional<StringRef> ModuleFormat = std::nullopt,
75+
std::unique_ptr<ASTUnit> *ErrAST = nullptr,
76+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
77+
78+
} // namespace clang
79+
80+
#endif // LLVM_CLANG_DRIVER_CREATEASTUNITFROMARGS_H
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===--- CreateInvocationFromArgs.h - CompilerInvocation from Args --------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Utility for creating a CompilerInvocation from command-line arguments, for
10+
// tools to use in preparation to parse a file.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H
15+
#define LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H
16+
17+
#include "clang/Basic/Diagnostic.h"
18+
#include "clang/Basic/LLVM.h"
19+
#include "llvm/Support/VirtualFileSystem.h"
20+
#include <memory>
21+
#include <string>
22+
#include <vector>
23+
24+
namespace clang {
25+
26+
class CompilerInvocation;
27+
class DiagnosticsEngine;
28+
29+
/// Optional inputs to createInvocation.
30+
struct CreateInvocationOptions {
31+
/// Receives diagnostics encountered while parsing command-line flags.
32+
/// If not provided, these are printed to stderr.
33+
IntrusiveRefCntPtr<DiagnosticsEngine> Diags = nullptr;
34+
/// Used e.g. to probe for system headers locations.
35+
/// If not provided, the real filesystem is used.
36+
/// FIXME: the driver does perform some non-virtualized IO.
37+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr;
38+
/// Whether to attempt to produce a non-null (possibly incorrect) invocation
39+
/// if any errors were encountered.
40+
/// By default, always return null on errors.
41+
bool RecoverOnError = false;
42+
/// Allow the driver to probe the filesystem for PCH files.
43+
/// This is used to replace -include with -include-pch in the cc1 args.
44+
/// FIXME: ProbePrecompiled=true is a poor, historical default.
45+
/// It misbehaves if the PCH file is from GCC, has the wrong version, etc.
46+
bool ProbePrecompiled = false;
47+
/// If set, the target is populated with the cc1 args produced by the driver.
48+
/// This may be populated even if createInvocation returns nullptr.
49+
std::vector<std::string> *CC1Args = nullptr;
50+
};
51+
52+
/// Interpret clang arguments in preparation to parse a file.
53+
///
54+
/// This simulates a number of steps Clang takes when its driver is invoked:
55+
/// - choosing actions (e.g compile + link) to run
56+
/// - probing the system for settings like standard library locations
57+
/// - spawning a cc1 subprocess to compile code, with more explicit arguments
58+
/// - in the cc1 process, assembling those arguments into a CompilerInvocation
59+
/// which is used to configure the parser
60+
///
61+
/// This simulation is lossy, e.g. in some situations one driver run would
62+
/// result in multiple parses. (Multi-arch, CUDA, ...).
63+
/// This function tries to select a reasonable invocation that tools should use.
64+
///
65+
/// Args[0] should be the driver name, such as "clang" or "/usr/bin/g++".
66+
/// Absolute path is preferred - this affects searching for system headers.
67+
///
68+
/// May return nullptr if an invocation could not be determined.
69+
/// See CreateInvocationOptions::RecoverOnError to try harder!
70+
std::unique_ptr<CompilerInvocation>
71+
createInvocation(ArrayRef<const char *> Args,
72+
CreateInvocationOptions Opts = {});
73+
74+
} // namespace clang
75+
76+
#endif // LLVM_CLANG_DRIVER_CREATEINVOCATIONFROMARGS_H

clang/include/clang/Driver/Driver.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,6 @@ class Driver {
406406
SmallString<128> &CrashDiagDir);
407407

408408
public:
409-
410-
/// Takes the path to a binary that's either in bin/ or lib/ and returns
411-
/// the path to clang's resource directory.
412-
static std::string GetResourcesPath(StringRef BinaryPath);
413-
414409
Driver(StringRef ClangExecutable, StringRef TargetTriple,
415410
DiagnosticsEngine &Diags, std::string Title = "clang LLVM compiler",
416411
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);

0 commit comments

Comments
 (0)