diff --git a/CMakeLists.txt b/CMakeLists.txt index 44fd91ec..db21e7ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,9 +237,9 @@ set_target_properties( ) # LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems -target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBS}" ${LIBCONFIG_LDFLAGS}) +target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBS}" ${LIBCONFIG_LDFLAGS} config++) if(WIN32) - target_link_libraries(${LDC_EXE} config++ imagehlp psapi) + target_link_libraries(${LDC_EXE} imagehlp psapi) set(CONF_INST_DIR bin) endif(WIN32) diff --git a/dmd2/expression.h b/dmd2/expression.h index 35d899a1..addf561a 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -46,6 +46,9 @@ struct InterState; struct Symbol; // back end symbol #endif struct OverloadSet; +#if IN_LLVM +struct AssignExp; +#endif enum TOK; @@ -183,6 +186,8 @@ struct Expression : Object virtual void cacheLvalue(IRState* irs); llvm::Value* cachedLvalue; + + virtual AssignExp* isAssignExp() { return NULL; } #endif }; @@ -1427,6 +1432,7 @@ struct AssignExp : BinExp #if IN_LLVM DValue* toElem(IRState* irs); + virtual AssignExp* isAssignExp() { return this; } #endif }; diff --git a/dmd2/module.c b/dmd2/module.c index 3accae05..5dd3ba84 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -46,6 +46,7 @@ #if IN_LLVM #include "llvm/Support/CommandLine.h" +#include static llvm::cl::opt preservePaths("op", llvm::cl::desc("Do not strip paths from source file"), @@ -305,38 +306,76 @@ void Module::setHdrfile() #endif #if IN_LLVM -void Module::buildTargetFiles() + +// LDC +static void check_and_add_output_file(Module* NewMod, const std::string& str) { - if(objfile && - (!doDocComment || docfile) && - (!doHdrGen || hdrfile)) - return; + typedef std::map map_t; + static map_t files; - if(!objfile) - objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.obj_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(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 && 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 && 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(); - } + map_t::iterator i = files.find(str); + if (i != files.end()) + { + Module* ThisMod = i->second; + error("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_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); + else + objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.obj_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(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 && 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 && 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) diff --git a/dmd2/module.h b/dmd2/module.h index 56a0f708..4b13721e 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -189,7 +189,7 @@ struct Module : Package #if IN_LLVM // LDC llvm::Module* genLLVMModule(llvm::LLVMContext& context, Ir* sir); - void buildTargetFiles(); + void buildTargetFiles(bool singleObj); File* buildFilePath(const char* forcename, const char* path, const char* ext); Module *isModule() { return this; } diff --git a/dmd2/statement.h b/dmd2/statement.h index aebdd6b3..8b894ddd 100644 --- a/dmd2/statement.h +++ b/dmd2/statement.h @@ -117,6 +117,9 @@ struct Statement : Object virtual GotoStatement *isGotoStatement() { return NULL; } virtual AsmStatement *isAsmStatement() { return NULL; } virtual AsmBlockStatement *isAsmBlockStatement() { return NULL; } +#if IN_LLVM + virtual LabelStatement *isLabelStatement() { return NULL; } +#endif #ifdef _DH int incontract; #endif @@ -883,6 +886,7 @@ struct LabelStatement : Statement #if IN_LLVM bool asmLabel; // for labels inside inline assembler void toNakedIR(IRState *irs); + virtual LabelStatement *isLabelStatement() { return this; } #endif }; diff --git a/gen/functions.h b/gen/functions.h index bc569e9f..e6785d56 100644 --- a/gen/functions.h +++ b/gen/functions.h @@ -13,6 +13,12 @@ namespace llvm class Value; } +// TODO: hack for old d2 frontends +#if DMDV2 +typedef Argument Parameter; +typedef Arguments Parameters; +#endif + const llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false); const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl); diff --git a/gen/main.cpp b/gen/main.cpp index e40b2533..9d9c3a5a 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -825,6 +825,8 @@ LDC_TARGETS fatal(); #endif +// TODO: hack for old d2 frontends +#if DMDV1 // load all unconditional imports for better symbol resolving for (int i = 0; i < modules.dim; i++) { @@ -835,6 +837,7 @@ LDC_TARGETS } if (global.errors) fatal(); +#endif // Do semantic analysis for (int i = 0; i < modules.dim; i++) diff --git a/gen/tocall.cpp b/gen/tocall.cpp index b3ebf638..132a0d33 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -13,6 +13,12 @@ #include "gen/logger.h" +// TODO: hack for old d2 frontends +#if DMDV2 +typedef Argument Parameter; +typedef Arguments Parameters; +#endif + ////////////////////////////////////////////////////////////////////////////////////////// TypeFunction* DtoTypeFunction(DValue* fnval) diff --git a/gen/typinf.cpp b/gen/typinf.cpp index e1c468be..ee39caf5 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -46,6 +46,12 @@ #include "ir/irvar.h" #include "ir/irtype.h" +// TODO: hack for old d2 frontends +#if DMDV2 +typedef Argument Parameter; +typedef Arguments Parameters; +#endif + /******************************************* * Get a canonicalized form of the TypeInfo for use with the internal * runtime library routines. Canonicalized in that static arrays are