view runtime/ldc.diff @ 837:331a176c1f4f

Removed error on naked, not fully complete, but I'll be doing more work on it during this Christmas, and some things do work. Fixed taking delegate of final class method. see mini/delegate3.d.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 09 Dec 2008 14:07:30 +0100
parents 43178a913a28
children e66c627c177e
line wrap: on
line source

Index: lib/common/tango/core/BitManip.d
===================================================================
--- lib/common/tango/core/BitManip.d	(revision 4145)
+++ lib/common/tango/core/BitManip.d	(working copy)
@@ -171,6 +171,10 @@
      */
     uint outpl( uint port_address, uint value );
 }
+else version( LDC )
+{
+    public import ldc.bitmanip;
+}
 else
 {
     public import std.intrinsic;
Index: lib/common/tango/core/Thread.d
===================================================================
--- lib/common/tango/core/Thread.d	(revision 4145)
+++ lib/common/tango/core/Thread.d	(working copy)
@@ -273,8 +273,50 @@
         }
         body
         {
-            version( D_InlineAsm_X86 )
+            version( LDC)
             {
+                version(X86)
+                {
+                    uint eax,ecx,edx,ebx,ebp,esi,edi;
+                    asm
+                    {
+                        mov eax[EBP], EAX      ;
+                        mov ecx[EBP], ECX      ;
+                        mov edx[EBP], EDX      ;
+                        mov ebx[EBP], EBX      ;
+                        mov ebp[EBP], EBP      ;
+                        mov esi[EBP], ESI      ;
+                        mov edi[EBP], EDI      ;
+                    }
+                }
+                else version (X86_64)
+                {
+                    ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r10,r11,r12,r13,r14,r15;
+                    asm
+                    {
+                        movq rax[RBP], RAX        ;
+                        movq rbx[RBP], RBX        ;
+                        movq rcx[RBP], RCX        ;
+                        movq rdx[RBP], RDX        ;
+                        movq rbp[RBP], RBP        ;
+                        movq rsi[RBP], RSI        ;
+                        movq rdi[RBP], RDI        ;
+                        movq rsp[RBP], RSP        ;
+                        movq r10[RBP], R10        ;
+                        movq r11[RBP], R11        ;
+                        movq r12[RBP], R12        ;
+                        movq r13[RBP], R13        ;
+                        movq r14[RBP], R14        ;
+                        movq r15[RBP], R15        ;
+                    }
+                }
+                else
+                {
+                    static assert( false, "Architecture not supported." );
+                }
+            }
+            else version( D_InlineAsm_X86 )
+            {
                 asm
                 {
                     pushad;
@@ -330,8 +372,12 @@
                 }
             }
 
-            version( D_InlineAsm_X86 )
+            version( LDC)
             {
+                // nothing to pop
+            }
+            else version( D_InlineAsm_X86 )
+            {
                 asm
                 {
                     popad;
@@ -2347,6 +2393,18 @@
         version( Posix )
             version = AsmPPC_Posix;
     }
+    version( LLVM_InlineAsm_X86 ) 
+    {
+        version( Win32 )
+            version = LLVM_AsmX86_Win32;
+        else version( Posix )
+            version = LLVM_AsmX86_Posix;
+    }
+    else version( LLVM_InlineAsm_X86_64 )
+    {
+        version( Posix )
+            version = LLVM_AsmX86_64_Posix;
+    }
 
     version( Posix )
     {
@@ -2357,6 +2415,10 @@
         version( AsmX86_Win32 ) {} else
         version( AsmX86_Posix ) {} else
         version( AsmPPC_Posix ) {} else
+        version( LLVM_AsmX86_Win32 ) {} else
+        version( LLVM_AsmX86_Posix ) {} else
+//TODO: Enable when x86-64 Posix supports fibers
+//        version( LLVM_AsmX86_64_Posix ) {} else
         {
             // NOTE: The ucontext implementation requires architecture specific
             //       data definitions to operate so testing for it must be done
@@ -2510,6 +2572,28 @@
                 ret;
             }
         }
+        else version( LLVM_AsmX86_Posix )
+        {
+            asm
+            {
+                // clobber registers to save
+                inc EBX;
+                inc ESI;
+                inc EDI;
+
+                // store oldp again with more accurate address
+                mov EAX, oldp;
+                mov [EAX], ESP;
+                // load newp to begin context switch
+                mov ESP, newp;
+            }
+        }
+/+
+        version( LLVM_AsmX86_64_Posix )
+        {
+            //TODO: Fiber implementation here
+        }
++/
         else static if( is( ucontext_t ) )
         {
             Fiber   cfib = Fiber.getThis();
@@ -2522,7 +2606,7 @@
     }
 }
 
-
+extern(C) int printf(char*, ...);
 ////////////////////////////////////////////////////////////////////////////////
 // Fiber
 ////////////////////////////////////////////////////////////////////////////////
@@ -3177,6 +3261,22 @@
             push( 0x00000000 );                                     // ESI
             push( 0x00000000 );                                     // EDI
         }
