comparison 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
comparison
equal deleted inserted replaced
54:28e99b04a132 55:0ccfae271c45
27 #include "expression.h" 27 #include "expression.h"
28 #include "dsymbol.h" 28 #include "dsymbol.h"
29 #include "aggregate.h" 29 #include "aggregate.h"
30 #include "module.h" 30 #include "module.h"
31 #include "parse.h" 31 #include "parse.h"
32 #include "template.h"
32 33
33 #include "../gen/enums.h" 34 #include "../gen/enums.h"
35 #include "../gen/logger.h"
34 36
35 extern void obj_includelib(char *name); 37 extern void obj_includelib(char *name);
36 38
37 39
38 /********************************* AttribDeclaration ****************************/ 40 /********************************* AttribDeclaration ****************************/
750 { // Should be merged with PragmaStatement 752 { // Should be merged with PragmaStatement
751 753
752 #if IN_LLVM 754 #if IN_LLVM
753 int llvm_internal = 0; 755 int llvm_internal = 0;
754 char* llvm_str1 = NULL; 756 char* llvm_str1 = NULL;
755 757
756 #endif 758 #endif
757 759
758 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); 760 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
759 if (ident == Id::msg) 761 if (ident == Id::msg)
760 { 762 {
761 if (args) 763 if (args)
762 { 764 {
871 } 873 }
872 else if (strcmp(str,"bind")==0) { 874 else if (strcmp(str,"bind")==0) {
873 llvm_internal = LLVMbind; 875 llvm_internal = LLVMbind;
874 assert(args->dim == 2); 876 assert(args->dim == 2);
875 } 877 }
878 else if (strcmp(str,"va_start")==0) {
879 llvm_internal = LLVMva_start;
880 assert(args->dim == 1);
881 }
882 else if (strcmp(str,"va_arg")==0) {
883 llvm_internal = LLVMva_arg;
884 assert(args->dim == 1);
885 }
886 else if (strcmp(str,"va_intrinsic")==0) {
887 llvm_internal = LLVMva_intrinsic;
888 assert(args->dim == 2);
889 }
876 else { 890 else {
877 error("unknown pragma command: %s", str); 891 error("unknown pragma command: %s", str);
878 } 892 }
879 } 893 }
880 else 894 else
884 switch (llvm_internal) 898 switch (llvm_internal)
885 { 899 {
886 case LLVMintrinsic: 900 case LLVMintrinsic:
887 case LLVMmangle: 901 case LLVMmangle:
888 case LLVMbind: 902 case LLVMbind:
903 case LLVMva_intrinsic:
889 e = (Expression *)args->data[1]; 904 e = (Expression *)args->data[1];
890 e = e->semantic(sc); 905 e = e->semantic(sc);
891 e = e->optimize(WANTvalue); 906 e = e->optimize(WANTvalue);
892 if (e->op == TOKstring && (s = (StringExp *)e)) { 907 if (e->op == TOKstring && (s = (StringExp *)e)) {
893 llvm_str1 = (char*)s->string; 908 llvm_str1 = (char*)s->string;
895 else 910 else
896 error("2nd argument must be a string"); 911 error("2nd argument must be a string");
897 break; 912 break;
898 913
899 case LLVMnull: 914 case LLVMnull:
915 case LLVMva_arg:
916 case LLVMva_start:
900 break; 917 break;
901 918
902 default: 919 default:
903 assert(0); 920 assert(0);
904 } 921 }
921 { 938 {
922 switch(llvm_internal) 939 switch(llvm_internal)
923 { 940 {
924 case LLVMintrinsic: 941 case LLVMintrinsic:
925 case LLVMmangle: 942 case LLVMmangle:
943 case LLVMva_intrinsic:
926 if (FuncDeclaration* fd = s->isFuncDeclaration()) { 944 if (FuncDeclaration* fd = s->isFuncDeclaration()) {
927 fd->llvmInternal = llvm_internal; 945 fd->llvmInternal = llvm_internal;
928 fd->llvmInternal1 = llvm_str1; 946 fd->llvmInternal1 = llvm_str1;
929 } 947 }
930 else { 948 else {
931 error("may only be used on function declarations"); 949 error("may only be used on function declarations");
932 assert(0); 950 assert(0);
933 } 951 }
934 break; 952 break;
935 953
936 case LLVMnull: 954 case LLVMnull:
937 if (StaticCtorDeclaration* sd = s->isStaticCtorDeclaration()) { 955 if (StaticCtorDeclaration* sd = s->isStaticCtorDeclaration()) {
938 sd->llvmInternal = llvm_internal; 956 sd->llvmInternal = llvm_internal;
939 } 957 }
940 else { 958 else {
941 error("may only be used on static constructors"); 959 error("may only be used on static constructors");
942 assert(0); 960 assert(0);
943 } 961 }
944 break; 962 break;
945 963
946 case LLVMbind: 964 case LLVMbind:
947 if (VarDeclaration* vd = s->isVarDeclaration()) { 965 if (VarDeclaration* vd = s->isVarDeclaration()) {
948 vd->llvmInternal = llvm_internal; 966 vd->llvmInternal = llvm_internal;
949 vd->llvmInternal1 = llvm_str1; 967 vd->llvmInternal1 = llvm_str1;
950 } 968 }
951 else { 969 else {
952 error("may only be used on var declarations"); 970 error("may only be used on var declarations");
953 assert(0); 971 assert(0);
954 } 972 }
955 break; 973 break;
956 974
975 case LLVMva_start:
976 case LLVMva_arg:
977 if (TemplateDeclaration* td = s->isTemplateDeclaration()) {
978 td->llvmInternal = llvm_internal;
979 assert(td->parameters->dim == 1);
980 assert(!td->overnext);
981 assert(!td->overroot);
982 assert(td->onemember);
983 Logger::println("template->onemember = %s", td->onemember->toChars());
984 }
985 else {
986 error("can only be used on templates");
987 assert(0);
988 }
989 break;
990
957 default: 991 default:
958 assert(0 && "invalid LLVM_internal pragma got through :/"); 992 assert(0 && "invalid LLVM_internal pragma got through :/");
959 } 993 }
960 } 994 }
961 995