changeset 988:2667e3a145be

- Fixed LLVM style CL args for D2. - Moved main() into its own file gen/main.cpp - Fixed basic cross compilation - removed the option for setting OS - added support for llc's mattr, mcpu and mtriple switches - added basic ABI abstraction for return value rewrites, it's not perfect and will probably be completely rewritten once I get to handling parameter rewrites as well. - x86-64 extern(C) abi for cfloat returns now match (llvm-)gcc.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Thu, 26 Feb 2009 14:11:49 +0100
parents 73ff89728d85
children 420ef073448d
files dmd/cond.h dmd/inifile.c dmd/mars.c dmd/mars.h dmd2/attrib.c dmd2/inifile.c dmd2/mars.c dmd2/mars.h dmd2/module.c gen/cl_options.cpp gen/cl_options.h gen/functions.cpp gen/irstate.cpp gen/irstate.h gen/naked.cpp gen/statements.cpp gen/tocall.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp
diffstat 20 files changed, 334 insertions(+), 2264 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/cond.h	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd/cond.h	Thu Feb 26 14:11:49 2009 +0100
@@ -55,8 +55,8 @@
 struct DebugCondition : DVCondition
 {
     static void setGlobalLevel(unsigned level);
-    static void addGlobalIdent(char *ident);
-    static void addPredefinedGlobalIdent(char *ident);
+    static void addGlobalIdent(const char *ident);
+    static void addPredefinedGlobalIdent(const char *ident);
 
     DebugCondition(Module *mod, unsigned level, Identifier *ident);
 
@@ -67,9 +67,9 @@
 struct VersionCondition : DVCondition
 {
     static void setGlobalLevel(unsigned level);
-    static void checkPredefined(Loc loc, char *ident);
-    static void addGlobalIdent(char *ident);
-    static void addPredefinedGlobalIdent(char *ident);
+    static void checkPredefined(Loc loc, const char *ident);
+    static void addGlobalIdent(const char *ident);
+    static void addPredefinedGlobalIdent(const char *ident);
 
     VersionCondition(Module *mod, unsigned level, Identifier *ident);
 
--- a/dmd/inifile.c	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd/inifile.c	Thu Feb 26 14:11:49 2009 +0100
@@ -47,7 +47,7 @@
  *	inifile	.ini file name
  */
 
-void inifile(char *argv0, char *inifile)
+void inifile(char *argv0, const char *inifile)
 {
     char *path;		// need path for @P macro
     char *filename;
--- a/dmd/mars.c	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd/mars.c	Thu Feb 26 14:11:49 2009 +0100
@@ -36,48 +36,8 @@
 #include "expression.h"
 #include "lexer.h"
 
-#include "gen/logger.h"
-#include "gen/linker.h"
 #include "revisions.h"
 
-#include "gen/cl_options.h"
-#include "gen/cl_helpers.h"
-using namespace opts;
-
-
-static cl::opt<bool> forceBE("forcebe",
-    cl::desc("Force big-endian"),
-    cl::Hidden,
-    cl::ZeroOrMore);
-
-static cl::opt<bool> noDefaultLib("nodefaultlib",
-    cl::desc("Don't add a default library for linking implicitly"),
-    cl::ZeroOrMore);
-
-static ArrayAdapter impPathsStore("I", global.params.imppath);
-static cl::list<std::string, ArrayAdapter> importPaths("I",
-    cl::desc("Where to look for imports"),
-    cl::value_desc("path"),
-    cl::location(impPathsStore),
-    cl::Prefix);
-
-static ArrayAdapter defaultLibStore("defaultlib", global.params.defaultlibnames);
-static cl::list<std::string, ArrayAdapter> defaultlibs("defaultlib",
-    cl::desc("Set default libraries for non-debug build"),
-    cl::value_desc("lib,..."),
-    cl::location(defaultLibStore),
-    cl::CommaSeparated);
-
-static ArrayAdapter debugLibStore("debuglib", global.params.debuglibnames);
-static cl::list<std::string, ArrayAdapter> debuglibs("debuglib",
-    cl::desc("Set default libraries for debug build"),
-    cl::value_desc("lib,..."),
-    cl::location(debugLibStore),
-    cl::CommaSeparated);
-
-
-void getenv_setargv(const char *envvar, int *pargc, char** *pargv);
-
 Global global;
 
 Global::Global()
@@ -187,763 +147,6 @@
 #endif
 }
 
-extern void backend_init();
-extern void backend_term();
-
-void printVersion() {
-    printf("LLVM D Compiler %s\nbased on DMD %s and %s\n%s\n%s\n",
-    global.ldc_version, global.version, global.llvm_version, global.copyright, global.written);
-    printf("D Language Documentation: http://www.digitalmars.com/d/1.0/index.html\n"
-           "LDC Homepage: http://www.dsource.org/projects/ldc\n");
-}
-
-// Helper function to handle -d-debug=* and -d-version=*
-static void processVersions(std::vector<std::string>& list, char* type,
-        void (*setLevel)(unsigned), void (*addIdent)(char*)) {
-    typedef std::vector<std::string>::iterator It;
-
-    for(It I = list.begin(), E = list.end(); I != E; ++I) {
-        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("Invalid %s level: %s", type, I->c_str());
-            } else {
-                setLevel((unsigned)level);
-            }
-        } else {
-            char* cstr = mem.strdup(value);
-            if (Lexer::isValidIdentifier(cstr)) {
-                addIdent(cstr);
-                continue;
-            } else {
-                error("Invalid %s identifier or level: '%s'", type, I->c_str());
-            }
-        }
-    }
-}
-
-// Helper function to handle -of, -od, etc.
-static void initFromString(char*& dest, const cl::opt<std::string>& src) {
-    dest = 0;
-    if (src.getNumOccurrences() != 0) {
-        if (src.empty())
-            error("Expected argument to '-%s'", src.ArgStr);
-        dest = mem.strdup(src.c_str());
-    }
-}
-
-int main(int argc, char *argv[])
-{
-    int i;
-    Array files;
-    char *p, *ext;
-    Module *m;
-    int status = EXIT_SUCCESS;
-
-    // Set default values
-#if _WIN32
-	char buf[MAX_PATH];
-	GetModuleFileName(NULL, buf, MAX_PATH);
-	global.params.argv0 = buf;
-#else
-    global.params.argv0 = argv[0];
-#endif
-    global.params.useSwitchError = 1;
-
-    global.params.linkswitches = new Array();
-    global.params.libfiles = new Array();
-    global.params.objfiles = new Array();
-    global.params.ddocfiles = new Array();
-
-    global.params.is64bit = sizeof(void*) == 8 ? 1 : 0;
-
-    uint16_t endiantest = 0xFF00;
-    uint8_t endianres = ((uint8_t*)&endiantest)[0];
-    if (endianres == 0x00)
-        global.params.isLE = true;
-    else if (endianres == 0xFF)
-        global.params.isLE = false;
-    else {
-        error("Endian test is broken");
-        fatal();
-    }
-
-    // Predefine version identifiers
-#if IN_LLVM
-    VersionCondition::addPredefinedGlobalIdent("LLVM");
-    VersionCondition::addPredefinedGlobalIdent("LDC");
-#endif
-
-    // setup default target os to be build os
-#if _WIN32
-    global.params.os = OSWindows;
-#elif linux
-    global.params.os = OSLinux;
-#elif __APPLE__
-    global.params.os = OSMacOSX;
-#elif __FreeBSD__
-    global.params.os = OSFreeBSD;
-#elif defined (__SVR4) && defined (__sun)
-    global.params.os = OSSolaris;
-#else
- #error Unsupported OS
-#endif /* linux */
-
-    assert(global.params.os != OSinvalid);
-
-    //VersionCondition::addPredefinedGlobalIdent("D_Bits");
-    VersionCondition::addPredefinedGlobalIdent("all");
-
-//#if _WIN32
-//    inifile(global.params.argv0, "ldc.ini");
-//#elif POSIX
-    inifile(global.params.argv0, "ldc.conf");
-//#else
-//#error
-//#endif
-    getenv_setargv("DFLAGS", &argc, &argv);
-
-#if 0
-    for (i = 0; i < argc; i++)
-    {
-	printf("argv[%d] = '%s'\n", i, argv[i]);
-    }
-#endif
-
-    cl::SetVersionPrinter(&printVersion);
-    cl::ParseCommandLineOptions(argc, argv, "LLVM-based D Compiler\n");
-
-    global.params.optimize = (global.params.optimizeLevel >= 0);
-
-    // Negated options
-    global.params.link = !compileOnly;
-    global.params.obj = !dontWriteObj;
-    global.params.useInlineAsm = !noAsm;
-
-    // String options: std::string --> char*
-    initFromString(global.params.objname, objectFile);
-    initFromString(global.params.objdir, objectDir);
-    
-    initFromString(global.params.docdir, ddocDir);
-    initFromString(global.params.docname, ddocFile);
-    global.params.doDocComments |=
-        global.params.docdir || global.params.docname;
-    
-#ifdef _DH
-    initFromString(global.params.hdrdir, hdrDir);
-    initFromString(global.params.hdrname, hdrFile);
-    global.params.doHdrGeneration |=
-        global.params.hdrdir || global.params.hdrname;
-#endif
-
-    processVersions(debugArgs, "debug",
-        DebugCondition::setGlobalLevel,
-        DebugCondition::addGlobalIdent);
-    processVersions(versions, "version",
-        VersionCondition::setGlobalLevel,
-        VersionCondition::addGlobalIdent);
-
-    global.params.output_o =
-        opts::output_o == cl::BOU_UNSET
-        ? OUTPUTFLAGdefault
-        : opts::output_o == cl::BOU_TRUE
-            ? OUTPUTFLAGset
-            : OUTPUTFLAGno;
-    global.params.output_bc = opts::output_bc ? OUTPUTFLAGset : OUTPUTFLAGno;
-    global.params.output_ll = opts::output_ll ? OUTPUTFLAGset : OUTPUTFLAGno;
-    global.params.output_s  = opts::output_s  ? OUTPUTFLAGset : OUTPUTFLAGno;
-
-    if (global.params.run || !runargs.empty()) {
-        // FIXME: how to properly detect the presence of a PositionalEatsArgs
-        // option without parameters? We want to emit an error in that case...
-        // You'd think getNumOccurrences would do it, but it just returns the
-        // number of parameters)
-        // NOTE: Hacked around it by detecting -run in getenv_setargv(), where
-        // we're looking for it anyway, and pre-setting the flag...
-        global.params.run = true;
-        if (!runargs.empty()) {
-            files.push(mem.strdup(runargs[0].c_str()));
-        } else {
-            global.params.run = false;
-            error("Expected at least one argument to '-run'\n");
-        }
-    }
-
-    if (mArch)
-        global.params.llvmArch = mArch->Name;
-
-    files.reserve(fileList.size());
-    typedef std::vector<std::string>::iterator It;
-    for(It I = fileList.begin(), E = fileList.end(); I != E; ++I)
-        if (!I->empty())
-            files.push(mem.strdup(I->c_str()));
-
-    if (global.errors)
-    {
-	fatal();
-    }
-    if (files.dim == 0)
-    {
-        cl::PrintHelpMessage();
-	return EXIT_FAILURE;
-    }
-
-    Array* libs;
-    if (global.params.symdebug)
-	libs = global.params.debuglibnames;
-    else
-	libs = global.params.defaultlibnames;
-
-    if (libs)
-    {
-	for (int i = 0; i < libs->dim; i++)
-	{
-	    char *arg = (char *)mem.malloc(64);
-	    strcpy(arg, "-l");
-	    strncat(arg, (char *)libs->data[i], 64);
-	    global.params.linkswitches->push(arg);
-	}
-    }
-    else if (!noDefaultLib)
-    {
-	char *arg;
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-lldc-runtime");
-	global.params.linkswitches->push(arg);
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-ltango-cc-tango");
-	global.params.linkswitches->push(arg);
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-ltango-gc-basic");
-	global.params.linkswitches->push(arg);
-	// pass the runtime again to resolve issues
-	// with linking order
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-lldc-runtime");
-	global.params.linkswitches->push(arg);
-    }
-
-    if (global.params.run)
-        quiet = 1;
-
-    if (global.params.useUnitTests)
-	global.params.useAssert = 1;
-
-    // LDC output determination
-
-    // if we don't link, autodetect target from extension
-    if(!global.params.link && global.params.objname) {
-	ext = FileName::ext(global.params.objname);
-	bool autofound = false;
-	if (!ext) {
-	    // keep things as they are
-	} else if (strcmp(ext, global.ll_ext) == 0) {
-	    global.params.output_ll = OUTPUTFLAGset;
-	    autofound = true;
-	} else if (strcmp(ext, global.bc_ext) == 0) {
-	    global.params.output_bc = OUTPUTFLAGset;
-	    autofound = true;
-	} else if (strcmp(ext, global.s_ext) == 0) {
-	    global.params.output_s = OUTPUTFLAGset;
-	    autofound = true;
-	} else if (strcmp(ext, global.obj_ext) == 0) {
-	    global.params.output_o = OUTPUTFLAGset;
-	    autofound = true;
-	} else {
-	    // append dot, so forceExt won't change existing name even if it contains dots
-	    size_t len = strlen(global.params.objname);
-	    size_t extlen = strlen(".");
-	    char* s = (char *)mem.malloc(len + 1 + extlen + 1);
-	    memcpy(s, global.params.objname, len);
-	    s[len] = '.';
-	    s[len+1+extlen] = 0;
-	    global.params.objname = s;
-
-	}
-	if(autofound && global.params.output_o == OUTPUTFLAGdefault)
-	    global.params.output_o = OUTPUTFLAGno;
-    }
-
-    // only link if possible
-    if (!global.params.obj || !global.params.output_o)
-	global.params.link = 0;
-
-    if (global.params.link)
-    {
-	global.params.exefile = global.params.objname;
-	if (files.dim > 1)
-	    global.params.objname = NULL;
-    }
-    else if (global.params.run)
-    {
-	error("flags conflict with -run");
-	fatal();
-    }
-    else
-    {
-	if (global.params.objname && files.dim > 1)
-	{
-	    error("multiple source files, but only one .obj name");
-	    fatal();
-	}
-    }
-
-    bool allowForceEndianness = false;
-
-    if (global.params.llvmArch == 0) {
-    #if defined(__x86_64__) || defined(_M_X64)
-        global.params.llvmArch = "x86-64";
-    #elif defined(__i386__) || defined(_M_IX86)
-        global.params.llvmArch = "x86";
-    #elif defined(__ppc__) || defined(_M_PPC)
-        if (global.params.is64bit)
-            global.params.llvmArch = "ppc64";
-        else
-            global.params.llvmArch = "ppc32";
-    #elif defined(__arm__)
-        global.params.llvmArch = "arm";
-    #elif defined(__thumb__)
-        global.params.llvmArch = "thumb";
-    #else
-    #error
-    #endif
-    }
-
-    if (strcmp(global.params.llvmArch,"x86")==0) {
-        VersionCondition::addPredefinedGlobalIdent("X86");
-        global.params.isLE = true;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHx86;
-        if (global.params.useInlineAsm) {
-            VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86");
-        }
-    }
-    else if (strcmp(global.params.llvmArch,"x86-64")==0) {
-        VersionCondition::addPredefinedGlobalIdent("X86_64");
-        global.params.isLE = true;
-        global.params.is64bit = true;
-        global.params.cpu = ARCHx86_64;
-        if (global.params.useInlineAsm) {
-            VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86_64");
-        }
-    }
-    else if (strcmp(global.params.llvmArch,"ppc32")==0) {
-        VersionCondition::addPredefinedGlobalIdent("PPC");
-        global.params.isLE = false;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHppc;
-    }
-    else if (strcmp(global.params.llvmArch,"ppc64")==0) {
-        VersionCondition::addPredefinedGlobalIdent("PPC64");
-        global.params.isLE = false;
-        global.params.is64bit = true;
-        global.params.cpu = ARCHppc_64;
-    }
-    else if (strcmp(global.params.llvmArch,"arm")==0) {
-        VersionCondition::addPredefinedGlobalIdent("ARM");
-        global.params.isLE = true;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHarm;
-    }
-    else if (strcmp(global.params.llvmArch,"thumb")==0) {
-        VersionCondition::addPredefinedGlobalIdent("Thumb");
-        global.params.isLE = true;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHthumb;
-    }
-    else {
-        error("invalid cpu architecture specified: %s", global.params.llvmArch);
-    }
-
-    assert(global.params.cpu != ARCHinvalid);
-
-    if (allowForceEndianness && forceBE) {
-        VersionCondition::addPredefinedGlobalIdent("BigEndian");
-        global.params.isLE = false;
-    }
-    else if (global.params.isLE) {
-        VersionCondition::addPredefinedGlobalIdent("LittleEndian");
-    }
-    else {
-        VersionCondition::addPredefinedGlobalIdent("BigEndian");
-    }
-
-    if (global.params.is64bit) {
-        VersionCondition::addPredefinedGlobalIdent("LLVM64");
-    }
-
-
-    // setup version idents and tt_os for chosen target os
-    switch(global.params.os)
-    {
-    case OSWindows:
-    // TODO Win64 stuff!
-	VersionCondition::addPredefinedGlobalIdent("Windows");
-	VersionCondition::addPredefinedGlobalIdent("Win32");
-	VersionCondition::addPredefinedGlobalIdent("mingw32");
-	break;
-
-    case OSLinux:
-	VersionCondition::addPredefinedGlobalIdent("linux");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    case OSMacOSX:
-	VersionCondition::addPredefinedGlobalIdent("OSX");
-	VersionCondition::addPredefinedGlobalIdent("darwin");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    case OSFreeBSD:
-	VersionCondition::addPredefinedGlobalIdent("freebsd");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    case OSSolaris:
-	VersionCondition::addPredefinedGlobalIdent("solaris");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    default:
-	assert(false && "Target OS not supported");
-    }
-
-    if (!global.params.targetTriple)
-        global.params.targetTriple = DEFAULT_TARGET_TRIPLE;
-
-    Logger::println("Target triple: %s", global.params.targetTriple);
-
-    // build a minimal data layout so llvm can find the target
-    global.params.dataLayout = global.params.isLE
-        ? (char*)(global.params.is64bit ? "e-p:64:64" : "e-p:32:32")
-        : (char*)(global.params.is64bit ? "E-p:64:64" : "E-p:32:32");
-    Logger::println("Layout: %s", global.params.dataLayout);
-
-    // added in 1.039
-    if (global.params.doDocComments)
-        VersionCondition::addPredefinedGlobalIdent("D_Ddoc");
-
-    // Initialization
-    Type::init();
-    Id::initialize();
-    Module::init();
-    initPrecedence();
-
-    backend_init();
-
-    //printf("%d source files\n",files.dim);
-
-    // Build import search path
-    if (global.params.imppath)
-    {
-	for (i = 0; i < global.params.imppath->dim; i++)
-	{
-	    char *path = (char *)global.params.imppath->data[i];
-	    Array *a = FileName::splitPath(path);
-
-	    if (a)
-	    {
-		if (!global.path)
-		    global.path = new Array();
-		global.path->append(a);
-	    }
-	}
-    }
-
-    // Build string import search path
-    if (global.params.fileImppath)
-    {
-	for (i = 0; i < global.params.fileImppath->dim; i++)
-	{
-	    char *path = (char *)global.params.fileImppath->data[i];
-	    Array *a = FileName::splitPath(path);
-
-	    if (a)
-	    {
-		if (!global.filePath)
-		    global.filePath = new Array();
-		global.filePath->append(a);
-	    }
-	}
-    }
-
-    // Create Modules
-    Array modules;
-    modules.reserve(files.dim);
-    for (i = 0; i < files.dim; i++)
-    {	Identifier *id;
-	char *ext;
-	char *name;
-
-	p = (char *) files.data[i];
-
-	p = FileName::name(p);		// strip path
-	ext = FileName::ext(p);
-	if (ext)
-	{
-#if POSIX
-	    if (strcmp(ext, global.obj_ext) == 0 ||
-		strcmp(ext, global.bc_ext) == 0)
-#else
-	    if (stricmp(ext, global.obj_ext) == 0 ||
-		stricmp(ext, global.bc_ext) == 0)
-#endif
-	    {
-		global.params.objfiles->push(files.data[i]);
-		continue;
-	    }
-
-#if POSIX
-	    if (strcmp(ext, "a") == 0)
-#elif __MINGW32__
-        if (stricmp(ext, "a") == 0)
-#else
-	    if (stricmp(ext, "lib") == 0)
-#endif
-	    {
-		global.params.libfiles->push(files.data[i]);
-		continue;
-	    }
-
-	    if (strcmp(ext, global.ddoc_ext) == 0)
-	    {
-		global.params.ddocfiles->push(files.data[i]);
-		continue;
-	    }
-
-#if !POSIX
-	    if (stricmp(ext, "res") == 0)
-	    {
-		global.params.resfile = (char *)files.data[i];
-		continue;
-	    }
-
-	    if (stricmp(ext, "def") == 0)
-	    {
-		global.params.deffile = (char *)files.data[i];
-		continue;
-	    }
-
-	    if (stricmp(ext, "exe") == 0)
-	    {
-		global.params.exefile = (char *)files.data[i];
-		continue;
-	    }
-#endif
-
-	    if (stricmp(ext, global.mars_ext) == 0 ||
-        stricmp(ext, global.hdr_ext) == 0 ||
-		stricmp(ext, "htm") == 0 ||
-		stricmp(ext, "html") == 0 ||
-		stricmp(ext, "xhtml") == 0)
-	    {
-		ext--;			// skip onto '.'
-		assert(*ext == '.');
-		name = (char *)mem.malloc((ext - p) + 1);
-		memcpy(name, p, ext - p);
-		name[ext - p] = 0;		// strip extension
-
-		if (name[0] == 0 ||
-		    strcmp(name, "..") == 0 ||
-		    strcmp(name, ".") == 0)
-		{
-		Linvalid:
-		    error("invalid file name '%s'", (char *)files.data[i]);
-		    fatal();
-		}
-	    }
-	    else
-	    {	error("unrecognized file extension %s\n", ext);
-		fatal();
-	    }
-	}
-	else
-	{   name = p;
-	    if (!*name)
-		goto Linvalid;
-	}
-
-	id = new Identifier(name, 0);
-	m = new Module((char *) files.data[i], id, global.params.doDocComments, global.params.doHdrGeneration);
-	modules.push(m);
-    }
-
-    // Read files, parse them
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("parse     %s\n", m->toChars());
-	if (!Module::rootModule)
-	    Module::rootModule = m;
-	m->importedFrom = m;
-	m->read(0);
-	m->parse();
-	m->buildTargetFiles();
-	m->deleteObjFile();
-	if (m->isDocFile)
-	{
-	    m->gendocfile();
-
-	    // Remove m from list of modules
-	    modules.remove(i);
-	    i--;
-	}
-    }
-    if (global.errors)
-	fatal();
-#ifdef _DH
-    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 (i = 0; i < modules.dim; i++)
-	{
-	    m = (Module *)modules.data[i];
-	    if (global.params.verbose)
-		printf("import    %s\n", m->toChars());
-	    m->genhdrfile();
-	}
-    }
-    if (global.errors)
-	fatal();
-#endif
-
-    // Do semantic analysis
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("semantic  %s\n", m->toChars());
-	m->semantic();
-    }
-    if (global.errors)
-	fatal();
-
-    // Do pass 2 semantic analysis
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("semantic2 %s\n", m->toChars());
-	m->semantic2();
-    }
-    if (global.errors)
-	fatal();
-
-    // Do pass 3 semantic analysis
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("semantic3 %s\n", m->toChars());
-	m->semantic3();
-    }
-    if (global.errors)
-	fatal();
-
-#if !IN_LLVM
-    // Scan for functions to inline
-    if (global.params.useInline)
-    {
-	/* The problem with useArrayBounds and useAssert is that the
-	 * module being linked to may not have generated them, so if
-	 * we inline functions from those modules, the symbols for them will
-	 * not be found at link time.
-	 */
-	if (!global.params.useArrayBounds && !global.params.useAssert)
-	{
-#endif
-	    // Do pass 3 semantic analysis on all imported modules,
-	    // since otherwise functions in them cannot be inlined
-	    for (i = 0; i < Module::amodules.dim; i++)
-	    {
-		m = (Module *)Module::amodules.data[i];
-		if (global.params.verbose)
-		    printf("semantic3 %s\n", m->toChars());
-		m->semantic3();
-	    }
-	    if (global.errors)
-		fatal();
-#if !IN_LLVM
-	}
-
-	for (i = 0; i < modules.dim; i++)
-	{
-	    m = (Module *)modules.data[i];
-	    if (global.params.verbose)
-		printf("inline scan %s\n", m->toChars());
-	    m->inlineScan();
-	}
-    }
-#endif
-    if (global.errors)
-	fatal();
-
-    // Generate output files
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("code      %s\n", m->toChars());
-	if (global.params.obj)
-	{
-	    m->genobjfile(0);
-	    global.params.objfiles->push(m->objfile->name->str);
-	}
-	if (global.errors)
-	    m->deleteObjFile();
-	else
-	{
-	    if (global.params.doDocComments)
-		m->gendocfile();
-	}
-    }
-
-    backend_term();
-    if (global.errors)
-	fatal();
-
-    if (!global.params.objfiles->dim)
-    {
-	if (global.params.link)
-	    error("no object files to link");
-    }
-    else
-    {
-	if (global.params.link)
-	    //status = runLINK();
-        linkObjToExecutable(global.params.argv0);
-
-	if (global.params.run)
-	{
-	    if (!status)
-	    {
-		status = runExectuable();
-
-		/* Delete .obj files and .exe file
-		 */
-		for (i = 0; i < modules.dim; i++)
-		{
-		    m = (Module *)modules.data[i];
-		    m->deleteObjFile();
-		}
-		deleteExecutable();
-	    }
-	}
-    }
-
-    return status;
-}
-
-
-
 /***********************************
  * Parse and append contents of environment variable envvar
  * to argc and argv[].
--- a/dmd/mars.h	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd/mars.h	Thu Feb 26 14:11:49 2009 +0100
@@ -144,7 +144,6 @@
     char *exefile;
 
     // LDC stuff
-    const char *llvmArch;
     OUTPUTFLAG output_ll;
     OUTPUTFLAG output_bc;
     OUTPUTFLAG output_s;
@@ -154,8 +153,9 @@
     bool useInlineAsm;
 
     // target stuff
-    char *targetTriple;
-    char *dataLayout;
+    const char* llvmArch;
+    const char *targetTriple;
+    const char *dataLayout;
 };
 
 struct Global
@@ -341,7 +341,7 @@
 void verror(Loc loc, const char *format, va_list);
 void fatal();
 void err_nomem();
-void inifile(char *argv0, char *inifile);
+void inifile(char *argv0, const char *inifile);
 void halt();
 
 /*** Where to send error messages ***/