+        else version( LLVM_AsmX86_Posix )
+        {
+            push( cast(size_t) &fiber_entryPoint );                 // EIP
+            push( 0x00000000 );                                     // newp
+            push( 0x00000000 );                                     // oldp
+            push( 0x00000000 );                                     // EBP
+            push( 0x00000000 );                                     // EBX
+            push( 0x00000000 );                                     // ESI
+            push( 0x00000000 );                                     // EDI
+        }
+//TODO: Implement x86-64 fibers
+/+
+        else version( LLVM_AsmX86_Posix )
+        {
+        }
++/
         else version( AsmPPC_Posix )
         {
             version( StackGrowsDown )
Index: lib/unittest.sh
===================================================================
--- lib/unittest.sh	(revision 4145)
+++ lib/unittest.sh	(working copy)
@@ -18,8 +18,9 @@
   --help: This message
   --run-all: Reports result instead of breaking. Do not use this if you want to
          run unittest runner through a debugger.
-  dmd: Builds unittests for dmd
-  gdc: Builds unittests for gdc
+  dmd:    Builds unittests for dmd
+  gdc:    Builds unittests for gdc
+  ldc: Builds unittests for ldc
 
   <none>: Builds unittests for all known compilers.'
   exit 0
@@ -86,7 +87,7 @@
 void main() {}
 EOF
 
-        rebuild -w -d -g -L-ldl -L-lz -L-lbz2 -debug=UnitTest -debug -full -clean -unittest \
+        rebuild -w -d -L-ldl -L-lz -L-lbz2 -debug=UnitTest -debug -full -clean -unittest \
         -version=UnitTest $EXE.d tango/core/*.d tango/core/sync/*.d tango/io/digest/*.d \
         tango/io/model/*.d tango/io/protocol/*.d tango/io/selector/*.d tango/io/*.d \
         tango/io/vfs/*.d tango/io/vfs/model/*.d \
@@ -125,6 +126,9 @@
         gdc)
             GDC=1
             ;;
+        ldc)
+            LDC=1
+            ;;
         *)
             usage
             ;;
@@ -132,10 +136,11 @@
     shift
 done
 
-if [ ! "$DMD" -a ! "$GDC" ]
+if [ ! "$DMD" -a ! "$GDC" -a ! "$LDC" ]
 then
     DMD=1
     GDC=1
+    LDC=1
 fi
 
 if [ "$DMD" = "1" ]
@@ -146,4 +151,7 @@
 then
     compile gdc runUnitTest_gdc
 fi
-
+if [ "$LDC" = "1" ]
+then
+    compile ldc runUnitTest_ldc
+fi
Index: lib/gc/basic/gcx.d
===================================================================
--- lib/gc/basic/gcx.d	(revision 4145)
+++ lib/gc/basic/gcx.d	(working copy)
@@ -65,6 +65,13 @@
 }
 
 
+struct BlkInfo
+{
+    void*  base;
+    size_t size;
+    uint   attr;
+}
+
 private
 {
     enum BlkAttr : uint
@@ -75,13 +82,6 @@
         ALL_BITS = 0b1111_1111
     }
 
-    struct BlkInfo
-    {
-        void*  base;
-        size_t size;
-        uint   attr;
-    }
-
     extern (C) void* rt_stackBottom();
     extern (C) void* rt_stackTop();
 
@@ -2178,6 +2178,49 @@
             __builtin_unwind_init();
             sp = & sp;
         }
+        else version(LDC)
+        {
+            version(X86)
+            {
+                uint eax,ecx,edx,ebx,ebp,esi,edi;
+                asm
+                {
+                    mov eax[EBP], EAX      ;
+                    mov ecx[EBP], ECX      ;
+                    mov edx[EBP], EDX      ;
+                    mov ebx[EBP], EBX      ;
+                    mov ebp[EBP], EBP      ;
+                    mov esi[EBP], ESI      ;
+                    mov edi[EBP], EDI      ;
+                    mov sp[EBP],ESP     ;
+                }
+            }
+            else version (X86_64)
+            {
+                ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r10,r11,r12,r13,r14,r15;
+                asm
+                {
+                    movq rax[RBP], RAX      ;
+                    movq rbx[RBP], RBX      ;
+                    movq rcx[RBP], RCX      ;
+                    movq rdx[RBP], RDX      ;
+                    movq rbp[RBP], RBP      ;
+                    movq rsi[RBP], RSI      ;
+                    movq rdi[RBP], RDI      ;
+                    movq rsp[RBP], RSP      ;
+                    movq r10[RBP], R10      ;
+                    movq r11[RBP], R11      ;
+                    movq r12[RBP], R12      ;
+                    movq r13[RBP], R13      ;
+                    movq r14[RBP], R14      ;
+                    movq r15[RBP], R15      ;
+                }
+            }
+            else
+            {
+                static assert( false, "Architecture not supported." );
+            }
+        }
         else
         {
         asm
@@ -2191,6 +2234,10 @@
         {
             // nothing to do
         }
+        else version(LDC)
+        {
+            // nothing to do
+        }
         else
         {
         asm
Index: lib/gc/basic/gcbits.d
===================================================================
--- lib/gc/basic/gcbits.d	(revision 4145)
+++ lib/gc/basic/gcbits.d	(working copy)
@@ -39,6 +39,10 @@
 {
     // use the unoptimized version
 }
+else version(LDC)
+{
+    // ditto
+}
 else version (D_InlineAsm_X86)
 {
     version = Asm86;
Index: lib/build-tango.sh
===================================================================
--- lib/build-tango.sh	(revision 4145)
+++ lib/build-tango.sh	(working copy)
@@ -23,7 +23,7 @@
   --debug: Will enable debug info
   --warn: Will enable warnings
   --verbose: Increase verbosity 
-  <identifier> is one of {dmd, gdc, mac} and will build libtango.a,
+  <identifier> is one of {dmd, gdc, ldc, mac} and will build libtango.a,
                 libgtango.a or universal Mac binaries respectively
 
   The script must be called from within lib/ and the resulting
@@ -105,7 +105,7 @@
     if filter $OBJNAME
     then
         if [ $VERBOSE == 1 ]; then echo "[$DC] $FILENAME"; fi
-        $DC $WARN -c $INLINE $DEBUG $RELEASE -version=Posix -version=Tango -of$OBJNAME $FILENAME
+        $DC $WARN -c $INLINE $DEBUG $RELEASE -version=Tango -of$OBJNAME $FILENAME
         if [ "$?" != 0 ]
         then
             return 1;
@@ -189,6 +189,9 @@
         gdc)
             build gdmd libgtango.a libgphobos.a
             ;;
+        ldc)
+            build ldc libtango-user-ldc.a build-tango.sh
+            ;;
         mac)
             # build Universal Binary version of the Tango library
             build powerpc-apple-darwin8-gdmd libgtango.a.ppc libgphobos.a.ppc
Index: tango/text/convert/Layout.d
===================================================================
--- tango/text/convert/Layout.d	(revision 4145)
+++ tango/text/convert/Layout.d	(working copy)
@@ -47,6 +47,12 @@
         alias void* Arg;
         alias va_list ArgList;
         }
+else version(LDC)
+        {
+        private import tango.core.Vararg;
+        alias void* Arg;
+        alias va_list ArgList;
+        }
      else
         {
         alias void* Arg;
@@ -295,7 +301,7 @@
                         foreach (i, arg; arguments)
                                 {
                                 arglist[i] = args;
-                                args += (arg.tsize + int.sizeof - 1) & ~ (int.sizeof - 1);
+                                args += (arg.tsize + size_t.sizeof - 1) & ~ (size_t.sizeof - 1);
                                 }
                         }
                 return parse (formatStr, arguments, arglist, sink);
Index: tango/net/cluster/CacheInvalidator.d
===================================================================
--- tango/net/cluster/CacheInvalidator.d	(revision 4145)
+++ tango/net/cluster/CacheInvalidator.d	(working copy)
@@ -79,7 +79,7 @@
 
 *******************************************************************************/
 
-private class InvalidatorPayload : NetworkMessage
+package class InvalidatorPayload : NetworkMessage
 {
         private char[] key_;
 
Index: tango/core/Vararg.d
===================================================================
--- tango/core/Vararg.d	(revision 4145)
+++ tango/core/Vararg.d	(working copy)
@@ -15,6 +15,10 @@
 {
     public import std.stdarg;
 }
+else version( LDC )
+{
+    public import ldc.vararg;
+}
 else
 {
     /**
Index: tango/core/sync/Semaphore.d
===================================================================
--- tango/core/sync/Semaphore.d	(revision 4145)
+++ tango/core/sync/Semaphore.d	(working copy)
@@ -384,7 +384,8 @@
             {
                 synchronized( synComplete )
                 {
-                    if( numComplete == numConsumers )
+                    // if( numComplete == numConsumers )
+                    if( numComplete == numToProduce )
                         break;
                 }
                 Thread.yield();
@@ -392,9 +393,9 @@
 
             synchronized( synComplete )
             {
-                assert( numComplete == numConsumers );
+                assert( numComplete == numToProduce );
+                // assert( numComplete == numConsumers );
             }
-
             synchronized( synConsumed )
             {
                 assert( numConsumed == numToProduce );
@@ -455,7 +456,8 @@
 
     unittest
     {
+        version(darwin){}else{
         testWait();
-        testWaitTimeout();
+        testWaitTimeout();}
     }
 }
Index: tango/core/sync/Condition.d
===================================================================
--- tango/core/sync/Condition.d	(revision 4145)
+++ tango/core/sync/Condition.d	(working copy)
@@ -553,8 +553,11 @@
 
     unittest
     {
+        version(darwin){}
+        else{
         testNotify();
         testNotifyAll();
         testWaitTimeout();
+        }
     }
 }
Index: tango/core/Atomic.d
===================================================================
--- tango/core/Atomic.d	(revision 4145)
+++ tango/core/Atomic.d	(working copy)
@@ -270,6 +270,167 @@
 
 
 ////////////////////////////////////////////////////////////////////////////////
+// LDC Atomics Implementation
+////////////////////////////////////////////////////////////////////////////////
+
+
+else version( LDC )
+{
+    import ldc.intrinsics;
+
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Atomic Load
+    ////////////////////////////////////////////////////////////////////////////
+
+
+    template atomicLoad( msync ms = msync.seq, T )
+    {
+        T atomicLoad(ref T val)
+        {
+            llvm_memory_barrier(
+                ms == msync.hlb || ms == msync.acq || ms == msync.seq,
+                ms == msync.hsb || ms == msync.acq || ms == msync.seq,
+                ms == msync.slb || ms == msync.rel || ms == msync.seq,
+                ms == msync.ssb || ms == msync.rel || ms == msync.seq,
+                false);
+            static if (isPointerType!(T))
+            {
+                return cast(T)llvm_atomic_load_add!(size_t)(cast(size_t*)&val, 0);
+            }
+            else static if (is(T == bool))
+            {
+                return llvm_atomic_load_add!(ubyte)(cast(ubyte*)&val, cast(ubyte)0) ? 1 : 0;
+            }
+            else
+            {
+                return llvm_atomic_load_add!(T)(&val, cast(T)0);
+            }
+        }
+    }
+
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Atomic Store
+    ////////////////////////////////////////////////////////////////////////////
+
+
+    template atomicStore( msync ms = msync.seq, T )
+    {
+        void atomicStore( ref T val, T newval )
+        {
+            llvm_memory_barrier(
+                ms == msync.hlb || ms == msync.acq || ms == msync.seq,
+                ms == msync.hsb || ms == msync.acq || ms == msync.seq,
+                ms == msync.slb || ms == msync.rel || ms == msync.seq,
+                ms == msync.ssb || ms == msync.rel || ms == msync.seq,
+                false);
+            static if (isPointerType!(T))
+            {
+                llvm_atomic_swap!(size_t)(cast(size_t*)&val, cast(size_t)newval);
+            }
+            else static if (is(T == bool))
+            {
+                llvm_atomic_swap!(ubyte)(cast(ubyte*)&val, newval?1:0);
+            }
+            else
+            {
+                llvm_atomic_swap!(T)(&val, newval);
+            }
+        }
+    }
+
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Atomic Store If
+    ////////////////////////////////////////////////////////////////////////////
+
+
+    template atomicStoreIf( msync ms = msync.seq, T )
+    {
+        bool atomicStoreIf( ref T val, T newval, T equalTo )
+        {
+            llvm_memory_barrier(
+                ms == msync.hlb || ms == msync.acq || ms == msync.seq,
+                ms == msync.hsb || ms == msync.acq || ms == msync.seq,
+                ms == msync.slb || ms == msync.rel || ms == msync.seq,
+                ms == msync.ssb || ms == msync.rel || ms == msync.seq,
+                false);
+            T oldval = void;
+            static if (isPointerType!(T))
+            {
+                oldval = cast(T)llvm_atomic_cmp_swap!(size_t)(cast(size_t*)&val, cast(size_t)equalTo, cast(size_t)newval);
+            }
+            else static if (is(T == bool))
+            {
+                oldval = llvm_atomic_cmp_swap!(ubyte)(cast(ubyte*)&val, equalTo?1:0, newval?1:0)?0:1;
+            }
+            else
+            {
+                oldval = llvm_atomic_cmp_swap!(T)(&val, equalTo, newval);
+            }
+            return oldval == equalTo;
+        }
+    }
+    
+    
+    ////////////////////////////////////////////////////////////////////////////
+    // Atomic Increment
+    ////////////////////////////////////////////////////////////////////////////
+
+
+    template atomicIncrement( msync ms = msync.seq, T )
+    {
+        //
+        // NOTE: This operation is only valid for integer or pointer types
+        //
+        static assert( isValidNumericType!(T) );
+
+
+        T atomicIncrement( ref T val )
+        {
+            static if (isPointerType!(T))
+            {
+                llvm_atomic_load_add!(size_t)(cast(size_t*)&val, 1);
+            }
+            else
+            {
+                llvm_atomic_load_add!(T)(&val, cast(T)1);
+            }
+            return val;
+        }
+    }
+    
+    
+    ////////////////////////////////////////////////////////////////////////////
+    // Atomic Decrement
+    ////////////////////////////////////////////////////////////////////////////
+
+
+    template atomicDecrement( msync ms = msync.seq, T )
+    {
+        //
+        // NOTE: This operation is only valid for integer or pointer types
+        //
+        static assert( isValidNumericType!(T) );
+
+
+        T atomicDecrement( ref T val )
+        {
+            static if (isPointerType!(T))
+            {
+                llvm_atomic_load_sub!(size_t)(cast(size_t*)&val, 1);
+            }
+            else
+            {
+                llvm_atomic_load_sub!(T)(&val, cast(T)1);
+            }
+            return val;
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // x86 Atomic Function Implementation
 ////////////////////////////////////////////////////////////////////////////////
 
Index: tango/math/IEEE.d
===================================================================
--- tango/math/IEEE.d	(revision 4145)
+++ tango/math/IEEE.d	(working copy)
@@ -1554,7 +1554,12 @@
         return (bitsdiff == 0 && !((pa[F.EXPPOS_SHORT] ^ pb[F.EXPPOS_SHORT])& F.EXPMASK)) ? 1 : 0;
      }
  } else {
-    assert(0, "Unsupported");
+     static if (is(X==real)){
+         static assert(0, X.stringof~" unsupported by feqrel");
+     } else {
+         int res=feqrel(cast(real)x,cast(real)y);
+         return ((res>X.mant_dig)?X.mant_dig:res);
+     }
  }
 }
 
Index: tango/math/Math.d
===================================================================
--- tango/math/Math.d	(revision 4145)
+++ tango/math/Math.d	(working copy)
@@ -76,6 +76,14 @@
         version = DigitalMars_D_InlineAsm_X86;
     }
 }
+else version(LDC)
+{
+    import ldc.intrinsics;
+    version(X86)
+    {
+        version = LDC_X86;
+    }
+}
 
 /*
  * Constants
@@ -298,6 +306,24 @@
  * Bugs:
  *  Results are undefined if |x| >= $(POWER 2,64).
  */
+version(LDC)
+{
+    alias llvm_cos_f32 cos;
+    alias llvm_cos_f64 cos;
+    version(X86)
+    {
+        alias llvm_cos_f80 cos;
+    }
+    else
+    {
+        real cos(real x)
+        {
+            return tango.stdc.math.cosl(x);
+        }
+    }
+}
+else
+{
 real cos(real x) /* intrinsic */
 {
     version(D_InlineAsm_X86)
@@ -313,6 +339,7 @@
         return tango.stdc.math.cosl(x);
     }
 }
+}
 
 debug(UnitTest) {
 unittest {
@@ -333,6 +360,24 @@
  * Bugs:
  *  Results are undefined if |x| >= $(POWER 2,64).
  */
+version(LDC)
+{
+    alias llvm_sin_f32 sin;
+    alias llvm_sin_f64 sin;
+    version(X86)
+    {
+        alias llvm_sin_f80 sin;
+    }
+    else
+    {
+        real sin(real x)
+        {
+            return tango.stdc.math.sinl(x);
+        }
+    }
+}
+else
+{
 real sin(real x) /* intrinsic */
 {
     version(D_InlineAsm_X86)
@@ -348,6 +393,7 @@
         return tango.stdc.math.sinl(x);
     }
 }
+}
 
 debug(UnitTest) {
 unittest {
@@ -374,7 +420,11 @@
 {
     version (GNU) {
         return tanl(x);
-    } else {
+    }
+    else version(LDC) {
+        return tango.stdc.math.tanl(x);
+    }
+    else {
     asm
     {
         fld x[EBP]      ; // load theta
@@ -947,6 +997,25 @@
  *  <tr> <td> +&infin; <td> +&infin; <td> no
  *  )
  */
+version(LDC)
+{
+    alias llvm_sqrt_f32 sqrt;
+    alias llvm_sqrt_f64 sqrt;
+    version(X86)
+    {
+        alias llvm_sqrt_f80 sqrt;
+    }
+    else
+    {
+        real sqrt(real x)
+        {
+            return tango.stdc.math.sqrtl(x);
+        }
+    }
+}
+else
+{
+
 float sqrt(float x) /* intrinsic */
 {
     version(D_InlineAsm_X86)
@@ -995,6 +1064,8 @@
     }
 }
 
+}
+
 /** ditto */
 creal sqrt(creal z)
 {
@@ -1477,7 +1548,14 @@
         }
     }
     }
-    return tango.stdc.math.powl(x, y);
+    version(LDC_X86)
+    {
+        return llvm_pow_f80(x, y);
+    }
+    else
+    {
+        return tango.stdc.math.powl(x, y);
+    }
 }
 
 debug(UnitTest) {
Index: tango/stdc/posix/sys/types.d
===================================================================
--- tango/stdc/posix/sys/types.d	(revision 4145)
+++ tango/stdc/posix/sys/types.d	(working copy)
@@ -422,7 +422,11 @@
 }
 else version( darwin )
 {
-    struct pthread_spinlock_t;
+    version (LDC)
+        alias void* pthread_spinlock_t;
+        
+    else
+        struct pthread_spinlock_t;
 }
 else version( freebsd )
 {
Index: tango/stdc/stdlib.d
===================================================================
--- tango/stdc/stdlib.d	(revision 4145)
+++ tango/stdc/stdlib.d	(working copy)
@@ -94,6 +94,11 @@
 {
     void* alloca(size_t size);
 }
+else version( LDC )
+{
+    pragma(alloca)
+        void* alloca(size_t size);
+}
 else version( GNU )
 {
     private import gcc.builtins;
Index: tango/stdc/stdarg.d
===================================================================
--- tango/stdc/stdarg.d	(revision 4145)
+++ tango/stdc/stdarg.d	(working copy)
@@ -13,6 +13,10 @@
 {
     public import std.c.stdarg;
 }
+else version( LDC )
+{
+    public import ldc.cstdarg;
+}
 else
 {
     alias void* va_list;