mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Changed use of toObjFile to a new codegen method.
More versioning of DMD specific codegen code.
This commit is contained in:
@@ -140,11 +140,17 @@ struct StructDeclaration : AggregateDeclaration
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDt(dt_t **pdt);
|
||||
void toDebug(); // to symbolic debug info
|
||||
#endif
|
||||
|
||||
StructDeclaration *isStructDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct UnionDeclaration : StructDeclaration
|
||||
@@ -250,9 +256,9 @@ struct ClassDeclaration : AggregateDeclaration
|
||||
|
||||
void addLocalClass(ClassDeclarations *);
|
||||
|
||||
#if IN_DMD
|
||||
// Back end
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_DMD
|
||||
void toDebug();
|
||||
unsigned baseVtblOffset(BaseClass *bc);
|
||||
Symbol *toSymbol();
|
||||
@@ -264,6 +270,10 @@ struct ClassDeclaration : AggregateDeclaration
|
||||
#endif
|
||||
|
||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||
|
||||
#if IN_LLVM
|
||||
virtual void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct InterfaceDeclaration : ClassDeclaration
|
||||
@@ -283,12 +293,16 @@ struct InterfaceDeclaration : ClassDeclaration
|
||||
#endif
|
||||
virtual int isCOMinterface();
|
||||
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
#endif
|
||||
|
||||
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* DMD_AGGREGATE_H */
|
||||
|
||||
@@ -171,6 +171,8 @@ void AttribDeclaration::emitComment(Scope *sc)
|
||||
}
|
||||
}
|
||||
|
||||
#if IN_DMD
|
||||
|
||||
void AttribDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
Array *d = include(NULL, NULL);
|
||||
@@ -184,7 +186,6 @@ void AttribDeclaration::toObjFile(int multiobj)
|
||||
}
|
||||
}
|
||||
|
||||
#if IN_DMD
|
||||
int AttribDeclaration::cvMember(unsigned char *p)
|
||||
{
|
||||
int nwritten = 0;
|
||||
@@ -1142,6 +1143,7 @@ const char *PragmaDeclaration::kind()
|
||||
return "pragma";
|
||||
}
|
||||
|
||||
#if IN_DMD
|
||||
void PragmaDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
if (ident == Id::lib)
|
||||
@@ -1160,6 +1162,7 @@ void PragmaDeclaration::toObjFile(int multiobj)
|
||||
}
|
||||
AttribDeclaration::toObjFile(multiobj);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
|
||||
18
dmd/attrib.h
18
dmd/attrib.h
@@ -50,8 +50,14 @@ struct AttribDeclaration : Dsymbol
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
AttribDeclaration *isAttribDeclaration() { return this; }
|
||||
|
||||
#if IN_DMD
|
||||
virtual void toObjFile(int multiobj); // compile to .obj file
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
virtual void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct StorageClassDeclaration: AttribDeclaration
|
||||
@@ -108,8 +114,9 @@ struct AnonDeclaration : AttribDeclaration
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
|
||||
// LDC
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PragmaDeclaration : AttribDeclaration
|
||||
@@ -122,7 +129,14 @@ struct PragmaDeclaration : AttribDeclaration
|
||||
int oneMember(Dsymbol **ps);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ConditionalDeclaration : AttribDeclaration
|
||||
|
||||
@@ -138,8 +138,10 @@ struct Declaration : Dsymbol
|
||||
|
||||
Declaration *isDeclaration() { return this; }
|
||||
|
||||
// llvm
|
||||
virtual void toObjFile(int unused = 0); // compile to .obj file
|
||||
#if IN_LLVM
|
||||
/// Codegen traversal
|
||||
virtual void codegen(Ir* ir);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
@@ -159,8 +161,10 @@ struct TupleDeclaration : Declaration
|
||||
|
||||
TupleDeclaration *isTupleDeclaration() { return this; }
|
||||
|
||||
// LDC we need this
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_LLVM
|
||||
/// Codegen traversal
|
||||
void codegen(Ir* ir);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
@@ -190,8 +194,8 @@ struct TypedefDeclaration : Declaration
|
||||
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDebug();
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
@@ -202,6 +206,11 @@ struct TypedefDeclaration : Declaration
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
/// Codegen traversal
|
||||
void codegen(Ir* ir);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
@@ -268,8 +277,8 @@ struct VarDeclaration : Declaration
|
||||
void checkNestedReference(Scope *sc, Loc loc);
|
||||
Dsymbol *toAlias();
|
||||
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
@@ -278,6 +287,9 @@ struct VarDeclaration : Declaration
|
||||
VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
|
||||
|
||||
#if IN_LLVM
|
||||
/// Codegen traversal
|
||||
void codegen(Ir* ir);
|
||||
|
||||
// LDC
|
||||
AnonDeclaration* anonDecl;
|
||||
unsigned offset2;
|
||||
@@ -345,8 +357,8 @@ struct TypeInfoDeclaration : VarDeclaration
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
virtual void toDt(dt_t **pdt);
|
||||
#endif
|
||||
@@ -354,7 +366,8 @@ struct TypeInfoDeclaration : VarDeclaration
|
||||
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
/// Codegen traversal
|
||||
void codegen(Ir* ir);
|
||||
virtual void llvmDeclare();
|
||||
virtual void llvmDefine();
|
||||
#endif
|
||||
@@ -369,7 +382,6 @@ struct TypeInfoStructDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -384,7 +396,6 @@ struct TypeInfoClassDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -399,7 +410,6 @@ struct TypeInfoInterfaceDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -414,7 +424,6 @@ struct TypeInfoTypedefDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -429,7 +438,6 @@ struct TypeInfoPointerDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -444,7 +452,6 @@ struct TypeInfoArrayDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -459,7 +466,6 @@ struct TypeInfoStaticArrayDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -474,7 +480,6 @@ struct TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -489,7 +494,6 @@ struct TypeInfoEnumDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -504,7 +508,6 @@ struct TypeInfoFunctionDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -519,7 +522,6 @@ struct TypeInfoDelegateDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -534,7 +536,6 @@ struct TypeInfoTupleDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -550,7 +551,6 @@ struct TypeInfoConstDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -565,7 +565,6 @@ struct TypeInfoInvariantDeclaration : TypeInfoDeclaration
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
void llvmDeclare();
|
||||
void llvmDefine();
|
||||
#endif
|
||||
@@ -716,9 +715,7 @@ struct FuncDeclaration : Declaration
|
||||
#if IN_DMD
|
||||
Symbol *toSymbol();
|
||||
Symbol *toThunkSymbol(int offset); // thunk version
|
||||
#endif
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_DMD
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
|
||||
@@ -727,6 +724,9 @@ struct FuncDeclaration : Declaration
|
||||
#if IN_LLVM
|
||||
// LDC stuff
|
||||
|
||||
/// Codegen traversal
|
||||
void codegen(Ir* ir);
|
||||
|
||||
// vars declared in this function that nested funcs reference
|
||||
// is this is not empty, nestedFrameRef is set and these VarDecls
|
||||
// probably have nestedref set too, see VarDeclaration::checkNestedReference
|
||||
|
||||
@@ -48,6 +48,7 @@ Dsymbol::Dsymbol()
|
||||
|
||||
#if IN_LLVM
|
||||
this->llvmInternal = LLVMnone;
|
||||
this->irsym = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -66,6 +67,7 @@ Dsymbol::Dsymbol(Identifier *ident)
|
||||
|
||||
#if IN_LLVM
|
||||
this->llvmInternal = LLVMnone;
|
||||
this->irsym = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ struct TYPE;
|
||||
|
||||
// llvm
|
||||
#if IN_LLVM
|
||||
struct Ir;
|
||||
struct IrSymbol;
|
||||
namespace llvm
|
||||
{
|
||||
class Value;
|
||||
@@ -180,9 +182,7 @@ struct Dsymbol : Object
|
||||
// Backend
|
||||
|
||||
virtual Symbol *toSymbol(); // to backend symbol
|
||||
#endif
|
||||
virtual void toObjFile(int multiobj); // compile to .obj file
|
||||
#if IN_DMD
|
||||
virtual int cvMember(unsigned char *p); // emit cv debug info for member
|
||||
|
||||
Symbol *toImport(); // to backend import symbol
|
||||
@@ -232,10 +232,14 @@ struct Dsymbol : Object
|
||||
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
|
||||
|
||||
#if IN_LLVM
|
||||
/// Codegen traversal
|
||||
virtual void codegen(Ir* ir);
|
||||
|
||||
// llvm stuff
|
||||
int llvmInternal;
|
||||
|
||||
IrDsymbol ir;
|
||||
IrSymbol* irsym;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -61,14 +61,18 @@ struct EnumDeclaration : ScopeDsymbol
|
||||
|
||||
EnumDeclaration *isEnumDeclaration() { return this; }
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDebug();
|
||||
int cvMember(unsigned char *p);
|
||||
|
||||
#if IN_DMD
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ struct Library;
|
||||
|
||||
// Back end
|
||||
#if IN_LLVM
|
||||
struct Ir;
|
||||
struct DValue;
|
||||
typedef DValue elem;
|
||||
namespace llvm { class Module; }
|
||||
@@ -175,16 +176,18 @@ struct Module : Package
|
||||
#endif
|
||||
void genmoduleinfo();
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
llvm::Module* genLLVMModule(int multiobj);
|
||||
llvm::Module* genLLVMModule(Ir* sir);
|
||||
void buildTargetFiles();
|
||||
File* buildFilePath(const char* forcename, const char* path, const char* ext);
|
||||
Module *isModule() { return this; }
|
||||
|
||||
|
||||
bool llvmForceLogging;
|
||||
|
||||
// array ops emitted in this module already
|
||||
StringTable arrayfuncs;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
19
dmd/mtype.c
19
dmd/mtype.c
@@ -15,7 +15,11 @@
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef __DMC__
|
||||
#include <math.h>
|
||||
#else
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
@@ -65,7 +69,11 @@ static double zero = 0;
|
||||
#include "aggregate.h"
|
||||
#include "hdrgen.h"
|
||||
|
||||
#include "gen/tollvm.h"
|
||||
#if IN_LLVM
|
||||
//#include "gen/tollvm.h"
|
||||
Ir* Type::sir = NULL;
|
||||
unsigned GetTypeAlignment(Ir* ir, Type* t);
|
||||
#endif
|
||||
|
||||
FuncDeclaration *hasThis(Scope *sc);
|
||||
|
||||
@@ -164,7 +172,11 @@ char Type::needThisPrefix()
|
||||
return 'M'; // name mangling prefix for functions needing 'this'
|
||||
}
|
||||
|
||||
#if IN_LLVM
|
||||
void Type::init(Ir* _sir)
|
||||
#else
|
||||
void Type::init()
|
||||
#endif
|
||||
{ int i;
|
||||
int j;
|
||||
|
||||
@@ -238,6 +250,9 @@ void Type::init()
|
||||
|
||||
tvoidptr = tvoid->pointerTo();
|
||||
|
||||
// LDC
|
||||
sir = _sir;
|
||||
|
||||
// set size_t / ptrdiff_t types and pointer size
|
||||
if (global.params.is64bit)
|
||||
{
|
||||
@@ -1017,7 +1032,7 @@ unsigned TypeBasic::alignsize()
|
||||
{
|
||||
if (ty == Tvoid)
|
||||
return 1;
|
||||
return getABITypeAlign(DtoType(this));
|
||||
return GetTypeAlignment(sir, this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "../ir/irtype.h"
|
||||
#include "../ir/irfuncty.h"
|
||||
namespace llvm { class Type; }
|
||||
struct Ir;
|
||||
#endif
|
||||
|
||||
struct Scope;
|
||||
@@ -207,7 +208,11 @@ struct Type : Object
|
||||
int covariant(Type *t);
|
||||
char *toChars();
|
||||
static char needThisPrefix();
|
||||
#if IN_LLVM
|
||||
static void init(Ir*);
|
||||
#else
|
||||
static void init();
|
||||
#endif
|
||||
d_uns64 size();
|
||||
virtual d_uns64 size(Loc loc);
|
||||
virtual unsigned alignsize();
|
||||
@@ -275,6 +280,7 @@ struct Type : Object
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
IrType ir;
|
||||
static Ir* sir;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -337,10 +337,12 @@ Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
|
||||
#endif
|
||||
d = Dsymbol::arraySyntaxCopy(members);
|
||||
td = new TemplateDeclaration(loc, ident, p, d);
|
||||
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
td->intrinsicName = intrinsicName;
|
||||
|
||||
#endif
|
||||
|
||||
return td;
|
||||
}
|
||||
|
||||
@@ -2950,10 +2952,12 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
|
||||
this->isnested = NULL;
|
||||
this->errors = 0;
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
this->emittedInModule = NULL;
|
||||
this->tinst = NULL;
|
||||
this->tmodule = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************
|
||||
@@ -2982,9 +2986,11 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti
|
||||
this->isnested = NULL;
|
||||
this->errors = 0;
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
this->tinst = NULL;
|
||||
this->tmodule = NULL;
|
||||
#endif
|
||||
|
||||
assert((size_t)tempdecl->scope > 0x10000);
|
||||
}
|
||||
@@ -3270,6 +3276,7 @@ void TemplateInstance::semantic(Scope *sc)
|
||||
//printf("setting aliasdecl\n");
|
||||
aliasdecl = new AliasDeclaration(loc, s->ident, s);
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC propagate internal information
|
||||
if (tempdecl->llvmInternal) {
|
||||
s->llvmInternal = tempdecl->llvmInternal;
|
||||
@@ -3277,6 +3284,7 @@ void TemplateInstance::semantic(Scope *sc)
|
||||
fd->intrinsicName = tempdecl->intrinsicName;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3957,6 +3965,8 @@ void TemplateInstance::semantic3(Scope *sc)
|
||||
}
|
||||
}
|
||||
|
||||
#if IN_DMD
|
||||
|
||||
void TemplateInstance::toObjFile(int multiobj)
|
||||
{
|
||||
#if LOG
|
||||
@@ -3979,6 +3989,8 @@ void TemplateInstance::toObjFile(int multiobj)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void TemplateInstance::inlineScan()
|
||||
{
|
||||
#if LOG
|
||||
@@ -4559,9 +4571,10 @@ void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
}
|
||||
|
||||
|
||||
#if IN_DMD
|
||||
void TemplateMixin::toObjFile(int multiobj)
|
||||
{
|
||||
//printf("TemplateMixin::toObjFile('%s')\n", toChars());
|
||||
TemplateInstance::toObjFile(multiobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -91,9 +91,11 @@ struct TemplateDeclaration : ScopeDsymbol
|
||||
|
||||
TemplateTupleParameter *isVariadic();
|
||||
int isOverloadable();
|
||||
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
std::string intrinsicName;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct TemplateParameter
|
||||
@@ -310,7 +312,9 @@ struct TemplateInstance : ScopeDsymbol
|
||||
char *toChars();
|
||||
char *mangle();
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#endif
|
||||
|
||||
// Internal
|
||||
static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs);
|
||||
@@ -324,11 +328,15 @@ struct TemplateInstance : ScopeDsymbol
|
||||
TemplateInstance *isTemplateInstance() { return this; }
|
||||
AliasDeclaration *isAliasDeclaration();
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
TemplateInstance *tinst; // enclosing template instance
|
||||
Module* tmodule; // module from outermost enclosing template instantiation
|
||||
Module* emittedInModule; // which module this template instance has been emitted in
|
||||
void printInstantiationTrace();
|
||||
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct TemplateMixin : TemplateInstance
|
||||
@@ -351,9 +359,15 @@ struct TemplateMixin : TemplateInstance
|
||||
char *mangle();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#endif
|
||||
|
||||
TemplateMixin *isTemplateMixin() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
Expression *isExpression(Object *o);
|
||||
|
||||
@@ -105,7 +105,7 @@ static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
|
||||
Array* arr = cd->members;
|
||||
for (int k=0; k < arr->dim; k++) {
|
||||
Dsymbol* s = (Dsymbol*)arr->data[k];
|
||||
s->toObjFile(0);
|
||||
s->codegen(Type::sir);
|
||||
}
|
||||
|
||||
// add interfaces
|
||||
@@ -177,7 +177,7 @@ static void DtoResolveInterface(InterfaceDeclaration* cd)
|
||||
Array* arr = cd->members;
|
||||
for (int k=0; k < arr->dim; k++) {
|
||||
Dsymbol* s = (Dsymbol*)arr->data[k];
|
||||
s->toObjFile(0);
|
||||
s->codegen(Type::sir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
268
gen/declarations.cpp
Normal file
268
gen/declarations.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
#include "gen/llvm.h"
|
||||
|
||||
#include "aggregate.h"
|
||||
#include "declaration.h"
|
||||
#include "enum.h"
|
||||
#include "id.h"
|
||||
#include "mem.h"
|
||||
#include "template.h"
|
||||
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "gen/llvmhelpers.h"
|
||||
#include "gen/logger.h"
|
||||
|
||||
#include "ir/ir.h"
|
||||
#include "ir/irvar.h"
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void Dsymbol::codegen(Ir*)
|
||||
{
|
||||
Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars());
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void Declaration::codegen(Ir*)
|
||||
{
|
||||
Logger::println("Ignoring Declaration::toObjFile for %s", toChars());
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void InterfaceDeclaration::codegen(Ir*)
|
||||
{
|
||||
//Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars());
|
||||
DtoResolveDsymbol(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void StructDeclaration::codegen(Ir*)
|
||||
{
|
||||
DtoResolveDsymbol(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void ClassDeclaration::codegen(Ir*)
|
||||
{
|
||||
DtoResolveDsymbol(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void TupleDeclaration::codegen(Ir* p)
|
||||
{
|
||||
Logger::println("TupleDeclaration::toObjFile(): %s", toChars());
|
||||
|
||||
assert(isexp);
|
||||
assert(objects);
|
||||
|
||||
int n = objects->dim;
|
||||
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
DsymbolExp* exp = (DsymbolExp*)objects->data[i];
|
||||
assert(exp->op == TOKdsymbol);
|
||||
exp->s->codegen(p);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void VarDeclaration::codegen(Ir* p)
|
||||
{
|
||||
Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
if (aliassym)
|
||||
{
|
||||
Logger::println("alias sym");
|
||||
toAlias()->codegen(p);
|
||||
return;
|
||||
}
|
||||
|
||||
// global variable or magic
|
||||
#if DMDV2
|
||||
// taken from dmd2/structs
|
||||
if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init))
|
||||
#else
|
||||
if (isDataseg())
|
||||
#endif
|
||||
{
|
||||
Logger::println("data segment");
|
||||
|
||||
#if DMDV2
|
||||
if (storage_class & STCmanifest)
|
||||
{
|
||||
assert(0 && "manifest constant being codegened!!!");
|
||||
}
|
||||
#endif
|
||||
|
||||
// don't duplicate work
|
||||
if (this->ir.resolved) return;
|
||||
this->ir.resolved = true;
|
||||
this->ir.declared = true;
|
||||
|
||||
this->ir.irGlobal = new IrGlobal(this);
|
||||
|
||||
Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
|
||||
|
||||
#if DMDV2
|
||||
// not sure why this is only needed for d2
|
||||
bool _isconst = isConst() && init;
|
||||
#else
|
||||
bool _isconst = isConst();
|
||||
#endif
|
||||
|
||||
|
||||
Logger::println("Creating global variable");
|
||||
|
||||
const LLType* _type = this->ir.irGlobal->type.get();
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
|
||||
std::string _name(mangle());
|
||||
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
|
||||
this->ir.irGlobal->value = gvar;
|
||||
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << *gvar << '\n';
|
||||
|
||||
// if this global is used from a nested function, this is necessary or
|
||||
// optimization could potentially remove the global (if it's the only use)
|
||||
if (nakedUse)
|
||||
gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
|
||||
|
||||
gIR->constInitList.push_back(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// might already have its irField, as classes derive each other without getting copies of the VarDeclaration
|
||||
if (!ir.irField)
|
||||
{
|
||||
assert(!ir.isSet());
|
||||
ir.irField = new IrField(this);
|
||||
}
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
irstruct->addVar(this);
|
||||
|
||||
Logger::println("added offset %u", offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void TypedefDeclaration::codegen(Ir*)
|
||||
{
|
||||
static int tdi = 0;
|
||||
Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// generate typeinfo
|
||||
DtoTypeInfoOf(type, false);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void EnumDeclaration::codegen(Ir*)
|
||||
{
|
||||
Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars());
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void FuncDeclaration::codegen(Ir*)
|
||||
{
|
||||
DtoResolveDsymbol(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void AnonDeclaration::codegen(Ir* p)
|
||||
{
|
||||
Array *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
// get real aggregate parent
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
|
||||
// push a block on the stack
|
||||
irstruct->pushAnon(isunion);
|
||||
|
||||
// go over children
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)d->data[i];
|
||||
s->codegen(p);
|
||||
}
|
||||
|
||||
// finish
|
||||
irstruct->popAnon();
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void TemplateInstance::codegen(Ir* p)
|
||||
{
|
||||
#if LOG
|
||||
printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this);
|
||||
#endif
|
||||
if (!errors && members)
|
||||
{
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
s->codegen(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void TemplateMixin::codegen(Ir* p)
|
||||
{
|
||||
TemplateInstance::codegen(p);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void AttribDeclaration::codegen(Ir* p)
|
||||
{
|
||||
Array *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)d->data[i];
|
||||
s->codegen(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void obj_includelib(const char* lib);
|
||||
|
||||
void PragmaDeclaration::codegen(Ir* p)
|
||||
{
|
||||
if (ident == Id::lib)
|
||||
{
|
||||
assert(args && args->dim == 1);
|
||||
|
||||
Expression *e = (Expression *)args->data[0];
|
||||
|
||||
assert(e->op == TOKstring);
|
||||
|
||||
StringExp *se = (StringExp *)e;
|
||||
char *name = (char *)mem.malloc(se->len + 1);
|
||||
memcpy(name, se->string, se->len);
|
||||
name[se->len] = 0;
|
||||
obj_includelib(name);
|
||||
}
|
||||
AttribDeclaration::codegen(p);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
@@ -979,99 +979,12 @@ void DtoConstInitGlobal(VarDeclaration* vd)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoEmptyResolveList()
|
||||
{
|
||||
//Logger::println("DtoEmptyResolveList()");
|
||||
Dsymbol* dsym;
|
||||
while (!gIR->resolveList.empty()) {
|
||||
dsym = gIR->resolveList.front();
|
||||
gIR->resolveList.pop_front();
|
||||
DtoResolveDsymbol(dsym);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoEmptyDeclareList()
|
||||
{
|
||||
//Logger::println("DtoEmptyDeclareList()");
|
||||
Dsymbol* dsym;
|
||||
while (!gIR->declareList.empty()) {
|
||||
dsym = gIR->declareList.front();
|
||||
gIR->declareList.pop_front();
|
||||
DtoDeclareDsymbol(dsym);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoEmptyConstInitList()
|
||||
{
|
||||
//Logger::println("DtoEmptyConstInitList()");
|
||||
Dsymbol* dsym;
|
||||
while (!gIR->constInitList.empty()) {
|
||||
dsym = gIR->constInitList.front();
|
||||
gIR->constInitList.pop_front();
|
||||
DtoConstInitDsymbol(dsym);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoEmptyDefineList()
|
||||
{
|
||||
//Logger::println("DtoEmptyDefineList()");
|
||||
Dsymbol* dsym;
|
||||
while (!gIR->defineList.empty()) {
|
||||
dsym = gIR->defineList.front();
|
||||
gIR->defineList.pop_front();
|
||||
DtoDefineDsymbol(dsym);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void DtoEmptyAllLists()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
Dsymbol* dsym;
|
||||
if (!gIR->resolveList.empty()) {
|
||||
dsym = gIR->resolveList.front();
|
||||
gIR->resolveList.pop_front();
|
||||
DtoResolveDsymbol(dsym);
|
||||
}
|
||||
else if (!gIR->declareList.empty()) {
|
||||
dsym = gIR->declareList.front();
|
||||
gIR->declareList.pop_front();
|
||||
DtoDeclareDsymbol(dsym);
|
||||
}
|
||||
else if (!gIR->constInitList.empty()) {
|
||||
dsym = gIR->constInitList.front();
|
||||
gIR->constInitList.pop_front();
|
||||
DtoConstInitDsymbol(dsym);
|
||||
}
|
||||
else if (!gIR->defineList.empty()) {
|
||||
dsym = gIR->defineList.front();
|
||||
gIR->defineList.pop_front();
|
||||
DtoDefineDsymbol(dsym);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoForceDeclareDsymbol(Dsymbol* dsym)
|
||||
{
|
||||
if (dsym->ir.declared) return;
|
||||
Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toPrettyChars());
|
||||
LOG_SCOPE;
|
||||
DtoResolveDsymbol(dsym);
|
||||
|
||||
DtoEmptyResolveList();
|
||||
|
||||
DtoDeclareDsymbol(dsym);
|
||||
}
|
||||
|
||||
@@ -1083,10 +996,7 @@ void DtoForceConstInitDsymbol(Dsymbol* dsym)
|
||||
Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toPrettyChars());
|
||||
LOG_SCOPE;
|
||||
DtoResolveDsymbol(dsym);
|
||||
|
||||
DtoEmptyResolveList();
|
||||
DtoEmptyDeclareList();
|
||||
|
||||
DtoDeclareDsymbol(dsym);
|
||||
DtoConstInitDsymbol(dsym);
|
||||
}
|
||||
|
||||
@@ -1098,11 +1008,8 @@ void DtoForceDefineDsymbol(Dsymbol* dsym)
|
||||
Logger::println("DtoForceDefineDsymbol(%s)", dsym->toPrettyChars());
|
||||
LOG_SCOPE;
|
||||
DtoResolveDsymbol(dsym);
|
||||
|
||||
DtoEmptyResolveList();
|
||||
DtoEmptyDeclareList();
|
||||
DtoEmptyConstInitList();
|
||||
|
||||
DtoDeclareDsymbol(dsym);
|
||||
DtoConstInitDsymbol(dsym);
|
||||
DtoDefineDsymbol(dsym);
|
||||
}
|
||||
|
||||
@@ -1129,7 +1036,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
|
||||
// static
|
||||
if (vd->isDataseg())
|
||||
{
|
||||
vd->toObjFile(0); // TODO: multiobj
|
||||
vd->codegen(Type::sir);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -94,10 +94,6 @@ void DtoDeclareDsymbol(Dsymbol* dsym);
|
||||
void DtoDefineDsymbol(Dsymbol* dsym);
|
||||
void DtoConstInitDsymbol(Dsymbol* dsym);
|
||||
void DtoConstInitGlobal(VarDeclaration* vd);
|
||||
void DtoEmptyResolveList();
|
||||
void DtoEmptyDeclareList();
|
||||
void DtoEmptyConstInitList();
|
||||
void DtoEmptyAllLists();
|
||||
void DtoForceDeclareDsymbol(Dsymbol* dsym);
|
||||
void DtoForceConstInitDsymbol(Dsymbol* dsym);
|
||||
void DtoForceDefineDsymbol(Dsymbol* dsym);
|
||||
|
||||
@@ -362,6 +362,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
// create a proper target
|
||||
Ir ir;
|
||||
|
||||
// check -m32/64 sanity
|
||||
if (m32bits && m64bits)
|
||||
@@ -562,7 +563,7 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
|
||||
// Initialization
|
||||
Type::init();
|
||||
Type::init(&ir);
|
||||
Id::initialize();
|
||||
Module::init();
|
||||
initPrecedence();
|
||||
@@ -832,7 +833,7 @@ int main(int argc, char** argv)
|
||||
printf("code %s\n", m->toChars());
|
||||
if (global.params.obj)
|
||||
{
|
||||
llvm::Module* lm = m->genLLVMModule(0);
|
||||
llvm::Module* lm = m->genLLVMModule(&ir);
|
||||
if (!singleObj)
|
||||
{
|
||||
m->deleteObjFile();
|
||||
|
||||
@@ -72,7 +72,7 @@ void ExpStatement::toNakedIR(IRState *p)
|
||||
// enum decls should always be safe
|
||||
|
||||
// make sure the symbols gets processed
|
||||
d->declaration->toObjFile(0);
|
||||
d->declaration->codegen(Type::sir);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -538,7 +538,7 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||
Array* arr = sd->members;
|
||||
for (int k=0; k < arr->dim; k++) {
|
||||
Dsymbol* s = (Dsymbol*)arr->data[k];
|
||||
s->toObjFile(0);
|
||||
s->codegen(Type::sir);
|
||||
}
|
||||
|
||||
const LLType* ST = irstruct->build();
|
||||
|
||||
@@ -147,7 +147,7 @@ DValue* VarExp::toElem(IRState* p)
|
||||
|
||||
// take care of forward references of global variables
|
||||
if (vd->isDataseg() || (vd->storage_class & STCextern)) {
|
||||
vd->toObjFile(0); // TODO: multiobj
|
||||
vd->codegen(Type::sir);
|
||||
}
|
||||
|
||||
LLValue* val;
|
||||
|
||||
206
gen/toobj.cpp
206
gen/toobj.cpp
@@ -70,7 +70,7 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Module* Module::genLLVMModule(int multiobj)
|
||||
llvm::Module* Module::genLLVMModule(Ir* sir)
|
||||
{
|
||||
bool logenabled = Logger::enabled();
|
||||
if (llvmForceLogging && !logenabled)
|
||||
@@ -100,6 +100,8 @@ llvm::Module* Module::genLLVMModule(int multiobj)
|
||||
IrDsymbol::resetAll();
|
||||
IrType::resetAll();
|
||||
|
||||
sir->setState(&ir);
|
||||
|
||||
// module ir state
|
||||
// might already exist via import, just overwrite since
|
||||
// the global created for the filename must belong to the right llvm module
|
||||
@@ -137,15 +139,11 @@ llvm::Module* Module::genLLVMModule(int multiobj)
|
||||
for (int k=0; k < members->dim; k++) {
|
||||
Dsymbol* dsym = (Dsymbol*)(members->data[k]);
|
||||
assert(dsym);
|
||||
dsym->toObjFile(multiobj);
|
||||
dsym->codegen(sir);
|
||||
}
|
||||
|
||||
// main driver loop
|
||||
DtoEmptyAllLists();
|
||||
// generate ModuleInfo
|
||||
genmoduleinfo();
|
||||
// do this again as moduleinfo might have pulled something in!
|
||||
DtoEmptyAllLists();
|
||||
|
||||
// emit usedArray
|
||||
if (!ir.usedArray.empty())
|
||||
@@ -172,12 +170,14 @@ llvm::Module* Module::genLLVMModule(int multiobj)
|
||||
}
|
||||
|
||||
gIR = NULL;
|
||||
|
||||
|
||||
if (llvmForceLogging && !logenabled)
|
||||
{
|
||||
Logger::disable();
|
||||
}
|
||||
|
||||
|
||||
sir->setState(NULL);
|
||||
|
||||
return ir.module;
|
||||
}
|
||||
|
||||
@@ -680,6 +680,8 @@ void Module::genmoduleinfo()
|
||||
for (size_t i = 0; i < aclasses.dim; i++)
|
||||
{
|
||||
ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i];
|
||||
cd->codegen(Type::sir);
|
||||
|
||||
if (cd->isInterfaceDeclaration())
|
||||
{
|
||||
Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars());
|
||||
@@ -790,191 +792,3 @@ void Module::genmoduleinfo()
|
||||
std::string appendName("llvm.global_ctors");
|
||||
llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void Dsymbol::toObjFile(int multiobj)
|
||||
{
|
||||
Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars());
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void Declaration::toObjFile(int unused)
|
||||
{
|
||||
Logger::println("Ignoring Declaration::toObjFile for %s", toChars());
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void InterfaceDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
//Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars());
|
||||
gIR->resolveList.push_back(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void StructDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
gIR->resolveList.push_back(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void ClassDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
gIR->resolveList.push_back(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void TupleDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
Logger::println("TupleDeclaration::toObjFile(): %s", toChars());
|
||||
|
||||
assert(isexp);
|
||||
assert(objects);
|
||||
|
||||
int n = objects->dim;
|
||||
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
DsymbolExp* exp = (DsymbolExp*)objects->data[i];
|
||||
assert(exp->op == TOKdsymbol);
|
||||
exp->s->toObjFile(multiobj);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void VarDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
if (aliassym)
|
||||
{
|
||||
Logger::println("alias sym");
|
||||
toAlias()->toObjFile(multiobj);
|
||||
return;
|
||||
}
|
||||
|
||||
// global variable or magic
|
||||
#if DMDV2
|
||||
// taken from dmd2/structs
|
||||
if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init))
|
||||
#else
|
||||
if (isDataseg())
|
||||
#endif
|
||||
{
|
||||
Logger::println("data segment");
|
||||
|
||||
#if DMDV2
|
||||
if (storage_class & STCmanifest)
|
||||
{
|
||||
assert(0 && "manifest constant being codegened!!!");
|
||||
}
|
||||
#endif
|
||||
|
||||
// don't duplicate work
|
||||
if (this->ir.resolved) return;
|
||||
this->ir.resolved = true;
|
||||
this->ir.declared = true;
|
||||
|
||||
this->ir.irGlobal = new IrGlobal(this);
|
||||
|
||||
Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
|
||||
|
||||
#if DMDV2
|
||||
// not sure why this is only needed for d2
|
||||
bool _isconst = isConst() && init;
|
||||
#else
|
||||
bool _isconst = isConst();
|
||||
#endif
|
||||
|
||||
|
||||
Logger::println("Creating global variable");
|
||||
|
||||
const LLType* _type = this->ir.irGlobal->type.get();
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
|
||||
std::string _name(mangle());
|
||||
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
|
||||
this->ir.irGlobal->value = gvar;
|
||||
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << *gvar << '\n';
|
||||
|
||||
// if this global is used from a nested function, this is necessary or
|
||||
// optimization could potentially remove the global (if it's the only use)
|
||||
if (nakedUse)
|
||||
gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
|
||||
|
||||
gIR->constInitList.push_back(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// might already have its irField, as classes derive each other without getting copies of the VarDeclaration
|
||||
if (!ir.irField)
|
||||
{
|
||||
assert(!ir.isSet());
|
||||
ir.irField = new IrField(this);
|
||||
}
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
irstruct->addVar(this);
|
||||
|
||||
Logger::println("added offset %u", offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void TypedefDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
static int tdi = 0;
|
||||
Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// generate typeinfo
|
||||
DtoTypeInfoOf(type, false);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void EnumDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars());
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void FuncDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
gIR->resolveList.push_back(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void AnonDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
Array *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
// get real aggregate parent
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
|
||||
// push a block on the stack
|
||||
irstruct->pushAnon(isunion);
|
||||
|
||||
// go over children
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)d->data[i];
|
||||
s->toObjFile(multiobj);
|
||||
}
|
||||
|
||||
// finish
|
||||
irstruct->popAnon();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,13 +138,17 @@ Expression *Type::getTypeInfo(Scope *sc)
|
||||
}
|
||||
else // if in obj generation pass
|
||||
{
|
||||
#if IN_DMD
|
||||
t->vtinfo->toObjFile(0); // TODO: multiobj
|
||||
#else
|
||||
t->vtinfo->codegen(sir);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
e = new VarExp(0, t->vtinfo);
|
||||
//e = e->addressOf(sc);
|
||||
//e->type = t->vtinfo->type; // do this so we don't get redundant dereference
|
||||
e = e->addressOf(sc);
|
||||
e->type = t->vtinfo->type; // do this so we don't get redundant dereference
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -267,11 +271,6 @@ Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
|
||||
// MAGIC PLACE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TypeInfoDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
gIR->resolveList.push_back(this);
|
||||
}
|
||||
|
||||
void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
|
||||
{
|
||||
if (tid->ir.resolved) return;
|
||||
@@ -285,6 +284,11 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
|
||||
gIR->declareList.push_back(tid);
|
||||
}
|
||||
|
||||
void TypeInfoDeclaration::codegen(Ir*)
|
||||
{
|
||||
DtoResolveTypeInfo(this);
|
||||
}
|
||||
|
||||
void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
|
||||
{
|
||||
if (tid->ir.declared) return;
|
||||
|
||||
Reference in New Issue
Block a user