Mercurial > projects > ddmd
comparison dmd/TemplateInstance.d @ 135:af1bebfd96a4 dmd2037
dmd 2.038
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 13 Sep 2010 22:19:42 +0100 |
parents | 206db751bd4c |
children | e7769d53e750 |
comparison
equal
deleted
inserted
replaced
134:4251f96733f4 | 135:af1bebfd96a4 |
---|---|
38 import dmd.Declaration; | 38 import dmd.Declaration; |
39 import dmd.MATCH; | 39 import dmd.MATCH; |
40 import dmd.TypeFunction; | 40 import dmd.TypeFunction; |
41 import dmd.TemplateTupleParameter; | 41 import dmd.TemplateTupleParameter; |
42 import dmd.FuncDeclaration; | 42 import dmd.FuncDeclaration; |
43 import dmd.OverloadSet; | |
43 import dmd.templates.Util; | 44 import dmd.templates.Util; |
44 | 45 |
45 import dmd.backend.glue; | 46 import dmd.backend.glue; |
46 | 47 |
47 Tuple isTuple(Object o) | 48 Tuple isTuple(Object o) |
261 return ti; | 262 return ti; |
262 } | 263 } |
263 | 264 |
264 override void semantic(Scope sc) | 265 override void semantic(Scope sc) |
265 { | 266 { |
267 semantic(sc, null); | |
268 } | |
269 | |
270 void semantic(Scope sc, Expressions fargs) | |
271 { | |
266 if (global.errors) | 272 if (global.errors) |
267 { | 273 { |
268 if (!global.gag) | 274 if (!global.gag) |
269 { | 275 { |
270 /* Trying to soldier on rarely generates useful messages | 276 /* Trying to soldier on rarely generates useful messages |
362 Object o1 = tdtypes[j]; | 368 Object o1 = tdtypes[j]; |
363 Object o2 = ti.tdtypes[j]; | 369 Object o2 = ti.tdtypes[j]; |
364 if (!match(o1, o2, tempdecl, sc)) | 370 if (!match(o1, o2, tempdecl, sc)) |
365 { | 371 { |
366 goto L1; | 372 goto L1; |
373 } | |
374 } | |
375 | |
376 /* Template functions may have different instantiations based on | |
377 * "auto ref" parameters. | |
378 */ | |
379 if (fargs) | |
380 { | |
381 FuncDeclaration fd = ti.toAlias().isFuncDeclaration(); | |
382 if (fd) | |
383 { | |
384 auto fparameters = fd.getParameters(null); | |
385 size_t nfparams = Parameter.dim(fparameters); // Num function parameters | |
386 for (int i = 0; i < nfparams && i < fargs.dim; i++) | |
387 { auto fparam = Parameter.getNth(fparameters, i); | |
388 auto farg = fargs[i]; | |
389 if (fparam.storageClass & STCauto) // if "auto ref" | |
390 { | |
391 if (farg.isLvalue()) | |
392 { if (!(fparam.storageClass & STC.STCref)) | |
393 goto L1; // auto ref's don't match | |
394 } | |
395 else | |
396 { if (fparam.storageClass & STC.STCref) | |
397 goto L1; // auto ref's don't match | |
398 } | |
399 } | |
400 } | |
367 } | 401 } |
368 } | 402 } |
369 | 403 |
370 // It's a match | 404 // It's a match |
371 inst = ti; | 405 inst = ti; |
512 //printf("setting aliasdecl\n"); | 546 //printf("setting aliasdecl\n"); |
513 aliasdecl = new AliasDeclaration(loc, s.ident, s); | 547 aliasdecl = new AliasDeclaration(loc, s.ident, s); |
514 } | 548 } |
515 } | 549 } |
516 } | 550 } |
551 | |
552 /* If function template declaration | |
553 */ | |
554 if (fargs && aliasdecl) | |
555 { | |
556 FuncDeclaration fd = aliasdecl.toAlias().isFuncDeclaration(); | |
557 if (fd) | |
558 { | |
559 /* Transmit fargs to type so that TypeFunction::semantic() can | |
560 * resolve any "auto ref" storage classes. | |
561 */ | |
562 auto tf = cast(TypeFunction)fd.type; | |
563 if (tf && tf.ty == TY.Tfunction) | |
564 tf.fargs = fargs; | |
565 } | |
566 } | |
517 | 567 |
518 // Do semantic() analysis on template instance members | 568 // Do semantic() analysis on template instance members |
519 version (LOG) { | 569 version (LOG) { |
520 printf("\tdo semantic() on template instance members '%s'\n", toChars()); | 570 printf("\tdo semantic() on template instance members '%s'\n", toChars()); |
521 } | 571 } |
608 | 658 |
609 // Give additional context info if error occurred during instantiation | 659 // Give additional context info if error occurred during instantiation |
610 if (global.errors != errorsave) | 660 if (global.errors != errorsave) |
611 { | 661 { |
612 error("error instantiating"); | 662 error("error instantiating"); |
613 if (tinst && !global.gag) | 663 if (tinst) |
614 { | 664 { |
615 tinst.printInstantiationTrace(); | 665 tinst.printInstantiationTrace(); |
616 fatal(); | |
617 } | 666 } |
618 errors = 1; | 667 errors = 1; |
619 if (global.gag) | 668 if (global.gag) |
620 tempdecl.instances.remove(tempdecl_instance_idx); | 669 tempdecl.instances.remove(tempdecl_instance_idx); |
621 } | 670 } |
830 buf.data = null; | 879 buf.data = null; |
831 //printf("TemplateInstance.mangle() %s = %s\n", toChars(), id); | 880 //printf("TemplateInstance.mangle() %s = %s\n", toChars(), id); |
832 return id; | 881 return id; |
833 } | 882 } |
834 | 883 |
884 /************************************** | |
885 * Given an error instantiating the TemplateInstance, | |
886 * give the nested TemplateInstance instantiations that got | |
887 * us here. Those are a list threaded into the nested scopes. | |
888 */ | |
835 void printInstantiationTrace() | 889 void printInstantiationTrace() |
836 { | 890 { |
837 if (global.gag) | 891 if (global.gag) |
838 return; | 892 return; |
893 /+ | |
894 const int max_shown = 6; | |
895 const string format = "%s: instantiated from here: %s\n"; | |
896 | |
897 // determine instantiation depth and number of recursive instantiations | |
898 int n_instantiations = 1; | |
899 int n_totalrecursions = 0; | |
900 for (TemplateInstance cur = this; cur; cur = cur.tinst) | |
901 { | |
902 ++n_instantiations; | |
903 // If two instantiations use the same declaration, they are recursive. | |
904 // (this works even if they are instantiated from different places in the | |
905 // same template). | |
906 // In principle, we could also check for multiple-template recursion, but it's | |
907 // probably not worthwhile. | |
908 if (cur.tinst && cur.tempdecl && cur.tinst.tempdecl | |
909 && cur.tempdecl.loc.equals(cur.tinst.tempdecl.loc)) | |
910 ++n_totalrecursions; | |
911 } | |
912 | |
913 // show full trace only if it's short or verbose is on | |
914 if (n_instantiations <= max_shown || global.params.verbose) | |
915 { | |
916 for (TemplateInstance cur = this; cur; cur = cur.tinst) | |
917 { | |
918 fprintf(stdmsg, format, cur.loc.toChars(), cur.toChars()); | |
919 } | |
920 } | |
921 else if (n_instantiations - n_totalrecursions <= max_shown) | |
922 { | |
923 // By collapsing recursive instantiations into a single line, | |
924 // we can stay under the limit. | |
925 int recursionDepth=0; | |
926 for (TemplateInstance cur = this; cur; cur = cur.tinst) | |
927 { | |
928 if (cur.tinst && cur.tempdecl && cur.tinst.tempdecl | |
929 && cur.tempdecl.loc.equals(cur.tinst.tempdecl.loc)) | |
930 { | |
931 ++recursionDepth; | |
932 } | |
933 else | |
934 { | |
935 if (recursionDepth) | |
936 fprintf(stdmsg, "%s: %d recursive instantiations from here: %s\n", cur.loc.toChars(), recursionDepth+2, cur.toChars()); | |
937 else | |
938 fprintf(stdmsg,format, cur.loc.toChars(), cur.toChars()); | |
939 recursionDepth = 0; | |
940 } | |
941 } | |
942 } | |
943 else | |
944 { | |
945 // Even after collapsing the recursions, the depth is too deep. | |
946 // Just display the first few and last few instantiations. | |
947 size_t i = 0; | |
948 for (TemplateInstance cur = this; cur; cur = cur.tinst) | |
949 { | |
950 if (i == max_shown / 2) | |
951 fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); | |
952 | |
953 if (i < max_shown / 2 || | |
954 i >= n_instantiations - max_shown + max_shown / 2) | |
955 fprintf(stdmsg, format, cur.loc.toChars(), cur.toChars()); | |
956 ++i; | |
957 } | |
958 } | |
959 +/ | |
839 } | 960 } |
840 | 961 |
841 override void toObjFile(int multiobj) // compile to .obj file | 962 override void toObjFile(int multiobj) // compile to .obj file |
842 { | 963 { |
843 version (LOG) { | 964 version (LOG) { |
1022 | 1143 |
1023 Identifier id = name; | 1144 Identifier id = name; |
1024 s = sc.search(loc, id, &scopesym); | 1145 s = sc.search(loc, id, &scopesym); |
1025 if (!s) | 1146 if (!s) |
1026 { | 1147 { |
1027 error("identifier '%s' is not defined", id.toChars()); | 1148 error("template '%s' is not defined", id.toChars()); |
1028 return null; | 1149 return null; |
1029 } | 1150 } |
1151 | |
1152 /* If an OverloadSet, look for a unique member that is a template declaration | |
1153 */ | |
1154 OverloadSet os = s.isOverloadSet(); | |
1155 if (os) | |
1156 { | |
1157 s = null; | |
1158 foreach (s2; os.a) | |
1159 { | |
1160 if (s2.isTemplateDeclaration()) | |
1161 { | |
1162 if (s) | |
1163 error("ambiguous template declaration %s and %s", s.toPrettyChars(), s2.toPrettyChars()); | |
1164 s = s2; | |
1165 } | |
1166 } | |
1167 if (!s) | |
1168 { | |
1169 error("template '%s' is not defined", id.toChars()); | |
1170 return null; | |
1171 } | |
1172 } | |
1173 | |
1030 version (LOG) { | 1174 version (LOG) { |
1031 printf("It's an instance of '%s' kind '%s'\n", s.toChars(), s.kind()); | 1175 printf("It's an instance of '%s' kind '%s'\n", s.toChars(), s.kind()); |
1032 if (s.parent) | 1176 if (s.parent) |
1033 printf("s.parent = '%s'\n", s.parent.toChars()); | 1177 printf("s.parent = '%s'\n", s.parent.toChars()); |
1034 } | 1178 } |