Files
carbon-lang/toolchain/sem_ir/cpp_file.h
T
David Blaikie f1f6005d4a Perform Clang IRGen during check (#6569)
Background:
https://docs.google.com/document/d/1wi85FRiWh4X9A-gCYMVGKR40-q5fM6-3JaSpePk-XCY/edit?usp=sharing
And specifically this work is essentially an alternative to #5543

Clang's code generation is implemented through an ASTListener
(clang::CodeGenerator) that is attached throughout Clang's
parsing/sema/code
generation phases and acts on Clang AST incrementally throughout that
process.

Prior to this patch, Carbon has only created the CodeGenerator during
Carbon's
`lower` phase, missing out on key callbacks that would be made by Clang
during
`check`. Some of these issues were addressed by #6237 and #6483 - but
there were
still remaining cases where the delayed processing lead to missing
functionality.

With #6483 much of the Clang code that made multithreaded complexity of
#5543 is
no longer present, and we have access to the point of ASTListener
registration
so we can register the CodeGenerator there and consume its resulting
llvm::Module during lower.

Examples of some of the bugs this addresses are seen in the linked doc,
and
checked in as tests in this change in
`clang_code_generator_callbacks.carbon`

An indicental bug that's also fixed, and caused all the other test case
churn,
is that the `CodeGenerator` created during `lower` wasn't getting passed
the
Clang `CodeGenOpts` and was creating its own default - so, most notably,
optimization flags were not respected. This meant that the LLVM IR from
Clang
was always -O0 style IR (optnone, no inlinehint, no TBAA, etc). With
this
change, now the Clang IRGen gets the real `CodeGenOpts` and respects
optimization/other flags specified there.

This is only meant to be a rough proof of concept - I'm totally open to
reworking this in any way (even quite substantially) if folks have ideas
about
how this should be implemented most generally/elegantly/etc.
2026-01-14 00:54:37 +00:00

73 lines
2.5 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef CARBON_TOOLCHAIN_SEM_IR_CPP_FILE_H_
#define CARBON_TOOLCHAIN_SEM_IR_CPP_FILE_H_
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/FileSystem.h"
namespace Carbon::SemIR {
// The result of compiling the C++ portion of a `File`, including both any
// imported C++ headers and any inline C++ fragments.
class CppFile {
public:
explicit CppFile(std::unique_ptr<clang::CompilerInstance> clang,
llvm::LLVMContext* llvm_context)
: clang_(std::move(clang)), llvm_context_(llvm_context) {}
// Access to compilation options.
auto diagnostic_options() const -> const clang::DiagnosticOptions& {
return clang_->getDiagnostics().getDiagnosticOptions();
}
auto lang_options() const -> const clang::LangOptions& {
return clang_->getLangOpts();
}
// Access to Clang's compilation environment.
auto source_manager() -> clang::SourceManager& {
return clang_->getSourceManager();
}
auto source_manager() const -> const clang::SourceManager& {
return clang_->getSourceManager();
}
// TODO: This doesn't really belong here, but is currently used by lowering
// because Clang's code generation may produce diagnostics.
auto diagnostics() const -> clang::DiagnosticsEngine& {
return clang_->getDiagnostics();
}
// Access to layers of Clang's C++ representation.
auto ast_context() -> clang::ASTContext& { return clang_->getASTContext(); }
auto ast_context() const -> const clang::ASTContext& {
return clang_->getASTContext();
}
auto llvm_context() const -> llvm::LLVMContext* { return llvm_context_; }
auto SetCodeGenerator(clang::CodeGenerator* code_generator) -> void {
code_generator_ = code_generator;
}
auto GetCodeGenerator() const -> clang::CodeGenerator* {
// Clang code generation should not actually modify the AST, but isn't
// const-correct.
return code_generator_;
}
private:
std::unique_ptr<clang::CompilerInstance> clang_;
llvm::LLVMContext* llvm_context_;
clang::CodeGenerator* code_generator_ = nullptr;
};
} // namespace Carbon::SemIR
#endif // CARBON_TOOLCHAIN_SEM_IR_CPP_FILE_H_