mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 20:06:03 +03:00
Fix nested functions.
My last patch was a little over-zealous in passing `undef`, it always passed `undef` to inner functions expecting a single context frame.
This commit is contained in:
parent
0262a6ec8f
commit
46565f1adc
3 changed files with 40 additions and 33 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "gen/llvmhelpers.h"
|
||||
#include "gen/logger.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "gen/functions.h"
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
namespace cl = llvm::cl;
|
||||
|
@ -237,16 +238,19 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
|||
return llvm::UndefValue::get(getVoidPtrType());
|
||||
}
|
||||
if (nestedCtx == NCHybrid) {
|
||||
// If sym is a nested function, and it's parent context is different than the
|
||||
// one we got, adjust it.
|
||||
if (FuncDeclaration* symfd = sym->isFuncDeclaration()) {
|
||||
// Make sure we've had a chance to analyze nested context usage
|
||||
DtoDefineFunction(symfd);
|
||||
|
||||
if (FuncDeclaration* fd = getParentFunc(sym->isFuncDeclaration(), true)) {
|
||||
// if this is for a function that doesn't access variables from
|
||||
// enclosing scopes, it doesn't matter what we pass.
|
||||
// Tell LLVM about it by passing an 'undef'.
|
||||
if (fd->ir.irFunc->depth == 0)
|
||||
if (symfd && symfd->ir.irFunc->depth == -1)
|
||||
return llvm::UndefValue::get(getVoidPtrType());
|
||||
|
||||
// If sym is a nested function, and it's parent context is different than the
|
||||
// one we got, adjust it.
|
||||
if (FuncDeclaration* fd = getParentFunc(symfd, true)) {
|
||||
Logger::println("For nested function, parent is %s", fd->toChars());
|
||||
FuncDeclaration* ctxfd = irfunc->decl;
|
||||
Logger::println("Current function is %s", ctxfd->toChars());
|
||||
|
@ -273,6 +277,7 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger::cout() << "result = " << *val << '\n';
|
||||
Logger::cout() << "of type " << *val->getType() << '\n';
|
||||
return val;
|
||||
|
@ -376,15 +381,15 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||
// start with adding all enclosing parent frames until a static parent is reached
|
||||
|
||||
const LLStructType* innerFrameType = NULL;
|
||||
unsigned depth = 0;
|
||||
unsigned depth = -1;
|
||||
if (!fd->isStatic()) {
|
||||
if (FuncDeclaration* parfd = getParentFunc(fd, true)) {
|
||||
innerFrameType = parfd->ir.irFunc->frameType;
|
||||
if (innerFrameType)
|
||||
depth = parfd->ir.irFunc->depth + 1;
|
||||
depth = parfd->ir.irFunc->depth;
|
||||
}
|
||||
}
|
||||
fd->ir.irFunc->depth = depth;
|
||||
fd->ir.irFunc->depth = ++depth;
|
||||
|
||||
Logger::cout() << "Function " << fd->toChars() << " has depth " << depth << '\n';
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ IrFunction::IrFunction(FuncDeclaration* fd)
|
|||
|
||||
nestedVar = NULL;
|
||||
frameType = NULL;
|
||||
depth = 0;
|
||||
depth = -1;
|
||||
|
||||
_arguments = NULL;
|
||||
_argptr = NULL;
|
||||
|
|
|
@ -46,7 +46,9 @@ struct IrFunction : IrBase
|
|||
|
||||
llvm::Value* nestedVar; // nested var alloca
|
||||
const llvm::StructType* frameType; // type of nested context (not for -nested-ctx=array)
|
||||
unsigned depth; // number of enclosing functions with variables accessed by nested functions
|
||||
// number of enclosing functions with variables accessed by nested functions
|
||||
// (-1 if neither this function nor any enclosing ones access variables from enclosing functions)
|
||||
int depth;
|
||||
|
||||
llvm::Value* _arguments;
|
||||
llvm::Value* _argptr;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue