LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "go.h" | 7 #include "go.h" |
8 #include "md5.h" | 8 #include "md5.h" |
9 #include "y.tab.h" | 9 #include "y.tab.h" |
10 #include "opnames.h" | |
11 #include "yerr.h" | 10 #include "yerr.h" |
12 | |
13 static void dodump(Node*, int); | |
14 | 11 |
15 typedef struct Error Error; | 12 typedef struct Error Error; |
16 struct Error | 13 struct Error |
17 { | 14 { |
18 int lineno; | 15 int lineno; |
19 int seq; | 16 int seq; |
20 char *msg; | 17 char *msg; |
21 }; | 18 }; |
22 static Error *err; | 19 static Error *err; |
23 static int nerr; | 20 static int nerr; |
(...skipping 16 matching lines...) Expand all Loading... |
40 return prevlineno; | 37 return prevlineno; |
41 return lineno; | 38 return lineno; |
42 } | 39 } |
43 | 40 |
44 static void | 41 static void |
45 adderr(int line, char *fmt, va_list arg) | 42 adderr(int line, char *fmt, va_list arg) |
46 { | 43 { |
47 Fmt f; | 44 Fmt f; |
48 Error *p; | 45 Error *p; |
49 | 46 |
50 erroring++; | |
51 fmtstrinit(&f); | 47 fmtstrinit(&f); |
52 fmtprint(&f, "%L: ", line); | 48 fmtprint(&f, "%L: ", line); |
53 fmtvprint(&f, fmt, arg); | 49 fmtvprint(&f, fmt, arg); |
54 fmtprint(&f, "\n"); | 50 fmtprint(&f, "\n"); |
55 erroring--; | |
56 | 51 |
57 if(nerr >= merr) { | 52 if(nerr >= merr) { |
58 if(merr == 0) | 53 if(merr == 0) |
59 merr = 16; | 54 merr = 16; |
60 else | 55 else |
61 merr *= 2; | 56 merr *= 2; |
62 p = realloc(err, merr*sizeof err[0]); | 57 p = realloc(err, merr*sizeof err[0]); |
63 if(p == nil) { | 58 if(p == nil) { |
64 merr = nerr; | 59 merr = nerr; |
65 flusherrors(); | 60 flusherrors(); |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 } | 715 } |
721 } | 716 } |
722 | 717 |
723 // fixed array | 718 // fixed array |
724 r = typ(TARRAY); | 719 r = typ(TARRAY); |
725 r->type = t; | 720 r->type = t; |
726 r->bound = bound; | 721 r->bound = bound; |
727 return r; | 722 return r; |
728 } | 723 } |
729 | 724 |
730 static void | |
731 indent(int dep) | |
732 { | |
733 int i; | |
734 | |
735 for(i=0; i<dep; i++) | |
736 print(". "); | |
737 } | |
738 | |
739 static void | |
740 dodumplist(NodeList *l, int dep) | |
741 { | |
742 for(; l; l=l->next) | |
743 dodump(l->n, dep); | |
744 } | |
745 | |
746 static void | |
747 dodump(Node *n, int dep) | |
748 { | |
749 if(n == N) | |
750 return; | |
751 | |
752 indent(dep); | |
753 if(dep > 10) { | |
754 print("...\n"); | |
755 return; | |
756 } | |
757 | |
758 if(n->ninit != nil) { | |
759 print("%O-init\n", n->op); | |
760 dodumplist(n->ninit, dep+1); | |
761 indent(dep); | |
762 } | |
763 | |
764 switch(n->op) { | |
765 default: | |
766 print("%N\n", n); | |
767 dodump(n->left, dep+1); | |
768 dodump(n->right, dep+1); | |
769 break; | |
770 | |
771 case OLITERAL: | |
772 print("%N v(%V)\n", n, &n->val); | |
773 break; | |
774 | |
775 case OTYPE: | |
776 print("%O %S type=%T\n", n->op, n->sym, n->type); | |
777 if(n->type == T && n->ntype) { | |
778 indent(dep); | |
779 print("%O-ntype\n", n->op); | |
780 dodump(n->ntype, dep+1); | |
781 } | |
782 break; | |
783 | |
784 case OIF: | |
785 print("%O%J\n", n->op, n); | |
786 dodump(n->ntest, dep+1); | |
787 if(n->nbody != nil) { | |
788 indent(dep); | |
789 print("%O-then\n", n->op); | |
790 dodumplist(n->nbody, dep+1); | |
791 } | |
792 if(n->nelse != nil) { | |
793 indent(dep); | |
794 print("%O-else\n", n->op); | |
795 dodumplist(n->nelse, dep+1); | |
796 } | |
797 break; | |
798 | |
799 case OSELECT: | |
800 print("%O%J\n", n->op, n); | |
801 dodumplist(n->nbody, dep+1); | |
802 break; | |
803 | |
804 case OSWITCH: | |
805 case OFOR: | |
806 print("%O%J\n", n->op, n); | |
807 dodump(n->ntest, dep+1); | |
808 | |
809 if(n->nbody != nil) { | |
810 indent(dep); | |
811 print("%O-body\n", n->op); | |
812 dodumplist(n->nbody, dep+1); | |
813 } | |
814 | |
815 if(n->nincr != N) { | |
816 indent(dep); | |
817 print("%O-incr\n", n->op); | |
818 dodump(n->nincr, dep+1); | |
819 } | |
820 break; | |
821 | |
822 case OCASE: | |
823 // the right side points to label of the body | |
824 if(n->right != N && n->right->op == OGOTO && n->right->left->op
== ONAME) | |
825 print("%O%J GOTO %N\n", n->op, n, n->right->left); | |
826 else | |
827 print("%O%J\n", n->op, n); | |
828 dodump(n->left, dep+1); | |
829 break; | |
830 | |
831 case OXCASE: | |
832 print("%N\n", n); | |
833 dodump(n->left, dep+1); | |
834 dodump(n->right, dep+1); | |
835 indent(dep); | |
836 print("%O-nbody\n", n->op); | |
837 dodumplist(n->nbody, dep+1); | |
838 break; | |
839 } | |
840 | |
841 if(0 && n->ntype != nil) { | |
842 indent(dep); | |
843 print("%O-ntype\n", n->op); | |
844 dodump(n->ntype, dep+1); | |
845 } | |
846 if(n->list != nil) { | |
847 indent(dep); | |
848 print("%O-list\n", n->op); | |
849 dodumplist(n->list, dep+1); | |
850 } | |
851 if(n->rlist != nil) { | |
852 indent(dep); | |
853 print("%O-rlist\n", n->op); | |
854 dodumplist(n->rlist, dep+1); | |
855 } | |
856 if(n->op != OIF && n->nbody != nil) { | |
857 indent(dep); | |
858 print("%O-nbody\n", n->op); | |
859 dodumplist(n->nbody, dep+1); | |
860 } | |
861 } | |
862 | |
863 void | |
864 dumplist(char *s, NodeList *l) | |
865 { | |
866 print("%s\n", s); | |
867 dodumplist(l, 1); | |
868 } | |
869 | |
870 void | |
871 dump(char *s, Node *n) | |
872 { | |
873 print("%s [%p]\n", s, n); | |
874 dodump(n, 1); | |
875 } | |
876 | |
877 int | |
878 Vconv(Fmt *fp) | |
879 { | |
880 Val *v; | |
881 | |
882 v = va_arg(fp->args, Val*); | |
883 · | |
884 switch(v->ctype) { | |
885 case CTINT: | |
886 return fmtprint(fp, "%B", v->u.xval); | |
887 case CTFLT: | |
888 return fmtprint(fp, "%g", mpgetflt(v->u.fval)); | |
889 case CTCPLX: | |
890 return fmtprint(fp, "(%g+%gi)", | |
891 mpgetflt(&v->u.cval->real), | |
892 mpgetflt(&v->u.cval->imag)); | |
893 case CTSTR: | |
894 return fmtprint(fp, "\"%Z\"", v->u.sval); | |
895 case CTBOOL: | |
896 return fmtprint(fp, "%d", v->u.bval); | |
897 case CTNIL: | |
898 return fmtprint(fp, "nil"); | |
899 } | |
900 return fmtprint(fp, "<%d>", v->ctype); | |
901 } | |
902 | |
903 static char* | |
904 goopnames[] = | |
905 { | |
906 [OADDR] = "&", | |
907 [OADD] = "+", | |
908 [OADDSTR] = "+", | |
909 [OANDAND] = "&&", | |
910 [OANDNOT] = "&^", | |
911 [OAND] = "&", | |
912 [OAPPEND] = "append", | |
913 [OAS] = "=", | |
914 [OAS2] = "=", | |
915 [OBREAK] = "break", | |
916 [OCALL] = "function call", | |
917 [OCAP] = "cap", | |
918 [OCASE] = "case", | |
919 [OCLOSE] = "close", | |
920 [OCOMPLEX] = "complex", | |
921 [OCOM] = "^", | |
922 [OCONTINUE] = "continue", | |
923 [OCOPY] = "copy", | |
924 [ODEC] = "--", | |
925 [ODEFER] = "defer", | |
926 [ODELETE] = "delete", | |
927 [ODIV] = "/", | |
928 [OEQ] = "==", | |
929 [OFALL] = "fallthrough", | |
930 [OFOR] = "for", | |
931 [OGE] = ">=", | |
932 [OGOTO] = "goto", | |
933 [OGT] = ">", | |
934 [OIF] = "if", | |
935 [OIMAG] = "imag", | |
936 [OINC] = "++", | |
937 [OIND] = "*", | |
938 [OLEN] = "len", | |
939 [OLE] = "<=", | |
940 [OLSH] = "<<", | |
941 [OLT] = "<", | |
942 [OMAKE] = "make", | |
943 [OMINUS] = "-", | |
944 [OMOD] = "%", | |
945 [OMUL] = "*", | |
946 [ONEW] = "new", | |
947 [ONE] = "!=", | |
948 [ONOT] = "!", | |
949 [OOROR] = "||", | |
950 [OOR] = "|", | |
951 [OPANIC] = "panic", | |
952 [OPLUS] = "+", | |
953 [OPRINTN] = "println", | |
954 [OPRINT] = "print", | |
955 [ORANGE] = "range", | |
956 [OREAL] = "real", | |
957 [ORECV] = "<-", | |
958 [ORETURN] = "return", | |
959 [ORSH] = ">>", | |
960 [OSELECT] = "select", | |
961 [OSEND] = "<-", | |
962 [OSUB] = "-", | |
963 [OSWITCH] = "switch", | |
964 [OXOR] = "^", | |
965 }; | |
966 | |
967 int | |
968 Oconv(Fmt *fp) | |
969 { | |
970 int o; | |
971 | |
972 o = va_arg(fp->args, int); | |
973 if((fp->flags & FmtSharp) && o >= 0 && o < nelem(goopnames) && goopnames
[o] != nil) | |
974 return fmtstrcpy(fp, goopnames[o]); | |
975 if(o < 0 || o >= nelem(opnames) || opnames[o] == nil) | |
976 return fmtprint(fp, "O-%d", o); | |
977 return fmtstrcpy(fp, opnames[o]); | |
978 } | |
979 | |
980 int | |
981 Lconv(Fmt *fp) | |
982 { | |
983 struct | |
984 { | |
985 Hist* incl; /* start of this include file */ | |
986 int32 idel; /* delta line number to apply to include */ | |
987 Hist* line; /* start of this #line directive */ | |
988 int32 ldel; /* delta line number to apply to #line */ | |
989 } a[HISTSZ]; | |
990 int32 lno, d; | |
991 int i, n; | |
992 Hist *h; | |
993 | |
994 lno = va_arg(fp->args, int32); | |
995 | |
996 n = 0; | |
997 for(h=hist; h!=H; h=h->link) { | |
998 if(h->offset < 0) | |
999 continue; | |
1000 if(lno < h->line) | |
1001 break; | |
1002 if(h->name) { | |
1003 if(h->offset > 0) { | |
1004 // #line directive | |
1005 if(n > 0 && n < HISTSZ) { | |
1006 a[n-1].line = h; | |
1007 a[n-1].ldel = h->line - h->offset + 1; | |
1008 } | |
1009 } else { | |
1010 // beginning of file | |
1011 if(n < HISTSZ) { | |
1012 a[n].incl = h; | |
1013 a[n].idel = h->line; | |
1014 a[n].line = 0; | |
1015 } | |
1016 n++; | |
1017 } | |
1018 continue; | |
1019 } | |
1020 n--; | |
1021 if(n > 0 && n < HISTSZ) { | |
1022 d = h->line - a[n].incl->line; | |
1023 a[n-1].ldel += d; | |
1024 a[n-1].idel += d; | |
1025 } | |
1026 } | |
1027 | |
1028 if(n > HISTSZ) | |
1029 n = HISTSZ; | |
1030 | |
1031 for(i=n-1; i>=0; i--) { | |
1032 if(i != n-1) { | |
1033 if(fp->flags & ~(FmtWidth|FmtPrec)) | |
1034 break; | |
1035 fmtprint(fp, " "); | |
1036 } | |
1037 if(debug['L']) | |
1038 fmtprint(fp, "%s/", pathname); | |
1039 if(a[i].line) | |
1040 fmtprint(fp, "%s:%d[%s:%d]", | |
1041 a[i].line->name, lno-a[i].ldel+1, | |
1042 a[i].incl->name, lno-a[i].idel+1); | |
1043 else | |
1044 fmtprint(fp, "%s:%d", | |
1045 a[i].incl->name, lno-a[i].idel+1); | |
1046 lno = a[i].incl->line - 1; // now print out start of this f
ile | |
1047 } | |
1048 if(n == 0) | |
1049 fmtprint(fp, "<epoch>"); | |
1050 | |
1051 return 0; | |
1052 } | |
1053 | |
1054 /* | |
1055 s%,%,\n%g | |
1056 s%\n+%\n%g | |
1057 s%^[ ]*T%%g | |
1058 s%,.*%%g | |
1059 s%.+% [T&] = "&",%g | |
1060 s%^ ........*\]%&~%g | |
1061 s%~ %%g | |
1062 */ | |
1063 | |
1064 static char* | |
1065 etnames[] = | |
1066 { | |
1067 [TINT] = "INT", | |
1068 [TUINT] = "UINT", | |
1069 [TINT8] = "INT8", | |
1070 [TUINT8] = "UINT8", | |
1071 [TINT16] = "INT16", | |
1072 [TUINT16] = "UINT16", | |
1073 [TINT32] = "INT32", | |
1074 [TUINT32] = "UINT32", | |
1075 [TINT64] = "INT64", | |
1076 [TUINT64] = "UINT64", | |
1077 [TUINTPTR] = "UINTPTR", | |
1078 [TFLOAT32] = "FLOAT32", | |
1079 [TFLOAT64] = "FLOAT64", | |
1080 [TCOMPLEX64] = "COMPLEX64", | |
1081 [TCOMPLEX128] = "COMPLEX128", | |
1082 [TBOOL] = "BOOL", | |
1083 [TPTR32] = "PTR32", | |
1084 [TPTR64] = "PTR64", | |
1085 [TFUNC] = "FUNC", | |
1086 [TARRAY] = "ARRAY", | |
1087 [TSTRUCT] = "STRUCT", | |
1088 [TCHAN] = "CHAN", | |
1089 [TMAP] = "MAP", | |
1090 [TINTER] = "INTER", | |
1091 [TFORW] = "FORW", | |
1092 [TFIELD] = "FIELD", | |
1093 [TSTRING] = "STRING", | |
1094 [TANY] = "ANY", | |
1095 }; | |
1096 | |
1097 int | |
1098 Econv(Fmt *fp) | |
1099 { | |
1100 int et; | |
1101 | |
1102 et = va_arg(fp->args, int); | |
1103 if(et < 0 || et >= nelem(etnames) || etnames[et] == nil) | |
1104 return fmtprint(fp, "E-%d", et); | |
1105 return fmtstrcpy(fp, etnames[et]); | |
1106 } | |
1107 | |
1108 static const char* classnames[] = { | |
1109 "Pxxx", | |
1110 "PEXTERN", | |
1111 "PAUTO", | |
1112 "PPARAM", | |
1113 "PPARAMOUT", | |
1114 "PPARAMREF", | |
1115 "PFUNC", | |
1116 }; | |
1117 | |
1118 int | |
1119 Jconv(Fmt *fp) | |
1120 { | |
1121 Node *n; | |
1122 char *s; | |
1123 int c; | |
1124 | |
1125 n = va_arg(fp->args, Node*); | |
1126 | |
1127 c = fp->flags&FmtShort; | |
1128 | |
1129 if(!c && n->ullman != 0) | |
1130 fmtprint(fp, " u(%d)", n->ullman); | |
1131 | |
1132 if(!c && n->addable != 0) | |
1133 fmtprint(fp, " a(%d)", n->addable); | |
1134 | |
1135 if(!c && n->vargen != 0) | |
1136 fmtprint(fp, " g(%d)", n->vargen); | |
1137 | |
1138 if(n->lineno != 0) | |
1139 fmtprint(fp, " l(%d)", n->lineno); | |
1140 | |
1141 if(!c && n->xoffset != BADWIDTH) | |
1142 fmtprint(fp, " x(%lld%+d)", n->xoffset, n->stkdelta); | |
1143 | |
1144 if(n->class != 0) { | |
1145 s = ""; | |
1146 if(n->class & PHEAP) s = ",heap"; | |
1147 if((n->class & ~PHEAP) < nelem(classnames)) | |
1148 fmtprint(fp, " class(%s%s)", classnames[n->class&~PHEAP]
, s); | |
1149 else | |
1150 fmtprint(fp, " class(%d?%s)", n->class&~PHEAP, s); | |
1151 } | |
1152 · | |
1153 if(n->colas != 0) | |
1154 fmtprint(fp, " colas(%d)", n->colas); | |
1155 | |
1156 if(n->funcdepth != 0) | |
1157 fmtprint(fp, " f(%d)", n->funcdepth); | |
1158 | |
1159 if(n->addrtaken != 0) | |
1160 fmtprint(fp, " addrtaken(1)"); | |
1161 | |
1162 switch(n->esc) { | |
1163 case EscUnknown: | |
1164 break; | |
1165 case EscHeap: | |
1166 fmtprint(fp, " esc(h)"); | |
1167 break; | |
1168 case EscScope: | |
1169 fmtprint(fp, " esc(s)"); | |
1170 break; | |
1171 case EscNone: | |
1172 fmtprint(fp, " esc(no)"); | |
1173 break; | |
1174 case EscNever: | |
1175 if(!c) | |
1176 fmtprint(fp, " esc(N)"); | |
1177 break; | |
1178 default: | |
1179 fmtprint(fp, " esc(%d)", n->esc); | |
1180 break; | |
1181 } | |
1182 | |
1183 if(n->escloopdepth) | |
1184 fmtprint(fp, " ld(%d)", n->escloopdepth); | |
1185 | |
1186 if(!c && n->typecheck != 0) | |
1187 fmtprint(fp, " tc(%d)", n->typecheck); | |
1188 | |
1189 if(!c && n->dodata != 0) | |
1190 fmtprint(fp, " dd(%d)", n->dodata); | |
1191 | |
1192 if(n->isddd != 0) | |
1193 fmtprint(fp, " isddd(%d)", n->isddd); | |
1194 | |
1195 if(n->implicit != 0) | |
1196 fmtprint(fp, " implicit(%d)", n->implicit); | |
1197 | |
1198 if(!c && n->used != 0) | |
1199 fmtprint(fp, " used(%d)", n->used); | |
1200 return 0; | |
1201 } | |
1202 | |
1203 // Flags for %S | |
1204 // 'h' FmtShort -> just print the name | |
1205 // '#' FmtSharp -> qualify with package prefix or @"path", depending on global f
lag packagequotes. | |
1206 // (automatic when global flag exporting is set) | |
1207 // 'l' FmtLong -> qualify with package name or "path" (automatic when global fl
ag· | |
1208 // longsymnames is set (by typehash) or sym is not in localpkg) | |
1209 int | |
1210 Sconv(Fmt *fp) | |
1211 { | |
1212 Sym *s; | |
1213 | |
1214 s = va_arg(fp->args, Sym*); | |
1215 if(s == S) | |
1216 return fmtstrcpy(fp, "<S>"); | |
1217 | |
1218 if(fp->flags & FmtShort) | |
1219 goto shrt; | |
1220 | |
1221 if(exporting || (fp->flags & FmtSharp)) { | |
1222 if(packagequotes) | |
1223 return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name)
; | |
1224 else | |
1225 return fmtprint(fp, "%s.%s", s->pkg->prefix, s->name); | |
1226 } | |
1227 | |
1228 if(s->pkg && s->pkg != localpkg || longsymnames || (fp->flags & FmtLong)
) { | |
1229 // This one is for the user. If the package name | |
1230 // was used by multiple packages, give the full | |
1231 // import path to disambiguate. | |
1232 if(erroring && pkglookup(s->pkg->name, nil)->npkg > 1) | |
1233 return fmtprint(fp, "\"%Z\".%s", s->pkg->path, s->name); | |
1234 return fmtprint(fp, "%s.%s", s->pkg->name, s->name); | |
1235 } | |
1236 | |
1237 shrt: | |
1238 return fmtstrcpy(fp, s->name); | |
1239 } | |
1240 | |
1241 static char* | |
1242 basicnames[] = | |
1243 { | |
1244 [TINT] = "int", | |
1245 [TUINT] = "uint", | |
1246 [TINT8] = "int8", | |
1247 [TUINT8] = "uint8", | |
1248 [TINT16] = "int16", | |
1249 [TUINT16] = "uint16", | |
1250 [TINT32] = "int32", | |
1251 [TUINT32] = "uint32", | |
1252 [TINT64] = "int64", | |
1253 [TUINT64] = "uint64", | |
1254 [TUINTPTR] = "uintptr", | |
1255 [TFLOAT32] = "float32", | |
1256 [TFLOAT64] = "float64", | |
1257 [TCOMPLEX64] = "complex64", | |
1258 [TCOMPLEX128] = "complex128", | |
1259 [TBOOL] = "bool", | |
1260 [TANY] = "any", | |
1261 [TSTRING] = "string", | |
1262 [TNIL] = "nil", | |
1263 [TIDEAL] = "ideal", | |
1264 [TBLANK] = "blank", | |
1265 }; | |
1266 | |
1267 // Global flag exporting· | |
1268 // Global flag noargnames | |
1269 // 'h' FmtShort | |
1270 // 'l' FmtLong | |
1271 static int | |
1272 Tpretty(Fmt *fp, Type *t) | |
1273 { | |
1274 Type *t1; | |
1275 Sym *s; | |
1276 ········ | |
1277 if(0 && debug['r']) { | |
1278 debug['r'] = 0; | |
1279 fmtprint(fp, "%T (orig=%T)", t, t->orig); | |
1280 debug['r'] = 1; | |
1281 return 0; | |
1282 } | |
1283 ········ | |
1284 if(noargnames) { | |
1285 // called from typesym | |
1286 if(t == bytetype) | |
1287 t = types[bytetype->etype]; | |
1288 if(t == runetype) | |
1289 t = types[runetype->etype]; | |
1290 } | |
1291 | |
1292 if(t->etype != TFIELD | |
1293 && t->sym != S | |
1294 && !(fp->flags&FmtLong)) { | |
1295 s = t->sym; | |
1296 if((t == types[t->etype] && t->etype != TUNSAFEPTR) || t == byte
type || t == runetype || t == errortype) | |
1297 return fmtprint(fp, "%s", s->name); | |
1298 if(exporting) { | |
1299 if(fp->flags & FmtShort) | |
1300 fmtprint(fp, "%hS", s); | |
1301 else | |
1302 fmtprint(fp, "%S", s); | |
1303 if(s->pkg == localpkg && t->vargen) | |
1304 fmtprint(fp, "·%d", t->vargen); | |
1305 return 0; | |
1306 } | |
1307 return fmtprint(fp, "%S", s); | |
1308 } | |
1309 | |
1310 if(t->etype < nelem(basicnames) && basicnames[t->etype] != nil) { | |
1311 if(isideal(t) && t->etype != TIDEAL && t->etype != TNIL) | |
1312 fmtprint(fp, "ideal "); | |
1313 return fmtprint(fp, "%s", basicnames[t->etype]); | |
1314 } | |
1315 | |
1316 switch(t->etype) { | |
1317 case TPTR32: | |
1318 case TPTR64: | |
1319 if(fp->flags&FmtShort) // pass flag thru for methodsym | |
1320 return fmtprint(fp, "*%hT", t->type); | |
1321 return fmtprint(fp, "*%T", t->type); | |
1322 | |
1323 case TCHAN: | |
1324 switch(t->chan) { | |
1325 case Crecv: | |
1326 return fmtprint(fp, "<-chan %T", t->type); | |
1327 case Csend: | |
1328 return fmtprint(fp, "chan<- %T", t->type); | |
1329 } | |
1330 if(t->type != T && t->type->etype == TCHAN && t->type->sym == S
&& t->type->chan == Crecv) | |
1331 return fmtprint(fp, "chan (%T)", t->type); | |
1332 return fmtprint(fp, "chan %T", t->type); | |
1333 | |
1334 case TMAP: | |
1335 return fmtprint(fp, "map[%T] %T", t->down, t->type); | |
1336 | |
1337 case TFUNC: | |
1338 // t->type is method struct | |
1339 // t->type->down is result struct | |
1340 // t->type->down->down is arg struct | |
1341 if(t->thistuple && !(fp->flags&FmtSharp) && !(fp->flags&FmtShort
)) { | |
1342 fmtprint(fp, "method("); | |
1343 for(t1=getthisx(t)->type; t1; t1=t1->down) { | |
1344 fmtprint(fp, "%T", t1); | |
1345 if(t1->down) | |
1346 fmtprint(fp, ", "); | |
1347 } | |
1348 fmtprint(fp, ")"); | |
1349 } | |
1350 | |
1351 if(!(fp->flags&FmtByte)) | |
1352 fmtprint(fp, "func"); | |
1353 fmtprint(fp, "("); | |
1354 for(t1=getinargx(t)->type; t1; t1=t1->down) { | |
1355 if(noargnames && t1->etype == TFIELD) { | |
1356 if(t1->isddd) | |
1357 fmtprint(fp, "...%T", t1->type->type); | |
1358 else | |
1359 fmtprint(fp, "%T", t1->type); | |
1360 } else | |
1361 fmtprint(fp, "%T", t1); | |
1362 if(t1->down) | |
1363 fmtprint(fp, ", "); | |
1364 } | |
1365 fmtprint(fp, ")"); | |
1366 switch(t->outtuple) { | |
1367 case 0: | |
1368 break; | |
1369 case 1: | |
1370 t1 = getoutargx(t)->type; | |
1371 if(t1 == T) { | |
1372 // failure to typecheck earlier; don't know the
type | |
1373 fmtprint(fp, " ?unknown-type?"); | |
1374 break; | |
1375 } | |
1376 if(t1->etype == TFIELD) | |
1377 t1 = t1->type; | |
1378 fmtprint(fp, " %T", t1); | |
1379 break; | |
1380 default: | |
1381 t1 = getoutargx(t)->type; | |
1382 fmtprint(fp, " ("); | |
1383 for(; t1; t1=t1->down) { | |
1384 if(noargnames && t1->etype == TFIELD) | |
1385 fmtprint(fp, "%T", t1->type); | |
1386 else | |
1387 fmtprint(fp, "%T", t1); | |
1388 if(t1->down) | |
1389 fmtprint(fp, ", "); | |
1390 } | |
1391 fmtprint(fp, ")"); | |
1392 break; | |
1393 } | |
1394 return 0; | |
1395 | |
1396 case TARRAY: | |
1397 if(t->bound >= 0) | |
1398 return fmtprint(fp, "[%d]%T", (int)t->bound, t->type); | |
1399 if(t->bound == -100) | |
1400 return fmtprint(fp, "[...]%T", t->type); | |
1401 return fmtprint(fp, "[]%T", t->type); | |
1402 | |
1403 case TINTER: | |
1404 fmtprint(fp, "interface {"); | |
1405 for(t1=t->type; t1!=T; t1=t1->down) { | |
1406 fmtprint(fp, " "); | |
1407 if(exportname(t1->sym->name)) | |
1408 fmtprint(fp, "%hS", t1->sym); | |
1409 else | |
1410 fmtprint(fp, "%S", t1->sym); | |
1411 fmtprint(fp, "%hhT", t1->type); | |
1412 if(t1->down) | |
1413 fmtprint(fp, ";"); | |
1414 } | |
1415 return fmtprint(fp, " }"); | |
1416 | |
1417 case TSTRUCT: | |
1418 if(t->funarg) { | |
1419 fmtprint(fp, "("); | |
1420 for(t1=t->type; t1!=T; t1=t1->down) { | |
1421 fmtprint(fp, "%T", t1); | |
1422 if(t1->down) | |
1423 fmtprint(fp, ", "); | |
1424 } | |
1425 return fmtprint(fp, ")"); | |
1426 } | |
1427 fmtprint(fp, "struct {"); | |
1428 for(t1=t->type; t1!=T; t1=t1->down) { | |
1429 fmtprint(fp, " %T", t1); | |
1430 if(t1->down) | |
1431 fmtprint(fp, ";"); | |
1432 } | |
1433 return fmtprint(fp, " }"); | |
1434 | |
1435 case TFIELD: | |
1436 if(t->sym == S || t->embedded) { | |
1437 if(exporting) | |
1438 fmtprint(fp, "? "); | |
1439 } else | |
1440 fmtprint(fp, "%hS ", t->sym); | |
1441 if(t->isddd) | |
1442 fmtprint(fp, "...%T", t->type->type); | |
1443 else | |
1444 fmtprint(fp, "%T", t->type); | |
1445 if(t->note) { | |
1446 fmtprint(fp, " "); | |
1447 fmtprint(fp, "\"%Z\"", t->note); | |
1448 } | |
1449 return 0; | |
1450 | |
1451 case TFORW: | |
1452 if(exporting) | |
1453 yyerror("undefined type %S", t->sym); | |
1454 if(t->sym) | |
1455 return fmtprint(fp, "undefined %S", t->sym); | |
1456 return fmtprint(fp, "undefined"); | |
1457 ········ | |
1458 case TUNSAFEPTR: | |
1459 if(exporting) | |
1460 return fmtprint(fp, "@\"unsafe\".Pointer"); | |
1461 return fmtprint(fp, "unsafe.Pointer"); | |
1462 default: | |
1463 if(exporting) | |
1464 fatal("missing %E case during export", t->etype); | |
1465 // Don't know how to handle - fall back to detailed prints. | |
1466 return fmtprint(fp, "%E <%S> %T", t->etype, t->sym, t->type); | |
1467 } | |
1468 | |
1469 fatal("not reached"); | |
1470 return -1; | |
1471 } | |
1472 | |
1473 // %T flags: | |
1474 // '#' FmtSharp -> 'exporting' mode global flag, affects Tpretty and Sconv | |
1475 // '-' FmtLeft -> 'noargnames' global flag, affects Tpretty | |
1476 // 'h' FmtShort -> handled by Tpretty | |
1477 // 'l' FmtLong -> handled by Tpretty | |
1478 int | |
1479 Tconv(Fmt *fp) | |
1480 { | |
1481 Type *t; | |
1482 int r,sharp, minus, sf; | |
1483 | |
1484 t = va_arg(fp->args, Type*); | |
1485 if(t == T) | |
1486 return fmtstrcpy(fp, "<T>"); | |
1487 | |
1488 if(t->trecur > 4) { | |
1489 return fmtstrcpy(fp, "..."); | |
1490 } | |
1491 | |
1492 t->trecur++; | |
1493 | |
1494 sharp = (fp->flags & FmtSharp); | |
1495 minus = (fp->flags & FmtLeft); | |
1496 sf = fp->flags; | |
1497 fp->flags &= ~(FmtSharp|FmtLeft); | |
1498 | |
1499 if(sharp) | |
1500 exporting++; | |
1501 if(minus) | |
1502 noargnames++; | |
1503 r = Tpretty(fp, t); | |
1504 if(sharp) | |
1505 exporting--; | |
1506 if(minus) | |
1507 noargnames--; | |
1508 | |
1509 fp->flags = sf; | |
1510 t->trecur--; | |
1511 return r; | |
1512 } | |
1513 | |
1514 int | |
1515 Nconv(Fmt *fp) | |
1516 { | |
1517 char buf1[500]; | |
1518 Node *n; | |
1519 | |
1520 n = va_arg(fp->args, Node*); | |
1521 if(n == N) { | |
1522 fmtprint(fp, "<N>"); | |
1523 goto out; | |
1524 } | |
1525 | |
1526 if(fp->flags & FmtSign) { | |
1527 if(n->type == T) | |
1528 fmtprint(fp, "%#hN", n); | |
1529 else if(n->type->etype == TNIL) | |
1530 fmtprint(fp, "nil"); | |
1531 else | |
1532 fmtprint(fp, "%#hN (type %T)", n, n->type); | |
1533 goto out; | |
1534 } | |
1535 | |
1536 if(fp->flags & FmtSharp) { | |
1537 if(n->orig != N) | |
1538 n = n->orig; | |
1539 exprfmt(fp, n, 0); | |
1540 goto out; | |
1541 } | |
1542 | |
1543 switch(n->op) { | |
1544 default: | |
1545 if(fp->flags & FmtShort) | |
1546 fmtprint(fp, "%O%hJ", n->op, n); | |
1547 else | |
1548 fmtprint(fp, "%O%J", n->op, n); | |
1549 break; | |
1550 | |
1551 case ONAME: | |
1552 case ONONAME: | |
1553 if(n->sym == S) { | |
1554 if(fp->flags & FmtShort) | |
1555 fmtprint(fp, "%O%hJ", n->op, n); | |
1556 else | |
1557 fmtprint(fp, "%O%J", n->op, n); | |
1558 break; | |
1559 } | |
1560 if(fp->flags & FmtShort) | |
1561 fmtprint(fp, "%O-%S%hJ", n->op, n->sym, n); | |
1562 else | |
1563 fmtprint(fp, "%O-%S%J", n->op, n->sym, n); | |
1564 goto ptyp; | |
1565 | |
1566 case OREGISTER: | |
1567 fmtprint(fp, "%O-%R%J", n->op, n->val.u.reg, n); | |
1568 break; | |
1569 | |
1570 case OLITERAL: | |
1571 switch(n->val.ctype) { | |
1572 default: | |
1573 snprint(buf1, sizeof(buf1), "LITERAL-ctype=%d", n->val.c
type); | |
1574 break; | |
1575 case CTINT: | |
1576 snprint(buf1, sizeof(buf1), "I%B", n->val.u.xval); | |
1577 break; | |
1578 case CTFLT: | |
1579 snprint(buf1, sizeof(buf1), "F%g", mpgetflt(n->val.u.fva
l)); | |
1580 break; | |
1581 case CTCPLX: | |
1582 snprint(buf1, sizeof(buf1), "(F%g+F%gi)", | |
1583 mpgetflt(&n->val.u.cval->real), | |
1584 mpgetflt(&n->val.u.cval->imag)); | |
1585 break; | |
1586 case CTSTR: | |
1587 snprint(buf1, sizeof(buf1), "S\"%Z\"", n->val.u.sval); | |
1588 break; | |
1589 case CTBOOL: | |
1590 snprint(buf1, sizeof(buf1), "B%d", n->val.u.bval); | |
1591 break; | |
1592 case CTNIL: | |
1593 snprint(buf1, sizeof(buf1), "N"); | |
1594 break; | |
1595 } | |
1596 fmtprint(fp, "%O-%s%J", n->op, buf1, n); | |
1597 break; | |
1598 | |
1599 case OASOP: | |
1600 fmtprint(fp, "%O-%O%J", n->op, n->etype, n); | |
1601 break; | |
1602 | |
1603 case OTYPE: | |
1604 fmtprint(fp, "%O %T", n->op, n->type); | |
1605 break; | |
1606 } | |
1607 if(n->sym != S) | |
1608 fmtprint(fp, " %S G%d", n->sym, n->vargen); | |
1609 | |
1610 ptyp: | |
1611 if(n->type != T) | |
1612 fmtprint(fp, " %T", n->type); | |
1613 | |
1614 out: | |
1615 return 0; | |
1616 } | |
1617 | |
1618 Node* | 725 Node* |
1619 treecopy(Node *n) | 726 treecopy(Node *n) |
1620 { | 727 { |
1621 Node *m; | 728 Node *m; |
1622 | 729 |
1623 if(n == N) | 730 if(n == N) |
1624 return N; | 731 return N; |
1625 | 732 |
1626 switch(n->op) { | 733 switch(n->op) { |
1627 default: | 734 default: |
(...skipping 20 matching lines...) Expand all Loading... |
1648 // fall through | 755 // fall through |
1649 case ONAME: | 756 case ONAME: |
1650 case OLITERAL: | 757 case OLITERAL: |
1651 case OTYPE: | 758 case OTYPE: |
1652 m = n; | 759 m = n; |
1653 break; | 760 break; |
1654 } | 761 } |
1655 return m; | 762 return m; |
1656 } | 763 } |
1657 | 764 |
1658 int | |
1659 Zconv(Fmt *fp) | |
1660 { | |
1661 Rune r; | |
1662 Strlit *sp; | |
1663 char *s, *se; | |
1664 int n; | |
1665 | |
1666 sp = va_arg(fp->args, Strlit*); | |
1667 if(sp == nil) | |
1668 return fmtstrcpy(fp, "<nil>"); | |
1669 | |
1670 s = sp->s; | |
1671 se = s + sp->len; | |
1672 while(s < se) { | |
1673 n = chartorune(&r, s); | |
1674 s += n; | |
1675 switch(r) { | |
1676 case Runeerror: | |
1677 if(n == 1) { | |
1678 fmtprint(fp, "\\x%02x", (uchar)*(s-1)); | |
1679 break; | |
1680 } | |
1681 // fall through | |
1682 default: | |
1683 if(r < ' ') { | |
1684 fmtprint(fp, "\\x%02x", r); | |
1685 break; | |
1686 } | |
1687 fmtrune(fp, r); | |
1688 break; | |
1689 case '\t': | |
1690 fmtstrcpy(fp, "\\t"); | |
1691 break; | |
1692 case '\n': | |
1693 fmtstrcpy(fp, "\\n"); | |
1694 break; | |
1695 case '\"': | |
1696 case '\\': | |
1697 fmtrune(fp, '\\'); | |
1698 fmtrune(fp, r); | |
1699 break; | |
1700 } | |
1701 } | |
1702 return 0; | |
1703 } | |
1704 | 765 |
1705 int | 766 int |
1706 isnil(Node *n) | 767 isnil(Node *n) |
1707 { | 768 { |
1708 if(n == N) | 769 if(n == N) |
1709 return 0; | 770 return 0; |
1710 if(n->op != OLITERAL) | 771 if(n->op != OLITERAL) |
1711 return 0; | 772 return 0; |
1712 if(n->val.ctype != CTNIL) | 773 if(n->val.ctype != CTNIL) |
1713 return 0; | 774 return 0; |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 old->diag--; | 1217 old->diag--; |
2157 if(t->etype == TBLANK) | 1218 if(t->etype == TBLANK) |
2158 return n; | 1219 return n; |
2159 | 1220 |
2160 exportassignok(n->type, context); | 1221 exportassignok(n->type, context); |
2161 if(eqtype(n->type, t)) | 1222 if(eqtype(n->type, t)) |
2162 return n; | 1223 return n; |
2163 | 1224 |
2164 op = assignop(n->type, t, &why); | 1225 op = assignop(n->type, t, &why); |
2165 if(op == 0) { | 1226 if(op == 0) { |
2166 » » yyerror("cannot use %+N as type %T in %s%s", n, t, context, why)
; | 1227 » » yyerror("cannot use %lN as type %T in %s%s", n, t, context, why)
; |
2167 op = OCONV; | 1228 op = OCONV; |
2168 } | 1229 } |
2169 | 1230 |
2170 r = nod(op, n, N); | 1231 r = nod(op, n, N); |
2171 r->type = t; | 1232 r->type = t; |
2172 r->typecheck = 1; | 1233 r->typecheck = 1; |
2173 r->implicit = 1; | 1234 r->implicit = 1; |
2174 return r; | 1235 return r; |
2175 } | 1236 } |
2176 | 1237 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2381 *n = *s->def; | 1442 *n = *s->def; |
2382 n->type = deep(s->def->type); | 1443 n->type = deep(s->def->type); |
2383 | 1444 |
2384 return n; | 1445 return n; |
2385 } | 1446 } |
2386 | 1447 |
2387 /* | 1448 /* |
2388 * compute a hash value for type t. | 1449 * compute a hash value for type t. |
2389 * if t is a method type, ignore the receiver | 1450 * if t is a method type, ignore the receiver |
2390 * so that the hash can be used in interface checks. | 1451 * so that the hash can be used in interface checks. |
2391 * %-T (which calls Tpretty, above) already contains | 1452 * %T already contains |
2392 * all the necessary logic to generate a representation | 1453 * all the necessary logic to generate a representation |
2393 * of the type that completely describes it. | 1454 * of the type that completely describes it. |
2394 * using smprint here avoids duplicating that code. | 1455 * using smprint here avoids duplicating that code. |
2395 * using md5 here is overkill, but i got tired of | 1456 * using md5 here is overkill, but i got tired of |
2396 * accidental collisions making the runtime think | 1457 * accidental collisions making the runtime think |
2397 * two types are equal when they really aren't. | 1458 * two types are equal when they really aren't. |
2398 */ | 1459 */ |
2399 uint32 | 1460 uint32 |
2400 typehash(Type *t) | 1461 typehash(Type *t) |
2401 { | 1462 { |
2402 char *p; | 1463 char *p; |
2403 MD5 d; | 1464 MD5 d; |
2404 | 1465 |
2405 longsymnames = 1; | |
2406 if(t->thistuple) { | 1466 if(t->thistuple) { |
2407 // hide method receiver from Tpretty | 1467 // hide method receiver from Tpretty |
2408 t->thistuple = 0; | 1468 t->thistuple = 0; |
2409 » » p = smprint("%-T", t); | 1469 » » p = smprint("%-uT", t); |
2410 t->thistuple = 1; | 1470 t->thistuple = 1; |
2411 » }else | 1471 » } else |
2412 » » p = smprint("%-T", t); | 1472 » » p = smprint("%-uT", t); |
2413 » longsymnames = 0; | 1473 » //print("typehash: %s\n", p); |
2414 md5reset(&d); | 1474 md5reset(&d); |
2415 md5write(&d, (uchar*)p, strlen(p)); | 1475 md5write(&d, (uchar*)p, strlen(p)); |
2416 free(p); | 1476 free(p); |
2417 return md5sum(&d); | 1477 return md5sum(&d); |
2418 } | 1478 } |
2419 | 1479 |
2420 Type* | 1480 Type* |
2421 ptrto(Type *t) | 1481 ptrto(Type *t) |
2422 { | 1482 { |
2423 Type *t1; | 1483 Type *t1; |
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3913 Strlit* | 2973 Strlit* |
3914 strlit(char *s) | 2974 strlit(char *s) |
3915 { | 2975 { |
3916 Strlit *t; | 2976 Strlit *t; |
3917 ········ | 2977 ········ |
3918 t = mal(sizeof *t + strlen(s)); | 2978 t = mal(sizeof *t + strlen(s)); |
3919 strcpy(t->s, s); | 2979 strcpy(t->s, s); |
3920 t->len = strlen(s); | 2980 t->len = strlen(s); |
3921 return t; | 2981 return t; |
3922 } | 2982 } |
LEFT | RIGHT |