mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:00:13 +01:00
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.
73 lines
2.5 KiB
C++
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_
|