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: