Mercurial > projects > ldc
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 |