First merge of 2.064 beta.

This corresponds to DMD commit a913ce4bc59a94a022a27e390fc841f4aededffb.

Doesn't build Phobos yet.
This commit is contained in:
David Nadlinger
2013-10-19 23:21:53 +02:00
committed by Kai Nacke
parent c400d180d2
commit cb341586e3
130 changed files with 13566 additions and 9190 deletions

View File

@@ -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);

View File

@@ -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())

View File

@@ -25,8 +25,8 @@
#endif
#include <vector>
struct Type;
struct TypeFunction;
class Type;
class TypeFunction;
struct IrFuncTy;
struct IrFuncTyArg;
class DValue;

View File

@@ -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);

View File

@@ -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 )

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -19,7 +19,7 @@
class DValue;
struct Loc;
struct Type;
class Type;
namespace llvm
{
class Constant;

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -16,8 +16,8 @@
#include <string>
struct PragmaDeclaration;
struct Dsymbol;
class PragmaDeclaration;
class Dsymbol;
struct Scope;
enum Pragma

View File

@@ -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

View File

@@ -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()));

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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");

View File

@@ -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.");

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();