--- a/dmd2/attrib.c	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd2/attrib.c	Thu Feb 26 14:11:49 2009 +0100
@@ -33,6 +33,15 @@
 
 #include "../gen/enums.h"
 
+
+#include "llvm/Support/CommandLine.h"
+
+static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore",
+    llvm::cl::desc("Ignore unsupported pragmas"),
+    llvm::cl::ZeroOrMore);
+
+
+
 extern void obj_includelib(const char *name);
 void obj_startaddress(Symbol *s);
 
@@ -1001,7 +1010,7 @@
     /////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////
 
-    else if (global.params.ignoreUnsupportedPragmas)
+    else if (ignoreUnsupportedPragmas)
     {
 	if (global.params.verbose)
 	{
--- a/dmd2/inifile.c	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd2/inifile.c	Thu Feb 26 14:11:49 2009 +0100
@@ -43,7 +43,7 @@
  *	inifile	.ini file name
  */
 
-void inifile(const char *argv0x, const char *inifilex)
+void inifile(char *argv0x, const char *inifilex)
 {
     char *argv0 = (char *)argv0x;
     char *inifile = (char *)inifilex;	// do const-correct later
--- a/dmd2/mars.c	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd2/mars.c	Thu Feb 26 14:11:49 2009 +0100
@@ -1,5 +1,5 @@
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -36,13 +36,8 @@
 #include "expression.h"
 #include "lexer.h"
 
-#include "gen/logger.h"
-#include "gen/linker.h"
-
 #include "revisions.h"
 
-void getenv_setargv(const char *envvar, int *pargc, char** *pargv);
-
 Global global;
 
 Global::Global()
@@ -62,27 +57,32 @@
     obj_ext_alt = "obj";
 #endif
 
-    copyright = "Copyright (c) 1999-2008 by Digital Mars and Tomas Lindquist Olsen";
+    copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen";
     written = "written by Walter Bright and Tomas Lindquist Olsen";
     version = "v2.021";
-    ldc_version = "0.1";
+    ldc_version = LDC_REV;
+    llvm_version = LLVM_REV;
     global.structalign = 8;
 
-    memset(&params, 0, sizeof(Param));
+    // This should only be used as a global, so the other fields are
+    // automatically initialized to zero when the program is loaded.
+    // In particular, DO NOT zero-initialize .params here (like DMD
+    // does) because command-line options initialize some of those
+    // fields to non-zero defaults, and do so from constructors that
+    // may run before this one.
 }
 
 char *Loc::toChars() const
 {
     OutBuffer buf;
-    char *p;
 
     if (filename)
     {
-	buf.printf("%s", filename);
+    buf.printf("%s", filename);
     }
 
     if (linnum)
-	buf.printf("(%d)", linnum);
+    buf.printf("(%d)", linnum);
     buf.writeByte(0);
     return (char *)buf.extractData();
 }
@@ -109,16 +109,16 @@
 {
     if (!global.gag)
     {
-	char *p = loc.toChars();
+    char *p = loc.toChars();
 
-	if (*p)
-	    fprintf(stdmsg, "%s: ", p);
-	mem.free(p);
+    if (*p)
+        fprintf(stdmsg, "%s: ", p);
+    mem.free(p);
 
-	fprintf(stdmsg, "Error: ");
-	vfprintf(stdmsg, format, ap);
-	fprintf(stdmsg, "\n");
-	fflush(stdmsg);
+    fprintf(stdmsg, "Error: ");
+    vfprintf(stdmsg, format, ap);
+    fprintf(stdmsg, "\n");
+    fflush(stdmsg);
     }
     global.errors++;
 }
@@ -147,1154 +147,6 @@
 #endif
 }
 
-extern void backend_init();
-extern void backend_term();
-
-void usage()
-{
-    printf("LLVM D Compiler %s\nbased on DMD %s and %s\n%s\n%s\n",
-    global.ldc_version, global.version, global.llvm_version, global.copyright, global.written);
-    printf("\
-D Language Documentation: http://www.digitalmars.com/d/2.0/index.html\n\
-LDC Homepage: http://www.dsource.org/projects/ldc\n\
-Usage:\n\
-  ldc files.d ... { -switch }\n\
-\n\
-  files.d        D source files\n%s\
-  -o-            do not write object file\n\
-  -od<objdir>    write object files to directory <objdir>\n\
-  -op            do not strip paths from source file\n\
-  -oq            write object files with fully qualified names\n\
-  -of<filename>  name output file to <filename>\n\
-                 if -c and extension of <filename> is known, it determines the output type\n\
-\n\
-  -output-ll     write LLVM IR\n\
-  -output-bc     write LLVM bitcode\n\
-  -output-s      write native assembly\n\
-  -output-o      write native object (default if no -output switch passed)\n\
-\n\
-  -c             do not link\n\
-  -L<linkerflag> pass <linkerflag> to linker\n\
-\n\
-  -w             enable warnings\n\
-\n\
-  -H             generate 'header' file\n\
-  -Hd<hdrdir>    write 'header' file to <hdrdir> directory\n\
-  -Hf<filename>  write 'header' file to <filename>\n\
-\n\
-  -D             generate documentation\n\
-  -Dd<docdir>    write documentation file to <docdir> directory\n\
-  -Df<filename>  write documentation file to <filename>\n\
-\n\
-Codegen control:\n\
-  -m<arch>       emit code specific to <arch> being one of:\n\
-                 x86 x86-64 ppc32 ppc64 arm thumb\n\
-  -t<os>         emit code specific to <os> being one of:\n\
-                 Linux, Windows, MacOSX, FreeBSD, Solaris\n\
-\n\
-  -g, -gc        add symbolic debug info\n\
-\n\
-  -O             optimize, same as -O2\n\
-  -O<n>          optimize at level <n> (0-5)\n\
-  -inline        do function inlining\n\
-\n\
-  -debug         enables asserts, invariants, contracts, boundscheck\n\
-                 and sets debug=1\n\
-  -release       disables asserts, invariants, contracts, boundscheck\n\
-\n\
-  -enable-<feature>    and\n\
-  -disable-<feature>   where <feature> is one of\n\
-    asserts      assert statements (default: on)\n\
-    invariants   class and struct invariants (default: on)\n\
-    contracts    function contracts (default: on)\n\
-    boundscheck  array bounds checking (default: on)\n\
-  -debug=level   compile in debug stmts <= level (default: 0)\n\
-  -debug=ident   compile in debug stmts identified by ident\n\
-  -version=level compile in version code >= level\n\
-  -version=ident compile in version code identified by ident\n\
-\n\
-  -noasm         do not allow use of inline asm\n\
-  -noruntime     do not allow code that generates implicit runtime calls\n\
-  -noverify      do not run the validation pass before writing bitcode\n\
-  -unittest      compile in unit tests\n\
-  -d             allow deprecated features\n\
-\n\
-  -annotate      annotate the bitcode with human readable source code\n\
-  -ignore        ignore unsupported pragmas\n\
-\n\
-Path options:\n\
-  -I<path>       where to look for imports\n\
-  -J<path>       where to look for string imports\n\
-  -defaultlib=name  set default library for non-debug build\n\
-  -debuglib=name    set default library for debug build\n\
-  -nodefaultlib  don't add a default library for linking implicitly\n\
-\n\
-Misc options:\n\
-  -v             verbose\n\
-  -vv            very verbose (does not include -v)\n\
-  -quiet         suppress unnecessary messages\n\
-  -run srcfile args...   run resulting program, passing args\n\
-  --help         print help\n\
-",
-#if WIN32
-"  @cmdfile       read arguments from cmdfile\n"
-#else
-""
-#endif
-);
-}
-
-int main(int argc, char *argv[])
-{
-    int i;
-    Array files;
-    char *p, *ext;
-    Module *m;
-    int status = EXIT_SUCCESS;
-    int argcstart = argc;
-    bool very_verbose = false;
-
-    // Check for malformed input
-    if (argc < 1 || !argv)
-    {
-      Largs:
-	error("missing or null command line arguments");
-	fatal();
-    }
-    for (i = 0; i < argc; i++)
-    {
-	if (!argv[i])
-	    goto Largs;
-    }
-
-#if __DMC__	// DMC unique support for response files
-    if (response_expand(&argc,&argv))	// expand response files
-	error("can't open response file");
-#endif
-
-    files.reserve(argc - 1);
-
-    // Set default values
-#if _WIN32
-	char buf[MAX_PATH];
-	GetModuleFileName(NULL, buf, MAX_PATH);
-	global.params.argv0 = buf;
-#else
-    global.params.argv0 = argv[0];
-#endif
-    global.params.link = 1;
-    global.params.useAssert = 1;
-    global.params.useInvariants = 1;
-    global.params.useIn = 1;
-    global.params.useOut = 1;
-    global.params.useArrayBounds = 1;
-    global.params.useSwitchError = 1;
-    global.params.useInline = 0; // this one messes things up to a point where codegen breaks
-    global.params.llvmInline = 0; // use this one instead to know if inline passes should be run
-    global.params.obj = 1;
-    global.params.Dversion = 2;
-    global.params.quiet = 1;
-
-    global.params.output_o = OUTPUTFLAGdefault;
-
-    global.params.linkswitches = new Array();
-    global.params.libfiles = new Array();
-    global.params.objfiles = new Array();
-    global.params.ddocfiles = new Array();
-
-    global.params.is64bit = sizeof(void*) == 8 ? 1 : 0;
-
-    uint16_t endiantest = 0xFF00;
-    uint8_t endianres = ((uint8_t*)&endiantest)[0];
-    if (endianres == 0x00)
-        global.params.isLE = true;
-    else if (endianres == 0xFF)
-        global.params.isLE = false;
-    else {
-        error("Endian test is broken");
-        fatal();
-    }
-
-    global.params.llvmArch = 0;
-    global.params.forceBE = 0;
-    global.params.noruntime = 0;
-    global.params.novalidate = 0;
-    global.params.optimizeLevel = -1;
-    global.params.runtimeImppath = 0;
-    global.params.useInlineAsm = 1;
-
-    // Predefine version identifiers
-#if IN_LLVM
-    VersionCondition::addPredefinedGlobalIdent("LLVM");
-    VersionCondition::addPredefinedGlobalIdent("LDC");
-#endif
-
-    // D2
-#if DMDV2
-    VersionCondition::addPredefinedGlobalIdent("D_Version2");
-#endif
-
-    // setup default target os to be build os
-#if _WIN32
-    global.params.os = OSWindows;
-#elif linux
-    global.params.os = OSLinux;
-#elif __APPLE__
-    global.params.os = OSMacOSX;
-#elif __FreeBSD__
-    global.params.os = OSFreeBSD;
-#elif defined (__SVR4) && defined (__sun)
-    global.params.os = OSSolaris;
-#else
-#error Unsupported OS
-#endif /* linux */
-
-    assert(global.params.os != OSinvalid);
-
-    //VersionCondition::addPredefinedGlobalIdent("D_Bits");
-    VersionCondition::addPredefinedGlobalIdent("all");
-
-//#if _WIN32
-
-//#if DMDV2
-//    inifile(global.params.argv0, "ldc2.ini");
-//#else
-//    inifile(global.params.argv0, "ldc.ini");
-//#endif
-
-//#elif POSIX
-
-#if DMDV2
-    inifile(global.params.argv0, "ldc2.conf");
-#else
-    inifile(global.params.argv0, "ldc.conf");
-#endif
-
-//#else
-//#error
-//#endif
-    getenv_setargv("DFLAGS", &argc, &argv);
-
-#if 0
-    for (i = 0; i < argc; i++)
-    {
-	printf("argv[%d] = '%s'\n", i, argv[i]);
-    }
-#endif
-
-    for (i = 1; i < argc; i++)
-    {
-	p = argv[i];
-	if (*p == '-')
-	{
-	    if (strcmp(p + 1, "d") == 0)
-		global.params.useDeprecated = 1;
-	    else if (strcmp(p + 1, "c") == 0)
-		global.params.link = 0;
-	    else if (strcmp(p + 1, "fPIC") == 0)
-		global.params.pic = 1;
-	    else if (strcmp(p + 1, "g") == 0)
-		global.params.symdebug = 1;
-        else if (strcmp(p + 1, "gc") == 0)
-        global.params.symdebug = 2;
-	    else if (strcmp(p + 1, "v") == 0)
-		global.params.verbose = 1;
-		else if (strcmp(p + 1, "vv") == 0) {
-    		Logger::enable();
-    		very_verbose = true;
-		}
-	    else if (strcmp(p + 1, "v1") == 0)
-		global.params.Dversion = 1;
-	    else if (strcmp(p + 1, "w") == 0)
-		global.params.warnings = 1;
-	    else if (p[1] == 'O')
-        {
-            global.params.optimize = 1;
-            global.params.optimizeLevel = 2;
-            if (p[2] != 0) {
-                int optlevel = atoi(p+2);
-                if (optlevel < 0 || optlevel > 5) {
-                    error("Optimization level must be between 0 and 5. Using default (%d)",
-                    global.params.optimizeLevel);
-                }
-                else {
-                    global.params.optimizeLevel = optlevel;
-                }
-            }
-        }
-        else if (strcmp(p + 1, "forcebe") == 0)
-            global.params.forceBE = 1;
-        else if (strcmp(p + 1, "noruntime") == 0)
-            global.params.noruntime = 1;
-        else if (strcmp(p + 1, "noverify") == 0)
-            global.params.novalidate = 1;
-        else if (strcmp(p + 1, "annotate") == 0)
-            global.params.llvmAnnotate = 1;
-        else if (strncmp(p + 1, "enable-", 7) == 0 ||
-                 strncmp(p + 1, "disable-", 8) == 0)
-        {
-            bool enable = (p[1] == 'e');
-            char* feature = p + 1 + (enable ? 7 : 8);
-            if (strcmp(feature, "asserts") == 0)
-                global.params.useAssert = enable;
-            else if (strcmp(feature, "boundscheck") == 0)
-                global.params.useArrayBounds = enable;
-            else if (strcmp(feature, "contracts") == 0)
-            {
-                global.params.useIn = enable;
-                global.params.useOut = enable;
-            }
-            else if (strcmp(feature, "invariants") == 0)
-                global.params.useInvariants = enable;
-            else
-                error("unrecognized feature '%s'", feature);
-        }
-        else if (strcmp(p + 1, "noasm") == 0)
-            global.params.useInlineAsm = 0;
-        else if (strcmp(p + 1, "nodefaultlib") == 0)
-            global.params.noDefaultLib = 1;
-	    else if (p[1] == 'o')
-	    {
-		switch (p[2])
-		{
-		    case '-':
-			global.params.obj = 0;
-			break;
-
-		    case 'd':
-			if (!p[3])
-			    goto Lnoarg;
-			global.params.objdir = p + 3;
-			break;
-
-		    case 'f':
-			if (!p[3])
-			    goto Lnoarg;
-			global.params.objname = p + 3;
-			break;
-
-		    case 'p':
-			if (p[3])
-			    goto Lerror;
-			global.params.preservePaths = 1;
-			break;
-
-		    case 'q':
-			if (p[3])
-			    goto Lerror;
-			global.params.fqnNames = 1;
-			break;
-
-		    case 'u':
-			if (strncmp(p+1, "output-", 7) != 0)
-			    goto Lerror;
-
-			// remove default output
-			if (global.params.output_o == OUTPUTFLAGdefault)
-			    global.params.output_o = OUTPUTFLAGno;
-
-			if (strcmp(p+8, global.ll_ext) == 0)
-			    global.params.output_ll = OUTPUTFLAGset;
-			else if (strcmp(p+8, global.bc_ext) == 0)
-			    global.params.output_bc = OUTPUTFLAGset;
-			else if (strcmp(p+8, global.s_ext) == 0)
-			    global.params.output_s = OUTPUTFLAGset;
-			else if (strcmp(p+8, global.obj_ext) == 0)
-			    global.params.output_o = OUTPUTFLAGset;
-			else
-			    goto Lerror;
-
-			break;
-
-		    case 0:
-			error("-o no longer supported, use -of or -od");
-			break;
-
-		    default:
-			goto Lerror;
-		}
-	    }
-	    else if (p[1] == 'D')
-	    {	global.params.doDocComments = 1;
-		switch (p[2])
-		{
-		    case 'd':
-			if (!p[3])
-			    goto Lnoarg;
-			global.params.docdir = p + 3;
-			break;
-		    case 'f':
-			if (!p[3])
-			    goto Lnoarg;
-			global.params.docname = p + 3;
-			break;
-
-		    case 0:
-			break;
-
-		    default:
-			goto Lerror;
-		}
-	    }
-#ifdef _DH
-	    else if (p[1] == 'H')
-	    {	global.params.doHdrGeneration = 1;
-		switch (p[2])
-		{
-		    case 'd':
-			if (!p[3])
-			    goto Lnoarg;
-			global.params.hdrdir = p + 3;
-			break;
-
-		    case 'f':
-			if (!p[3])
-			    goto Lnoarg;
-			global.params.hdrname = p + 3;
-			break;
-
-		    case 0:
-			break;
-
-		    default:
-			goto Lerror;
-		}
-	    }
-#endif
-	    else if (strcmp(p + 1, "ignore") == 0)
-		global.params.ignoreUnsupportedPragmas = 1;
-	    else if (strcmp(p + 1, "inline") == 0) {
-            // TODO
-            // the ast rewrites dmd does for inlining messes up the ast.
-            // someday maybe we can support it, for now llvm does an excellent job at inlining
-            global.params.useInline = 0; //1
-            global.params.llvmInline = 1;
-        }
-	    else if (strcmp(p + 1, "quiet") == 0)
-		global.params.quiet = 1;
-	    else if (strcmp(p + 1, "release") == 0)
-	    {
-		global.params.useInvariants = 0;
-		global.params.useIn = 0;
-		global.params.useOut = 0;
-		global.params.useAssert = 0;
-		global.params.useArrayBounds = 0;
-	    }
-	    else if (strcmp(p + 1, "unittest") == 0)
-		global.params.useUnitTests = 1;
-	    else if (p[1] == 'I')
-	    {
-		if (!global.params.imppath)
-		    global.params.imppath = new Array();
-		global.params.imppath->push(p + 2);
-	    }
-	    else if (p[1] == 'J')
-	    {
-		if (!global.params.fileImppath)
-		    global.params.fileImppath = new Array();
-		global.params.fileImppath->push(p + 2);
-	    }
-	    else if (memcmp(p + 1, "debug", 5) == 0 && p[6] != 'l')
-	    {
-		// Parse:
-		//	-debug
-		//	-debug=number
-		//	-debug=identifier
-		if (p[6] == '=')
-		{
-		    if (isdigit(p[7]))
-		    {	long level;
-
-			errno = 0;
-			level = strtol(p + 7, &p, 10);
-			if (*p || errno || level > INT_MAX)
-			    goto Lerror;
-			DebugCondition::setGlobalLevel((int)level);
-		    }
-		    else if (Lexer::isValidIdentifier(p + 7))
-			DebugCondition::addGlobalIdent(p + 7);
-		    else
-			goto Lerror;
-		}
-		else if (p[6])
-		    goto Lerror;
-		else
-		{
-		    global.params.useInvariants = 1;
-		    global.params.useIn = 1;
-		    global.params.useOut = 1;
-		    global.params.useAssert = 1;
-		    global.params.useArrayBounds = 1;
-		    global.params.debuglevel = 1;
-		}
-	    }
-	    else if (memcmp(p + 1, "version", 5) == 0)
-	    {
-		// Parse:
-		//	-version=number
-		//	-version=identifier
-		if (p[8] == '=')
-		{
-		    if (isdigit(p[9]))
-		    {	long level;
-
-			errno = 0;
-			level = strtol(p + 9, &p, 10);
-			if (*p || errno || level > INT_MAX)
-			    goto Lerror;
-			VersionCondition::setGlobalLevel((int)level);
-		    }
-		    else if (Lexer::isValidIdentifier(p + 9))
-			VersionCondition::addGlobalIdent(p + 9);
-		    else
-			goto Lerror;
-		}
-		else
-		    goto Lerror;
-	    }
-	    else if (strcmp(p + 1, "-b") == 0)
-		global.params.debugb = 1;
-	    else if (strcmp(p + 1, "-c") == 0)
-		global.params.debugc = 1;
-	    else if (strcmp(p + 1, "-f") == 0)
-		global.params.debugf = 1;
-	    else if (strcmp(p + 1, "-help") == 0)
-	    {	usage();
-		exit(EXIT_SUCCESS);
-	    }
-	    else if (strcmp(p + 1, "-r") == 0)
-		global.params.debugr = 1;
-	    else if (strcmp(p + 1, "-x") == 0)
-		global.params.debugx = 1;
-	    else if (strcmp(p + 1, "-y") == 0)
-		global.params.debugy = 1;
-	    else if (p[1] == 'L')
-	    {
-		global.params.linkswitches->push(p + 2);
-	    }
-	    else if (memcmp(p + 1, "defaultlib=", 11) == 0)
-	    {
-		if(!global.params.defaultlibnames)
-		    global.params.defaultlibnames = new Array();
-		global.params.defaultlibnames->push(p + 1 + 11);
-	    }
-	    else if (memcmp(p + 1, "debuglib=", 9) == 0)
-	    {
-		if(!global.params.debuglibnames)
-		    global.params.debuglibnames = new Array();
-		global.params.debuglibnames->push(p + 1 + 9);
-	    }
-	    else if (strcmp(p + 1, "run") == 0)
-	    {	global.params.run = 1;
-		global.params.runargs_length = ((i >= argcstart) ? argc : argcstart) - i - 1;
-		if (global.params.runargs_length)
-		{
-		    files.push(argv[i + 1]);
-		    global.params.runargs = &argv[i + 2];
-		    i += global.params.runargs_length;
-		    global.params.runargs_length--;
-		}
-		else
-		{   global.params.run = 0;
-		    goto Lnoarg;
-		}
-	    }
-        else if (p[1] == 'm')
-        {
-            global.params.llvmArch = p+2;
-        }
-        else if (p[1] == 't')
-        {
-            if(strcmp(p + 2, "Linux") == 0)
-                global.params.os = OSLinux;
-            else if(strcmp(p + 2, "Windows") == 0)
-                global.params.os = OSWindows;
-            else if(strcmp(p + 2, "MacOSX") == 0)
-                global.params.os = OSMacOSX;
-            else if(strcmp(p + 2, "FreeBSD") == 0)
-                global.params.os = OSFreeBSD;
-            else if(strcmp(p + 2, "Solaris") == 0)
-                global.params.os = OSSolaris;
-            else
-                error("unrecognized target os '%s'", p + 2);
-        }
-	    else
-	    {
-	     Lerror:
-		error("unrecognized switch '%s'", argv[i]);
-		continue;
-
-	     Lnoarg:
-		error("argument expected for switch '%s'", argv[i]);
-		continue;
-	    }
-	}
-	else
-	    files.push(p);
-    }
-    if (global.errors)
-    {
-	fatal();
-    }
-    if (files.dim == 0)
-    {	usage();
-	return EXIT_FAILURE;
-    }
-
-    Array* libs;
-    if (global.params.symdebug)
-	libs = global.params.debuglibnames;
-    else
-	libs = global.params.defaultlibnames;
-
-    if (libs)
-    {
-	for (int i = 0; i < libs->dim; i++)
-	{
-	    char *arg = (char *)mem.malloc(64);
-	    strcpy(arg, "-l");
-	    strncat(arg, (char *)libs->data[i], 64);
-	    global.params.linkswitches->push(arg);
-	}
-    }
-    else if (!global.params.noDefaultLib)
-    {
-#if DMDV2
-    char *arg;
-    arg = (char *)mem.malloc(64);
-    strcpy(arg, "-ldruntime-ldc");
-    global.params.linkswitches->push(arg);
-#else
-	char *arg;
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-lldc-runtime");
-	global.params.linkswitches->push(arg);
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-ltango-cc-tango");
-	global.params.linkswitches->push(arg);
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-ltango-gc-basic");
-	global.params.linkswitches->push(arg);
-	// pass the runtime again to resolve issues
-	// with linking order
-	arg = (char *)mem.malloc(64);
-	strcpy(arg, "-lldc-runtime");
-	global.params.linkswitches->push(arg);
-#endif
-    }
-
-    if (global.params.run)
-	global.params.quiet = 1;
-
-    if (global.params.useUnitTests)
-	global.params.useAssert = 1;
-
-    // LDC output determination
-
-    // if we don't link, autodetect target from extension
-    if(!global.params.link && global.params.objname) {
-	ext = FileName::ext(global.params.objname);
-	bool autofound = false;
-	if (!ext) {
-	    // keep things as they are
-	} else if (strcmp(ext, global.ll_ext) == 0) {
-	    global.params.output_ll = OUTPUTFLAGset;
-	    autofound = true;
-	} else if (strcmp(ext, global.bc_ext) == 0) {
-	    global.params.output_bc = OUTPUTFLAGset;
-	    autofound = true;
-	} else if (strcmp(ext, global.s_ext) == 0) {
-	    global.params.output_s = OUTPUTFLAGset;
-	    autofound = true;
-	} else if (strcmp(ext, global.obj_ext) == 0) {
-	    global.params.output_o = OUTPUTFLAGset;
-	    autofound = true;
-	} else {
-	    // append dot, so forceExt won't change existing name even if it contains dots
-	    size_t len = strlen(global.params.objname);
-	    size_t extlen = strlen(".");
-	    char* s = (char *)mem.malloc(len + 1 + extlen + 1);
-	    memcpy(s, global.params.objname, len);
-	    s[len] = '.';
-	    s[len+1+extlen] = 0;
-	    global.params.objname = s;
-
-	}
-	if(autofound && global.params.output_o == OUTPUTFLAGdefault)
-	    global.params.output_o = OUTPUTFLAGno;
-    }
-
-    // only link if possible
-    if (!global.params.obj || !global.params.output_o)
-	global.params.link = 0;
-
-    if (global.params.link)
-    {
-	global.params.exefile = global.params.objname;
-	if (files.dim > 1)
-	    global.params.objname = NULL;
-    }
-    else if (global.params.run)
-    {
-	error("flags conflict with -run");
-	fatal();
-    }
-    else
-    {
-	if (global.params.objname && files.dim > 1)
-	{
-	    error("multiple source files, but only one .obj name");
-	    fatal();
-	}
-    }
-
-    bool allowForceEndianness = false;
-
-    if (global.params.llvmArch == 0) {
-    #if defined(__x86_64__) || defined(_M_X64)
-        global.params.llvmArch = "x86-64";
-    #elif defined(__i386__) || defined(_M_IX86)
-        global.params.llvmArch = "x86";
-    #elif defined(__ppc__) || defined(_M_PPC)
-        if (global.params.is64bit)
-            global.params.llvmArch = "ppc64";
-        else
-            global.params.llvmArch = "ppc32";
-    #elif defined(__arm__)
-        global.params.llvmArch = "arm";
-    #elif defined(__thumb__)
-        global.params.llvmArch = "thumb";
-    #else
-    #error
-    #endif
-    }
-
-    if (strcmp(global.params.llvmArch,"x86")==0) {
-        VersionCondition::addPredefinedGlobalIdent("X86");
-        global.params.isLE = true;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHx86;
-        if (global.params.useInlineAsm) {
-            VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86");
-        }
-    }
-    else if (strcmp(global.params.llvmArch,"x86-64")==0) {
-        VersionCondition::addPredefinedGlobalIdent("X86_64");
-        global.params.isLE = true;
-        global.params.is64bit = true;
-        global.params.cpu = ARCHx86_64;
-        if (global.params.useInlineAsm) {
-            VersionCondition::addPredefinedGlobalIdent("LLVM_InlineAsm_X86_64");
-        }
-    }
-    else if (strcmp(global.params.llvmArch,"ppc32")==0) {
-        VersionCondition::addPredefinedGlobalIdent("PPC");
-        global.params.isLE = false;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHppc;
-    }
-    else if (strcmp(global.params.llvmArch,"ppc64")==0) {
-        VersionCondition::addPredefinedGlobalIdent("PPC64");
-        global.params.isLE = false;
-        global.params.is64bit = true;
-        global.params.cpu = ARCHppc_64;
-    }
-    else if (strcmp(global.params.llvmArch,"arm")==0) {
-        VersionCondition::addPredefinedGlobalIdent("ARM");
-        global.params.isLE = true;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHarm;
-    }
-    else if (strcmp(global.params.llvmArch,"thumb")==0) {
-        VersionCondition::addPredefinedGlobalIdent("Thumb");
-        global.params.isLE = true;
-        global.params.is64bit = false;
-        global.params.cpu = ARCHthumb;
-    }
-    else {
-        error("invalid cpu architecture specified: %s", global.params.llvmArch); 
-    }
-
-    assert(global.params.cpu != ARCHinvalid);
-
-    if (allowForceEndianness && global.params.forceBE) {
-        VersionCondition::addPredefinedGlobalIdent("BigEndian");
-        global.params.isLE = false;
-    }
-    else if (global.params.isLE) {
-        VersionCondition::addPredefinedGlobalIdent("LittleEndian");
-    }
-    else {
-        VersionCondition::addPredefinedGlobalIdent("BigEndian");
-    }
-
-    if (global.params.is64bit) {
-        VersionCondition::addPredefinedGlobalIdent("LLVM64");
-    }
-
-
-    // setup version idents and tt_os for chosen target os
-    switch(global.params.os)
-    {
-    case OSWindows:
-	VersionCondition::addPredefinedGlobalIdent("Windows");
-	VersionCondition::addPredefinedGlobalIdent("Win32");
-	VersionCondition::addPredefinedGlobalIdent("mingw32");
-	break;
-
-    case OSLinux:
-	VersionCondition::addPredefinedGlobalIdent("linux");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    case OSMacOSX:
-	VersionCondition::addPredefinedGlobalIdent("darwin");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    case OSFreeBSD:
-	VersionCondition::addPredefinedGlobalIdent("freebsd");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    case OSSolaris:
-	VersionCondition::addPredefinedGlobalIdent("solaris");
-	VersionCondition::addPredefinedGlobalIdent("Posix");
-	break;
-
-    default:
-	assert(false && "Target OS not supported");
-    }
-
-    if (!global.params.targetTriple)
-        global.params.targetTriple = DEFAULT_TARGET_TRIPLE;
-
-    Logger::println("Target triple: %s", global.params.targetTriple);
-
-    // build a minimal data layout so llvm can find the target
-    global.params.dataLayout = global.params.isLE
-        ? (char*)(global.params.is64bit ? "e-p:64:64" : "e-p:32:32")
-        : (char*)(global.params.is64bit ? "E-p:64:64" : "E-p:32:32");
-    Logger::println("Layout: %s", global.params.dataLayout);
-
-    // Initialization
-    Type::init();
-    Id::initialize();
-    Module::init();
-    initPrecedence();
-
-    backend_init();
-
-    //printf("%d source files\n",files.dim);
-
-    // Build import search path
-    if (global.params.imppath)
-    {
-	for (i = 0; i < global.params.imppath->dim; i++)
-	{
-	    char *path = (char *)global.params.imppath->data[i];
-	    Array *a = FileName::splitPath(path);
-
-	    if (a)
-	    {
-		if (!global.path)
-		    global.path = new Array();
-		global.path->append(a);
-	    }
-	}
-    }
-
-    // Build string import search path
-    if (global.params.fileImppath)
-    {
-	for (i = 0; i < global.params.fileImppath->dim; i++)
-	{
-	    char *path = (char *)global.params.fileImppath->data[i];
-	    Array *a = FileName::splitPath(path);
-
-	    if (a)
-	    {
-		if (!global.filePath)
-		    global.filePath = new Array();
-		global.filePath->append(a);
-	    }
-	}
-    }
-
-    // Create Modules
-    Array modules;
-    modules.reserve(files.dim);
-    for (i = 0; i < files.dim; i++)
-    {	Identifier *id;
-	char *ext;
-	char *name;
-
-	p = (char *) files.data[i];
-
-	p = FileName::name(p);		// strip path
-	ext = FileName::ext(p);
-	if (ext)
-	{
-#if POSIX
-	    if (strcmp(ext, global.obj_ext) == 0 ||
-		strcmp(ext, global.bc_ext) == 0)
-#else
-	    if (stricmp(ext, global.obj_ext) == 0 ||
-		stricmp(ext, global.bc_ext) == 0)
-#endif
-	    {
-		global.params.objfiles->push(files.data[i]);
-		continue;
-	    }
-
-#if POSIX
-	    if (strcmp(ext, "a") == 0)
-#elif __MINGW32__
-        if (stricmp(ext, "a") == 0)
-#else
-	    if (stricmp(ext, "lib") == 0)
-#endif
-	    {
-		global.params.libfiles->push(files.data[i]);
-		continue;
-	    }
-
-	    if (strcmp(ext, global.ddoc_ext) == 0)
-	    {
-		global.params.ddocfiles->push(files.data[i]);
-		continue;
-	    }
-
-#if !POSIX
-	    if (stricmp(ext, "res") == 0)
-	    {
-		global.params.resfile = (char *)files.data[i];
-		continue;
-	    }
-
-	    if (stricmp(ext, "def") == 0)
-	    {
-		global.params.deffile = (char *)files.data[i];
-		continue;
-	    }
-
-	    if (stricmp(ext, "exe") == 0)
-	    {
-		global.params.exefile = (char *)files.data[i];
-		continue;
-	    }
-#endif
-
-	    if (stricmp(ext, global.mars_ext) == 0 ||
-        stricmp(ext, global.hdr_ext) == 0 ||
-		stricmp(ext, "htm") == 0 ||
-		stricmp(ext, "html") == 0 ||
-		stricmp(ext, "xhtml") == 0)
-	    {
-		ext--;			// skip onto '.'
-		assert(*ext == '.');
-		name = (char *)mem.malloc((ext - p) + 1);
-		memcpy(name, p, ext - p);
-		name[ext - p] = 0;		// strip extension
-
-		if (name[0] == 0 ||
-		    strcmp(name, "..") == 0 ||
-		    strcmp(name, ".") == 0)
-		{
-		Linvalid:
-		    error("invalid file name '%s'", (char *)files.data[i]);
-		    fatal();
-		}
-	    }
-	    else
-	    {	error("unrecognized file extension %s\n", ext);
-		fatal();
-	    }
-	}
-	else
-	{   name = p;
-	    if (!*name)
-		goto Linvalid;
-	}
-
-	id = new Identifier(name, 0);
-	m = new Module((char *) files.data[i], id, global.params.doDocComments, global.params.doHdrGeneration);
-	modules.push(m);
-    }
-
-    // Read files, parse them
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("parse     %s\n", m->toChars());
-	if (!Module::rootModule)
-	    Module::rootModule = m;
-	m->importedFrom = m;
-	m->read(0);
-	m->parse();
-	m->buildTargetFiles();
-	m->deleteObjFile();
-	if (m->isDocFile)
-	{
-	    m->gendocfile();
-
-	    // Remove m from list of modules
-	    modules.remove(i);
-	    i--;
-	}
-    }
-    if (global.errors)
-	fatal();
-#ifdef _DH
-    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 (i = 0; i < modules.dim; i++)
-	{
-	    m = (Module *)modules.data[i];
-	    if (global.params.verbose)
-		printf("import    %s\n", m->toChars());
-	    m->genhdrfile();
-	}
-    }
-    if (global.errors)
-	fatal();
-#endif
-
-    // Do semantic analysis
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("semantic  %s\n", m->toChars());
-	m->semantic();
-    }
-    if (global.errors)
-	fatal();
-
-    // Do pass 2 semantic analysis
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("semantic2 %s\n", m->toChars());
-	m->semantic2();
-    }
-    if (global.errors)
-	fatal();
-
-    // Do pass 3 semantic analysis
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("semantic3 %s\n", m->toChars());
-	m->semantic3();
-    }
-    if (global.errors)
-	fatal();
-
-#if !IN_LLVM
-    // Scan for functions to inline
-    if (global.params.useInline)
-    {
-	/* The problem with useArrayBounds and useAssert is that the
-	 * module being linked to may not have generated them, so if
-	 * we inline functions from those modules, the symbols for them will
-	 * not be found at link time.
-	 */
-	if (!global.params.useArrayBounds && !global.params.useAssert)
-	{
-#endif
-	    // Do pass 3 semantic analysis on all imported modules,
-	    // since otherwise functions in them cannot be inlined
-	    for (i = 0; i < Module::amodules.dim; i++)
-	    {
-		m = (Module *)Module::amodules.data[i];
-		if (global.params.verbose)
-		    printf("semantic3 %s\n", m->toChars());
-		m->semantic3();
-	    }
-	    if (global.errors)
-		fatal();
-#if !IN_LLVM
-	}
-
-	for (i = 0; i < modules.dim; i++)
-	{
-	    m = (Module *)modules.data[i];
-	    if (global.params.verbose)
-		printf("inline scan %s\n", m->toChars());
-	    m->inlineScan();
-	}
-    }
-#endif
-    if (global.errors)
-	fatal();
-
-    // Generate output files
-    for (i = 0; i < modules.dim; i++)
-    {
-	m = (Module *)modules.data[i];
-	if (global.params.verbose)
-	    printf("code      %s\n", m->toChars());
-	if (global.params.obj)
-	{
-	    m->genobjfile(0);
-	    global.params.objfiles->push(m->objfile->name->str);
-	}
-	if (global.errors)
-	    m->deleteObjFile();
-	else
-	{
-	    if (global.params.doDocComments)
-		m->gendocfile();
-	}
-    }
-
-    backend_term();
-    if (global.errors)
-	fatal();
-
-    if (!global.params.objfiles->dim)
-    {
-	if (global.params.link)
-	    error("no object files to link");
-    }
-    else
-    {
-	if (global.params.link)
-	    //status = runLINK();
-        linkObjToExecutable(global.params.argv0);
-
-	if (global.params.run)
-	{
-	    if (!status)
-	    {
-		status = runExectuable();
-
-		/* Delete .obj files and .exe file
-		 */
-		for (i = 0; i < modules.dim; i++)
-		{
-		    m = (Module *)modules.data[i];
-		    m->deleteObjFile();
-		}
-		deleteExecutable();
-	    }
-	}
-    }
-
-    return status;
-}
-
-
-
 /***********************************
  * Parse and append contents of environment variable envvar
  * to argc and argv[].
@@ -1308,7 +160,7 @@
     Array *argv;
     int argc;
 
-    int wildcard;		// do wildcard expansion
+    int wildcard;       // do wildcard expansion
     int instring;
     int slash;
     char c;
@@ -1316,90 +168,111 @@
 
     env = getenv(envvar);
     if (!env)
-	return;
+    return;
 
-    env = mem.strdup(env);	// create our own writable copy
+    env = mem.strdup(env);  // create our own writable copy
 
     argc = *pargc;
     argv = new Array();
     argv->setDim(argc);
 
-    for (int i = 0; i < argc; i++)
-	argv->data[i] = (void *)(*pargv)[i];
+    int argc_left = 0;
+    for (int i = 0; i < argc; i++) {
+        if (!strcmp((*pargv)[i], "-run") || !strcmp((*pargv)[i], "--run")) {
+            // HACK: set flag to indicate we saw '-run' here
+            global.params.run = true;
+            // Don't eat -run yet so the program arguments don't get changed
+            argc_left = argc - i;
+            argc = i;
+            *pargv = &(*pargv)[i];
+            argv->setDim(i);
+            break;
+        } else {
+            argv->data[i] = (void *)(*pargv)[i];
+        }
+    }
+    // HACK to stop required values from command line being drawn from DFLAGS
+    argv->push((char*)"");
+    argc++;
 
-    j = 1;			// leave argv[0] alone
+    j = 1;          // leave argv[0] alone
     while (1)
     {
-	wildcard = 1;
-	switch (*env)
-	{
-	    case ' ':
-	    case '\t':
-		env++;
-		break;
+    wildcard = 1;
+    switch (*env)
+    {
+        case ' ':
+        case '\t':
+        env++;
+        break;
 
-	    case 0:
-		goto Ldone;
+        case 0:
+        goto Ldone;
 
-	    case '"':
-		wildcard = 0;
-	    default:
-		argv->push(env);		// append
-		//argv->insert(j, env);		// insert at position j
-		j++;
-		argc++;
-		p = env;
-		slash = 0;
-		instring = 0;
-		c = 0;
+        case '"':
+        wildcard = 0;
+        default:
+        argv->push(env);        // append
+        //argv->insert(j, env);     // insert at position j
+        j++;
+        argc++;
+        p = env;
+        slash = 0;
+        instring = 0;
+        c = 0;
 
-		while (1)
-		{
-		    c = *env++;
-		    switch (c)
-		    {
-			case '"':
-			    p -= (slash >> 1);
-			    if (slash & 1)
-			    {	p--;
-				goto Laddc;
-			    }
-			    instring ^= 1;
-			    slash = 0;
-			    continue;
+        while (1)
+        {
+            c = *env++;
+            switch (c)
+            {
+            case '"':
+                p -= (slash >> 1);
+                if (slash & 1)
+                {   p--;
+                goto Laddc;
+                }
+                instring ^= 1;
+                slash = 0;
+                continue;
 
-			case ' ':
-			case '\t':
-			    if (instring)
-				goto Laddc;
-			    *p = 0;
-			    //if (wildcard)
-				//wildcardexpand();	// not implemented
-			    break;
+            case ' ':
+            case '\t':
+                if (instring)
+                goto Laddc;
+                *p = 0;
+                //if (wildcard)
+                //wildcardexpand(); // not implemented
+                break;
 
-			case '\\':
-			    slash++;
-			    *p++ = c;
-			    continue;
+            case '\\':
+                slash++;
+                *p++ = c;
+                continue;
 
-			case 0:
-			    *p = 0;
-			    //if (wildcard)
-				//wildcardexpand();	// not implemented
-			    goto Ldone;
+            case 0:
+                *p = 0;
+                //if (wildcard)
+                //wildcardexpand(); // not implemented
+                goto Ldone;
 
-			default:
-			Laddc:
-			    slash = 0;
-			    *p++ = c;
-			    continue;
-		    }
-		    break;
-		}
-	}
+            default:
+            Laddc:
+                slash = 0;
+                *p++ = c;
+                continue;
+            }
+            break;
+        }
+    }
     }
 
 Ldone:
+    assert(argc == argv->dim);
+    argv->reserve(argc_left);
+    for (int i = 0; i < argc_left; i++)
+        argv->data[argc++] = (void *)(*pargv)[i];
+
     *pargc = argc;
     *pargv = (char **)argv->data;
 }
--- a/dmd2/mars.h	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd2/mars.h	Thu Feb 26 14:11:49 2009 +0100
@@ -17,6 +17,7 @@
 
 #include <stdint.h>
 #include <stdarg.h>
+#include <stddef.h>
 #define __STDC_FORMAT_MACROS 1
 #include <inttypes.h>
 #include <stdarg.h>
@@ -32,8 +33,8 @@
 /* Changes for the GDC compiler by David Friedman */
 #endif
 
-#define BREAKABI 1	// 0 if not ready to break the ABI just yet
-#define STRUCTTHISREF V2	// if 'this' for struct is a reference, not a pointer
+#define BREAKABI 1  // 0 if not ready to break the ABI just yet
+#define STRUCTTHISREF V2    // if 'this' for struct is a reference, not a pointer
 
 struct Array;
 
@@ -72,83 +73,68 @@
 // Put command line switches in here
 struct Param
 {
-    char obj;		// write object file
-    char link;		// perform link
-    char lib;		// write library file instead of object file(s)
-    char multiobj;	// break one object file into multiple ones
-    char oneobj;	// write one object file instead of multiple ones
-    char trace;		// insert profiling hooks
-    char quiet;		// suppress non-error messages
-    char verbose;	// verbose compile
-    char symdebug;	// insert debug symbolic information
-    char optimize;	// run optimizer
+    bool obj;           // write object file
+    bool link;          // perform link
+    bool verbose;       // verbose compile
+    char symdebug;  // insert debug symbolic information
+    bool optimize;      // run optimizer
     char optimizeLevel; // optimization level
-    ARCH cpu;		// target CPU
-    OS   os;		// target OS
-    char is64bit;	// generate 64 bit code
-    char isLE;      // generate little endian code
-    char scheduler;	// which scheduler to use
-    char useDeprecated;	// allow use of deprecated features
-    char useAssert;	// generate runtime code for assert()'s
-    char useInvariants;	// generate class invariant checks
-    char useIn;		// generate precondition checks
-    char useOut;	// generate postcondition checks
-    char useArrayBounds; // generate array bounds checks
-    char useSwitchError; // check for switches without a default
-    char useUnitTests;	// generate unittest code
-    char useInline;	// inline expand functions
-    char release;	// build release version
-    char preservePaths;	// !=0 means don't strip path from source file
-    char warnings;	// enable warnings
-    char pic;		// generate position-independent-code for shared libs
-    char noruntime;	// code is not allowed to make implicit calls to the runtime
-    char novalidate;// no bitcode validation
-    char Dversion;	// D version number
-    char ignoreUnsupportedPragmas;	// rather than error on them
-    char safe;		// enforce safe memory model
+    ARCH cpu;       // target CPU
+    OS   os;        // target OS
+    bool is64bit;       // generate 64 bit code
+    bool isLE;          // generate little endian code
+    bool useDeprecated; // allow use of deprecated features
+    bool useAssert;     // generate runtime code for assert()'s
+    bool useInvariants; // generate class invariant checks
+    bool useIn;         // generate precondition checks
+    bool useOut;        // generate postcondition checks
+    bool useArrayBounds; // generate array bounds checks
+    bool useSwitchError; // check for switches without a default
+    bool useUnitTests;  // generate unittest code
+    bool useInline;     // inline expand functions
+    bool warnings;      // enable warnings
+    bool safe;          // enforce safe memory model
+    char Dversion;  // D version number
 
-    char *argv0;	// program name
-    Array *imppath;	// array of char*'s of where to look for import modules
-    Array *fileImppath;	// array of char*'s of where to look for file import modules
-    char *runtimeImppath; // char* of where to look for the core runtime
-    char *objdir;	// .obj file output directory
-    char *objname;	// .obj file output name
+    char *argv0;    // program name
+    Array *imppath; // array of char*'s of where to look for import modules
+    Array *fileImppath; // array of char*'s of where to look for file import modules
+    char *objdir;   // .obj file output directory
+    char *objname;  // .obj file output name
 
-    char doDocComments;	// process embedded documentation comments
-    char *docdir;	// write documentation file to docdir directory
-    char *docname;	// write documentation file to docname
-    Array *ddocfiles;	// macro include files for Ddoc
+    bool doDocComments; // process embedded documentation comments
+    char *docdir;   // write documentation file to docdir directory
+    char *docname;  // write documentation file to docname
+    Array *ddocfiles;   // macro include files for Ddoc
 
-    char doHdrGeneration;	// process embedded documentation comments
-    char *hdrdir;		// write 'header' file to docdir directory
-    char *hdrname;		// write 'header' file to docname
+    bool doHdrGeneration;       // process embedded documentation comments
+    char *hdrdir;       // write 'header' file to docdir directory
+    char *hdrname;      // write 'header' file to docname
 
-    unsigned debuglevel;	// debug level
-    Array *debugids;		// debug identifiers
+    unsigned debuglevel;    // debug level
+    Array *debugids;        // debug identifiers
 
-    unsigned versionlevel;	// version level
-    Array *versionids;		// version identifiers
+    unsigned versionlevel;  // version level
+    Array *versionids;      // version identifiers
 
     bool dump_source;
 
-    Array *defaultlibnames;	// default libraries for non-debug builds
-    Array *debuglibnames;	// default libraries for debug builds
+    Array *defaultlibnames; // default libraries for non-debug builds
+    Array *debuglibnames;   // default libraries for debug builds
 
-    const char *xmlname;	// filename for XML output
+    char *xmlname;      // filename for XML output
 
     // Hidden debug switches
-    char debuga;
-    char debugb;
-    char debugc;
-    char debugf;
-    char debugr;
-    char debugw;
-    char debugx;
-    char debugy;
+    bool debuga;
+    bool debugb;
+    bool debugc;
+    bool debugf;
+    bool debugr;
+    bool debugw;
+    bool debugx;
+    bool debugy;
 
-    char run;		// run resulting executable
-    size_t runargs_length;
-    char** runargs;	// arguments for executable
+    bool run;           // run resulting executable
 
     // Linker stuff
     Array *objfiles;
@@ -159,50 +145,46 @@
     char *exefile;
 
     // LDC stuff
-    const char *llvmArch;
-    char forceBE;
-    char output_ll;
-    char output_bc;
-    char output_s;
-    char output_o;
-    char llvmInline;
-    char llvmAnnotate;
-    char useInlineAsm;
-    char fqnNames; // use fully qualified object names
-    char noDefaultLib;
+    OUTPUTFLAG output_ll;
+    OUTPUTFLAG output_bc;
+    OUTPUTFLAG output_s;
+    OUTPUTFLAG output_o;
+    bool llvmInline;
+    bool llvmAnnotate;
+    bool useInlineAsm;
 
     // target stuff
+    const char* llvmArch;
     const char *targetTriple;
     const char *dataLayout;
 };
 
 struct Global
 {
-    const char *mars_ext;
-    const char *sym_ext;
-    const char *obj_ext;
+    char *mars_ext;
+    char *sym_ext;
+    char *obj_ext;
 #if _WIN32
-    const char *obj_ext_alt;
+    char *obj_ext_alt;
 #endif
-    const char *ll_ext;
-    const char *bc_ext;
-    const char *s_ext;
-    const char *lib_ext;
-    const char *doc_ext;	// for Ddoc generated files
-    const char *ddoc_ext;	// for Ddoc macro include files
-    const char *hdr_ext;	// for D 'header' import files
-    const char *copyright;
-    const char *written;
-    Array *path;	// Array of char*'s which form the import lookup path
-    Array *filePath;	// Array of char*'s which form the file import lookup path
+    char *ll_ext;
+    char *bc_ext;
+    char *s_ext;
+    char *doc_ext;  // for Ddoc generated files
+    char *ddoc_ext; // for Ddoc macro include files
+    char *hdr_ext;  // for D 'header' import files
+    char *copyright;
+    char *written;
+    Array *path;    // Array of char*'s which form the import lookup path
+    Array *filePath;    // Array of char*'s which form the file import lookup path
     int structalign;
-    const char *version;
-    const char *ldc_version;
-    const char *llvm_version;
+    char *version;
+    char *ldc_version;
+    char *llvm_version;
 
     Param params;
-    unsigned errors;	// number of errors reported so far
-    unsigned gag;	// !=0 means gag reporting of errors
+    unsigned errors;    // number of errors reported so far
+    unsigned gag;   // !=0 means gag reporting of errors
 
     Global();
 };
