mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-01 01:53:16 +01:00
Merge pull request #345 from klickverbot/template-function-label
Fix inline asm labels in template functions.
This commit is contained in:
@@ -5509,9 +5509,6 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
|
||||
#endif
|
||||
this->lblock = NULL;
|
||||
this->fwdrefs = NULL;
|
||||
#if IN_LLVM
|
||||
this->asmLabel = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
Statement *LabelStatement::syntaxCopy()
|
||||
|
||||
@@ -943,7 +943,6 @@ struct LabelStatement : Statement
|
||||
void toIR(IRState *irs);
|
||||
|
||||
#if IN_LLVM
|
||||
bool asmLabel; // for labels inside inline assembler
|
||||
void toNakedIR(IRState *irs);
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#if defined(_MSC_VER)
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#include "gen/llvmhelpers.h" // printLabelName
|
||||
|
||||
#ifndef ASM_X86_64
|
||||
namespace AsmParserx8632
|
||||
@@ -1889,7 +1890,9 @@ namespace AsmParserx8664
|
||||
|
||||
void addLabel ( char* id )
|
||||
{
|
||||
printLabelName(insnTemplate, sc->func->mangle(), id);
|
||||
// We need to delay emitting the actual function name, see
|
||||
// replace_func_name in asmstmt.cpp for details.
|
||||
printLabelName(insnTemplate, "<<func>>", id);
|
||||
}
|
||||
|
||||
/* Determines whether the operand is a register, memory reference
|
||||
@@ -2496,7 +2499,7 @@ namespace AsmParserx8664
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain memory reference to variable
|
||||
// Plain memory reference to variable or reference to label.
|
||||
|
||||
/* If in a reg, DMD moves to memory.. even with -O, so we'll do the same
|
||||
by always using the "m" contraint.
|
||||
|
||||
@@ -149,7 +149,25 @@ AsmParserCommon* asmparser = NULL;
|
||||
#include "asm-x86.h" // x86_64 assembly parser
|
||||
#undef ASM_X86_64
|
||||
|
||||
bool d_have_inline_asm() { return true; }
|
||||
/**
|
||||
* Replaces <<func>> with the name of the currently codegen'd function.
|
||||
*
|
||||
* This kludge is required to handle labels correctly, as the instruction
|
||||
* strings for jumps, … are generated during semantic3, but attribute inference
|
||||
* might change the function type (and hence the mangled name) right at the end
|
||||
* of semantic3.
|
||||
*/
|
||||
static void replace_func_name(IRState* p, std::string& insnt)
|
||||
{
|
||||
static const std::string needle("<<func>>");
|
||||
|
||||
size_t pos;
|
||||
while (std::string::npos != (pos = insnt.find(needle)))
|
||||
{
|
||||
// This will only happen for few instructions, and only once for those.
|
||||
insnt.replace(pos, needle.size(), p->func()->decl->mangle(false));
|
||||
}
|
||||
}
|
||||
|
||||
Statement *AsmStatement::semantic(Scope *sc)
|
||||
{
|
||||
@@ -444,6 +462,8 @@ AsmStatement::toIR(IRState * irs)
|
||||
|
||||
// excessive commas are removed later...
|
||||
|
||||
replace_func_name(irs, code->insnTemplate);
|
||||
|
||||
// push asm statement
|
||||
IRAsmStmt* asmStmt = new IRAsmStmt;
|
||||
asmStmt->code = code->insnTemplate;
|
||||
@@ -838,6 +858,7 @@ void AsmStatement::toNakedIR(IRState *p)
|
||||
AsmCode * code = (AsmCode *) asmcode;
|
||||
|
||||
// build asm stmt
|
||||
replace_func_name(p, code->insnTemplate);
|
||||
p->nakedAsm << "\t" << code->insnTemplate << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -232,12 +232,6 @@ void DtoGoto(Loc loc, Identifier* target, TryFinallyStatement* sourceFinally)
|
||||
fatal();
|
||||
}
|
||||
|
||||
// if the target label is inside inline asm, error
|
||||
if(lblstmt->asmLabel) {
|
||||
error(loc, "cannot goto to label %s inside an inline asm block", target->toChars());
|
||||
fatal();
|
||||
}
|
||||
|
||||
// find target basic block
|
||||
std::string labelname = gIR->func()->gen->getScopedLabelName(target->toChars());
|
||||
llvm::BasicBlock*& targetBB = gIR->func()->gen->labelToBB[labelname];
|
||||
|
||||
Reference in New Issue
Block a user