mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-21 03:21:52 +01:00
First merge of 2.064 beta.
This corresponds to DMD commit a913ce4bc59a94a022a27e390fc841f4aededffb. Doesn't build Phobos yet.
This commit is contained in:
committed by
Kai Nacke
parent
c400d180d2
commit
cb341586e3
2
gen/aa.h
2
gen/aa.h
@@ -19,7 +19,7 @@
|
||||
enum TOK;
|
||||
class DValue;
|
||||
struct Loc;
|
||||
struct Type;
|
||||
class Type;
|
||||
namespace llvm { class Value; }
|
||||
|
||||
DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue);
|
||||
|
||||
@@ -177,10 +177,9 @@ namespace {
|
||||
}
|
||||
}
|
||||
} else if (ty->ty == Tstruct) {
|
||||
Array* fields = &static_cast<TypeStruct*>(ty)->sym->fields;
|
||||
for (size_t i = 0; i < fields->dim; i++) {
|
||||
VarDeclaration* field = static_cast<VarDeclaration*>(fields->data[i]);
|
||||
classifyType(accum, field->type, offset + field->offset);
|
||||
VarDeclarations& fields = static_cast<TypeStruct*>(ty)->sym->fields;
|
||||
for (size_t i = 0; i < fields.dim; i++) {
|
||||
classifyType(accum, fields[i]->type, offset + fields[i]->offset);
|
||||
}
|
||||
} else {
|
||||
if (Logger::enabled())
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#endif
|
||||
#include <vector>
|
||||
|
||||
struct Type;
|
||||
struct TypeFunction;
|
||||
class Type;
|
||||
class TypeFunction;
|
||||
struct IrFuncTy;
|
||||
struct IrFuncTyArg;
|
||||
class DValue;
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
#include "lexer.h"
|
||||
#include "gen/llvm.h"
|
||||
|
||||
struct ArrayInitializer;
|
||||
struct ArrayLiteralExp;
|
||||
class ArrayInitializer;
|
||||
class ArrayLiteralExp;
|
||||
class DSliceValue;
|
||||
class DValue;
|
||||
struct Expression;
|
||||
class Expression;
|
||||
struct IRState;
|
||||
struct Loc;
|
||||
struct Type;
|
||||
class Type;
|
||||
|
||||
llvm::StructType* DtoArrayType(Type* arrayTy);
|
||||
llvm::StructType* DtoArrayType(LLType* elemTy);
|
||||
|
||||
@@ -1870,7 +1870,7 @@ namespace AsmParserx8664
|
||||
Reg segmentPrefix;
|
||||
Reg reg;
|
||||
sinteger_t constDisplacement; // use to build up.. should be int constant in the end..
|
||||
Array symbolDisplacement; // array of expressions or..
|
||||
Expressions symbolDisplacement; // array of expressions or..
|
||||
Reg baseReg;
|
||||
Reg indexReg;
|
||||
int scale;
|
||||
@@ -3158,7 +3158,7 @@ namespace AsmParserx8664
|
||||
llvm_unreachable("Unknown integer operation.");
|
||||
}
|
||||
e = e->semantic ( sc );
|
||||
return e->optimize ( WANTvalue | WANTinterpret );
|
||||
return e->ctfeInterpret();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3626,7 +3626,7 @@ namespace AsmParserx8664
|
||||
|
||||
// parse primary: DMD allows 'MyAlign' (const int) but not '2+2'
|
||||
// GAS is padding with NOPs last time I checked.
|
||||
Expression * e = parseAsmExp()->optimize ( WANTvalue | WANTinterpret );
|
||||
Expression * e = parseAsmExp()->ctfeInterpret();
|
||||
uinteger_t align = e->toUInteger();
|
||||
|
||||
if ( ( align & ( align - 1 ) ) == 0 )
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <string>
|
||||
|
||||
template <typename TYPE> struct ArrayBase;
|
||||
typedef ArrayBase<char> Strings;
|
||||
template <typename TYPE> struct Array;
|
||||
typedef Array<char> Strings;
|
||||
|
||||
namespace opts {
|
||||
namespace cl = llvm::cl;
|
||||
|
||||
@@ -321,7 +321,7 @@ DValue* DtoDynamicCastObject(DValue* val, Type* _to)
|
||||
// Object _d_dynamic_cast(Object o, ClassInfo c)
|
||||
|
||||
DtoResolveClass(ClassDeclaration::object);
|
||||
DtoResolveClass(ClassDeclaration::classinfo);
|
||||
DtoResolveClass(Type::typeinfoclass);
|
||||
|
||||
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast");
|
||||
LLFunctionType* funcTy = func->getFunctionType();
|
||||
@@ -384,7 +384,7 @@ DValue* DtoDynamicCastInterface(DValue* val, Type* _to)
|
||||
// Object _d_interface_cast(void* p, ClassInfo c)
|
||||
|
||||
DtoResolveClass(ClassDeclaration::object);
|
||||
DtoResolveClass(ClassDeclaration::classinfo);
|
||||
DtoResolveClass(Type::typeinfoclass);
|
||||
|
||||
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast");
|
||||
LLFunctionType* funcTy = func->getFunctionType();
|
||||
@@ -467,7 +467,7 @@ LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl, char* n
|
||||
{
|
||||
// sanity checks
|
||||
assert(fdecl->isVirtual());
|
||||
assert(!fdecl->isFinal());
|
||||
assert(!fdecl->isFinalFunc());
|
||||
assert(inst->getType()->toBasetype()->ty == Tclass);
|
||||
// 0 is always ClassInfo/Interface* unless it is a CPP interface
|
||||
assert(fdecl->vtblIndex > 0 || (fdecl->vtblIndex == 0 && fdecl->linkage == LINKcpp));
|
||||
@@ -650,7 +650,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
IrAggr* ir = cd->ir.irAggr;
|
||||
assert(ir);
|
||||
|
||||
ClassDeclaration* cinfo = ClassDeclaration::classinfo;
|
||||
ClassDeclaration* cinfo = Type::typeinfoclass;
|
||||
|
||||
if (cinfo->fields.dim != 12)
|
||||
{
|
||||
@@ -659,7 +659,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
}
|
||||
|
||||
// use the rtti builder
|
||||
RTTIBuilder b(ClassDeclaration::classinfo);
|
||||
RTTIBuilder b(cinfo);
|
||||
|
||||
LLConstant* c;
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
#include "gen/structs.h"
|
||||
|
||||
struct ClassDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct NewExp;
|
||||
struct TypeClass;
|
||||
class ClassDeclaration;
|
||||
class CtorDeclaration;
|
||||
class FuncDeclaration;
|
||||
class NewExp;
|
||||
class TypeClass;
|
||||
|
||||
/// Resolves the llvm type for a class declaration
|
||||
void DtoResolveClass(ClassDeclaration* cd);
|
||||
@@ -41,7 +41,6 @@ llvm::Constant* DtoDefineClassInfo(ClassDeclaration* cd);
|
||||
|
||||
DValue* DtoNewClass(Loc loc, TypeClass* type, NewExp* newexp);
|
||||
void DtoInitClass(TypeClass* tc, llvm::Value* dst);
|
||||
DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* arguments, llvm::Value* mem);
|
||||
void DtoFinalizeClass(llvm::Value* inst);
|
||||
|
||||
DValue* DtoCastClass(DValue* val, Type* to);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
class DValue;
|
||||
struct Loc;
|
||||
struct Type;
|
||||
class Type;
|
||||
namespace llvm
|
||||
{
|
||||
class Constant;
|
||||
|
||||
@@ -340,13 +340,13 @@ void TemplateMixin::codegen(IRState *p)
|
||||
|
||||
void AttribDeclaration::codegen(IRState *p)
|
||||
{
|
||||
Array *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = static_cast<Dsymbol *>(d->data[i]);
|
||||
s->codegen(p);
|
||||
{
|
||||
(*d)[i]->codegen(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,7 +578,7 @@ llvm::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd)
|
||||
return DBuilder.createFunction(
|
||||
CU, // context
|
||||
fd->toPrettyChars(), // name
|
||||
fd->mangle(), // linkage name
|
||||
fd->mangleExact(), // linkage name
|
||||
file, // file
|
||||
fd->loc.linnum, // line no
|
||||
DIFnType, // type
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
|
||||
struct IRState;
|
||||
|
||||
struct ClassDeclaration;
|
||||
struct Dsymbol;
|
||||
struct FuncDeclaration;
|
||||
struct Module;
|
||||
struct Type;
|
||||
struct VarDeclaration;
|
||||
class ClassDeclaration;
|
||||
class Dsymbol;
|
||||
class FuncDeclaration;
|
||||
class Module;
|
||||
class Type;
|
||||
class VarDeclaration;
|
||||
|
||||
namespace llvm {
|
||||
class GlobalVariable;
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#include "root.h"
|
||||
#include <cassert>
|
||||
|
||||
struct Type;
|
||||
struct Dsymbol;
|
||||
struct VarDeclaration;
|
||||
struct FuncDeclaration;
|
||||
class Type;
|
||||
class Dsymbol;
|
||||
class VarDeclaration;
|
||||
class FuncDeclaration;
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
|
||||
@@ -49,6 +49,8 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
|
||||
// sanity check
|
||||
assert(type->ty == Tfunction);
|
||||
TypeFunction* f = static_cast<TypeFunction*>(type);
|
||||
assert(f->next && "Encountered function type with invalid return type; "
|
||||
"trying to codegen function ignored by the frontend?");
|
||||
|
||||
TargetABI* abi = (f->linkage == LINKintrinsic ? TargetABI::getIntrinsic() : gABI);
|
||||
// Tell the ABI we're resolving a new function type
|
||||
@@ -158,7 +160,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
|
||||
if (f->varargs == 1)
|
||||
{
|
||||
// _arguments
|
||||
newIrFty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false);
|
||||
newIrFty.arg_arguments = new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
|
||||
lidx++;
|
||||
// _argptr
|
||||
#if LDC_LLVM_VER >= 303
|
||||
@@ -298,7 +300,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
|
||||
|
||||
LLFunction* DtoInlineIRFunction(FuncDeclaration* fdecl)
|
||||
{
|
||||
const char* mangled_name = fdecl->mangle();
|
||||
const char* mangled_name = fdecl->mangleExact();
|
||||
TemplateInstance* tinst = fdecl->parent->isTemplateInstance();
|
||||
assert(tinst);
|
||||
|
||||
@@ -483,54 +485,56 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
|
||||
if (fdecl->parent)
|
||||
if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance())
|
||||
{
|
||||
TemplateDeclaration* tempdecl = tinst->tempdecl;
|
||||
if (tempdecl->llvmInternal == LLVMva_arg)
|
||||
if (TemplateDeclaration* tempdecl = tinst->tempdecl->isTemplateDeclaration())
|
||||
{
|
||||
Logger::println("magic va_arg found");
|
||||
fdecl->llvmInternal = LLVMva_arg;
|
||||
fdecl->ir.resolved = true;
|
||||
fdecl->ir.declared = true;
|
||||
fdecl->ir.initialized = true;
|
||||
fdecl->ir.defined = true;
|
||||
return; // this gets mapped to an instruction so a declaration makes no sence
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMva_start)
|
||||
{
|
||||
Logger::println("magic va_start found");
|
||||
fdecl->llvmInternal = LLVMva_start;
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMintrinsic)
|
||||
{
|
||||
Logger::println("overloaded intrinsic found");
|
||||
fdecl->llvmInternal = LLVMintrinsic;
|
||||
DtoOverloadedIntrinsicName(tinst, tempdecl, fdecl->intrinsicName);
|
||||
fdecl->linkage = LINKintrinsic;
|
||||
static_cast<TypeFunction*>(fdecl->type)->linkage = LINKintrinsic;
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMinline_asm)
|
||||
{
|
||||
Logger::println("magic inline asm found");
|
||||
TypeFunction* tf = static_cast<TypeFunction*>(fdecl->type);
|
||||
if (tf->varargs != 1 || (fdecl->parameters && fdecl->parameters->dim != 0))
|
||||
if (tempdecl->llvmInternal == LLVMva_arg)
|
||||
{
|
||||
error("invalid __asm declaration, must be a D style variadic with no explicit parameters");
|
||||
fatal();
|
||||
Logger::println("magic va_arg found");
|
||||
fdecl->llvmInternal = LLVMva_arg;
|
||||
fdecl->ir.resolved = true;
|
||||
fdecl->ir.declared = true;
|
||||
fdecl->ir.initialized = true;
|
||||
fdecl->ir.defined = true;
|
||||
return; // this gets mapped to an instruction so a declaration makes no sence
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMva_start)
|
||||
{
|
||||
Logger::println("magic va_start found");
|
||||
fdecl->llvmInternal = LLVMva_start;
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMintrinsic)
|
||||
{
|
||||
Logger::println("overloaded intrinsic found");
|
||||
fdecl->llvmInternal = LLVMintrinsic;
|
||||
DtoOverloadedIntrinsicName(tinst, tempdecl, fdecl->intrinsicName);
|
||||
fdecl->linkage = LINKintrinsic;
|
||||
static_cast<TypeFunction*>(fdecl->type)->linkage = LINKintrinsic;
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMinline_asm)
|
||||
{
|
||||
Logger::println("magic inline asm found");
|
||||
TypeFunction* tf = static_cast<TypeFunction*>(fdecl->type);
|
||||
if (tf->varargs != 1 || (fdecl->parameters && fdecl->parameters->dim != 0))
|
||||
{
|
||||
error("invalid __asm declaration, must be a D style variadic with no explicit parameters");
|
||||
fatal();
|
||||
}
|
||||
fdecl->llvmInternal = LLVMinline_asm;
|
||||
fdecl->ir.resolved = true;
|
||||
fdecl->ir.declared = true;
|
||||
fdecl->ir.initialized = true;
|
||||
fdecl->ir.defined = true;
|
||||
return; // this gets mapped to a special inline asm call, no point in going on.
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMinline_ir)
|
||||
{
|
||||
fdecl->llvmInternal = LLVMinline_ir;
|
||||
fdecl->linkage = LINKc;
|
||||
fdecl->ir.defined = true;
|
||||
Type* type = fdecl->type;
|
||||
assert(type->ty == Tfunction);
|
||||
static_cast<TypeFunction*>(type)->linkage = LINKc;
|
||||
}
|
||||
fdecl->llvmInternal = LLVMinline_asm;
|
||||
fdecl->ir.resolved = true;
|
||||
fdecl->ir.declared = true;
|
||||
fdecl->ir.initialized = true;
|
||||
fdecl->ir.defined = true;
|
||||
return; // this gets mapped to a special inline asm call, no point in going on.
|
||||
}
|
||||
else if (tempdecl->llvmInternal == LLVMinline_ir)
|
||||
{
|
||||
fdecl->llvmInternal = LLVMinline_ir;
|
||||
fdecl->linkage = LINKc;
|
||||
fdecl->ir.defined = true;
|
||||
Type* type = fdecl->type;
|
||||
assert(type->ty == Tfunction);
|
||||
static_cast<TypeFunction*>(type)->linkage = LINKc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,7 +751,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
if (fdecl->llvmInternal == LLVMintrinsic)
|
||||
mangledName = fdecl->intrinsicName;
|
||||
else
|
||||
mangledName = fdecl->mangle();
|
||||
mangledName = fdecl->mangleExact();
|
||||
mangledName = gABI->mangleForLLVM(mangledName, link);
|
||||
|
||||
// construct function
|
||||
@@ -766,7 +770,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
llvm::GlobalValue::ExternalLinkage, mangledName, gIR->module);
|
||||
}
|
||||
} else if (func->getFunctionType() != functype) {
|
||||
error(fdecl->loc, "Function type does not match previously declared function with the same mangled name: %s", fdecl->mangle());
|
||||
error(fdecl->loc, "Function type does not match previously declared function with the same mangled name: %s", fdecl->mangleExact());
|
||||
fatal();
|
||||
}
|
||||
|
||||
@@ -898,16 +902,56 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
|
||||
void DtoDefineFunction(FuncDeclaration* fd)
|
||||
{
|
||||
DtoDeclareFunction(fd);
|
||||
|
||||
assert(fd->ir.declared);
|
||||
|
||||
if (Logger::enabled())
|
||||
Logger::println("DtoDefineFunction(%s): %s", fd->toPrettyChars(), fd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// Be sure to call DtoDeclareFunction first, as LDC_inline_asm functions are
|
||||
// "defined" there. TODO: Clean this up.
|
||||
if (fd->ir.defined) return;
|
||||
|
||||
// Skip generating code if this part of a TemplateInstance that is instantiated
|
||||
// only by non-root modules (i.e. modules not listed on the command line).
|
||||
// See DMD's FuncDeclaration::toObjFile. Check this before calling
|
||||
// DtoDeclareFunction DtoDeclareFunction to avoid touching unanalyzed code.
|
||||
TemplateInstance *ti = fd->inTemplateInstance();
|
||||
if (!global.params.useUnitTests &&
|
||||
ti && ti->instantiatingModule && !ti->instantiatingModule->isRoot())
|
||||
{
|
||||
Module *mi = ti->instantiatingModule;
|
||||
|
||||
// If mi imports any root modules, we still need to generate the code.
|
||||
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
||||
{
|
||||
Module *m = Module::amodules[i];
|
||||
m->insearch = 0;
|
||||
}
|
||||
bool importsRoot = false;
|
||||
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
||||
{
|
||||
Module *m = Module::amodules[i];
|
||||
if (m->isRoot() && mi->imports(m))
|
||||
{
|
||||
importsRoot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < Module::amodules.dim; ++i)
|
||||
{
|
||||
Module *m = Module::amodules[i];
|
||||
m->insearch = 0;
|
||||
}
|
||||
if (!importsRoot)
|
||||
{
|
||||
IF_LOG Logger::println("Ignoring; already instantiated in %s (%s)", ti->instantiatingModule->toChars(), ti->toChars());
|
||||
fd->ir.defined = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DtoDeclareFunction(fd);
|
||||
assert(fd->ir.declared);
|
||||
|
||||
// DtoResolveFunction might also set the defined flag for functions we
|
||||
// should not touch.
|
||||
if (fd->ir.defined) return;
|
||||
fd->ir.defined = true;
|
||||
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
#include "mars.h"
|
||||
|
||||
class DValue;
|
||||
struct Expression;
|
||||
struct FuncDeclaration;
|
||||
class Expression;
|
||||
class FuncDeclaration;
|
||||
struct IRAsmBlock;
|
||||
struct IrFuncTy;
|
||||
struct Parameter;
|
||||
struct Type;
|
||||
class Parameter;
|
||||
class Type;
|
||||
namespace llvm
|
||||
{
|
||||
class FunctionType;
|
||||
|
||||
@@ -46,14 +46,14 @@ extern const llvm::TargetData* gDataLayout;
|
||||
#endif
|
||||
extern TargetABI* gABI;
|
||||
|
||||
struct TypeFunction;
|
||||
struct TypeStruct;
|
||||
struct ClassDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct Module;
|
||||
struct TypeStruct;
|
||||
class TypeFunction;
|
||||
class TypeStruct;
|
||||
class ClassDeclaration;
|
||||
class FuncDeclaration;
|
||||
class Module;
|
||||
class TypeStruct;
|
||||
struct BaseClass;
|
||||
struct AnonDeclaration;
|
||||
class AnonDeclaration;
|
||||
|
||||
struct IrModule;
|
||||
|
||||
|
||||
@@ -1247,11 +1247,11 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
|
||||
{
|
||||
Logger::println("AttribDeclaration");
|
||||
// choose the right set in case this is a conditional declaration
|
||||
Array *d = a->include(NULL, NULL);
|
||||
Dsymbols *d = a->include(NULL, NULL);
|
||||
if (d)
|
||||
for (unsigned i=0; i < d->dim; ++i)
|
||||
{
|
||||
DtoDeclarationExp(static_cast<Dsymbol*>(d->data[i]));
|
||||
DtoDeclarationExp((*d)[i]);
|
||||
}
|
||||
}
|
||||
// mixin declaration
|
||||
@@ -1368,12 +1368,6 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
|
||||
Logger::println("const expression initializer");
|
||||
_init = DtoConstExpInit(loc, type, ex->exp);
|
||||
}
|
||||
else if (StructInitializer* si = init->isStructInitializer())
|
||||
{
|
||||
Logger::println("const struct initializer");
|
||||
DtoResolveDsymbol(si->ad);
|
||||
return si->ad->ir.irAggr->createStructInitializer(si);
|
||||
}
|
||||
else if (ArrayInitializer* ai = init->isArrayInitializer())
|
||||
{
|
||||
Logger::println("const array initializer");
|
||||
@@ -1385,7 +1379,10 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
|
||||
LLType* ty = voidToI8(DtoType(type));
|
||||
_init = LLConstant::getNullValue(ty);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// StructInitializer is no longer suposed to make it to the glue layer
|
||||
// in DMD 2.064.
|
||||
Logger::println("unsupported const initializer: %s", init->toChars());
|
||||
}
|
||||
return _init;
|
||||
@@ -1488,7 +1485,7 @@ LLConstant* DtoTypeInfoOf(Type* type, bool base)
|
||||
LLConstant* c = isaConstant(tidecl->ir.irGlobal->value);
|
||||
assert(c != NULL);
|
||||
if (base)
|
||||
return llvm::ConstantExpr::getBitCast(c, DtoType(Type::typeinfo->type));
|
||||
return llvm::ConstantExpr::getBitCast(c, DtoType(Type::dtypeinfo->type));
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
@@ -382,10 +382,6 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context)
|
||||
error("is missing 'class Object'");
|
||||
fatal();
|
||||
}
|
||||
if (!ClassDeclaration::classinfo) {
|
||||
error("is missing 'class ClassInfo'");
|
||||
fatal();
|
||||
}
|
||||
|
||||
LLVM_D_InitRuntime();
|
||||
|
||||
@@ -471,8 +467,8 @@ void Module::genmoduleinfo()
|
||||
// check for patch
|
||||
else
|
||||
{
|
||||
unsigned sizeof_ModuleInfo = 16 * Target::ptrsize;
|
||||
if (sizeof_ModuleInfo != moduleinfo->structsize)
|
||||
// The base struct should consist only of _flags/_index.
|
||||
if (moduleinfo->structsize != 4 + 4)
|
||||
{
|
||||
error("object.d ModuleInfo class is incorrect");
|
||||
fatal();
|
||||
@@ -484,7 +480,7 @@ void Module::genmoduleinfo()
|
||||
|
||||
// some types
|
||||
LLType* moduleinfoTy = moduleinfo->type->irtype->getLLType();
|
||||
LLType* classinfoTy = ClassDeclaration::classinfo->type->irtype->getLLType();
|
||||
LLType* classinfoTy = Type::typeinfoclass->type->irtype->getLLType();
|
||||
|
||||
// importedModules[]
|
||||
std::vector<LLConstant*> importInits;
|
||||
|
||||
@@ -96,7 +96,7 @@ void LabelStatement::toNakedIR(IRState *p)
|
||||
Logger::println("LabelStatement::toNakedIR(): %s", loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
printLabelName(p->nakedAsm, p->func()->decl->mangle(), ident->toChars());
|
||||
printLabelName(p->nakedAsm, p->func()->decl->mangleExact(), ident->toChars());
|
||||
p->nakedAsm << ":";
|
||||
|
||||
if (statement)
|
||||
@@ -107,7 +107,7 @@ void LabelStatement::toNakedIR(IRState *p)
|
||||
|
||||
void DtoDefineNakedFunction(FuncDeclaration* fd)
|
||||
{
|
||||
Logger::println("DtoDefineNakedFunction(%s)", fd->mangle());
|
||||
Logger::println("DtoDefineNakedFunction(%s)", fd->mangleExact());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(fd->ir.irFunc);
|
||||
@@ -122,7 +122,7 @@ void DtoDefineNakedFunction(FuncDeclaration* fd)
|
||||
|
||||
// FIXME: could we perhaps use llvm asmwriter to give us these details ?
|
||||
|
||||
const char* mangle = fd->mangle();
|
||||
const char* mangle = fd->mangleExact();
|
||||
std::ostringstream tmpstr;
|
||||
|
||||
bool const isWin = global.params.targetTriple.isOSWindows();
|
||||
@@ -215,7 +215,7 @@ void DtoDefineNakedFunction(FuncDeclaration* fd)
|
||||
|
||||
void emitABIReturnAsmStmt(IRAsmBlock* asmblock, Loc loc, FuncDeclaration* fdecl)
|
||||
{
|
||||
Logger::println("emitABIReturnAsmStmt(%s)", fdecl->mangle());
|
||||
Logger::println("emitABIReturnAsmStmt(%s)", fdecl->mangleExact());
|
||||
LOG_SCOPE;
|
||||
|
||||
IRAsmStmt* as = new IRAsmStmt;
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
struct PragmaDeclaration;
|
||||
struct Dsymbol;
|
||||
class PragmaDeclaration;
|
||||
class Dsymbol;
|
||||
struct Scope;
|
||||
|
||||
enum Pragma
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
#include "llvm/Constant.h"
|
||||
#endif
|
||||
|
||||
struct AggregateDeclaration;
|
||||
struct ClassDeclaration;
|
||||
struct Dsymbol;
|
||||
struct FuncDeclaration;
|
||||
class AggregateDeclaration;
|
||||
class ClassDeclaration;
|
||||
class Dsymbol;
|
||||
class FuncDeclaration;
|
||||
struct IrGlobal;
|
||||
struct IrAggr;
|
||||
struct Type;
|
||||
struct TypeClass;
|
||||
class Type;
|
||||
class TypeClass;
|
||||
namespace llvm { class StructType; }
|
||||
|
||||
struct RTTIBuilder
|
||||
|
||||
@@ -188,8 +188,8 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
LLType* dstringTy = DtoType(Type::tdchar->arrayOf());
|
||||
|
||||
LLType* objectTy = DtoType(ClassDeclaration::object->type);
|
||||
LLType* classInfoTy = DtoType(ClassDeclaration::classinfo->type);
|
||||
LLType* typeInfoTy = DtoType(Type::typeinfo->type);
|
||||
LLType* classInfoTy = DtoType(Type::typeinfoclass->type);
|
||||
LLType* typeInfoTy = DtoType(Type::dtypeinfo->type);
|
||||
LLType* aaTypeInfoTy = DtoType(Type::typeinfoassociativearray->type);
|
||||
|
||||
LLType* aaTy = rt_ptr(LLStructType::get(gIR->context()));
|
||||
|
||||
@@ -805,7 +805,7 @@ void ThrowStatement::toIR(IRState* p)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// used to build the sorted list of cases
|
||||
struct Case : Object
|
||||
struct Case : RootObject
|
||||
{
|
||||
StringExp* str;
|
||||
size_t index;
|
||||
@@ -815,7 +815,7 @@ struct Case : Object
|
||||
index = i;
|
||||
}
|
||||
|
||||
int compare(Object *obj) {
|
||||
int compare(RootObject *obj) {
|
||||
Case* c2 = static_cast<Case*>(obj);
|
||||
return str->compare(c2->str);
|
||||
}
|
||||
@@ -922,7 +922,7 @@ void SwitchStatement::toIR(IRState* p)
|
||||
{
|
||||
// string switch?
|
||||
llvm::Value* switchTable = 0;
|
||||
Array caseArray;
|
||||
Objects caseArray;
|
||||
if (!condition->type->isintegral())
|
||||
{
|
||||
Logger::println("is string switch");
|
||||
@@ -1388,7 +1388,7 @@ void LabelStatement::toIR(IRState* p)
|
||||
{
|
||||
IRAsmStmt* a = new IRAsmStmt;
|
||||
std::stringstream label;
|
||||
printLabelName(label, p->func()->decl->mangle(), ident->toChars());
|
||||
printLabelName(label, p->func()->decl->mangleExact(), ident->toChars());
|
||||
label << ":";
|
||||
a->code = label.str();
|
||||
p->asmBlock->s.push_back(a);
|
||||
|
||||
@@ -137,19 +137,18 @@ LLType* DtoUnpaddedStructType(Type* dty) {
|
||||
return it->second;
|
||||
|
||||
TypeStruct* sty = static_cast<TypeStruct*>(dty);
|
||||
Array& fields = sty->sym->fields;
|
||||
VarDeclarations& fields = sty->sym->fields;
|
||||
|
||||
std::vector<LLType*> types;
|
||||
types.reserve(fields.dim);
|
||||
|
||||
for (unsigned i = 0; i < fields.dim; i++) {
|
||||
VarDeclaration* vd = static_cast<VarDeclaration*>(fields.data[i]);
|
||||
LLType* fty;
|
||||
if (vd->type->ty == Tstruct) {
|
||||
if (fields[i]->type->ty == Tstruct) {
|
||||
// Nested structs are the only members that can contain padding
|
||||
fty = DtoUnpaddedStructType(vd->type);
|
||||
fty = DtoUnpaddedStructType(fields[i]->type);
|
||||
} else {
|
||||
fty = DtoType(vd->type);
|
||||
fty = DtoType(fields[i]->type);
|
||||
}
|
||||
types.push_back(fty);
|
||||
}
|
||||
@@ -165,17 +164,16 @@ LLType* DtoUnpaddedStructType(Type* dty) {
|
||||
LLValue* DtoUnpaddedStruct(Type* dty, LLValue* v) {
|
||||
assert(dty->ty == Tstruct);
|
||||
TypeStruct* sty = static_cast<TypeStruct*>(dty);
|
||||
Array& fields = sty->sym->fields;
|
||||
VarDeclarations& fields = sty->sym->fields;
|
||||
|
||||
LLValue* newval = llvm::UndefValue::get(DtoUnpaddedStructType(dty));
|
||||
|
||||
for (unsigned i = 0; i < fields.dim; i++) {
|
||||
VarDeclaration* vd = static_cast<VarDeclaration*>(fields.data[i]);
|
||||
LLValue* fieldptr = DtoIndexStruct(v, sty->sym, vd);
|
||||
LLValue* fieldptr = DtoIndexStruct(v, sty->sym, fields[i]);
|
||||
LLValue* fieldval;
|
||||
if (vd->type->ty == Tstruct) {
|
||||
if (fields[i]->type->ty == Tstruct) {
|
||||
// Nested structs are the only members that can contain padding
|
||||
fieldval = DtoUnpaddedStruct(vd->type, fieldptr);
|
||||
fieldval = DtoUnpaddedStruct(fields[i]->type, fieldptr);
|
||||
} else {
|
||||
fieldval = DtoLoad(fieldptr);
|
||||
}
|
||||
@@ -188,15 +186,14 @@ LLValue* DtoUnpaddedStruct(Type* dty, LLValue* v) {
|
||||
void DtoPaddedStruct(Type* dty, LLValue* v, LLValue* lval) {
|
||||
assert(dty->ty == Tstruct);
|
||||
TypeStruct* sty = static_cast<TypeStruct*>(dty);
|
||||
Array& fields = sty->sym->fields;
|
||||
VarDeclarations& fields = sty->sym->fields;
|
||||
|
||||
for (unsigned i = 0; i < fields.dim; i++) {
|
||||
VarDeclaration* vd = static_cast<VarDeclaration*>(fields.data[i]);
|
||||
LLValue* fieldptr = DtoIndexStruct(lval, sty->sym, vd);
|
||||
LLValue* fieldptr = DtoIndexStruct(lval, sty->sym, fields[i]);
|
||||
LLValue* fieldval = DtoExtractValue(v, i);
|
||||
if (vd->type->ty == Tstruct) {
|
||||
if (fields[i]->type->ty == Tstruct) {
|
||||
// Nested structs are the only members that can contain padding
|
||||
DtoPaddedStruct(vd->type, fieldval, fieldptr);
|
||||
DtoPaddedStruct(fields[i]->type, fieldval, fieldptr);
|
||||
} else {
|
||||
DtoStore(fieldval, fieldptr);
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#include <vector>
|
||||
|
||||
class DValue;
|
||||
struct StructDeclaration;
|
||||
struct StructInitializer;
|
||||
struct Type;
|
||||
struct VarDeclaration;
|
||||
class StructDeclaration;
|
||||
class StructInitializer;
|
||||
class Type;
|
||||
class VarDeclaration;
|
||||
namespace llvm
|
||||
{
|
||||
class Constant;
|
||||
|
||||
@@ -7,12 +7,17 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "target.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "mars.h"
|
||||
#include "mtype.h"
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
int Target::ptrsize;
|
||||
int Target::realsize;
|
||||
@@ -49,3 +54,19 @@ unsigned Target::fieldalign (Type* type)
|
||||
// LDC_FIXME: Verify this.
|
||||
return type->alignsize();
|
||||
}
|
||||
|
||||
// sizes based on those from tollvm.cpp:DtoMutexType()
|
||||
unsigned Target::critsecsize()
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
// Return sizeof(RTL_CRITICAL_SECTION)
|
||||
return global.params.is64bit ? 40 : 24;
|
||||
#else
|
||||
if (global.params.targetTriple.isOSWindows())
|
||||
return global.params.is64bit ? 40 : 24;
|
||||
else if (global.params.targetTriple.getOS() == llvm::Triple::FreeBSD)
|
||||
return sizeof(size_t);
|
||||
else
|
||||
return sizeof(pthread_mutex_t);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
|
||||
}
|
||||
|
||||
// build type info array
|
||||
LLType* typeinfotype = DtoType(Type::typeinfo->type);
|
||||
LLType* typeinfotype = DtoType(Type::dtypeinfo->type);
|
||||
LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements());
|
||||
|
||||
llvm::GlobalVariable* typeinfomem =
|
||||
@@ -294,7 +294,7 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
|
||||
DtoConstSize_t(vtype->getNumElements()),
|
||||
llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype))
|
||||
};
|
||||
LLType* tiarrty = DtoType(Type::typeinfo->type->arrayOf());
|
||||
LLType* tiarrty = DtoType(Type::dtypeinfo->type->arrayOf());
|
||||
tiinits = LLConstantStruct::get(isaStruct(tiarrty), llvm::ArrayRef<LLConstant*>(pinits));
|
||||
LLValue* typeinfoarrayparam = new llvm::GlobalVariable(*gIR->module, tiarrty,
|
||||
true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array");
|
||||
|
||||
@@ -1589,8 +1589,8 @@ DValue* DotVarExp::toElem(IRState* p)
|
||||
|
||||
// This is a bit more convoluted than it would need to be, because it
|
||||
// has to take templated interface methods into account, for which
|
||||
// isFinal is not necessarily true.
|
||||
const bool nonFinal = !fdecl->isFinal() &&
|
||||
// isFinalFunc is not necessarily true.
|
||||
const bool nonFinal = !fdecl->isFinalFunc() &&
|
||||
(fdecl->isAbstract() || fdecl->isVirtual());
|
||||
|
||||
// If we are calling a non-final interface function, we need to get
|
||||
@@ -2532,7 +2532,7 @@ DValue* DelegateExp::toElem(IRState* p)
|
||||
|
||||
LLValue* castfptr;
|
||||
|
||||
if (e1->op != TOKsuper && e1->op != TOKdottype && func->isVirtual() && !func->isFinal())
|
||||
if (e1->op != TOKsuper && e1->op != TOKdottype && func->isVirtual() && !func->isFinalFunc())
|
||||
castfptr = DtoVirtualFunctionPointer(u, func, toChars());
|
||||
else if (func->isAbstract())
|
||||
llvm_unreachable("Delegate to abstract method not implemented.");
|
||||
|
||||
@@ -937,7 +937,7 @@ LLStructType* DtoInterfaceInfoType()
|
||||
// build interface info type
|
||||
LLSmallVector<LLType*, 3> types;
|
||||
// ClassInfo classinfo
|
||||
ClassDeclaration* cd2 = ClassDeclaration::classinfo;
|
||||
ClassDeclaration* cd2 = Type::typeinfoclass;
|
||||
DtoResolveClass(cd2);
|
||||
types.push_back(DtoType(cd2->type));
|
||||
// void*[] vtbl
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef LDC_GEN_TYPEINF_H
|
||||
#define LDC_GEN_TYPEINF_H
|
||||
|
||||
struct TypeInfoDeclaration;
|
||||
class TypeInfoDeclaration;
|
||||
void DtoResolveTypeInfo(TypeInfoDeclaration* tid);
|
||||
void DtoConstInitTypeInfo(TypeInfoDeclaration* tid);
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ Expression *Type::getTypeInfo(Scope *sc)
|
||||
IF_LOG Logger::println("Type::getTypeInfo(): %s", toChars());
|
||||
LOG_SCOPE
|
||||
|
||||
if (!Type::typeinfo)
|
||||
if (!Type::dtypeinfo)
|
||||
{
|
||||
error(Loc(), "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
|
||||
fatal();
|
||||
@@ -343,7 +343,7 @@ void TypeInfoDeclaration::codegen(IRState* p)
|
||||
assert(irg->type->isStructTy());
|
||||
} else {
|
||||
if (tinfo->builtinTypeInfo()) // this is a declaration of a builtin __initZ var
|
||||
irg->type = Type::typeinfo->type->irtype->isClass()->getMemoryLLType();
|
||||
irg->type = Type::dtypeinfo->type->irtype->isClass()->getMemoryLLType();
|
||||
else
|
||||
irg->type = LLStructType::create(gIR->context(), toPrettyChars());
|
||||
irg->value = new llvm::GlobalVariable(*gIR->module, irg->type, true,
|
||||
@@ -370,7 +370,7 @@ void TypeInfoDeclaration::llvmDefine()
|
||||
Logger::println("TypeInfoDeclaration::llvmDefine() %s", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
RTTIBuilder b(Type::typeinfo);
|
||||
RTTIBuilder b(Type::dtypeinfo);
|
||||
b.finalize(ir.irGlobal);
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||
// void[] init
|
||||
// emit void[] with the default initialier, the array is null if the default
|
||||
// initializer is zero
|
||||
if (!sd->defaultval || tinfo->isZeroInit(Loc()))
|
||||
if (!sd->members || tinfo->isZeroInit(loc))
|
||||
{
|
||||
b.push_null_void_array();
|
||||
}
|
||||
@@ -444,10 +444,11 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||
Type *memtype = sd->memtype;
|
||||
LLType *memty = DtoType(memtype);
|
||||
LLConstant *C;
|
||||
Expression *defaultval = sd->getDefaultValue(loc);
|
||||
if (memtype->isintegral())
|
||||
C = LLConstantInt::get(memty, sd->defaultval->toInteger(), !isLLVMUnsigned(memtype));
|
||||
C = LLConstantInt::get(memty, defaultval->toInteger(), !isLLVMUnsigned(memtype));
|
||||
else if (memtype->isString())
|
||||
C = DtoConstString(static_cast<const char *>(sd->defaultval->toString()->string));
|
||||
C = DtoConstString(static_cast<const char *>(defaultval->toString()->string));
|
||||
else
|
||||
llvm_unreachable("Unsupported type");
|
||||
|
||||
@@ -631,7 +632,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
tftohash ->mod = MODconst;
|
||||
tftohash = static_cast<TypeFunction *>(tftohash->semantic(Loc(), &sc));
|
||||
|
||||
Type *retType = Type::tchar->invariantOf()->arrayOf();
|
||||
Type *retType = Type::tchar->immutableOf()->arrayOf();
|
||||
tftostring = new TypeFunction(NULL, retType, 0, LINKd);
|
||||
tftostring = static_cast<TypeFunction *>(tftostring->semantic(Loc(), &sc));
|
||||
}
|
||||
@@ -708,7 +709,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
b.push_typeinfo(targ);
|
||||
}
|
||||
else
|
||||
b.push_null(Type::typeinfo->type);
|
||||
b.push_null(Type::dtypeinfo->type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,7 +792,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||
std::vector<LLConstant*> arrInits;
|
||||
arrInits.reserve(dim);
|
||||
|
||||
LLType* tiTy = DtoType(Type::typeinfo->type);
|
||||
LLType* tiTy = DtoType(Type::dtypeinfo->type);
|
||||
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{
|
||||
@@ -806,7 +807,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||
RTTIBuilder b(Type::typeinfotypelist);
|
||||
|
||||
// push TypeInfo[]
|
||||
b.push_array(arrC, dim, Type::typeinfo->type, NULL);
|
||||
b.push_array(arrC, dim, Type::dtypeinfo->type, NULL);
|
||||
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
|
||||
16
gen/utils.h
16
gen/utils.h
@@ -20,26 +20,26 @@
|
||||
template<class C>
|
||||
struct ArrayIter
|
||||
{
|
||||
Array* array;
|
||||
Array<C>* array;
|
||||
size_t index;
|
||||
|
||||
ArrayIter(Array& arr, size_t idx = 0)
|
||||
ArrayIter(Array<C>& arr, size_t idx = 0)
|
||||
: array(&arr), index(idx)
|
||||
{ }
|
||||
ArrayIter(Array* arr, size_t idx = 0)
|
||||
ArrayIter(Array<C>* arr, size_t idx = 0)
|
||||
: array(arr), index(idx)
|
||||
{ assert(arr && "null array"); }
|
||||
|
||||
ArrayIter<C>& operator=(const Array& arr)
|
||||
ArrayIter<C>& operator=(const Array<C>& arr)
|
||||
{
|
||||
array = const_cast<Array*>(&arr);
|
||||
array = const_cast<Array<C>*>(&arr);
|
||||
index = 0;
|
||||
return *this;
|
||||
}
|
||||
ArrayIter<C>& operator=(const Array* arr)
|
||||
ArrayIter<C>& operator=(const Array<C>* arr)
|
||||
{
|
||||
assert(arr && "null array");
|
||||
array = const_cast<Array*>(arr);
|
||||
array = const_cast<Array<C>*>(arr);
|
||||
index = 0;
|
||||
return *this;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ struct ArrayIter
|
||||
}
|
||||
|
||||
C* get() {
|
||||
return static_cast<C*>(array->data[index]);
|
||||
return (*array)[index];
|
||||
}
|
||||
C* operator->() {
|
||||
return get();
|
||||
|
||||
Reference in New Issue
Block a user