@@ -212,7 +194,7 @@
 /* Set if Windows Structured Exception Handling C extensions are supported.
  * Apparently, VC has dropped support for these?
  */
-#define WINDOWS_SEH	_WIN32 && __DMC__
+#define WINDOWS_SEH (_WIN32 && __DMC__)
 
 
 #if __GNUC__
@@ -239,22 +221,22 @@
 typedef int64_t sinteger_t;
 typedef uint64_t uinteger_t;
 
-typedef int8_t			d_int8;
-typedef uint8_t			d_uns8;
-typedef int16_t			d_int16;
-typedef uint16_t		d_uns16;
-typedef int32_t			d_int32;
-typedef uint32_t		d_uns32;
-typedef int64_t			d_int64;
-typedef uint64_t		d_uns64;
+typedef int8_t          d_int8;
+typedef uint8_t         d_uns8;
+typedef int16_t         d_int16;
+typedef uint16_t        d_uns16;
+typedef int32_t         d_int32;
+typedef uint32_t        d_uns32;
+typedef int64_t         d_int64;
+typedef uint64_t        d_uns64;
 
-typedef float			d_float32;
-typedef double			d_float64;
-typedef long double		d_float80;
+typedef float           d_float32;
+typedef double          d_float64;
+typedef long double     d_float80;
 
-typedef d_uns8			d_char;
-typedef d_uns16			d_wchar;
-typedef d_uns32			d_dchar;
+typedef d_uns8          d_char;
+typedef d_uns16         d_wchar;
+typedef d_uns32         d_dchar;
 
 #ifdef IN_GCC
 #include "d-gcc-real.h"
@@ -289,7 +271,7 @@
 
 struct Module;
 
-//typedef unsigned Loc;		// file location
+//typedef unsigned Loc;     // file location
 struct Loc
 {
     char *filename;
@@ -297,14 +279,14 @@
 
     Loc()
     {
-	linnum = 0;
-	filename = NULL;
+    linnum = 0;
+    filename = NULL;
     }
 
     Loc(int x)
     {
-	linnum = x;
-	filename = NULL;
+    linnum = x;
+    filename = NULL;
     }
 
     Loc(Module *mod, unsigned linnum);
@@ -313,15 +295,15 @@
 };
 
 #ifndef GCC_SAFE_DMD
-#define TRUE	1
-#define FALSE	0
+#define TRUE    1
+#define FALSE   0
 #endif
 
-#define INTERFACE_OFFSET	0	// if 1, put classinfo as first entry
-					// in interface vtbl[]'s
-#define INTERFACE_VIRTUAL	0	// 1 means if an interface appears
-					// in the inheritance graph multiple
-					// times, only one is used
+#define INTERFACE_OFFSET    0   // if 1, put classinfo as first entry
+                    // in interface vtbl[]'s
+#define INTERFACE_VIRTUAL   0   // 1 means if an interface appears
+                    // in the inheritance graph multiple
+                    // times, only one is used
 
 enum LINK
 {
@@ -348,19 +330,19 @@
 
 enum MATCH
 {
-    MATCHnomatch,	// no match
-    MATCHconvert,	// match with conversions
+    MATCHnomatch,   // no match
+    MATCHconvert,   // match with conversions
 #if DMDV2
-    MATCHconst,		// match with conversion to const
+    MATCHconst,     // match with conversion to const
 #endif
-    MATCHexact		// exact match
+    MATCHexact      // exact match
 };
 
 void error(Loc loc, const char *format, ...);
 void verror(Loc loc, const char *format, va_list);
 void fatal();
 void err_nomem();
-void inifile(const char *argv0, const char *inifile);
+void inifile(char *argv0, const char *inifile);
 void halt();
 
 /*** Where to send error messages ***/
--- a/dmd2/module.c	Wed Feb 25 19:30:06 2009 +0100
+++ b/dmd2/module.c	Thu Feb 26 14:11:49 2009 +0100
@@ -40,6 +40,19 @@
 #include "d-dmd-gcc.h"
 #endif
 
+
+#include "llvm/Support/CommandLine.h"
+
+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);
+
+
+
 ClassDeclaration *Module::moduleinfo;
 
 Module *Module::rootModule;
