diff dmd/attrib.c @ 55:0ccfae271c45 trunk

[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown. Updates to runtime. Rebuild!
author lindquist
date Wed, 24 Oct 2007 22:18:06 +0200
parents 788401029ecf
children b706170e24a9
line wrap: on
line diff
--- a/dmd/attrib.c	Wed Oct 24 01:37:34 2007 +0200
+++ b/dmd/attrib.c	Wed Oct 24 22:18:06 2007 +0200
@@ -29,8 +29,10 @@
 #include "aggregate.h"
 #include "module.h"
 #include "parse.h"
+#include "template.h"
 
 #include "../gen/enums.h"
+#include "../gen/logger.h"
 
 extern void obj_includelib(char *name);
 
@@ -752,9 +754,9 @@
 #if IN_LLVM
     int llvm_internal = 0;
     char* llvm_str1 = NULL;
-    
+
 #endif
-    
+
     //printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
     if (ident == Id::msg)
     {
@@ -873,6 +875,18 @@
                     llvm_internal = LLVMbind;
                     assert(args->dim == 2);
                 }
+                else if (strcmp(str,"va_start")==0) {
+                    llvm_internal = LLVMva_start;
+                    assert(args->dim == 1);
+                }
+                else if (strcmp(str,"va_arg")==0) {
+                    llvm_internal = LLVMva_arg;
+                    assert(args->dim == 1);
+                }
+                else if (strcmp(str,"va_intrinsic")==0) {
+                    llvm_internal = LLVMva_intrinsic;
+                    assert(args->dim == 2);
+                }
                 else {
                     error("unknown pragma command: %s", str);
                 }
@@ -886,6 +900,7 @@
             case LLVMintrinsic:
             case LLVMmangle:
             case LLVMbind:
+            case LLVMva_intrinsic:
                 e = (Expression *)args->data[1];
                 e = e->semantic(sc);
                 e = e->optimize(WANTvalue);
@@ -897,6 +912,8 @@
                 break;
             
             case LLVMnull:
+            case LLVMva_arg:
+            case LLVMva_start:
                 break;
             
             default:
@@ -923,6 +940,7 @@
             {
             case LLVMintrinsic:
             case LLVMmangle:
+            case LLVMva_intrinsic:
                 if (FuncDeclaration* fd = s->isFuncDeclaration()) {
                     fd->llvmInternal = llvm_internal;
                     fd->llvmInternal1 = llvm_str1;
@@ -932,7 +950,7 @@
                     assert(0);
                 }
                 break;
-            
+
             case LLVMnull:
                 if (StaticCtorDeclaration* sd = s->isStaticCtorDeclaration()) {
                     sd->llvmInternal = llvm_internal;
@@ -942,7 +960,7 @@
                     assert(0);
                 }
                 break;
-            
+
             case LLVMbind:
                 if (VarDeclaration* vd = s->isVarDeclaration()) {
                     vd->llvmInternal = llvm_internal;
@@ -953,7 +971,23 @@
                     assert(0);
                 }
                 break;
-            
+
+            case LLVMva_start:
+            case LLVMva_arg:
+                if (TemplateDeclaration* td = s->isTemplateDeclaration()) {
+                    td->llvmInternal = llvm_internal;
+                    assert(td->parameters->dim == 1);
+                    assert(!td->overnext);
+                    assert(!td->overroot);
+                    assert(td->onemember);
+                    Logger::println("template->onemember = %s", td->onemember->toChars());
+                }
+                else {
+                    error("can only be used on templates");
+                    assert(0);
+                }
+                break;
+
             default:
                 assert(0 && "invalid LLVM_internal pragma got through :/");
             }