diff --git a/gen/asm-x86.h b/gen/asm-x86.h index 2d243326..8e1e5334 100644 --- a/gen/asm-x86.h +++ b/gen/asm-x86.h @@ -1890,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, "<>", id); } /* Determines whether the operand is a register, memory reference diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index d3a8217b..8acc2e00 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -149,6 +149,26 @@ AsmParserCommon* asmparser = NULL; #include "asm-x86.h" // x86_64 assembly parser #undef ASM_X86_64 +/** + * Replaces <> 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("<>"); + + 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) { if (sc->func && sc->func->isSafe()) @@ -442,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; @@ -836,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; }