[clang] [clang] Introduce copy-on-write `CompilerInvocation` (PR #65412)
Ben Langmuir via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 7 08:30:34 PDT 2023
================
@@ -154,46 +146,158 @@ class CompilerInvocationValueBase {
PreprocessorOutputOptions PreprocessorOutputOpts;
public:
- MigratorOptions &getMigratorOpts() { return MigratorOpts; }
+ // clang-format off
const MigratorOptions &getMigratorOpts() const { return MigratorOpts; }
-
- CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
+ const DependencyOutputOptions &getDependencyOutputOpts() const { return DependencyOutputOpts; }
+ const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
+ const FrontendOptions &getFrontendOpts() const { return FrontendOpts; }
+ const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { return PreprocessorOutputOpts; }
+ // clang-format on
+};
+} // namespace CompilerInvocationDetail
- DependencyOutputOptions &getDependencyOutputOpts() {
- return DependencyOutputOpts;
- }
+struct CompilerInvocationBase : CompilerInvocationDetail::RefBase,
+ CompilerInvocationDetail::ValBase {
+ CompilerInvocationBase() = default;
- const DependencyOutputOptions &getDependencyOutputOpts() const {
- return DependencyOutputOpts;
- }
+ CompilerInvocationBase(const CompilerInvocationBase &X, DeepCopy)
+ : RefBase(X, DeepCopy{}), ValBase(X) {}
- FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
+ CompilerInvocationBase(const CompilerInvocationBase &X, ShallowCopy)
+ : RefBase(X, ShallowCopy{}), ValBase(X) {}
- const FileSystemOptions &getFileSystemOpts() const {
- return FileSystemOpts;
+ CompilerInvocationBase &assign(const CompilerInvocationBase &X, DeepCopy) {
+ RefBase::assign(X, DeepCopy{});
+ ValBase::operator=(X);
+ return *this;
}
- FrontendOptions &getFrontendOpts() { return FrontendOpts; }
- const FrontendOptions &getFrontendOpts() const { return FrontendOpts; }
-
- PreprocessorOutputOptions &getPreprocessorOutputOpts() {
- return PreprocessorOutputOpts;
+ CompilerInvocationBase &assign(const CompilerInvocationBase &X, ShallowCopy) {
+ RefBase::assign(X, ShallowCopy{});
+ ValBase::operator=(X);
+ return *this;
}
- const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
- return PreprocessorOutputOpts;
+ using StringAllocator = llvm::function_ref<const char *(const Twine &)>;
+ /// Generate cc1-compatible command line arguments from this instance.
+ ///
+ /// \param [out] Args - The generated arguments. Note that the caller is
+ /// responsible for inserting the path to the clang executable and "-cc1" if
+ /// desired.
+ /// \param SA - A function that given a Twine can allocate storage for a given
+ /// command line argument and return a pointer to the newly allocated string.
+ /// The returned pointer is what gets appended to Args.
+ void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
+ StringAllocator SA) const {
+ generateCC1CommandLine([&](const Twine &Arg) {
+ // No need to allocate static string literals.
+ Args.push_back(Arg.isSingleStringLiteral()
+ ? Arg.getSingleStringRef().data()
+ : SA(Arg));
+ });
}
+
+ using ArgumentConsumer = llvm::function_ref<void(const Twine &)>;
+ /// Generate cc1-compatible command line arguments from this instance.
+ ///
+ /// \param Consumer - Callback that gets invoked for every single generated
+ /// command line argument.
+ void generateCC1CommandLine(ArgumentConsumer Consumer) const;
+
+ /// Generate cc1-compatible command line arguments from this instance,
+ /// wrapping the result as a std::vector<std::string>.
+ ///
+ /// This is a (less-efficient) wrapper over generateCC1CommandLine().
+ std::vector<std::string> getCC1CommandLine() const;
+
+ /// Generate command line options from DiagnosticOptions.
+ static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts,
+ ArgumentConsumer Consumer,
+ bool DefaultDiagColor);
+
+ /// Generate command line options from LangOptions.
+ static void GenerateLangArgs(const LangOptions &Opts,
+ ArgumentConsumer Consumer, const llvm::Triple &T,
+ InputKind IK);
+
+ // Generate command line options from CodeGenOptions.
+ static void GenerateCodeGenArgs(const CodeGenOptions &Opts,
+ ArgumentConsumer Consumer,
+ const llvm::Triple &T,
+ const std::string &OutputFile,
+ const LangOptions *LangOpts);
};
/// Helper class for holding the data necessary to invoke the compiler.
///
/// This class is designed to represent an abstract "invocation" of the
/// compiler, including data such as the include paths, the code generation
/// options, the warning flags, and so on.
-class CompilerInvocation : public CompilerInvocationRefBase,
- public CompilerInvocationValueBase {
+class CompilerInvocation : public CompilerInvocationBase {
public:
+ CompilerInvocation() = default;
+
+ CompilerInvocation(const CompilerInvocation &X)
+ : CompilerInvocationBase(X, DeepCopy{}) {}
+
+ CompilerInvocation &operator=(const CompilerInvocation &X) {
+ CompilerInvocationBase::assign(X, DeepCopy{});
+ return *this;
+ }
+
+ // Mutable RefBase accessors.
+
+ LangOptions &getLangOpts() { return *LangOpts; }
+ TargetOptions &getTargetOpts() { return *TargetOpts; }
+ DiagnosticOptions &getDiagnosticOpts() { return *DiagnosticOpts; }
+ HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; }
+ PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; }
+ AnalyzerOptions &getAnalyzerOpts() { return *AnalyzerOpts; }
+
+ // Const RefBase accessors.
+
+ using RefBase::getLangOpts;
+ using RefBase::getTargetOpts;
+ using RefBase::getDiagnosticOpts;
+ using RefBase::getHeaderSearchOpts;
+ using RefBase::getPreprocessorOpts;
+ using RefBase::getAnalyzerOpts;
+
+ // Mutable ValBase accessors.
+
+ // clang-format off
+ MigratorOptions &getMigratorOpts() { return MigratorOpts; }
+ CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
+ DependencyOutputOptions &getDependencyOutputOpts() { return DependencyOutputOpts; }
+ FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
+ FrontendOptions &getFrontendOpts() { return FrontendOpts; }
+ PreprocessorOutputOptions &getPreprocessorOutputOpts() { return PreprocessorOutputOpts; }
+ // clang-format on
+
+ // Const ValBase accessors.
+
+ using ValBase::getMigratorOpts;
+ using ValBase::getCodeGenOpts;
+ using ValBase::getDependencyOutputOpts;
+ using ValBase::getFileSystemOpts;
+ using ValBase::getFrontendOpts;
+ using ValBase::getPreprocessorOutputOpts;
+
+ /// RefBase innards
----------------
benlangmuir wrote:
nit: Detached doc comment
https://github.com/llvm/llvm-project/pull/65412
More information about the cfe-commits
mailing list