view runtime/ldc.diff @ 715:30b42a283c8e

Removed TypeOpaque from DMD. Changed runtime functions taking opaque[] to void[]. Implemented proper type painting, to avoid "resizing" array casts in runtime calls that previously took opaque[]. Implemented dynamic arrays as first class types, this implements proper ABI for these types on x86. Added dwarf region end after call to assert function, fixes some problems with llvm not allowing this to be missing. Reverted change to WithStatement from rev [704] it breaks MiniD, mini/with2.d needs to be fixed some other way... Fixed tango bug 1339 in runtime, problem with _adReverseChar on invalid UTF-8. Disabled .bc generation in the compiler runtime part, genobj.d triggers some llvm bug when using debug info. the .o seems to work fine.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 22 Oct 2008 14:55:33 +0200
parents f0ba5d37dd86
children f34b552619fd
line wrap: on
line source

Index: object.di
===================================================================
--- object.di	(revision 4002)
+++ object.di	(working copy)
@@ -150,6 +150,9 @@
     void function() dtor;
     void function() unitTest;
 
+    void* xgetMembers;
+    void function() ictor;
+
     static int opApply( int delegate( inout ModuleInfo ) );
 }
 
Index: lib/common/tango/core/BitManip.d
===================================================================
--- lib/common/tango/core/BitManip.d	(revision 4002)
+++ 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 4002)
+++ lib/common/tango/core/Thread.d	(working copy)
@@ -235,6 +235,7 @@
         // used to track the number of suspended threads
         //
         sem_t   suspendCount;
+        sem_t*  suspendCountPtr;
 
 
         extern (C) void thread_suspendHandler( int sig )
@@ -244,8 +245,29 @@
         }
         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
+                {
+                    static assert( false, "Architecture not supported." );
+                }
+            }
+            else version( D_InlineAsm_X86 )
+            {
                 asm
                 {
                     pushad;
@@ -286,7 +308,7 @@
                 status = sigdelset( &sigres, SIGUSR2 );
                 assert( status == 0 );
 
-                status = sem_post( &suspendCount );
+                status = sem_post( suspendCountPtr );
                 assert( status == 0 );
 
                 sigsuspend( &sigres );
@@ -297,8 +319,12 @@
                 }
             }
 
-            version( D_InlineAsm_X86 )
+            version( LDC)
             {
+                // nothing to pop
+            }
+            else version( D_InlineAsm_X86 )
+            {
                 asm
                 {
                     popad;
@@ -1572,8 +1598,14 @@
         status = sigaction( SIGUSR2, &sigusr2, null );
         assert( status == 0 );
 
-        status = sem_init( &suspendCount, 0, 0 );
-        assert( status == 0 );
+        version(darwin){
+            suspendCountPtr = sem_open( "/thread_init/sem\0".ptr, 0 );
+            assert( suspendCountPtr !is null );
+        }else {
+            status=sem_init(&suspendCount,0,0);
+            suspendCountPtr=&suspendCount;
+            assert(status==0);
+        }
 
         status = pthread_key_create( &Thread.sm_this, null );
         assert( status == 0 );
@@ -1781,7 +1813,7 @@
                 //       to simply loop on sem_wait at the end, but I'm not
                 //       convinced that this would be much faster than the
                 //       current approach.
-                sem_wait( &suspendCount );
+                sem_wait( suspendCountPtr );
             }
             else if( !t.m_lock )
             {
@@ -2286,6 +2318,13 @@
             version = AsmPPC_Posix;
     }
 
+    version( LLVM_InlineAsm_X86 )
+    {
+        version( Win32 )
+            version = LLVM_AsmX86_Win32;
+        else version( Posix )
+            version = LLVM_AsmX86_Posix;
+    }
 
     version( Posix )
     {
@@ -2296,6 +2328,8 @@
         version( AsmX86_Win32 ) {} else
         version( AsmX86_Posix ) {} else
         version( AsmPPC_Posix ) {} else
+        version( LLVM_AsmX86_Win32 ) {} else
+        version( LLVM_AsmX86_Posix ) {} else
         {
             // NOTE: The ucontext implementation requires architecture specific
             //       data definitions to operate so testing for it must be done
@@ -2306,10 +2340,10 @@
             import tango.stdc.posix.ucontext;
         }
     }
-
-    const size_t PAGESIZE;
 }
 
