std::string gdbmiModules(CIDebugSymbols *syms, bool humanReadable, std::string *errorMessage) { const Modules modules = getModules(syms, errorMessage); if (modules.empty()) return std::string(); std::ostringstream str; str << '[' << std::hex << std::showbase; const Modules::size_type size = modules.size(); for (Modules::size_type m = 0; m < size; ++m) { const Module &module = modules.at(m); if (m) str << ','; str << "{name=\"" << module.name << "\",image=\"" << gdbmiStringFormat(module.image) << "\",start=\"" << module.base << "\",end=\"" << (module.base + module.size - 1) << '"'; if (module.deferred) str << "{deferred=\"true\""; str << '}'; if (humanReadable) str << '\n'; } str << ']'; return str.str(); }
int main(int argc, char **argv) { global.langPlugins.push_back(&cpp::calypso); // stack trace on signals llvm::sys::PrintStackTraceOnErrorSignal(); exe_path::initialize(argv[0], reinterpret_cast<void *>(main)); global.init(); global.version = ldc::dmd_version; global.ldc_version = ldc::ldc_version; global.llvm_version = ldc::llvm_version; // Initialize LLVM before parsing the command line so that --version shows // registered targets. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargets(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); initializePasses(); bool helpOnly; Strings files; parseCommandLine(argc, argv, files, helpOnly); if (files.dim == 0 && !helpOnly) { cl::PrintHelpMessage(); return EXIT_FAILURE; } if (global.errors) { fatal(); } // Set up the TargetMachine. ExplicitBitness::Type bitness = ExplicitBitness::None; if ((m32bits || m64bits) && (!mArch.empty() || !mTargetTriple.empty())) { error(Loc(), "-m32 and -m64 switches cannot be used together with -march " "and -mtriple switches"); } if (m32bits) { bitness = ExplicitBitness::M32; } if (m64bits) { if (bitness != ExplicitBitness::None) { error(Loc(), "cannot use both -m32 and -m64 options"); } bitness = ExplicitBitness::M64; } if (global.errors) { fatal(); } gTargetMachine = createTargetMachine( mTargetTriple, mArch, mCPU, mAttrs, bitness, mFloatABI, mRelocModel, mCodeModel, codeGenOptLevel(), disableFpElim, disableLinkerStripDead); #if LDC_LLVM_VER >= 308 static llvm::DataLayout DL = gTargetMachine->createDataLayout(); gDataLayout = &DL; #elif LDC_LLVM_VER >= 307 gDataLayout = gTargetMachine->getDataLayout(); #elif LDC_LLVM_VER >= 306 gDataLayout = gTargetMachine->getSubtargetImpl()->getDataLayout(); #else gDataLayout = gTargetMachine->getDataLayout(); #endif { llvm::Triple triple = llvm::Triple(gTargetMachine->getTargetTriple()); global.params.targetTriple = triple; global.params.isWindows = triple.isOSWindows(); global.params.isLP64 = gDataLayout->getPointerSizeInBits() == 64; global.params.is64bit = triple.isArch64Bit(); } // allocate the target abi gABI = TargetABI::getTarget(); // Set predefined version identifiers. registerPredefinedVersions(); dumpPredefinedVersions(); if (global.params.targetTriple.isOSWindows()) { global.dll_ext = "dll"; global.lib_ext = "lib"; } else { global.dll_ext = "so"; global.lib_ext = "a"; } // Initialization Lexer::initLexer(); Type::init(); Id::initialize(); Module::init(); Target::init(); Expression::init(); initPrecedence(); builtin_init(); initTraitsStringTable(); cpp::calypso.init(argv[0]); // CALYPSO HACK // Build import search path if (global.params.imppath) { for (unsigned i = 0; i < global.params.imppath->dim; i++) { const char *path = static_cast<const char *>(global.params.imppath->data[i]); Strings *a = FileName::splitPath(path); if (a) { if (!global.path) { global.path = new Strings(); } global.path->append(a); } } } // Build string import search path if (global.params.fileImppath) { for (unsigned i = 0; i < global.params.fileImppath->dim; i++) { const char *path = static_cast<const char *>(global.params.fileImppath->data[i]); Strings *a = FileName::splitPath(path); if (a) { if (!global.filePath) { global.filePath = new Strings(); } global.filePath->append(a); } } } if (global.params.addMain) { // a dummy name, we never actually look up this file files.push(const_cast<char *>(global.main_d)); } // Create Modules Modules modules; modules.reserve(files.dim); for (unsigned i = 0; i < files.dim; i++) { Identifier *id; const char *ext; const char *name; const char *p = files.data[i]; p = FileName::name(p); // strip path ext = FileName::ext(p); if (ext) { #if LDC_POSIX if (strcmp(ext, global.obj_ext) == 0 || strcmp(ext, global.bc_ext) == 0) #else if (Port::stricmp(ext, global.obj_ext) == 0 || Port::stricmp(ext, global.obj_ext_alt) == 0 || Port::stricmp(ext, global.bc_ext) == 0) #endif { global.params.objfiles->push(static_cast<const char *>(files.data[i])); continue; } #if LDC_POSIX if (strcmp(ext, "a") == 0) #elif __MINGW32__ if (Port::stricmp(ext, "a") == 0) #else if (Port::stricmp(ext, "lib") == 0) #endif { global.params.libfiles->push(static_cast<const char *>(files.data[i])); continue; } if (strcmp(ext, global.ddoc_ext) == 0) { global.params.ddocfiles->push(static_cast<const char *>(files.data[i])); continue; } if (FileName::equals(ext, global.json_ext)) { global.params.doJsonGeneration = 1; global.params.jsonfilename = static_cast<const char *>(files.data[i]); continue; } #if !LDC_POSIX if (Port::stricmp(ext, "res") == 0) { global.params.resfile = static_cast<const char *>(files.data[i]); continue; } if (Port::stricmp(ext, "def") == 0) { global.params.deffile = static_cast<const char *>(files.data[i]); continue; } if (Port::stricmp(ext, "exe") == 0) { global.params.exefile = static_cast<const char *>(files.data[i]); continue; } #endif if (Port::stricmp(ext, global.mars_ext) == 0 || Port::stricmp(ext, global.hdr_ext) == 0 || FileName::equals(ext, "dd")) { ext--; // skip onto '.' assert(*ext == '.'); char *tmp = static_cast<char *>(mem.xmalloc((ext - p) + 1)); memcpy(tmp, p, ext - p); tmp[ext - p] = 0; // strip extension name = tmp; if (name[0] == 0 || strcmp(name, "..") == 0 || strcmp(name, ".") == 0) { goto Linvalid; } } else { error(Loc(), "unrecognized file extension %s\n", ext); fatal(); } } else { name = p; if (!*p) { Linvalid: error(Loc(), "invalid file name '%s'", static_cast<const char *>(files.data[i])); fatal(); } name = p; } id = Identifier::idPool(name); auto m = new Module(files.data[i], id, global.params.doDocComments, global.params.doHdrGeneration); modules.push(m); } // Read files, parse them for (unsigned i = 0; i < modules.dim; i++) { Module *m = modules[i]; if (global.params.verbose) { fprintf(global.stdmsg, "parse %s\n", m->toChars()); } if (!Module::rootModule) { Module::rootModule = m; } m->importedFrom = m; if (strcmp(m->srcfile->name->str, global.main_d) == 0) { static const char buf[] = "void main(){}"; m->srcfile->setbuffer(const_cast<char *>(buf), sizeof(buf)); m->srcfile->ref = 1; } else { m->read(Loc()); } m->parse(global.params.doDocComments); m->buildTargetFiles(singleObj, createSharedLib || createStaticLib); /* m->deleteObjFile(); */ // CALYPSO: deleteObjFile moved to just before .o generation if (m->isDocFile) { gendocfile(m); // Remove m from list of modules modules.remove(i); i--; } } if (global.errors) { fatal(); } if (global.params.doHdrGeneration) { /* Generate 'header' import files. * Since 'header' import files must be independent of command * line switches and what else is imported, they are generated * before any semantic analysis. */ for (unsigned i = 0; i < modules.dim; i++) { if (global.params.verbose) { fprintf(global.stdmsg, "import %s\n", modules[i]->toChars()); } genhdrfile(modules[i]); } } if (global.errors) { fatal(); } // load all unconditional imports for better symbol resolving for (unsigned i = 0; i < modules.dim; i++) { if (global.params.verbose) { fprintf(global.stdmsg, "importall %s\n", modules[i]->toChars()); } modules[i]->importAll(nullptr); } if (global.errors) { fatal(); } // CALYPSO HACK & NOTE: this must be done after the importAll pass for D modules for modmap to kick in // Replace modmap by a monolithic header instead of twisting importAll()? for (auto m: cpp::Module::amodules) { m->importedFrom = m; m->buildTargetFiles(singleObj, createSharedLib || createStaticLib); m->importAll(0); modules.push(m); } // Do semantic analysis for (unsigned i = 0; i < modules.dim; i++) { if (global.params.verbose) { fprintf(global.stdmsg, "semantic %s\n", modules[i]->toChars()); } modules[i]->semantic(); } if (global.errors) { fatal(); } Module::dprogress = 1; Module::runDeferredSemantic(); // Do pass 2 semantic analysis for (unsigned i = 0; i < modules.dim; i++) { if (global.params.verbose) { fprintf(global.stdmsg, "semantic2 %s\n", modules[i]->toChars()); } modules[i]->semantic2(); } if (global.errors) { fatal(); } // Do pass 3 semantic analysis for (unsigned i = 0; i < modules.dim; i++) { if (global.params.verbose) { fprintf(global.stdmsg, "semantic3 %s\n", modules[i]->toChars()); } modules[i]->semantic3(); } if (global.errors) { fatal(); } Module::runDeferredSemantic3(); if (global.errors || global.warnings) { fatal(); } // Now that we analyzed all modules, write the module dependency file if // the user requested it. if (global.params.moduleDepsFile != nullptr) { File deps(global.params.moduleDepsFile); OutBuffer *ob = global.params.moduleDeps; deps.setbuffer(static_cast<void *>(ob->data), ob->offset); deps.write(); } // Generate one or more object/IR/bitcode files. if (global.params.obj && !modules.empty()) { ldc::CodeGenerator cg(llvm::getGlobalContext(), singleObj); for (unsigned i = 0; i < modules.dim; i++) { Module *const m = modules[i]; if (global.params.verbose) { fprintf(global.stdmsg, "code %s\n", m->toChars()); } auto lp = m->langPlugin(); if (lp && !singleObj && !lp->needsCodegen(m)) { // CALYPSO UGLY? global.params.objfiles->push(m->objfile->name->str); continue; } m->deleteObjFile(); // CALYPSO cg.emit(m); if (global.errors) { fatal(); } } } // Generate DDoc output files. if (global.params.doDocComments) { for (unsigned i = 0; i < modules.dim; i++) { gendocfile(modules[i]); } } // Generate the AST-describing JSON file. if (global.params.doJsonGeneration) { emitJson(modules); } freeRuntime(); llvm::llvm_shutdown(); if (global.errors) { fatal(); } // Finally, produce the final executable/archive and run it, if we are // supposed to. int status = EXIT_SUCCESS; if (!global.params.objfiles->dim) { if (global.params.link) { error(Loc(), "no object files to link"); } else if (createStaticLib) { error(Loc(), "no object files"); } } else { if (global.params.link) { status = linkObjToBinary(createSharedLib, staticFlag); } else if (createStaticLib) { status = createStaticLibrary(); } if (global.params.run && status == EXIT_SUCCESS) { status = runExecutable(); /// Delete .obj files and .exe file. for (unsigned i = 0; i < modules.dim; i++) { modules[i]->deleteObjFile(); } deleteExecutable(); } } return status; }