示例#1
0
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();
}
示例#2
0
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;
}