mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:00:11 +01:00
Change CodeGen to use a diagnostic consumer (#5847)
We've been trying to have errors/warnings all go through the diagnostics consumers instead of straight to stderr.
This commit is contained in:
@@ -17,6 +17,8 @@ cc_library(
|
||||
hdrs = ["codegen.h"],
|
||||
deps = [
|
||||
"//common:check",
|
||||
"//toolchain/diagnostics:diagnostic_emitter",
|
||||
"//toolchain/diagnostics:file_diagnostics",
|
||||
"@llvm-project//llvm:Core",
|
||||
"@llvm-project//llvm:MC",
|
||||
"@llvm-project//llvm:Support",
|
||||
|
||||
@@ -13,15 +13,16 @@
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/TargetParser/Host.h"
|
||||
#include "toolchain/diagnostics/diagnostic_consumer.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto CodeGen::Make(llvm::Module* module, llvm::StringRef target_triple_str,
|
||||
llvm::raw_pwrite_stream* errors) -> std::optional<CodeGen> {
|
||||
Diagnostics::Consumer* consumer) -> std::optional<CodeGen> {
|
||||
std::string error;
|
||||
const llvm::Target* target =
|
||||
llvm::TargetRegistry::lookupTarget(target_triple_str, error);
|
||||
CARBON_CHECK(target, "Target should be validated before codegen");
|
||||
CARBON_CHECK(target, "Target should be validated before codegen: {0}", error);
|
||||
|
||||
llvm::Triple target_triple(target_triple_str);
|
||||
module->setTargetTriple(target_triple);
|
||||
@@ -30,7 +31,8 @@ auto CodeGen::Make(llvm::Module* module, llvm::StringRef target_triple_str,
|
||||
constexpr llvm::StringLiteral Features = "";
|
||||
|
||||
llvm::TargetOptions target_opts;
|
||||
CodeGen codegen(module, errors);
|
||||
CodeGen codegen(module,
|
||||
consumer ? consumer : &Diagnostics::ConsoleConsumer());
|
||||
codegen.target_machine_.reset(target->createTargetMachine(
|
||||
target_triple, CPU, Features, target_opts, llvm::Reloc::PIC_));
|
||||
return codegen;
|
||||
@@ -54,7 +56,9 @@ auto CodeGen::EmitCode(llvm::raw_pwrite_stream& out,
|
||||
llvm::legacy::PassManager pass;
|
||||
// Note that this returns true on an error.
|
||||
if (target_machine_->addPassesToEmitFile(pass, out, nullptr, file_type)) {
|
||||
*errors_ << "error: unable to emit to this file\n";
|
||||
CARBON_DIAGNOSTIC(CodeGenUnableToEmit, Error,
|
||||
"unable to emit to this file");
|
||||
emitter_.Emit(module_->getName(), CodeGenUnableToEmit);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+15
-10
@@ -7,35 +7,37 @@
|
||||
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "toolchain/diagnostics/diagnostic_consumer.h"
|
||||
#include "toolchain/diagnostics/file_diagnostics.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
class CodeGen {
|
||||
public:
|
||||
// `module` and `errors` must not be null.
|
||||
// `module` and `errors` must not be null. `consumer` may be null, in which
|
||||
// case diagnostics go to stderr.
|
||||
static auto Make(llvm::Module* module, llvm::StringRef target_triple_str,
|
||||
llvm::raw_pwrite_stream* errors) -> std::optional<CodeGen>;
|
||||
Diagnostics::Consumer* consumer = nullptr)
|
||||
-> std::optional<CodeGen>;
|
||||
|
||||
// Generates the object code file.
|
||||
// Returns false in case of failure, and any information about the failure is
|
||||
// printed to the error stream.
|
||||
//
|
||||
// Note that unlike the error stream, this requires a `pwrite` stream to allow
|
||||
// patching the output.
|
||||
// Note this requires a `pwrite` stream to allow patching the output.
|
||||
auto EmitObject(llvm::raw_pwrite_stream& out) -> bool;
|
||||
|
||||
// Prints the assembly to stdout.
|
||||
// Returns false in case of failure, and any information about the failure is
|
||||
// printed to the error stream.
|
||||
//
|
||||
// Note that unlike the error stream, this requires a `pwrite` stream to allow
|
||||
// patching the output.
|
||||
// Note this requires a `pwrite` stream to allow patching the output.
|
||||
auto EmitAssembly(llvm::raw_pwrite_stream& out) -> bool;
|
||||
|
||||
private:
|
||||
// `module` and `errors` must not be null.
|
||||
explicit CodeGen(llvm::Module* module, llvm::raw_pwrite_stream* errors)
|
||||
: module_(module), errors_(errors) {}
|
||||
// `module` and `consumer` must not be null.
|
||||
explicit CodeGen(llvm::Module* module, Diagnostics::Consumer* consumer)
|
||||
: module_(module), emitter_(consumer) {}
|
||||
|
||||
// Using the llvm pass emits either assembly or object code to dest.
|
||||
// Returns false in case of failure, and any information about the failure is
|
||||
@@ -44,7 +46,10 @@ class CodeGen {
|
||||
-> bool;
|
||||
|
||||
llvm::Module* module_;
|
||||
llvm::raw_pwrite_stream* errors_;
|
||||
|
||||
// The emitter for diagnostics.
|
||||
Diagnostics::FileEmitter emitter_;
|
||||
|
||||
std::unique_ptr<llvm::TargetMachine> target_machine_;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ constexpr Kind UntestedKinds[] = {
|
||||
// This is a little long but is tested in lex/numeric_literal_test.cpp.
|
||||
Kind::TooManyDigits,
|
||||
|
||||
// Producing an emit failure may be infeasible.
|
||||
Kind::CodeGenUnableToEmit,
|
||||
|
||||
// TODO: This can only fire if the first message in a diagnostic is rooted
|
||||
// in a file other than the file being compiled. The language server
|
||||
// currently only supports compiling one file at a time. Do one of:
|
||||
|
||||
@@ -499,6 +499,12 @@ CARBON_DIAGNOSTIC_KIND(GenericMissingExplicitParameters)
|
||||
// Pattern matching diagnostics.
|
||||
CARBON_DIAGNOSTIC_KIND(TuplePatternSizeDoesntMatchLiteral)
|
||||
|
||||
// ============================================================================
|
||||
// CodeGen diagnostics
|
||||
// ============================================================================
|
||||
|
||||
CARBON_DIAGNOSTIC_KIND(CodeGenUnableToEmit)
|
||||
|
||||
// ============================================================================
|
||||
// Language server diagnostics
|
||||
// ============================================================================
|
||||
|
||||
@@ -741,8 +741,7 @@ auto CompilationUnit::PostCompile() -> void {
|
||||
|
||||
auto CompilationUnit::RunCodeGenHelper() -> bool {
|
||||
std::optional<CodeGen> codegen =
|
||||
CodeGen::Make(module_.get(), options_->codegen_options.target,
|
||||
driver_env_->error_stream);
|
||||
CodeGen::Make(module_.get(), options_->codegen_options.target, consumer_);
|
||||
if (!codegen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user