Mercurial > projects > ldc
comparison dmd/attrib.c @ 443:44f08170f4ef
Removed tango from the repository and instead added a runtime dir with the files needed to patch and build tango from svn.
Reworked the LLVMDC specific pragmas.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Fri, 01 Aug 2008 00:32:06 +0200 |
parents | aaade6ded589 |
children | cc40db549aea |
comparison
equal
deleted
inserted
replaced
442:76078c8ab5b9 | 443:44f08170f4ef |
---|---|
700 return (char *)(isunion ? "anonymous union" : "anonymous struct"); | 700 return (char *)(isunion ? "anonymous union" : "anonymous struct"); |
701 } | 701 } |
702 | 702 |
703 /********************************* PragmaDeclaration ****************************/ | 703 /********************************* PragmaDeclaration ****************************/ |
704 | 704 |
705 static bool parseStringExp(Expression* e, std::string& res) | |
706 { | |
707 StringExp *s = NULL; | |
708 | |
709 e = e->optimize(WANTvalue); | |
710 if (e->op == TOKstring && (s = (StringExp *)e)) | |
711 { | |
712 char* str = (char*)s->string; | |
713 res = str; | |
714 return true; | |
715 } | |
716 return false; | |
717 } | |
718 | |
705 PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl) | 719 PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl) |
706 : AttribDeclaration(decl) | 720 : AttribDeclaration(decl) |
707 { | 721 { |
708 this->loc = loc; | 722 this->loc = loc; |
709 this->ident = ident; | 723 this->ident = ident; |
723 void PragmaDeclaration::semantic(Scope *sc) | 737 void PragmaDeclaration::semantic(Scope *sc) |
724 { // Should be merged with PragmaStatement | 738 { // Should be merged with PragmaStatement |
725 | 739 |
726 #if IN_LLVM | 740 #if IN_LLVM |
727 int llvm_internal = 0; | 741 int llvm_internal = 0; |
728 char* llvm_str1 = NULL; | 742 std::string arg1str; |
729 | 743 |
730 #endif | 744 #endif |
731 | 745 |
732 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); | 746 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); |
733 if (ident == Id::msg) | 747 if (ident == Id::msg) |
811 d->c_ident = Lexer::idPool((char*) s->string); | 825 d->c_ident = Lexer::idPool((char*) s->string); |
812 } | 826 } |
813 goto Lnodecl; | 827 goto Lnodecl; |
814 } | 828 } |
815 #endif | 829 #endif |
830 | |
831 // LLVMDC | |
816 #if IN_LLVM | 832 #if IN_LLVM |
817 else if (ident == Id::LLVM_internal) | 833 |
818 { | 834 // pragma(intrinsic, dotExpS) { funcdecl(s) } |
819 if (!args || args->dim < 1 || args->dim > 2) | 835 else if (ident == Id::intrinsic) |
820 error("needs 1-3 parameters"); | 836 { |
821 else if (!decl || decl->dim < 1) | 837 Expression* expr = (Expression *)args->data[0]; |
822 error("must apply to at least one declaration"); | 838 expr = expr->semantic(sc); |
823 else | 839 if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) |
824 { | 840 { |
825 Expression *e; | 841 error("pragma intrinsic requires exactly 1 string literal parameter"); |
826 StringExp *s = NULL; | 842 fatal(); |
827 | |
828 e = (Expression *)args->data[0]; | |
829 e = e->semantic(sc); | |
830 e = e->optimize(WANTvalue); | |
831 if (e->op == TOKstring && (s = (StringExp *)e)) | |
832 { | |
833 char* str = (char*)s->string; | |
834 if (strcmp(str,"intrinsic")==0) { | |
835 llvm_internal = LLVMintrinsic; | |
836 assert(args->dim == 2); | |
837 } | |
838 else if (strcmp(str,"va_start")==0) { | |
839 llvm_internal = LLVMva_start; | |
840 assert(args->dim == 1); | |
841 } | |
842 else if (strcmp(str,"va_arg")==0) { | |
843 llvm_internal = LLVMva_arg; | |
844 assert(args->dim == 1); | |
845 } | |
846 else if (strcmp(str,"va_intrinsic")==0) { | |
847 llvm_internal = LLVMva_intrinsic; | |
848 assert(args->dim == 2); | |
849 } | |
850 else if (strcmp(str,"notypeinfo")==0) { | |
851 llvm_internal = LLVMnotypeinfo; | |
852 assert(args->dim == 1); | |
853 } | |
854 else if (strcmp(str,"alloca")==0) { | |
855 llvm_internal = LLVMalloca; | |
856 assert(args->dim == 1); | |
857 } | |
858 else { | |
859 error("unknown pragma command: %s", str); | |
860 } | |
861 } | |
862 else | |
863 error("1st argument must be a string"); | |
864 | |
865 if (llvm_internal) | |
866 switch (llvm_internal) | |
867 { | |
868 case LLVMintrinsic: | |
869 case LLVMva_intrinsic: | |
870 e = (Expression *)args->data[1]; | |
871 e = e->semantic(sc); | |
872 e = e->optimize(WANTvalue); | |
873 if (e->op == TOKstring && (s = (StringExp *)e)) { | |
874 llvm_str1 = (char*)s->string; | |
875 } | |
876 else | |
877 error("2nd argument must be a string"); | |
878 break; | |
879 | |
880 case LLVMva_arg: | |
881 case LLVMva_start: | |
882 case LLVMnotypeinfo: | |
883 case LLVMalloca: | |
884 break; | |
885 | |
886 default: | |
887 assert(0); | |
888 } | |
889 } | 843 } |
890 } | 844 llvm_internal = LLVMintrinsic; |
891 #endif | 845 } |
846 | |
847 // pragma(va_intrinsic, dotExpS) { funcdecl(s) } | |
848 else if (ident == Id::va_intrinsic) | |
849 { | |
850 Expression* expr = (Expression *)args->data[0]; | |
851 expr = expr->semantic(sc); | |
852 if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) | |
853 { | |
854 error("pragma va_intrinsic requires exactly 1 string literal parameter"); | |
855 fatal(); | |
856 } | |
857 llvm_internal = LLVMva_intrinsic; | |
858 } | |
859 | |
860 // pragma(notypeinfo) { typedecl(s) } | |
861 else if (ident == Id::no_typeinfo) | |
862 { | |
863 if (args && args->dim > 0) | |
864 { | |
865 error("pragma no_typeinfo takes no parameters"); | |
866 fatal(); | |
867 } | |
868 llvm_internal = LLVMno_typeinfo; | |
869 } | |
870 | |
871 // pragma(nomoduleinfo) ; | |
872 else if (ident == Id::no_moduleinfo) | |
873 { | |
874 if (args && args->dim > 0) | |
875 { | |
876 error("pragma no_moduleinfo takes no parameters"); | |
877 fatal(); | |
878 } | |
879 llvm_internal = LLVMno_moduleinfo; | |
880 } | |
881 | |
882 // pragma(alloca) { funcdecl(s) } | |
883 else if (ident == Id::alloca) | |
884 { | |
885 if (args && args->dim > 0) | |
886 { | |
887 error("pragma alloca takes no parameters"); | |
888 fatal(); | |
889 } | |
890 llvm_internal = LLVMalloca; | |
891 } | |
892 | |
893 // pragma(va_start) { templdecl(s) } | |
894 else if (ident == Id::va_start) | |
895 { | |
896 if (args && args->dim > 0) | |
897 { | |
898 error("pragma va_start takes no parameters"); | |
899 fatal(); | |
900 } | |
901 llvm_internal = LLVMva_start; | |
902 } | |
903 | |
904 // pragma(va_arg) { templdecl(s) } | |
905 else if (ident == Id::va_arg) | |
906 { | |
907 if (args && args->dim > 0) | |
908 { | |
909 error("pragma va_arg takes no parameters"); | |
910 fatal(); | |
911 } | |
912 llvm_internal = LLVMva_arg; | |
913 } | |
914 | |
915 #endif // LLVMDC | |
916 | |
892 else if (global.params.ignoreUnsupportedPragmas) | 917 else if (global.params.ignoreUnsupportedPragmas) |
893 { | 918 { |
894 if (global.params.verbose) | 919 if (global.params.verbose) |
895 { | 920 { |
896 /* Print unrecognized pragmas | 921 /* Print unrecognized pragmas |
924 for (unsigned i = 0; i < decl->dim; i++) | 949 for (unsigned i = 0; i < decl->dim; i++) |
925 { | 950 { |
926 Dsymbol *s = (Dsymbol *)decl->data[i]; | 951 Dsymbol *s = (Dsymbol *)decl->data[i]; |
927 | 952 |
928 s->semantic(sc); | 953 s->semantic(sc); |
929 | 954 |
955 // LLVMDC | |
930 #if IN_LLVM | 956 #if IN_LLVM |
957 | |
931 if (llvm_internal) | 958 if (llvm_internal) |
932 { | 959 { |
933 switch(llvm_internal) | 960 if (s->llvmInternal) |
961 { | |
962 error("multiple LLVMDC specific pragmas not allowed not affect the same declaration (%s at '%s')", s->toChars(), s->loc.toChars()); | |
963 fatal(); | |
964 } | |
965 switch(llvm_internal) | |
966 { | |
967 case LLVMintrinsic: | |
968 case LLVMva_intrinsic: | |
969 if (FuncDeclaration* fd = s->isFuncDeclaration()) | |
934 { | 970 { |
935 case LLVMintrinsic: | 971 fd->llvmInternal = llvm_internal; |
936 case LLVMva_intrinsic: | 972 fd->intrinsicName = arg1str; |
937 if (FuncDeclaration* fd = s->isFuncDeclaration()) { | 973 } |
938 fd->llvmInternal = llvm_internal; | 974 else |
939 fd->llvmInternal1 = llvm_str1; | 975 { |
976 error("intrinsic pragmas are only allowed to affect function declarations"); | |
977 fatal(); | |
978 } | |
979 break; | |
980 | |
981 case LLVMva_start: | |
982 case LLVMva_arg: | |
983 if (TemplateDeclaration* td = s->isTemplateDeclaration()) | |
984 { | |
985 if (td->parameters->dim != 1) | |
986 { | |
987 error("the %s pragma template must have exactly one template parameter", ident->toChars()); | |
988 fatal(); | |
940 } | 989 } |
941 else { | 990 else if (!td->onemember) |
942 error("may only be used on function declarations"); | 991 { |
943 assert(0); | 992 error("the %s pragma template must have exactly one member", ident->toChars()); |
993 fatal(); | |
944 } | 994 } |
945 break; | 995 else if (td->overnext || td->overroot) |
946 | 996 { |
947 case LLVMva_start: | 997 error("the %s pragma template must not be overloaded", ident->toChars()); |
948 case LLVMva_arg: | 998 fatal(); |
949 if (TemplateDeclaration* td = s->isTemplateDeclaration()) { | |
950 td->llvmInternal = llvm_internal; | |
951 assert(td->parameters->dim == 1); | |
952 assert(!td->overnext); | |
953 assert(!td->overroot); | |
954 assert(td->onemember); | |
955 Logger::println("template->onemember = %s", td->onemember->toChars()); | |
956 } | 999 } |
957 else { | 1000 td->llvmInternal = llvm_internal; |
958 error("can only be used on templates"); | |
959 assert(0); | |
960 } | |
961 break; | |
962 | |
963 case LLVMnotypeinfo: | |
964 s->llvmInternal = llvm_internal; | |
965 break; | |
966 | |
967 case LLVMalloca: | |
968 if (FuncDeclaration* fd = s->isFuncDeclaration()) { | |
969 fd->llvmInternal = llvm_internal; | |
970 } | |
971 else { | |
972 error("may only be used on function declarations"); | |
973 assert(0); | |
974 } | |
975 break; | |
976 | |
977 default: | |
978 assert(0 && "invalid LLVM_internal pragma got through :/"); | |
979 } | 1001 } |
1002 else | |
1003 { | |
1004 error("the %s pragma is only allowed on template declarations", ident->toChars()); | |
1005 fatal(); | |
1006 } | |
1007 break; | |
1008 | |
1009 case LLVMno_typeinfo: | |
1010 s->llvmInternal = llvm_internal; | |
1011 break; | |
1012 | |
1013 case LLVMalloca: | |
1014 if (FuncDeclaration* fd = s->isFuncDeclaration()) | |
1015 { | |
1016 fd->llvmInternal = llvm_internal; | |
1017 } | |
1018 else | |
1019 { | |
1020 error("the %s pragma must only be used on function declarations of type 'void* function(uint nbytes)'", ident->toChars()); | |
1021 fatal(); | |
1022 } | |
1023 break; | |
1024 | |
1025 default: | |
1026 warning("LLVMDC specific pragma %s not yet implemented, ignoring", ident->toChars()); | |
980 } | 1027 } |
981 | 1028 } |
982 #endif | 1029 |
1030 #endif // LLVMDC | |
1031 | |
983 } | 1032 } |
984 } | 1033 } |
985 return; | 1034 return; |
986 | 1035 |
987 Lnodecl: | 1036 Lnodecl: |