+// this can't be private since it's used as default argument to a public function
+const size_t PAGESIZE;
 
 static this()
 {
@@ -2336,7 +2370,7 @@
     }
 }
 
-
+extern(C) int printf(char*, ...);
 ////////////////////////////////////////////////////////////////////////////////
 // Fiber Entry Point and Context Switch
 ////////////////////////////////////////////////////////////////////////////////
@@ -2450,6 +2484,22 @@
                 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;
+            }
+        }
         else static if( is( ucontext_t ) )
         {
             Fiber   cfib = Fiber.getThis();
@@ -3115,6 +3165,16 @@
             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
+        }
         else version( AsmPPC_Posix )
         {
             version( StackGrowsDown )
Index: lib/unittest.sh
===================================================================
--- lib/unittest.sh	(revision 4002)
+++ 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 4002)
+++ 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,28 @@
             __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
+            {
+                static assert( false, "Architecture not supported." );
+            }
+        }
         else
         {
         asm
@@ -2191,6 +2213,10 @@
         {
             // nothing to do
         }
+        else version(LDC)
+        {
+            // nothing to do
+        }
         else
         {
         asm
Index: lib/gc/basic/gcbits.d
===================================================================
--- lib/gc/basic/gcbits.d	(revision 4002)
+++ 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 4002)
+++ 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 4002)
+++ 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;
@@ -197,9 +203,18 @@
                 assert (formatStr, "null format specifier");
                 assert (arguments.length < 64, "too many args in Layout.convert");
 
-                version (GNU)
+                version (LDC)
                         {
                         Arg[64] arglist = void;
+                        foreach (i, arg; arguments)
+                                {
+                                arglist[i] = args;
+                                args += (arg.tsize + size_t.sizeof - 1) & ~ (size_t.sizeof - 1);
+                                }
+                        }
+                else version (GNU)
+                        {
+                        Arg[64] arglist = void;
                         int[64] intargs = void;
                         byte[64] byteargs = void;
                         long[64] longargs = void;
Index: tango/net/cluster/CacheInvalidator.d
===================================================================
--- tango/net/cluster/CacheInvalidator.d	(revision 4002)
+++ 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 4002)
+++ 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 3979)
+++ tango/core/sync/Semaphore.d	(working copy)
@@ -329,7 +329,8 @@
             {
                 synchronized( synComplete )
                 {
-                    if( numComplete == numConsumers )
+                    // if( numComplete == numConsumers )
+                    if( numComplete == numToProduce )
                         break;
                 }
                 Thread.yield();
@@ -337,9 +338,9 @@
 
             synchronized( synComplete )
             {
-                assert( numComplete == numConsumers );
+                assert( numComplete == numToProduce );
+                // assert( numComplete == numConsumers );
             }
-
             synchronized( synConsumed )
             {
                 assert( numConsumed == numToProduce );
@@ -400,7 +401,8 @@
 
     unittest
     {
+        version(darwin){}else{
         testWait();
-        testWaitTimeout();
+        testWaitTimeout();}
     }
 }
Index: tango/core/sync/Condition.d
===================================================================
--- tango/core/sync/Condition.d	(revision 3979)
+++ 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 4002)
+++ 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
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -282,9 +598,9 @@
         {
             pragma( msg, "tango.core.Atomic: using IA-32 inline asm" );
         }
-
+        version(darwin){}
+        else { version = Has64BitCAS; }
         version = Has32BitOps;
-        version = Has64BitCAS;
     }
     version( X86_64 )
     {
Index: tango/math/IEEE.d
===================================================================
--- tango/math/IEEE.d	(revision 3979)
+++ tango/math/IEEE.d	(working copy)
@@ -1543,7 +1543,12 @@
         else return 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 4002)
+++ 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 3979)
+++ 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 4002)
+++ 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 4002)
+++ 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;