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 }