Skip to content

Commit

Permalink
driver: add support for a more generic diagnostic handler
Browse files Browse the repository at this point in the history
Signed-off-by: Luís Ferreira <[email protected]>
  • Loading branch information
ljmf00 committed Jan 22, 2023
1 parent 338f352 commit 626823c
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 9 deletions.
68 changes: 59 additions & 9 deletions driver/codegenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#else
#include "llvm/IR/RemarkStreamer.h"
#endif
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ToolOutputFile.h"
Expand Down Expand Up @@ -166,19 +167,68 @@ void inlineAsmDiagnosticHandler(const llvm::SMDiagnostic &d, void *context,
inlineAsmDiagnostic(static_cast<IRState *>(context), d, locCookie);
}
#else
struct InlineAsmDiagnosticHandler : public llvm::DiagnosticHandler {
struct LDCDiagnosticHandler : public llvm::DiagnosticHandler {
IRState *irs;
InlineAsmDiagnosticHandler(IRState *irs) : irs(irs) {}
LDCDiagnosticHandler(IRState *irs) : irs(irs) {}

// return false to defer to LLVMContext::diagnose()
bool handleDiagnostics(const llvm::DiagnosticInfo &DI) override {
if (DI.getKind() != llvm::DK_SrcMgr)
switch (DI.getKind())
{
case llvm::DK_SrcMgr:
{
const auto &DISM = llvm::cast<llvm::DiagnosticInfoSrcMgr>(DI);
switch (DISM.getSeverity())
{
case llvm::DS_Error:
++global.errors;
break;
case llvm::DS_Warning:
++global.warnings;
break;
case llvm::DS_Remark:
case llvm::DS_Note:
return false;
}

inlineAsmDiagnostic(irs, DISM.getSMDiag(), DISM.getLocCookie());
return true;
}
case llvm::DK_StackSize:
{
const auto &DISS = llvm::cast<llvm::DiagnosticInfoStackSize>(DI);
#if LDC_LLVM_VER >= 1500
llvm::StringRef fname;
unsigned line, column;
DISS.getLocation(fname, line, column);
const auto loc = Loc(fname.str().c_str(), line, column);
#else
const auto loc = Loc(nullptr, 0, 0);
#endif
switch (DISS.getSeverity())
{
case llvm::DS_Error:
error(loc, "stack frame size (%ld) exceeds limit (%ld) in '%s'",
DISS.getStackSize(),
DISS.getStackLimit(),
llvm::demangle(DISS.getFunction().getName().str()).c_str()
);
return true;
case llvm::DS_Warning:
warning(loc, "stack frame size (%ld) exceeds limit (%ld) in '%s'",
DISS.getStackSize(),
DISS.getStackLimit(),
llvm::demangle(DISS.getFunction().getName().str()).c_str()
);
return true;
case llvm::DS_Remark:
case llvm::DS_Note:
return false;
}
return false;

const auto &DISM = llvm::cast<llvm::DiagnosticInfoSrcMgr>(DI);
if (DISM.getKind() == llvm::SourceMgr::DK_Error)
++global.errors;
return inlineAsmDiagnostic(irs, DISM.getSMDiag(), DISM.getLocCookie());
}
}
return false;
}
};
#endif
Expand Down Expand Up @@ -280,7 +330,7 @@ void CodeGenerator::writeAndFreeLLModule(const char *filename) {
context_.setInlineAsmDiagnosticHandler(inlineAsmDiagnosticHandler, ir_);
#else
context_.setDiagnosticHandler(
std::make_unique<InlineAsmDiagnosticHandler>(ir_));
std::make_unique<LDCDiagnosticHandler>(ir_));
#endif

std::unique_ptr<llvm::ToolOutputFile> diagnosticsOutputFile =
Expand Down
15 changes: 15 additions & 0 deletions tests/codegen/attr_warn_stack_size.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Test diagnostics for warnings on stack size

// REQUIRES: atleast_llvm1400

// RUN: %ldc -wi -c %s 2>&1 | FileCheck %s

import ldc.attributes;

// CHECK: {{.*}}Warning: stack frame size (8) exceeds limit (1) in '{{.*}}foobar{{.*}}'
@llvmAttr("warn-stack-size", "1")
float foobar(int f)
{
float _ = f;
return _;
}

0 comments on commit 626823c

Please sign in to comment.