Skip to content

Commit a539f13

Browse files
committed
driver: add support for a more generic diagnostic handler
Signed-off-by: Luís Ferreira <[email protected]>
1 parent 338f352 commit a539f13

File tree

2 files changed

+73
-9
lines changed

2 files changed

+73
-9
lines changed

driver/codegenerator.cpp

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#else
3434
#include "llvm/IR/RemarkStreamer.h"
3535
#endif
36+
#include "llvm/Demangle/Demangle.h"
3637
#include "llvm/Support/FileSystem.h"
3738
#include "llvm/Support/Path.h"
3839
#include "llvm/Support/ToolOutputFile.h"
@@ -166,19 +167,68 @@ void inlineAsmDiagnosticHandler(const llvm::SMDiagnostic &d, void *context,
166167
inlineAsmDiagnostic(static_cast<IRState *>(context), d, locCookie);
167168
}
168169
#else
169-
struct InlineAsmDiagnosticHandler : public llvm::DiagnosticHandler {
170+
struct LDCDiagnosticHandler : public llvm::DiagnosticHandler {
170171
IRState *irs;
171-
InlineAsmDiagnosticHandler(IRState *irs) : irs(irs) {}
172+
LDCDiagnosticHandler(IRState *irs) : irs(irs) {}
172173

173174
// return false to defer to LLVMContext::diagnose()
174175
bool handleDiagnostics(const llvm::DiagnosticInfo &DI) override {
175-
if (DI.getKind() != llvm::DK_SrcMgr)
176+
switch (DI.getKind())
177+
{
178+
case llvm::DK_SrcMgr:
179+
{
180+
const auto &DISM = llvm::cast<llvm::DiagnosticInfoSrcMgr>(DI);
181+
switch (DISM.getSeverity())
182+
{
183+
case llvm::DS_Error:
184+
++global.errors;
185+
break;
186+
case llvm::DS_Warning:
187+
++global.warnings;
188+
break;
189+
case llvm::DS_Remark:
190+
case llvm::DS_Note:
191+
return false;
192+
}
193+
194+
inlineAsmDiagnostic(irs, DISM.getSMDiag(), DISM.getLocCookie());
195+
return true;
196+
}
197+
case llvm::DK_StackSize:
198+
{
199+
const auto &DISS = llvm::cast<llvm::DiagnosticInfoStackSize>(DI);
200+
#if LDC_LLVM_VER > 1400
201+
llvm::StringRef fname;
202+
unsigned line, column;
203+
DISS.getLocation(fname, line, column);
204+
const auto loc = Loc(fname.str().c_str(), line, column);
205+
#else
206+
const auto loc = Loc(nullptr, 0, 0);
207+
#endif
208+
switch (DISS.getSeverity())
209+
{
210+
case llvm::DS_Error:
211+
error(loc, "stack frame size (%ld) exceeds limit (%ld) in '%s'",
212+
DISS.getStackSize(),
213+
DISS.getStackLimit(),
214+
llvm::demangle(DISS.getFunction().getName().str()).c_str()
215+
);
216+
return true;
217+
case llvm::DS_Warning:
218+
warning(loc, "stack frame size (%ld) exceeds limit (%ld) in '%s'",
219+
DISS.getStackSize(),
220+
DISS.getStackLimit(),
221+
llvm::demangle(DISS.getFunction().getName().str()).c_str()
222+
);
223+
return true;
224+
case llvm::DS_Remark:
225+
case llvm::DS_Note:
226+
return false;
227+
}
176228
return false;
177-
178-
const auto &DISM = llvm::cast<llvm::DiagnosticInfoSrcMgr>(DI);
179-
if (DISM.getKind() == llvm::SourceMgr::DK_Error)
180-
++global.errors;
181-
return inlineAsmDiagnostic(irs, DISM.getSMDiag(), DISM.getLocCookie());
229+
}
230+
}
231+
return false;
182232
}
183233
};
184234
#endif
@@ -280,7 +330,7 @@ void CodeGenerator::writeAndFreeLLModule(const char *filename) {
280330
context_.setInlineAsmDiagnosticHandler(inlineAsmDiagnosticHandler, ir_);
281331
#else
282332
context_.setDiagnosticHandler(
283-
std::make_unique<InlineAsmDiagnosticHandler>(ir_));
333+
std::make_unique<LDCDiagnosticHandler>(ir_));
284334
#endif
285335

286336
std::unique_ptr<llvm::ToolOutputFile> diagnosticsOutputFile =

tests/codegen/attr_warn_stack_size.d

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module attr_warn_stack_size;
2+
// Test diagnostics for warnings on stack size
3+
4+
// RUN: %ldc -wi -c %s 2>&1 | FileCheck %s
5+
6+
import ldc.attributes;
7+
8+
// CHECK: {{.*}}Warning: stack frame size (8) exceeds limit (1) in '_D20attr_warn_stack_size6foobarFiZf'
9+
@llvmAttr("warn-stack-size", "1")
10+
float foobar(int f)
11+
{
12+
float _ = f;
13+
return _;
14+
}

0 commit comments

Comments
 (0)