@@ -139,12 +152,12 @@
 	argobj = forcename;
     else
     {
-	if (global.params.preservePaths)
+	if (preservePaths)
 	    argobj = (char*)this->arg;
 	else
 	    argobj = FileName::name((char*)this->arg);
 
-	if (global.params.fqnNames)
+	if (fqnNames)
 	{
 	    if(md)
 		argobj = FileName::replaceName(argobj, md->toChars());
--- a/gen/cl_options.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/cl_options.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -230,22 +230,18 @@
     cl::Prefix,
     cl::aliasopt(mArch));
 
+cl::opt<std::string> mCPU("mcpu",
+    cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+    cl::value_desc("cpu-name"),
+    cl::init(""));
 
-static cl::opt<OS, true> os("t",
-    cl::desc("Emit code for the specified OS:"),
-    cl::values(
-#define ENUMVAL_N(Name, Desc) clEnumValN(OS##Name, #Name, Desc)
-#define ENUMVAL(Name) ENUMVAL_N(Name, #Name)
-        ENUMVAL(Linux),
-        ENUMVAL(Windows),
-        ENUMVAL_N(MacOSX, "Mac OS X"),
-        ENUMVAL(FreeBSD),
-        ENUMVAL(Solaris),
-#undef ENUMVAL
-#undef ENUMVAL_N
-        clEnumValEnd),
-    cl::Prefix,
-    cl::location(global.params.os));
+cl::list<std::string> mAttrs("mattr",
+    cl::CommaSeparated,
+    cl::desc("Target specific attributes (-mattr=help for details)"),
+    cl::value_desc("a1,+a2,-a3,..."));
+
+cl::opt<std::string> mTargetTriple("mtriple",
+    cl::desc("Override target triple"));
 
 
 // "Hidden debug switches"
--- a/gen/cl_options.h	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/cl_options.h	Thu Feb 26 14:11:49 2009 +0100
@@ -38,7 +38,10 @@
 
     extern cl::opt<const llvm::TargetMachineRegistry::entry*, false,
                     llvm::RegistryParser<llvm::TargetMachine> > mArch;
-    
+    extern cl::opt<std::string> mCPU;
+    extern cl::list<std::string> mAttrs;
+    extern cl::opt<std::string> mTargetTriple;
+
     // Arguments to -d-debug
     extern std::vector<std::string> debugArgs;
     // Arguments to -run
--- a/gen/functions.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/functions.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -20,6 +20,7 @@
 #include "gen/todebug.h"
 #include "gen/classes.h"
 #include "gen/dvalue.h"
+#include "gen/abi.h"
 
 #include <algorithm>
 
@@ -53,40 +54,49 @@
     // parameter types
     std::vector<const LLType*> paramvec;
 
+    // special case main
     if (ismain)
     {
         rettype = LLType::Int32Ty;
         actualRettype = rettype;
         if (Argument::dim(f->parameters) == 0)
         {
-        const LLType* arrTy = DtoArrayType(LLType::Int8Ty);
-        const LLType* arrArrTy = DtoArrayType(arrTy);
-        paramvec.push_back(arrArrTy);
+            const LLType* arrTy = DtoArrayType(LLType::Int8Ty);
+            const LLType* arrArrTy = DtoArrayType(arrTy);
+            paramvec.push_back(arrArrTy);
         }
     }
-    else{
+    // default handling
+    else
+    {
         assert(rt);
-        if (DtoIsReturnedInArg(rt)) {
+        if (gABI->returnInArg(rt))
+        {
             rettype = getPtrToType(DtoType(rt));
             actualRettype = LLType::VoidTy;
             f->retInPtr = retinptr = true;
         }
-        else {
+        else
+        {
             rettype = DtoType(rt);
-            actualRettype = rettype;
+            // do abi specific transformations
+            actualRettype = gABI->getRetType(f, rettype);
         }
 
+        // FIXME: should probably be part of the abi
         if (unsigned ea = DtoShouldExtend(rt))
         {
             f->retAttrs |= ea;
         }
     }
 
+    // build up parameter list
     if (retinptr) {
         //Logger::cout() << "returning through pointer parameter: " << *rettype << '\n';
         paramvec.push_back(rettype);
     }
 
+    // this/context param
     if (thistype) {
         paramvec.push_back(thistype);
         usesthis = true;
@@ -96,6 +106,7 @@
         usesnest = true;
     }
 
+    // dstyle vararg
     if (dVararg) {
         paramvec.push_back(DtoType(Type::typeinfo->type->arrayOf())); // _arguments
         paramvec.push_back(getVoidPtrType()); // _argptr
--- a/gen/irstate.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/irstate.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -16,7 +16,9 @@
 #include "tollvm.h"
 
 IRState* gIR = 0;
+llvm::TargetMachine* gTargetMachine = 0;
 const llvm::TargetData* gTargetData = 0;
+TargetABI* gABI = 0;
 
 //////////////////////////////////////////////////////////////////////////////////////////
 IRScope::IRScope()
--- a/gen/irstate.h	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/irstate.h	Thu Feb 26 14:11:49 2009 +0100
@@ -13,10 +13,18 @@
 #include "ir/irstruct.h"
 #include "ir/irvar.h"
 
+namespace llvm {
+    class TargetMachine;
+}
+
 // global ir state for current module
 struct IRState;
+struct TargetABI;
+
 extern IRState* gIR;
+extern llvm::TargetMachine* gTargetMachine;
 extern const llvm::TargetData* gTargetData;
+extern TargetABI* gABI;
 
 struct TypeFunction;
 struct TypeStruct;
--- a/gen/naked.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/naked.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -218,6 +218,8 @@
             // this is to show how to allocate a temporary for the return value
             // in case the appropriate multi register constraint isn't supported.
             // this way abi return from inline asm can still be emulated.
+            // note that "$<<out0>>" etc in the asm will translate to the correct
+            // numbered output when the asm block in finalized
 
             // generate asm
             as->out_c = "=*m,=*m,";
@@ -231,7 +233,7 @@
             asmblock->retemu = true;
             asmblock->asmBlock->abiret = tmp;
 
-            // add "ret" stmt
+            // add "ret" stmt at the end of the block
             asmblock->s.push_back(as);
 
             // done, we don't want anything pushed in the front of the block
@@ -276,17 +278,9 @@
                 // LLVM and GCC disagree on how to return {float, float}.
                 // For compatibility, use the GCC/LLVM-GCC way for extern(C/Windows)
                 // extern(C) cfloat -> %xmm0 (extract two floats)
-            #if 0
-                // Disabled because "regular" extern(C) functions aren't
-                // ABI-compatible with GCC yet.
-                // TODO: enable when "extern(C) cfloat foo();" compiles to "declare { double } @foo();"
                 as->out_c = "={xmm0},";
                 asmblock->retty = LLStructType::get(LLType::DoubleTy, NULL);;
                 asmblock->retfixup = &x86_64_cfloatRetFixup;
-            #else
-                error(loc, "unimplemented return type '%s' for implicit abi return", rt->toChars());
-                fatal();
-            #endif
             } else if (rt->iscomplex()) {
                 // cdouble and extern(D) cfloat -> re=%xmm0, im=%xmm1
                 as->out_c = "={xmm0},={xmm1},";
--- a/gen/statements.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/statements.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -25,6 +25,7 @@
 #include "gen/arrays.h"
 #include "gen/todebug.h"
 #include "gen/dvalue.h"
+#include "gen/abi.h"
 
 #include "ir/irfunction.h"
 #include "ir/irmodule.h"
@@ -54,38 +55,47 @@
     Logger::println("ReturnStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    // is there a return value expression?
     if (exp)
     {
-        if (p->topfunc()->getReturnType() == LLType::VoidTy) {
+        // if the functions return type is void this means that
+        // we are returning through a pointer argument
+        if (p->topfunc()->getReturnType() == LLType::VoidTy)
+        {
+            // sanity check
             IrFunction* f = p->func();
             assert(f->type->retInPtr);
             assert(f->decl->ir.irFunc->retArg);
 
+            // emit dbg line
             if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
 
+            // get return pointer
             DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg);
-
             DValue* e = exp->toElem(p);
-
+            // store return value
             DtoAssign(loc, rvar, e);
 
+            // emit scopes
             DtoEnclosingHandlers(enclosinghandler, NULL);
 
+            // emit dbg end function
             if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
+
+            // emit ret
             llvm::ReturnInst::Create(p->scopebb());
 
         }
-        else {
+        // the return type is not void, so this is a normal "register" return
+        else
+        {
             if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
             DValue* e = exp->toElem(p);
             LLValue* v = e->getRVal();
             delete e;
 
-            // swap real/imag parts on a x87
-            if (global.params.cpu == ARCHx86 && exp->type->toBasetype()->iscomplex())
-            {
-                v = DtoAggrPairSwap(v);
-            }
+            // do abi specific transformations on the return value
+            v = gABI->putRet(p->func()->type, v);
 
             if (Logger::enabled())
                 Logger::cout() << "return value is '" <<*v << "'\n";
@@ -113,6 +123,7 @@
             llvm::ReturnInst::Create(v, p->scopebb());
         }
     }
+    // no return value expression means it's a void function
     else
     {
         assert(p->topfunc()->getReturnType() == LLType::VoidTy);
--- a/gen/tocall.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/tocall.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -8,6 +8,7 @@
 #include "gen/irstate.h"
 #include "gen/dvalue.h"
 #include "gen/functions.h"
+#include "gen/abi.h"
 
 #include "gen/logger.h"
 
@@ -463,11 +464,8 @@
     // get return value
     LLValue* retllval = (retinptr) ? args[0] : call->get();
 
-    // swap real/imag parts on a x87
-    if (global.params.cpu == ARCHx86 && tf->nextOf()->toBasetype()->iscomplex())
-    {
-        retllval = DtoAggrPairSwap(retllval);
-    }
+    // do abi specific return value fixups
+    retllval = gABI->getRet(tf, retllval);
 
     // repaint the type if necessary
     if (resulttype)
--- a/gen/tollvm.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/tollvm.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -28,13 +28,6 @@
     return (t == Tstruct || t == Tsarray);
 }
 
-bool DtoIsReturnedInArg(Type* type)
-{
-    Type* typ = type->toBasetype();
-    TY t = typ->ty;
-    return (t == Tstruct || t == Tsarray);
-}
-
 unsigned DtoShouldExtend(Type* type)
 {
     type = type->toBasetype();
--- a/gen/tollvm.h	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/tollvm.h	Thu Feb 26 14:11:49 2009 +0100
@@ -18,9 +18,7 @@
 // returns true is the type must be passed by pointer
 bool DtoIsPassedByRef(Type* type);
 
-// returns if the type should be returned in a hidden pointer arguement
-bool DtoIsReturnedInArg(Type* type);
-
+// should argument be zero or sign extended
 unsigned DtoShouldExtend(Type* type);
 
 // tuple helper
--- a/gen/toobj.cpp	Wed Feb 25 19:30:06 2009 +0100
+++ b/gen/toobj.cpp	Thu Feb 26 14:11:49 2009 +0100
@@ -14,9 +14,6 @@
 #include "gen/llvm.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Target/SubtargetFeature.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetMachineRegistry.h"
 #include "llvm/Module.h"
 #include "llvm/ModuleProvider.h"
 #include "llvm/PassManager.h"
@@ -25,6 +22,7 @@
 #include "llvm/System/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetMachine.h"
 
 #include "mars.h"
 #include "module.h"
@@ -50,6 +48,8 @@
 #include "gen/functions.h"
 #include "gen/todebug.h"
 #include "gen/runtime.h"
+#include "gen/abi.h"
+#include "gen/cl_options.h"
 
 #include "ir/irvar.h"
 #include "ir/irmodule.h"
@@ -110,40 +110,16 @@
     // FIXME: but shouldn't this always get reset between modules? like other IrSymbols
     this->ir.irModule = new IrModule(this, srcfile->toChars());
 
-    // set target stuff
-
+    // set target triple
     ir.module->setTargetTriple(global.params.targetTriple);
-    ir.module->setDataLayout(global.params.dataLayout);
-
-    // get the target machine
-    const llvm::TargetMachineRegistry::entry* MArch;
-
-    std::string Err;
-    MArch = llvm::TargetMachineRegistry::getClosestStaticTargetForModule(*ir.module, Err);
-    if (MArch == 0) {
-        error("error auto-selecting target for module '%s'", Err.c_str());
-        fatal();
-    }
-
-    llvm::SubtargetFeatures Features;
-//TODO: Features?
-//    Features.setCPU(MCPU);
-//    for (unsigned i = 0; i != MAttrs.size(); ++i)
-//      Features.AddFeature(MAttrs[i]);
-
-    // allocate the target machine
-    std::auto_ptr<llvm::TargetMachine> target(MArch->CtorFn(*ir.module, Features.getString()));
-    assert(target.get() && "Could not allocate target machine!");
-    llvm::TargetMachine &Target = *target.get();
-
-    gTargetData = Target.getTargetData();
 
     // set final data layout
-    std::string datalayout = gTargetData->getStringRepresentation();
-    ir.module->setDataLayout(datalayout);
+    ir.module->setDataLayout(global.params.dataLayout);
     if (Logger::enabled())
-        Logger::cout() << "Final data layout: " << datalayout << '\n';
-    assert(memcmp(global.params.dataLayout, datalayout.c_str(), 9) == 0); // "E-p:xx:xx"
+        Logger::cout() << "Final data layout: " << global.params.dataLayout << '\n';
+
+    // allocate the target abi
+    gABI = TargetABI::getTarget();
 
     // debug info
     if (global.params.symdebug) {
@@ -252,7 +228,7 @@
         std::string err;
         {
             llvm::raw_fd_ostream out(spath.c_str(), false, err);
-            write_asm_to_file(Target, *ir.module, out);
+            write_asm_to_file(*gTargetMachine, *ir.module, out);
         }
 
         // call gcc to convert assembly to object file