mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-07 23:43:13 +01:00
Merge pull request #434 from AlexeyProkhin/minimize-dmd-diff
Minimize dmd diff
This commit is contained in:
@@ -129,7 +129,7 @@ int StructLiteralExp::apply(fp_t fp, void *param)
|
||||
stageflags |= stageApply;
|
||||
int ret = condApply(elements, fp, param) ||
|
||||
(*fp)(this, param);
|
||||
stageflags = old;
|
||||
stageflags = old;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ int isDruntimeArrayOp(Identifier *ident)
|
||||
ArrayOp *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc)
|
||||
{
|
||||
ArrayOp *op = new ArrayOp;
|
||||
#if IN_LLVM
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
Parameters *fparams = new Parameters();
|
||||
Expression *loopbody = exp->buildArrayLoop(fparams);
|
||||
if (isDruntimeArrayOp(ident))
|
||||
|
||||
@@ -588,11 +588,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
||||
|
||||
if (isCOMclass())
|
||||
{
|
||||
#if IN_LLVM
|
||||
if (global.params.targetTriple.isOSWindows())
|
||||
#else
|
||||
if (global.params.isWindows)
|
||||
#endif
|
||||
sc->linkage = LINKwindows;
|
||||
else
|
||||
/* This enables us to use COM objects under Linux and
|
||||
|
||||
@@ -164,7 +164,7 @@ Lneed:
|
||||
* Note that s will be constructed onto the stack, and probably
|
||||
* copy-constructed in caller site.
|
||||
*
|
||||
* If S has copy copy construction and/or destructor,
|
||||
* If S has copy copy construction and/or destructor,
|
||||
* the body will make bit-wise object swap:
|
||||
* S __tmp = this; // bit copy
|
||||
* this = s; // bit copy
|
||||
|
||||
@@ -160,11 +160,7 @@ char *cpp_mangle(Dsymbol *s)
|
||||
cms.components.setDim(0);
|
||||
|
||||
OutBuffer buf;
|
||||
#if IN_LLVM
|
||||
buf.writestring("__Z" + !(global.params.targetTriple.isMacOSX())); // "_Z" for OSX
|
||||
#else
|
||||
buf.writestring("__Z" + !global.params.isOSX); // "_Z" for OSX
|
||||
#endif
|
||||
|
||||
cpp_mangle_name(&buf, &cms, s);
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ struct Declaration : Dsymbol
|
||||
enum PROT protection;
|
||||
enum LINK linkage;
|
||||
int inuse; // used to detect cycles
|
||||
const char *mangleOverride; // overridden symbol with pragma(mangle, "...")
|
||||
const char *mangleOverride; // overridden symbol with pragma(mangle, "...")
|
||||
enum Semantic sem;
|
||||
|
||||
Declaration(Identifier *id);
|
||||
|
||||
@@ -163,7 +163,7 @@ struct Dsymbol : Object
|
||||
void deprecation(Loc loc, const char *format, ...);
|
||||
void deprecation(const char *format, ...);
|
||||
void checkDeprecated(Loc loc, Scope *sc);
|
||||
Module *getModule(); // module where declared
|
||||
Module *getModule();
|
||||
Module *getAccessModule();
|
||||
Dsymbol *pastMixin();
|
||||
Dsymbol *toParent();
|
||||
|
||||
10
dmd2/func.c
10
dmd2/func.c
@@ -1888,16 +1888,8 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||
if (cd)
|
||||
{
|
||||
if (!global.params.is64bit &&
|
||||
#if IN_LLVM
|
||||
global.params.targetTriple.isOSWindows() &&
|
||||
#else
|
||||
global.params.isWindows &&
|
||||
#endif
|
||||
!isStatic() && !fbody->usesEH()
|
||||
#if !IN_LLVM
|
||||
&& !global.params.trace
|
||||
#endif
|
||||
)
|
||||
!isStatic() && !fbody->usesEH() && !global.params.trace)
|
||||
{
|
||||
/* The back end uses the "jmonitor" hack for syncing;
|
||||
* no need to do the sync at this level.
|
||||
|
||||
@@ -907,7 +907,7 @@ bool hasNonConstPointers(Expression *e)
|
||||
int old = se->stageflags;
|
||||
se->stageflags |= stageSearchPointers;
|
||||
bool ret = arrayHasNonConstPointers(se->elements);
|
||||
se->stageflags = old;
|
||||
se->stageflags = old;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -162,7 +162,14 @@ struct Param
|
||||
bool vtls; // identify thread local variables
|
||||
bool vfield; // identify non-mutable field variables
|
||||
ubyte symdebug; // insert debug symbolic information
|
||||
bool trace; // insert profiling hooks
|
||||
bool is64bit; // generate 64 bit code
|
||||
bool isLinux; // generate code for linux
|
||||
bool isOSX; // generate code for Mac OSX
|
||||
bool isWindows; // generate code for Windows
|
||||
bool isFreeBSD; // generate code for FreeBSD
|
||||
bool isOpenBSD; // generate code for OpenBSD
|
||||
bool isSolaris; // generate code for Solaris
|
||||
#else
|
||||
char dll; // generate shared dynamic library
|
||||
char lib; // write library file instead of object file(s)
|
||||
|
||||
161
dmd2/module.c
161
dmd2/module.c
@@ -27,28 +27,6 @@
|
||||
#include "d-dmd-gcc.h"
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
#if LDC_LLVM_VER >= 303
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#else
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#endif
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include <map>
|
||||
|
||||
static llvm::cl::opt<bool> preservePaths("op",
|
||||
llvm::cl::desc("Do not strip paths from source file"),
|
||||
llvm::cl::ZeroOrMore);
|
||||
|
||||
static llvm::cl::opt<bool> fqnNames("oq",
|
||||
llvm::cl::desc("Write object files with fully qualified names"),
|
||||
llvm::cl::ZeroOrMore);
|
||||
#endif
|
||||
|
||||
AggregateDeclaration *Module::moduleinfo;
|
||||
|
||||
Module *Module::rootModule;
|
||||
@@ -154,65 +132,13 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
|
||||
// LDC
|
||||
llvmForceLogging = false;
|
||||
moduleInfoVar = NULL;
|
||||
moduleInfoType = llvm::StructType::create(llvm::getGlobalContext());
|
||||
this->doDocComment = doDocComment;
|
||||
this->doHdrGen = doHdrGen;
|
||||
this->isRoot = false;
|
||||
this->arrayfuncs = 0;
|
||||
#endif
|
||||
}
|
||||
#if IN_LLVM
|
||||
File* Module::buildFilePath(const char* forcename, const char* path, const char* ext)
|
||||
{
|
||||
const char *argobj;
|
||||
if (forcename)
|
||||
argobj = forcename;
|
||||
else
|
||||
{
|
||||
if (preservePaths)
|
||||
argobj = (char*)this->arg;
|
||||
else
|
||||
argobj = FileName::name((char*)this->arg);
|
||||
|
||||
if (fqnNames)
|
||||
{
|
||||
if(md)
|
||||
argobj = FileName::replaceName((char*)argobj, md->toChars());
|
||||
else
|
||||
argobj = FileName::replaceName((char*)argobj, toChars());
|
||||
|
||||
// add ext, otherwise forceExt will make nested.module into nested.bc
|
||||
size_t len = strlen(argobj);
|
||||
size_t extlen = strlen(ext);
|
||||
char* s = (char *)alloca(len + 1 + extlen + 1);
|
||||
memcpy(s, argobj, len);
|
||||
s[len] = '.';
|
||||
memcpy(s + len + 1, ext, extlen + 1);
|
||||
s[len+1+extlen] = 0;
|
||||
argobj = s;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FileName::absolute(argobj))
|
||||
{
|
||||
argobj = FileName::combine(path, argobj);
|
||||
}
|
||||
|
||||
FileName::ensurePathExists(FileName::path(argobj));
|
||||
|
||||
// always append the extension! otherwise hard to make output switches consistent
|
||||
// if (forcename)
|
||||
// return new File(argobj);
|
||||
// else
|
||||
// allow for .o and .obj on windows
|
||||
#if _WIN32
|
||||
if (ext == global.params.objdir && FileName::ext(argobj)
|
||||
&& Port::stricmp(FileName::ext(argobj), global.obj_ext_alt) == 0)
|
||||
return new File((char*)argobj);
|
||||
#endif
|
||||
return new File(FileName::forceExt(argobj, ext));
|
||||
}
|
||||
#endif
|
||||
#if IN_DMD
|
||||
void Module::setDocfile()
|
||||
{
|
||||
@@ -263,78 +189,6 @@ File *Module::setOutfile(const char *name, const char *dir, const char *arg, con
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
|
||||
// LDC
|
||||
static void check_and_add_output_file(Module* NewMod, const std::string& str)
|
||||
{
|
||||
typedef std::map<std::string, Module*> map_t;
|
||||
static map_t files;
|
||||
|
||||
map_t::iterator i = files.find(str);
|
||||
if (i != files.end())
|
||||
{
|
||||
Module* ThisMod = i->second;
|
||||
error(Loc(), "Output file '%s' for module '%s' collides with previous module '%s'. See the -oq option",
|
||||
str.c_str(), NewMod->toPrettyChars(), ThisMod->toPrettyChars());
|
||||
fatal();
|
||||
}
|
||||
files.insert(std::make_pair(str, NewMod));
|
||||
}
|
||||
|
||||
void Module::buildTargetFiles(bool singleObj)
|
||||
{
|
||||
if(objfile &&
|
||||
(!doDocComment || docfile) &&
|
||||
(!doHdrGen || hdrfile))
|
||||
return;
|
||||
|
||||
if(!objfile)
|
||||
{
|
||||
if (global.params.output_o)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir,
|
||||
global.params.targetTriple.isOSWindows() ? global.obj_ext_alt : global.obj_ext);
|
||||
else if (global.params.output_bc)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.bc_ext);
|
||||
else if (global.params.output_ll)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.ll_ext);
|
||||
else if (global.params.output_s)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.s_ext);
|
||||
}
|
||||
if(doDocComment && !docfile)
|
||||
docfile = Module::buildFilePath(global.params.docname, global.params.docdir, global.doc_ext);
|
||||
if(doHdrGen && !hdrfile)
|
||||
hdrfile = Module::buildFilePath(global.params.hdrname, global.params.hdrdir, global.hdr_ext);
|
||||
|
||||
// safety check: never allow obj, doc or hdr file to have the source file's name
|
||||
if(Port::stricmp(FileName::name(objfile->name->str), FileName::name((char*)this->arg)) == 0)
|
||||
{
|
||||
error("Output object files with the same name as the source file are forbidden");
|
||||
fatal();
|
||||
}
|
||||
if(docfile && Port::stricmp(FileName::name(docfile->name->str), FileName::name((char*)this->arg)) == 0)
|
||||
{
|
||||
error("Output doc files with the same name as the source file are forbidden");
|
||||
fatal();
|
||||
}
|
||||
if(hdrfile && Port::stricmp(FileName::name(hdrfile->name->str), FileName::name((char*)this->arg)) == 0)
|
||||
{
|
||||
error("Output header files with the same name as the source file are forbidden");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// LDC
|
||||
// another safety check to make sure we don't overwrite previous output files
|
||||
if (!singleObj)
|
||||
check_and_add_output_file(this, objfile->name->str);
|
||||
if (docfile)
|
||||
check_and_add_output_file(this, docfile->name->str);
|
||||
if (hdrfile)
|
||||
check_and_add_output_file(this, hdrfile->name->str);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Module::deleteObjFile()
|
||||
{
|
||||
if (global.params.obj)
|
||||
@@ -347,9 +201,6 @@ void Module::deleteObjFile()
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
#if IN_LLVM
|
||||
delete moduleInfoType;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *Module::kind()
|
||||
@@ -890,7 +741,7 @@ void Module::importAll(Scope *prevsc)
|
||||
sc->pop(); // 2 pops because Scope::createGlobal() created 2
|
||||
}
|
||||
|
||||
void Module::semantic(Scope* unused_sc)
|
||||
void Module::semantic()
|
||||
{
|
||||
if (semanticstarted)
|
||||
return;
|
||||
@@ -960,7 +811,7 @@ void Module::semantic(Scope* unused_sc)
|
||||
//printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
|
||||
}
|
||||
|
||||
void Module::semantic2(Scope* unused_sc)
|
||||
void Module::semantic2()
|
||||
{
|
||||
if (deferred.dim)
|
||||
{
|
||||
@@ -1000,7 +851,7 @@ void Module::semantic2(Scope* unused_sc)
|
||||
//printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent);
|
||||
}
|
||||
|
||||
void Module::semantic3(Scope* unused_sc)
|
||||
void Module::semantic3()
|
||||
{
|
||||
//printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent);
|
||||
if (semanticstarted >= 3)
|
||||
@@ -1053,8 +904,7 @@ void Module::inlineScan()
|
||||
/****************************************************
|
||||
*/
|
||||
|
||||
// is this used anywhere?
|
||||
/*
|
||||
#if IN_DMD
|
||||
void Module::gensymfile()
|
||||
{
|
||||
OutBuffer buf;
|
||||
@@ -1076,7 +926,8 @@ void Module::gensymfile()
|
||||
buf.data = NULL;
|
||||
|
||||
symfile->writev();
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************
|
||||
* Determine if we need to generate an instance of ModuleInfo
|
||||
|
||||
@@ -143,12 +143,15 @@ struct Module : Package
|
||||
void parse(); // syntactic parse
|
||||
#endif
|
||||
void importAll(Scope *sc);
|
||||
void semantic(Scope* unused_sc = NULL); // semantic analysis
|
||||
void semantic2(Scope* unused_sc = NULL); // pass 2 semantic analysis
|
||||
void semantic3(Scope* unused_sc = NULL); // pass 3 semantic analysis
|
||||
void semantic(); // semantic analysis
|
||||
void semantic2(); // pass 2 semantic analysis
|
||||
void semantic3(); // pass 3 semantic analysis
|
||||
void inlineScan(); // scan for functions to inline
|
||||
void genhdrfile(); // generate D import file
|
||||
// void gensymfile();
|
||||
#if IN_DMD
|
||||
void genobjfile(int multiobj);
|
||||
void gensymfile();
|
||||
#endif
|
||||
void gendocfile();
|
||||
int needModuleInfo();
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
@@ -201,7 +204,6 @@ struct Module : Package
|
||||
|
||||
bool llvmForceLogging;
|
||||
llvm::GlobalVariable* moduleInfoVar;
|
||||
llvm::StructType* moduleInfoType;
|
||||
|
||||
// array ops emitted in this module already
|
||||
AA *arrayfuncs;
|
||||
|
||||
131
dmd2/mtype.c
131
dmd2/mtype.c
@@ -3624,37 +3624,24 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
|
||||
|
||||
if (ident == Id::reverse && (n->ty == Tchar || n->ty == Twchar))
|
||||
{
|
||||
|
||||
#if IN_LLVM
|
||||
Expression *ec;
|
||||
|
||||
//LDC: Build arguments.
|
||||
static FuncDeclaration *adReverseChar_fd = NULL;
|
||||
if(!adReverseChar_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
Type* arrty = Type::tchar->arrayOf();
|
||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||
adReverseChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseChar");
|
||||
}
|
||||
static FuncDeclaration *adReverseWchar_fd = NULL;
|
||||
if(!adReverseWchar_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
Type* arrty = Type::twchar->arrayOf();
|
||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||
adReverseWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseWchar");
|
||||
}
|
||||
|
||||
if(n->ty == Twchar)
|
||||
ec = new VarExp(Loc(), adReverseWchar_fd);
|
||||
else
|
||||
ec = new VarExp(Loc(), adReverseChar_fd);
|
||||
#else
|
||||
static const char *name[2] = { "_adReverseChar", "_adReverseWchar" };
|
||||
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
static FuncDeclaration *funcs[2] = { 0, 0 };
|
||||
int i = n->ty == Twchar;
|
||||
if (!funcs[i]) {
|
||||
Parameters *args = new Parameters;
|
||||
Type *next = n->ty == Twchar ? Type::twchar : Type::tchar;
|
||||
Type *arrty = next->arrayOf();
|
||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||
funcs[i] = FuncDeclaration::genCfunc(args, arrty, name[i]);
|
||||
}
|
||||
FuncDeclaration *fd = funcs[i];
|
||||
#else
|
||||
const char *nm = name[n->ty == Twchar];
|
||||
FuncDeclaration *fd = FuncDeclaration::genCfunc(Type::tindex, nm);
|
||||
Expression *ec = new VarExp(Loc(), fd);
|
||||
#endif
|
||||
Expression *ec = new VarExp(Loc(), fd);
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
Expressions *arguments = new Expressions();
|
||||
arguments->push(e);
|
||||
@@ -3664,34 +3651,28 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
|
||||
else if (ident == Id::sort && (n->ty == Tchar || n->ty == Twchar))
|
||||
{
|
||||
Expression *ec;
|
||||
FuncDeclaration *fd;
|
||||
Expressions *arguments;
|
||||
const char *nm;
|
||||
static const char *name[2] = { "_adSortChar", "_adSortWchar" };
|
||||
|
||||
#if IN_LLVM
|
||||
//LDC: Build arguments.
|
||||
static FuncDeclaration *adSortChar_fd = NULL;
|
||||
if(!adSortChar_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
Type* arrty = Type::tchar->arrayOf();
|
||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||
adSortChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortChar");
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
static FuncDeclaration *funcs[2] = { 0, 0 };
|
||||
int i = n->ty == Twchar;
|
||||
if (!funcs[i]) {
|
||||
Parameters *args = new Parameters;
|
||||
Type *next = n->ty == Twchar ? Type::twchar : Type::tchar;
|
||||
Type *arrty = next->arrayOf();
|
||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||
funcs[i] = FuncDeclaration::genCfunc(args, arrty, name[i]);
|
||||
}
|
||||
static FuncDeclaration *adSortWchar_fd = NULL;
|
||||
if(!adSortWchar_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
Type* arrty = Type::twchar->arrayOf();
|
||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||
adSortWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortWchar");
|
||||
}
|
||||
|
||||
if(n->ty == Twchar)
|
||||
ec = new VarExp(Loc(), adSortWchar_fd);
|
||||
else
|
||||
ec = new VarExp(Loc(), adSortChar_fd);
|
||||
fd = funcs[i];
|
||||
#else
|
||||
nm = name[n->ty == Twchar];
|
||||
fd = FuncDeclaration::genCfunc(Type::tindex, nm);
|
||||
ec = new VarExp(Loc(), fd);
|
||||
#endif
|
||||
ec = new VarExp(Loc(), fd);
|
||||
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
arguments = new Expressions();
|
||||
arguments->push(e);
|
||||
@@ -3701,6 +3682,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
|
||||
else if (ident == Id::reverse || ident == Id::dup || ident == Id::idup)
|
||||
{
|
||||
Expression *ec;
|
||||
FuncDeclaration *fd;
|
||||
Expressions *arguments;
|
||||
int size = next->size(e->loc);
|
||||
int dup;
|
||||
@@ -3708,31 +3690,31 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
|
||||
Expression *olde = e;
|
||||
assert(size);
|
||||
dup = (ident == Id::dup || ident == Id::idup);
|
||||
#if IN_LLVM
|
||||
//LDC: Build arguments.
|
||||
static FuncDeclaration *adDup_fd = NULL;
|
||||
if(!adDup_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||
adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup);
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
Parameters *args = new Parameters;
|
||||
if (dup) {
|
||||
static FuncDeclaration *adDup_fd = 0;
|
||||
if (!adDup_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||
adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup);
|
||||
}
|
||||
fd = adDup_fd;
|
||||
} else {
|
||||
static FuncDeclaration *adReverse_fd = 0;
|
||||
if (!adReverse_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
|
||||
adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse);
|
||||
}
|
||||
fd = adReverse_fd;
|
||||
}
|
||||
static FuncDeclaration *adReverse_fd = NULL;
|
||||
if(!adReverse_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
|
||||
adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse);
|
||||
}
|
||||
|
||||
if(dup)
|
||||
ec = new VarExp(Loc(), adDup_fd);
|
||||
else
|
||||
ec = new VarExp(Loc(), adReverse_fd);
|
||||
#else
|
||||
fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse);
|
||||
ec = new VarExp(Loc(), fd);
|
||||
#endif
|
||||
ec = new VarExp(Loc(), fd);
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
arguments = new Expressions();
|
||||
if (dup)
|
||||
@@ -3768,21 +3750,18 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f
|
||||
Expression *ec;
|
||||
Expressions *arguments;
|
||||
|
||||
#if IN_LLVM
|
||||
//LDC: Build arguments.
|
||||
static FuncDeclaration *adSort_fd = NULL;
|
||||
if(!adSort_fd) {
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
static FuncDeclaration *fd = NULL;
|
||||
if (!fd) {
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
||||
adSort_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort");
|
||||
fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort");
|
||||
}
|
||||
|
||||
ec = new VarExp(Loc(), adSort_fd);
|
||||
#else
|
||||
fd = FuncDeclaration::genCfunc(tint32->arrayOf(), "_adSort");
|
||||
ec = new VarExp(Loc(), fd);
|
||||
#endif
|
||||
ec = new VarExp(Loc(), fd);
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
arguments = new Expressions();
|
||||
arguments->push(e);
|
||||
|
||||
@@ -52,6 +52,9 @@ struct Parameter;
|
||||
#ifdef IN_GCC
|
||||
union tree_node; typedef union tree_node TYPE;
|
||||
typedef TYPE type;
|
||||
#elif IN_LLVM
|
||||
#else
|
||||
typedef struct TYPE type;
|
||||
#endif
|
||||
|
||||
#if IN_DMD
|
||||
|
||||
@@ -993,7 +993,7 @@ enum LINK Parser::parseLinkage()
|
||||
else if (id == Id::System)
|
||||
{
|
||||
#if IN_LLVM
|
||||
if (global.params.targetTriple.isOSWindows())
|
||||
if (global.params.isWindows)
|
||||
link = LINKwindows;
|
||||
else
|
||||
link = LINKc;
|
||||
|
||||
@@ -1989,11 +1989,6 @@ Lagain:
|
||||
{
|
||||
Expression *ec;
|
||||
Expression *e;
|
||||
#if IN_LLVM
|
||||
FuncDeclaration *fdapply;
|
||||
TypeDelegate* dgty;
|
||||
TypeDelegate* fldeTy;
|
||||
#endif
|
||||
|
||||
if (!checkForArgTypes())
|
||||
{ body = body->semanticNoScope(sc);
|
||||
@@ -2135,46 +2130,36 @@ Lagain:
|
||||
/* Call:
|
||||
* _aaApply(aggr, keysize, flde)
|
||||
*/
|
||||
#if !IN_LLVM
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
static const char *names[2] = { "_aaApply", "_aaApply2" };
|
||||
static FuncDeclaration *funcs[2] = { NULL, NULL };
|
||||
static TypeDelegate *dgs[2] = { NULL, NULL };
|
||||
|
||||
FuncDeclaration *fdapply;
|
||||
if (dim == 2)
|
||||
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2");
|
||||
else
|
||||
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply");
|
||||
#else
|
||||
//LDC: Build arguments.
|
||||
static FuncDeclaration *aaApply2_fd = NULL;
|
||||
static TypeDelegate* aaApply2_dg;
|
||||
if(!aaApply2_fd) {
|
||||
TypeDelegate *fldeTy;
|
||||
|
||||
unsigned char i = dim == 2;
|
||||
if (!funcs[i]) {
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL));
|
||||
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
|
||||
Parameters* dgargs = new Parameters;
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd));
|
||||
args->push(new Parameter(STCin, aaApply2_dg, NULL, NULL));
|
||||
aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tint32, "_aaApply2");
|
||||
}
|
||||
static FuncDeclaration *aaApply_fd = NULL;
|
||||
static TypeDelegate* aaApply_dg;
|
||||
if(!aaApply_fd) {
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL)); // FIXME: Real parameter type is AA.
|
||||
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
|
||||
Parameters* dgargs = new Parameters;
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd));
|
||||
args->push(new Parameter(STCin, aaApply_dg, NULL, NULL));
|
||||
aaApply_fd = FuncDeclaration::genCfunc(args, Type::tint32, "_aaApply");
|
||||
}
|
||||
if (dim == 2) {
|
||||
fdapply = aaApply2_fd;
|
||||
fldeTy = aaApply2_dg;
|
||||
} else {
|
||||
fdapply = aaApply_fd;
|
||||
fldeTy = aaApply_dg;
|
||||
if (dim == 2)
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
dgs[i] = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd));
|
||||
args->push(new Parameter(STCin, dgs[i], NULL, NULL));
|
||||
funcs[i] = FuncDeclaration::genCfunc(args, Type::tint32, names[i]);
|
||||
}
|
||||
fdapply = funcs[i];
|
||||
fldeTy = dgs[i];
|
||||
|
||||
#else
|
||||
FuncDeclaration *fdapply;
|
||||
if (dim == 2)
|
||||
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2");
|
||||
else
|
||||
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply");
|
||||
#endif
|
||||
ec = new VarExp(Loc(), fdapply);
|
||||
Expressions *exps = new Expressions();
|
||||
@@ -2229,24 +2214,19 @@ Lagain:
|
||||
const char *r = (op == TOKforeach_reverse) ? "R" : "";
|
||||
int j = sprintf(fdname, "_aApply%s%.*s%llu", r, 2, fntab[flag], (ulonglong)dim);
|
||||
assert(j < sizeof(fdname) / sizeof(fdname[0]));
|
||||
#if IN_LLVM
|
||||
//LDC: Build arguments.
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
FuncDeclaration *fdapply;
|
||||
TypeDelegate *dgty;
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, tn->arrayOf(), NULL, NULL));
|
||||
if (dim == 2) {
|
||||
Parameters* dgargs = new Parameters;
|
||||
Parameters* dgargs = new Parameters;
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
if (dim == 2)
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd));
|
||||
args->push(new Parameter(STCin, dgty, NULL, NULL));
|
||||
fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname);
|
||||
} else {
|
||||
Parameters* dgargs = new Parameters;
|
||||
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
|
||||
dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd));
|
||||
args->push(new Parameter(STCin, dgty, NULL, NULL));
|
||||
fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname);
|
||||
}
|
||||
dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd));
|
||||
args->push(new Parameter(STCin, dgty, NULL, NULL));
|
||||
fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname);
|
||||
|
||||
#else
|
||||
FuncDeclaration *fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname);
|
||||
#endif
|
||||
@@ -4419,8 +4399,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
|
||||
Statements *cs = new Statements();
|
||||
cs->push(new ExpStatement(loc, tmp));
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC: Build args
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, ClassDeclaration::object->type, NULL, NULL));
|
||||
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorenter);
|
||||
@@ -4431,7 +4410,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
|
||||
e->type = Type::tvoid; // do not run semantic on e
|
||||
cs->push(new ExpStatement(loc, e));
|
||||
|
||||
#if IN_LLVM
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorexit);
|
||||
#else
|
||||
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::monitorexit);
|
||||
@@ -4465,8 +4444,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
|
||||
Statements *cs = new Statements();
|
||||
cs->push(new ExpStatement(loc, tmp));
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC: Build args
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
Parameters* args = new Parameters;
|
||||
args->push(new Parameter(STCin, t->pointerTo(), NULL, NULL));
|
||||
|
||||
@@ -4480,7 +4458,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
|
||||
e->type = Type::tvoid; // do not run semantic on e
|
||||
cs->push(new ExpStatement(loc, e));
|
||||
|
||||
#if IN_LLVM
|
||||
#if IN_LLVM // LDC: Build parameters.
|
||||
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(args, Type::tvoid, Id::criticalexit);
|
||||
#else
|
||||
FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::criticalexit);
|
||||
|
||||
@@ -75,17 +75,16 @@ typedef bool (*sapply_fp_t)(Statement *, void *);
|
||||
// Back end
|
||||
struct IRState;
|
||||
struct Blockx;
|
||||
#if IN_LLVM
|
||||
class DValue;
|
||||
typedef DValue elem;
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
union tree_node; typedef union tree_node block;
|
||||
//union tree_node; typedef union tree_node elem;
|
||||
union tree_node; typedef union tree_node elem;
|
||||
#elif IN_LLVM
|
||||
class DValue;
|
||||
typedef DValue elem;
|
||||
#else
|
||||
struct block;
|
||||
//struct elem;
|
||||
struct elem;
|
||||
#endif
|
||||
struct code;
|
||||
|
||||
|
||||
125
dmd2/target.c
125
dmd2/target.c
@@ -1,125 +0,0 @@
|
||||
|
||||
// Copyright (c) 2013 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Iain Buclaw
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "target.h"
|
||||
#include "mars.h"
|
||||
#include "mtype.h"
|
||||
|
||||
#if IN_LLVM
|
||||
unsigned GetTypeAlignment(Type* t);
|
||||
unsigned GetPointerSize();
|
||||
unsigned GetTypeStoreSize(Type* t);
|
||||
unsigned GetTypeAllocSize(Type* t);
|
||||
#endif
|
||||
|
||||
int Target::ptrsize;
|
||||
int Target::realsize;
|
||||
int Target::realpad;
|
||||
int Target::realalignsize;
|
||||
|
||||
void Target::init()
|
||||
{
|
||||
#if IN_LLVM
|
||||
ptrsize = GetPointerSize();
|
||||
realsize = GetTypeAllocSize(Type::basic[Tfloat80]);
|
||||
realpad = realsize - GetTypeStoreSize(Type::basic[Tfloat80]);
|
||||
realalignsize = GetTypeAlignment(Type::basic[Tfloat80]);
|
||||
#else
|
||||
// These have default values for 32 bit code, they get
|
||||
// adjusted for 64 bit code.
|
||||
ptrsize = 4;
|
||||
|
||||
if (global.params.isLinux || global.params.isFreeBSD
|
||||
|| global.params.isOpenBSD || global.params.isSolaris)
|
||||
{
|
||||
realsize = 12;
|
||||
realpad = 2;
|
||||
realalignsize = 4;
|
||||
}
|
||||
else if (global.params.isOSX)
|
||||
{
|
||||
realsize = 16;
|
||||
realpad = 6;
|
||||
realalignsize = 16;
|
||||
}
|
||||
else if (global.params.isWindows)
|
||||
{
|
||||
realsize = 10;
|
||||
realpad = 0;
|
||||
realalignsize = 2;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
if (global.params.is64bit)
|
||||
{
|
||||
ptrsize = 8;
|
||||
if (global.params.isLinux || global.params.isFreeBSD || global.params.isSolaris)
|
||||
{
|
||||
realsize = 16;
|
||||
realpad = 6;
|
||||
realalignsize = 16;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Return memory alignment size of type.
|
||||
*/
|
||||
|
||||
unsigned Target::alignsize (Type* type)
|
||||
{
|
||||
assert (type->isTypeBasic());
|
||||
|
||||
#if IN_LLVM
|
||||
if (type->ty == Tvoid) return 1;
|
||||
return GetTypeAlignment(type);
|
||||
#else
|
||||
switch (type->ty)
|
||||
{
|
||||
case Tfloat80:
|
||||
case Timaginary80:
|
||||
case Tcomplex80:
|
||||
return Target::realalignsize;
|
||||
|
||||
case Tcomplex32:
|
||||
if (global.params.isLinux || global.params.isOSX || global.params.isFreeBSD
|
||||
|| global.params.isOpenBSD || global.params.isSolaris)
|
||||
return 4;
|
||||
break;
|
||||
|
||||
case Tint64:
|
||||
case Tuns64:
|
||||
case Tfloat64:
|
||||
case Timaginary64:
|
||||
case Tcomplex64:
|
||||
if (global.params.isLinux || global.params.isOSX || global.params.isFreeBSD
|
||||
|| global.params.isOpenBSD || global.params.isSolaris)
|
||||
return global.params.is64bit ? 8 : 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return type->size(Loc());
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Return field alignment size of type.
|
||||
*/
|
||||
|
||||
unsigned Target::fieldalign (Type* type)
|
||||
{
|
||||
// LDC_FIXME: Verify this.
|
||||
return type->alignsize();
|
||||
}
|
||||
@@ -22,7 +22,7 @@ struct Target
|
||||
static int realsize; // size a real consumes in memory
|
||||
static int realpad; // 'padding' added to the CPU real size to bring it up to realsize
|
||||
static int realalignsize; // alignment for reals
|
||||
|
||||
|
||||
static void init();
|
||||
static unsigned alignsize(Type* type);
|
||||
static unsigned fieldalign(Type* type);
|
||||
|
||||
@@ -5509,7 +5509,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f
|
||||
{
|
||||
ea = ea->optimize(WANTvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ea->op == TOKvar)
|
||||
{ /* This test is to skip substituting a const var with
|
||||
* its initializer. The problem is the initializer won't
|
||||
@@ -6999,3 +6999,5 @@ void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
buf->writebyte(';');
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -209,9 +209,7 @@ int main(int argc, char** argv)
|
||||
ConfigFile cfg_file;
|
||||
|
||||
// just ignore errors for now, they are still printed
|
||||
#define CFG_FILENAME "ldc2.conf"
|
||||
cfg_file.read(global.params.argv0, (void*)main, CFG_FILENAME);
|
||||
#undef CFG_FILENAME
|
||||
cfg_file.read(global.params.argv0, (void*)main, "ldc2.conf");
|
||||
|
||||
// insert config file additions to the argument list
|
||||
final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end());
|
||||
@@ -477,7 +475,15 @@ int main(int argc, char** argv)
|
||||
|
||||
gTargetMachine = createTargetMachine(mTargetTriple, mArch, mCPU, mAttrs, bitness,
|
||||
mRelocModel, mCodeModel, codeGenOptLevel(), global.params.symdebug);
|
||||
global.params.targetTriple = llvm::Triple(gTargetMachine->getTargetTriple());
|
||||
llvm::Triple targetTriple = llvm::Triple(gTargetMachine->getTargetTriple());
|
||||
global.params.targetTriple = targetTriple;
|
||||
global.params.trace = false;
|
||||
global.params.isLinux = targetTriple.getOS() == llvm::Triple::Linux;
|
||||
global.params.isOSX = targetTriple.isMacOSX();
|
||||
global.params.isWindows = targetTriple.isOSWindows();
|
||||
global.params.isFreeBSD = targetTriple.getOS() == llvm::Triple::FreeBSD;
|
||||
global.params.isOpenBSD = targetTriple.getOS() == llvm::Triple::OpenBSD;
|
||||
global.params.isSolaris = targetTriple.getOS() == llvm::Triple::Solaris;
|
||||
|
||||
#if LDC_LLVM_VER >= 302
|
||||
gDataLayout = gTargetMachine->getDataLayout();
|
||||
|
||||
135
gen/module.cpp
135
gen/module.cpp
@@ -39,6 +39,7 @@
|
||||
#include "ir/irmodule.h"
|
||||
#include "ir/irtype.h"
|
||||
#include "ir/irvar.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/LinkAllPasses.h"
|
||||
#if LDC_LLVM_VER >= 303
|
||||
@@ -53,6 +54,121 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static llvm::cl::opt<bool> preservePaths("op",
|
||||
llvm::cl::desc("Do not strip paths from source file"),
|
||||
llvm::cl::ZeroOrMore);
|
||||
|
||||
static llvm::cl::opt<bool> fqnNames("oq",
|
||||
llvm::cl::desc("Write object files with fully qualified names"),
|
||||
llvm::cl::ZeroOrMore);
|
||||
|
||||
static void check_and_add_output_file(Module* NewMod, const std::string& str)
|
||||
{
|
||||
typedef std::map<std::string, Module*> map_t;
|
||||
static map_t files;
|
||||
|
||||
map_t::iterator i = files.find(str);
|
||||
if (i != files.end()) {
|
||||
Module* ThisMod = i->second;
|
||||
error(Loc(), "Output file '%s' for module '%s' collides with previous module '%s'. See the -oq option",
|
||||
str.c_str(), NewMod->toPrettyChars(), ThisMod->toPrettyChars());
|
||||
fatal();
|
||||
}
|
||||
files.insert(std::make_pair(str, NewMod));
|
||||
}
|
||||
|
||||
void Module::buildTargetFiles(bool singleObj)
|
||||
{
|
||||
if (objfile &&
|
||||
(!doDocComment || docfile) &&
|
||||
(!doHdrGen || hdrfile))
|
||||
return;
|
||||
|
||||
if (!objfile) {
|
||||
if (global.params.output_o)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir,
|
||||
global.params.targetTriple.isOSWindows() ? global.obj_ext_alt : global.obj_ext);
|
||||
else if (global.params.output_bc)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.bc_ext);
|
||||
else if (global.params.output_ll)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.ll_ext);
|
||||
else if (global.params.output_s)
|
||||
objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.s_ext);
|
||||
}
|
||||
if (doDocComment && !docfile)
|
||||
docfile = Module::buildFilePath(global.params.docname, global.params.docdir, global.doc_ext);
|
||||
if (doHdrGen && !hdrfile)
|
||||
hdrfile = Module::buildFilePath(global.params.hdrname, global.params.hdrdir, global.hdr_ext);
|
||||
|
||||
// safety check: never allow obj, doc or hdr file to have the source file's name
|
||||
if (Port::stricmp(FileName::name(objfile->name->str), FileName::name((char*)this->arg)) == 0) {
|
||||
error("Output object files with the same name as the source file are forbidden");
|
||||
fatal();
|
||||
}
|
||||
if (docfile && Port::stricmp(FileName::name(docfile->name->str), FileName::name((char*)this->arg)) == 0) {
|
||||
error("Output doc files with the same name as the source file are forbidden");
|
||||
fatal();
|
||||
}
|
||||
if (hdrfile && Port::stricmp(FileName::name(hdrfile->name->str), FileName::name((char*)this->arg)) == 0) {
|
||||
error("Output header files with the same name as the source file are forbidden");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// LDC
|
||||
// another safety check to make sure we don't overwrite previous output files
|
||||
if (!singleObj)
|
||||
check_and_add_output_file(this, objfile->name->str);
|
||||
if (docfile)
|
||||
check_and_add_output_file(this, docfile->name->str);
|
||||
if (hdrfile)
|
||||
check_and_add_output_file(this, hdrfile->name->str);
|
||||
}
|
||||
|
||||
File* Module::buildFilePath(const char* forcename, const char* path, const char* ext)
|
||||
{
|
||||
const char *argobj;
|
||||
if (forcename) {
|
||||
argobj = forcename;
|
||||
} else {
|
||||
if (preservePaths)
|
||||
argobj = (char*)this->arg;
|
||||
else
|
||||
argobj = FileName::name((char*)this->arg);
|
||||
|
||||
if (fqnNames) {
|
||||
char *name = md ? md->toChars() : toChars();
|
||||
argobj = FileName::replaceName((char*)argobj, name);
|
||||
|
||||
// add ext, otherwise forceExt will make nested.module into nested.bc
|
||||
size_t len = strlen(argobj);
|
||||
size_t extlen = strlen(ext);
|
||||
char* s = (char *)alloca(len + 1 + extlen + 1);
|
||||
memcpy(s, argobj, len);
|
||||
s[len] = '.';
|
||||
memcpy(s + len + 1, ext, extlen + 1);
|
||||
s[len+1+extlen] = 0;
|
||||
argobj = s;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FileName::absolute(argobj))
|
||||
argobj = FileName::combine(path, argobj);
|
||||
|
||||
FileName::ensurePathExists(FileName::path(argobj));
|
||||
|
||||
// always append the extension! otherwise hard to make output switches consistent
|
||||
// if (forcename)
|
||||
// return new File(argobj);
|
||||
// else
|
||||
// allow for .o and .obj on windows
|
||||
#if _WIN32
|
||||
if (ext == global.params.objdir && FileName::ext(argobj)
|
||||
&& Port::stricmp(FileName::ext(argobj), global.obj_ext_alt) == 0)
|
||||
return new File((char*)argobj);
|
||||
#endif
|
||||
return new File(FileName::forceExt(argobj, ext));
|
||||
}
|
||||
|
||||
static llvm::Function* build_module_function(const std::string &name, const std::list<FuncDeclaration*> &funcs,
|
||||
const std::list<VarDeclaration*> &gates = std::list<VarDeclaration*>())
|
||||
{
|
||||
@@ -336,13 +452,13 @@ llvm::GlobalVariable* Module::moduleInfoSymbol()
|
||||
return var;
|
||||
}
|
||||
|
||||
if (moduleInfoVar)
|
||||
return moduleInfoVar;
|
||||
|
||||
// declare global
|
||||
// flags will be modified at runtime so can't make it constant
|
||||
moduleInfoVar = getOrCreateGlobal(loc, *gIR->module, moduleInfoType,
|
||||
false, llvm::GlobalValue::ExternalLinkage, NULL, MIname);
|
||||
if (!moduleInfoVar) {
|
||||
// declare global
|
||||
// flags will be modified at runtime so can't make it constant
|
||||
LLType *moduleInfoType = llvm::StructType::create(llvm::getGlobalContext());
|
||||
moduleInfoVar = getOrCreateGlobal(loc, *gIR->module, moduleInfoType,
|
||||
false, llvm::GlobalValue::ExternalLinkage, NULL, MIname);
|
||||
}
|
||||
|
||||
return moduleInfoVar;
|
||||
}
|
||||
@@ -520,10 +636,11 @@ void Module::genmoduleinfo()
|
||||
b.push(toConstantArray(it, at, name, len, false));
|
||||
|
||||
// create and set initializer
|
||||
b.finalize(moduleInfoType, moduleInfoSymbol());
|
||||
LLGlobalVariable *moduleInfoSym = moduleInfoSymbol();
|
||||
b.finalize(moduleInfoSym->getType()->getPointerElementType(), moduleInfoSym);
|
||||
|
||||
// build the modulereference and ctor for registering it
|
||||
LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSymbol());
|
||||
LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSym);
|
||||
|
||||
AppendFunctionToLLVMGlobalCtorsDtors(mictor, 65535, true);
|
||||
}
|
||||
|
||||
53
gen/target.cpp
Normal file
53
gen/target.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
//===-- target.cpp -------------------------------------------------------===//
|
||||
//
|
||||
// LDC – the LLVM D compiler
|
||||
//
|
||||
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
||||
// file for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "target.h"
|
||||
#include "mars.h"
|
||||
#include "mtype.h"
|
||||
|
||||
unsigned GetTypeAlignment(Type* t);
|
||||
unsigned GetPointerSize();
|
||||
unsigned GetTypeStoreSize(Type* t);
|
||||
unsigned GetTypeAllocSize(Type* t);
|
||||
|
||||
int Target::ptrsize;
|
||||
int Target::realsize;
|
||||
int Target::realpad;
|
||||
int Target::realalignsize;
|
||||
|
||||
void Target::init()
|
||||
{
|
||||
ptrsize = GetPointerSize();
|
||||
realsize = GetTypeAllocSize(Type::basic[Tfloat80]);
|
||||
realpad = realsize - GetTypeStoreSize(Type::basic[Tfloat80]);
|
||||
realalignsize = GetTypeAlignment(Type::basic[Tfloat80]);
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Return memory alignment size of type.
|
||||
*/
|
||||
|
||||
unsigned Target::alignsize (Type* type)
|
||||
{
|
||||
assert (type->isTypeBasic());
|
||||
if (type->ty == Tvoid) return 1;
|
||||
return GetTypeAlignment(type);
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Return field alignment size of type.
|
||||
*/
|
||||
|
||||
unsigned Target::fieldalign (Type* type)
|
||||
{
|
||||
// LDC_FIXME: Verify this.
|
||||
return type->alignsize();
|
||||
}
|
||||
Reference in New Issue
Block a user