//===-- main.cpp --------------------------------------------------------===// // // LDC – the LLVM D compiler // // This file is distributed under the BSD-style LDC license. See the LICENSE // file for details. // //===----------------------------------------------------------------------===// #include "dmd/compiler.h" #include "dmd/cond.h" #include "dmd/errors.h" #include "dmd/id.h" #include "dmd/identifier.h" #include "dmd/hdrgen.h" #include "dmd/json.h" #include "dmd/ldcbindings.h" #include "dmd/mars.h" #include "dmd/module.h" #include "dmd/mtype.h" #include "dmd/root/rmem.h" #include "dmd/scope.h" #include "dmd/target.h" #include "driver/args.h" #include "driver/cache.h" #include "driver/cl_helpers.h" #include "driver/cl_options.h" #include "driver/cl_options_instrumentation.h" #include "driver/cl_options_sanitizers.h" #include "driver/codegenerator.h" #include "driver/configfile.h" #include "driver/cpreprocessor.h" #include "driver/dcomputecodegenerator.h" #include "driver/exe_path.h" #include "driver/ldc-version.h" #include "driver/linker.h" #include "driver/plugins.h" #include "driver/targetmachine.h" #include "driver/timetrace.h" #include "gen/abi/abi.h" #include "gen/irstate.h" #include "gen/ldctraits.h" #include "gen/linkage.h" #include "gen/llvm.h" #include "gen/llvmhelpers.h" #include "gen/logger.h" #include "gen/modules.h" #include "gen/objcgen.h" #include "gen/optimizer.h" #include "gen/passes/metadata.h" #include "gen/passes/Passes.h" #include "gen/runtime.h" #include "gen/uda.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/InitializePasses.h" #include "llvm/IR/LLVMContext.h" #include "llvm/LinkAllIR.h" #include "llvm/LinkAllPasses.h" #include "llvm/Support/FileSystem.h" #if LDC_LLVM_VER >= 1700 #include "llvm/TargetParser/Host.h" #else #include "llvm/Support/Host.h" #endif #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" #if LDC_LLVM_VER >= 1400 #include "llvm/MC/TargetRegistry.h" #else #include "llvm/Support/TargetRegistry.h" #endif #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetMachine.h" #if LDC_MLIR_ENABLED #include "mlir/IR/MLIRContext.h" #endif #include #include #include #include #if _WIN32 #include "llvm/Support/ConvertUTF.h" #include #endif // In dmd/doc.d void gendocfile(Module *m); // In dmd/mars.d void generateJson(Modules *modules); using namespace dmd; using namespace opts; static StringsAdapter impPathsStore("I", global.params.imppath); static cl::list importPaths("I", cl::desc("Look for imports also in "), cl::value_desc("directory"), cl::location(impPathsStore), cl::Prefix); // Note: this option is parsed manually in C main(). static cl::opt enableGC( "lowmem", cl::ZeroOrMore, cl::desc("Enable the garbage collector for the LDC front-end. This reduces " "the compiler memory requirements but increases compile times.")); // Deprecated options extern llvm::cl::opt checkPrintf; namespace { // This function exits the program. void printVersion(llvm::raw_ostream &OS) { OS << "LDC - the LLVM D compiler (" << ldc::ldc_version << "):\n"; OS << " based on DMD " << ldc::dmd_version << " and LLVM " << ldc::llvm_version << "\n"; OS << " built with " << ldc::built_with_Dcompiler_version << "\n"; #if defined(__has_feature) #if __has_feature(address_sanitizer) OS << " compiled with address sanitizer enabled\n"; #endif #endif OS << " Default target: " << llvm::sys::getDefaultTargetTriple() << "\n"; std::string CPU(llvm::sys::getHostCPUName()); if (CPU == "generic" || env::has("SOURCE_DATE_EPOCH")) { // Env variable SOURCE_DATE_EPOCH indicates that a reproducible build is // wanted. Don't print the actual host CPU in such an environment to aid // in man page generation etc. CPU = "(unknown)"; } OS << " Host CPU: " << CPU << "\n"; OS << " http://dlang.org - http://wiki.dlang.org/LDC\n"; OS << "\n"; // Without explicitly flushing here, only the target list is visible when // redirecting stdout to a file. OS.flush(); llvm::TargetRegistry::printRegisteredTargetsForVersion(OS); exit(EXIT_SUCCESS); } // Helper function to handle -d-debug=* and -d-version=* template void processVersions(const std::vector &list, const char *type, unsigned &globalLevel) { for (const auto &i : list) { const char *value = i.c_str(); if (isdigit(value[0])) { errno = 0; char *end; long level = strtol(value, &end, 10); if (*end || errno || level > INT_MAX) { error(Loc(), "Invalid %s level: %s", type, i.c_str()); } else { globalLevel = static_cast(level); } } else { char *cstr = mem.xstrdup(value); if (Identifier::isValidIdentifier(cstr)) { Condition::addGlobalIdent(cstr); } else { error(Loc(), "Invalid %s identifier or level: '%s'", type, cstr); } } } } // Tries to parse the value of `-[-]